diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..bb11c0b
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,22 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+trim_trailing_whitespace = true
+insert_final_newline = false
+
+[*.{lua,xml,toc,luacheckrc}]
+indent_style = tab
+tab_width = 4
+
+[*.{lua,xml,toc}]
+insert_final_newline = true
+
+[*/Libs/**.{lua,xml,toc}]
+trim_trailing_whitespace = false
+insert_final_newline = none
+
+[*.{md,yml,gitattributes,gitignore}]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..53b97f3
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,38 @@
+.github export-ignore
+.gitattributes export-ignore
+.gitignore export-ignore
+.luacheckrc export-ignore
+.travis.yml export-ignore
+.editorconfig export-ignore
+README.md export-ignore
+CHANGELOG.md export-ignore
+CITATION.cff export-ignore
+
+* text=auto
+*.gitattributes text eol=lf
+*.lua text eol=lf
+*.toc text eol=lf
+*.xml text eol=lf
+*.md text eol=lf
+
+# GitHub
+.github text
+.gitattributes text
+*.md text
+
+# Source files
+*.lua text
+*.xml text
+*.toc text
+
+# Fonts
+*.ttf binary
+
+# Sounds
+*.ogg binary
+*.mp3 binary
+*.wav binary
+
+# Textures
+*.blp binary
+*.tga binary
\ No newline at end of file
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..1e58df2
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,5 @@
+# These are supported funding model platforms
+
+ko_fi: bkader
+liberapay: bkader
+custom: https://www.buymeacoffee.com/bkader
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..efbffde
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,87 @@
+name: "🪲 Bug Report"
+description: Create a report to help us improve this project
+title: "[Bug]: "
+labels: ["type: bug"]
+assignees:
+ - bkader
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Please search for existing issues before creating a new one.
+
+ - type: checkboxes
+ attributes:
+ label: Are you using the latest version of the addon?
+ options:
+ - label: "Yes"
+ - label: "No"
+ validations:
+ required: true
+
+ - type: input
+ attributes:
+ label: Addon Version
+ description: "`/skada version` to check your current version (including the date and time)."
+ placeholder: "Version: 1.8.84 - Date: 2023-02-21 @ 22:03 UTC"
+ validations:
+ required: true
+
+ - type: checkboxes
+ attributes:
+ label: Did you try having only this addon enabled?
+ options:
+ - label: "Yes"
+ - label: "No"
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Current Behavior
+ description: A concise description of what you're experiencing.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Expected Behavior
+ description: What did you expect to happen?
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Lua Error
+ description: "Paste your LUA error if you have any (enable error reporting: `/console scriptErrors 1`)"
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Reproduction Steps
+ description: Please list out the steps to reproduce your bug.
+ placeholder: |
+ 1. Go to...
+ 2. With this config...
+ 3. Click on '...'
+ 4. See error...
+ validations:
+ required: true
+
+ - type: input
+ attributes:
+ label: Last Good Version
+ description: |
+ Was it working in a previous version? If yes, which update did it stop working? If you don't know, when was the last date you were aware it was working
+ placeholder: "MM/DD/YYYY"
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Screenshots
+ description: If applicable, add screenshots to help explain your problem.
+ placeholder: Click here to attach your screenshots via the editor button in the top right.
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..678ea2b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,14 @@
+blank_issues_enabled: false
+contact_links:
+ - name: Discord
+ url: https://discord.gg/a8z5CyS3eW
+ about: "Github issues are ONLY for bug reports and feature requests. Check #skada-faq and #skada-support channels on Discord before creating a new issue."
+ - name: Wrath of the Lich King (3.3.5)
+ url: https://github.com/bkader/Skada-WoTLK/issues/new/choose
+ about: Private Servers
+ - name: Cataclysm (4.x.x)
+ url: https://github.com/bkader/Skada-Cata/issues/new/choose
+ about: Private Servers
+ - name: Dragonflight and Classic Wrath
+ url: https://github.com/bkader/Skada-Damage-Meter/issues/new/choose
+ about: Retail
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..bf352b9
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,39 @@
+name: "✨ Feature Request"
+description: "Suggest an idea for this project"
+title: "[Request]: "
+labels: ["type: feature request"]
+assignees:
+ - bkader
+body:
+ - type: textarea
+ attributes:
+ label: Is your feature request related to a problem? Please describe.
+ description: A clear and concise description of what the problem is.
+ placeholder: The addon is not [...]
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Desired Solution
+ description: Describe the solution you'd like
+ placeholder: The addon should [...]
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Describe alternatives you've considered
+ description: A clear and concise description of any alternative solutions or features you've considered or seen elsewhere
+ placeholder: I saw the addon X doing Y [...]
+ validations:
+ required: false
+
+ - type: textarea
+ attributes:
+ label: Anything else?
+ description: |
+ Links? References? Streams? Anything that will give us more context about the issue you are encountering!
+ Tip: You can attach images or video files by clicking this area to highlight it and then dragging files in.
+ validations:
+ required: false
\ No newline at end of file
diff --git a/.github/workflows/lint-pr.yml b/.github/workflows/lint-pr.yml
new file mode 100644
index 0000000..ef401cf
--- /dev/null
+++ b/.github/workflows/lint-pr.yml
@@ -0,0 +1,62 @@
+name: lint
+
+on:
+ pull_request:
+ paths:
+ - "**.lua"
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ env:
+ LUA_VERSION: 5.1.5
+ LUAROCKS_VERSION: 2.4.2
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Cache Lua
+ uses: actions/cache@v1
+ id: luacache
+ with:
+ path: .lua
+ key: ${{ runner.os }}-lua-${{ env.LUA_VERSION }}
+ restore-keys: |
+ ${{ runner.os }}-lua-${{ env.LUA_VERSION }}
+
+ - name: Cache LuaRocks
+ uses: actions/cache@v1
+ id: luarockscache
+ with:
+ path: .luarocks
+ key: ${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
+ restore-keys: |
+ ${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
+
+ - name: Install Lua
+ if: steps.luacache.outputs.cache-hit != 'true'
+ run: |
+ sudo apt-get install libreadline-dev libncurses-dev
+ wget https://www.lua.org/ftp/lua-${{ env.LUA_VERSION }}.tar.gz -O - | tar -xzf -
+ cd lua-${{ env.LUA_VERSION }}
+ make linux
+ make -j INSTALL_TOP=$GITHUB_WORKSPACE/.lua install
+ rm -rf $GITHUB_WORKSPACE/lua-${{ env.LUA_VERSION }}
+
+ - name: Install LuaRocks and Luacheck
+ if: steps.luarockscache.outputs.cache-hit != 'true'
+ run: |
+ wget https://luarocks.org/releases/luarocks-${{ env.LUAROCKS_VERSION }}.tar.gz -O - | tar -xzf -
+ cd luarocks-${{ env.LUAROCKS_VERSION }}
+ ./configure --with-lua-bin=$GITHUB_WORKSPACE/.lua/bin --prefix=$GITHUB_WORKSPACE/.luarocks
+ make build
+ make install
+ PATH=$PATH:$GITHUB_WORKSPACE/.luarocks/bin
+ luarocks install luacheck
+ luarocks install lanes
+ rm -rf $GITHUB_WORKSPACE/luarocks-${{ env.LUAROCKS_VERSION }}
+
+ - name: Luacheck
+ run: .luarocks/bin/luacheck . -q
\ No newline at end of file
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
new file mode 100644
index 0000000..dc55a38
--- /dev/null
+++ b/.github/workflows/lint.yml
@@ -0,0 +1,62 @@
+name: lint
+
+on:
+ push:
+ paths:
+ - ".github/workflows/**.yml"
+ - "**.lua"
+
+jobs:
+ lint:
+ runs-on: ubuntu-latest
+
+ env:
+ LUA_VERSION: 5.1.5
+ LUAROCKS_VERSION: 2.4.2
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Cache Lua
+ uses: actions/cache@v2
+ id: luacache
+ with:
+ path: .lua
+ key: ${{ runner.os }}-lua-${{ env.LUA_VERSION }}
+ restore-keys: |
+ ${{ runner.os }}-lua-${{ env.LUA_VERSION }}
+
+ - name: Cache LuaRocks
+ uses: actions/cache@v2
+ id: luarockscache
+ with:
+ path: .luarocks
+ key: ${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
+ restore-keys: ${{ runner.os }}-luarocks-${{ env.LUAROCKS_VERSION }}
+
+ - name: Install Lua
+ if: steps.luacache.outputs.cache-hit != 'true'
+ run: |
+ sudo apt-get install libreadline-dev libncurses-dev
+ wget https://www.lua.org/ftp/lua-${{ env.LUA_VERSION }}.tar.gz -O - | tar -xzf -
+ cd lua-${{ env.LUA_VERSION }}
+ make linux
+ make -j INSTALL_TOP=$GITHUB_WORKSPACE/.lua install
+ rm -rf $GITHUB_WORKSPACE/lua-${{ env.LUA_VERSION }}
+
+ - name: Install LuaRocks and Luacheck
+ if: steps.luarockscache.outputs.cache-hit != 'true'
+ run: |
+ wget https://luarocks.org/releases/luarocks-${{ env.LUAROCKS_VERSION }}.tar.gz -O - | tar -xzf -
+ cd luarocks-${{ env.LUAROCKS_VERSION }}
+ ./configure --with-lua-bin=$GITHUB_WORKSPACE/.lua/bin --prefix=$GITHUB_WORKSPACE/.luarocks
+ make build
+ make install
+ PATH=$PATH:$GITHUB_WORKSPACE/.luarocks/bin
+ luarocks install luacheck
+ luarocks install lanes
+ rm -rf $GITHUB_WORKSPACE/luarocks-${{ env.LUAROCKS_VERSION }}
+
+ - name: Luacheck
+ run: .luarocks/bin/luacheck . -q
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..6eca31d
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+_dev
+Makefile
+*_bak*.*
+*.zip
+*.7z
+*.sublime-project
+*.sublime-workspace
+*.todolist
\ No newline at end of file
diff --git a/.luacheckrc b/.luacheckrc
new file mode 100644
index 0000000..922682c
--- /dev/null
+++ b/.luacheckrc
@@ -0,0 +1,33690 @@
+std = "lua51c"
+codes = true
+ranges = true
+quiet = 1
+
+cache = false
+
+max_line_length = false
+max_code_line_length = false
+max_string_line_length = false
+max_comment_line_length = false
+
+allow_defined = true
+
+exclude_files = {
+ "./.git",
+ "./.github",
+ "./.lua",
+ "./.luarocks",
+ "**/Libs/**/*.lua",
+ "**/Libs/**/**/*.lua",
+ ".luacheckrc",
+ "ElvUI_AddOnSkins/*",
+ "_dev/*",
+}
+
+ignore = {
+ "11./BINDING_.*", -- Setting an undefined (Keybinding header) global variable
+ "11./SLASH_.*", -- Setting an undefined (Slash handler) global variable
+ "111/[A-Z][A-Z0-9_]+", -- Setting an undefined global variable
+ "113/LE_.*", -- accessing undefined variable 'LE_XX'
+ "113/L_.*", -- accessing undefined variable 'L_XX'
+ "113/COMBATLOG_OBJECT_.*", -- accessing undefined variable 'COMBATLOG_OBJECT_XX'
+ "113/NUM_LE_.*", -- accessing undefined variable (Lua ENUM type) global variable
+ "131/[A-Z][A-Z0-9_]+", -- Unused implicitly defined global variable (GlobalStrings and Constants 2char+)
+ "211", -- Unused local variable
+ "211/CL", -- Unused local variable "CL"
+ "211/L", -- Unused local variable "L"
+ "212", -- Unused argument
+ "213", -- Unused loop variable
+ "214", -- Used variable
+ "231/_.*", -- unused variables starting with _
+ "311", -- Value assigned to a local variable is unused
+ "312/self", -- Value assigned is overwritten
+ "314", -- Value of a field in a table literal is unused
+ "43.", -- Shadowing an upvalue, an upvalue argument, an upvalue loop variable.
+ "512", -- loop is executed at most once
+ "542", -- An empty if branch
+ "581", -- Negation of a relational operator- operator can be flipped
+ "582", -- Error prone negation: negation has a higher priority than equality
+}
+
+globals = {
+ "ACHIEVEMENTFRAME_SUBFRAMES",
+ "ACHIEVEMENTUI_CATEGORIES",
+ "ACHIEVEMENTUI_DEFAULTSUMMARYACHIEVEMENTS",
+ "ACHIEVEMENTUI_SELECTEDFILTER",
+ "ACHIEVEMENT_TEXTURES_TO_LOAD",
+ "ADDED_PLAYERS",
+ "AUTOCAST_SHINE_SPEEDS",
+ "AUTOCAST_SHINE_TIMERS",
+ "AUTOCOMPLETE_LIST",
+ "AUTOCOMPLETE_LIST_TEMPLATES",
+ "AbandonQuest",
+ "AbandonSkill",
+ "AcceptAreaSpiritHeal",
+ "AcceptArenaTeam",
+ "AcceptBattlefieldPort",
+ "AcceptDuel",
+ "AcceptGroup",
+ "AcceptGuild",
+ "AcceptLevelGrant",
+ "AcceptProposal",
+ "AcceptQuest",
+ "AcceptResurrect",
+ "AcceptSkillUps",
+ "AcceptSockets",
+ "AcceptTrade",
+ "AcceptXPLoss",
+ "AceGUIWidgetLSMlists",
+ "AchievementAlertFrame_FixAnchors",
+ "AchievementAlertFrame_GetAlertFrame",
+ "AchievementAlertFrame_OnClick",
+ "AchievementAlertFrame_OnHide",
+ "AchievementAlertFrame_OnLoad",
+ "AchievementAlertFrame_ShowAlert",
+ "AchievementButton_Collapse",
+ "AchievementButton_Desaturate",
+ "AchievementButton_DisplayAchievement",
+ "AchievementButton_DisplayObjectives",
+ "AchievementButton_Expand",
+ "AchievementButton_GetCriteria",
+ "AchievementButton_GetMeta",
+ "AchievementButton_GetMiniAchievement",
+ "AchievementButton_GetProgressBar",
+ "AchievementButton_GetProgressivePoints",
+ "AchievementButton_LocalizeMetaAchievement",
+ "AchievementButton_LocalizeMiniAchievement",
+ "AchievementButton_LocalizeProgressBar",
+ "AchievementButton_OnClick",
+ "AchievementButton_OnLoad",
+ "AchievementButton_ResetCriteria",
+ "AchievementButton_ResetMetas",
+ "AchievementButton_ResetMiniAchievements",
+ "AchievementButton_ResetObjectives",
+ "AchievementButton_ResetProgressBars",
+ "AchievementButton_ResetTable",
+ "AchievementButton_Saturate",
+ "AchievementButton_ToggleTracking",
+ "AchievementButton_UpdatePlusMinusTexture",
+ "AchievementCategoryButton_OnClick",
+ "AchievementCategoryButton_OnLoad",
+ "AchievementComparisonFriendButton_Desaturate",
+ "AchievementComparisonFriendButton_OnLoad",
+ "AchievementComparisonFriendButton_Saturate",
+ "AchievementComparisonPlayerButton_Desaturate",
+ "AchievementComparisonPlayerButton_OnLoad",
+ "AchievementComparisonPlayerButton_Saturate",
+ "AchievementCriteriaFont",
+ "AchievementDateFont",
+ "AchievementDescriptionFont",
+ "AchievementFont_Small",
+ "AchievementFrame",
+ "AchievementFrameAchievements",
+ "AchievementFrameAchievementsBackdrop_OnLoad",
+ "AchievementFrameAchievementsBackground",
+ "AchievementFrameAchievementsContainer",
+ "AchievementFrameAchievementsContainerButton1",
+ "AchievementFrameAchievementsContainerButton1Background",
+ "AchievementFrameAchievementsContainerButton1BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton1BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton1BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton1Check",
+ "AchievementFrameAchievementsContainerButton1DateCompleted",
+ "AchievementFrameAchievementsContainerButton1Description",
+ "AchievementFrameAchievementsContainerButton1Glow",
+ "AchievementFrameAchievementsContainerButton1HiddenDescription",
+ "AchievementFrameAchievementsContainerButton1Highlight",
+ "AchievementFrameAchievementsContainerButton1HighlightBottom",
+ "AchievementFrameAchievementsContainerButton1HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton1HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton1HighlightLeft",
+ "AchievementFrameAchievementsContainerButton1HighlightRight",
+ "AchievementFrameAchievementsContainerButton1HighlightTop",
+ "AchievementFrameAchievementsContainerButton1HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton1HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton1Icon",
+ "AchievementFrameAchievementsContainerButton1IconBackfill",
+ "AchievementFrameAchievementsContainerButton1IconBling",
+ "AchievementFrameAchievementsContainerButton1IconOverlay",
+ "AchievementFrameAchievementsContainerButton1IconTexture",
+ "AchievementFrameAchievementsContainerButton1Label",
+ "AchievementFrameAchievementsContainerButton1Objectives",
+ "AchievementFrameAchievementsContainerButton1PlusMinus",
+ "AchievementFrameAchievementsContainerButton1Reward",
+ "AchievementFrameAchievementsContainerButton1RewardBackground",
+ "AchievementFrameAchievementsContainerButton1Shield",
+ "AchievementFrameAchievementsContainerButton1ShieldIcon",
+ "AchievementFrameAchievementsContainerButton1ShieldPoints",
+ "AchievementFrameAchievementsContainerButton1TitleBackground",
+ "AchievementFrameAchievementsContainerButton1TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton1TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton1TopTsunami1",
+ "AchievementFrameAchievementsContainerButton1Tracked",
+ "AchievementFrameAchievementsContainerButton1TrackedText",
+ "AchievementFrameAchievementsContainerButton2",
+ "AchievementFrameAchievementsContainerButton2Background",
+ "AchievementFrameAchievementsContainerButton2BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton2BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton2BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton2Check",
+ "AchievementFrameAchievementsContainerButton2DateCompleted",
+ "AchievementFrameAchievementsContainerButton2Description",
+ "AchievementFrameAchievementsContainerButton2Glow",
+ "AchievementFrameAchievementsContainerButton2HiddenDescription",
+ "AchievementFrameAchievementsContainerButton2Highlight",
+ "AchievementFrameAchievementsContainerButton2HighlightBottom",
+ "AchievementFrameAchievementsContainerButton2HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton2HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton2HighlightLeft",
+ "AchievementFrameAchievementsContainerButton2HighlightRight",
+ "AchievementFrameAchievementsContainerButton2HighlightTop",
+ "AchievementFrameAchievementsContainerButton2HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton2HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton2Icon",
+ "AchievementFrameAchievementsContainerButton2IconBackfill",
+ "AchievementFrameAchievementsContainerButton2IconBling",
+ "AchievementFrameAchievementsContainerButton2IconOverlay",
+ "AchievementFrameAchievementsContainerButton2IconTexture",
+ "AchievementFrameAchievementsContainerButton2Label",
+ "AchievementFrameAchievementsContainerButton2Objectives",
+ "AchievementFrameAchievementsContainerButton2PlusMinus",
+ "AchievementFrameAchievementsContainerButton2Reward",
+ "AchievementFrameAchievementsContainerButton2RewardBackground",
+ "AchievementFrameAchievementsContainerButton2Shield",
+ "AchievementFrameAchievementsContainerButton2ShieldIcon",
+ "AchievementFrameAchievementsContainerButton2ShieldPoints",
+ "AchievementFrameAchievementsContainerButton2TitleBackground",
+ "AchievementFrameAchievementsContainerButton2TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton2TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton2TopTsunami1",
+ "AchievementFrameAchievementsContainerButton2Tracked",
+ "AchievementFrameAchievementsContainerButton2TrackedText",
+ "AchievementFrameAchievementsContainerButton3",
+ "AchievementFrameAchievementsContainerButton3Background",
+ "AchievementFrameAchievementsContainerButton3BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton3BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton3BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton3Check",
+ "AchievementFrameAchievementsContainerButton3DateCompleted",
+ "AchievementFrameAchievementsContainerButton3Description",
+ "AchievementFrameAchievementsContainerButton3Glow",
+ "AchievementFrameAchievementsContainerButton3HiddenDescription",
+ "AchievementFrameAchievementsContainerButton3Highlight",
+ "AchievementFrameAchievementsContainerButton3HighlightBottom",
+ "AchievementFrameAchievementsContainerButton3HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton3HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton3HighlightLeft",
+ "AchievementFrameAchievementsContainerButton3HighlightRight",
+ "AchievementFrameAchievementsContainerButton3HighlightTop",
+ "AchievementFrameAchievementsContainerButton3HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton3HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton3Icon",
+ "AchievementFrameAchievementsContainerButton3IconBackfill",
+ "AchievementFrameAchievementsContainerButton3IconBling",
+ "AchievementFrameAchievementsContainerButton3IconOverlay",
+ "AchievementFrameAchievementsContainerButton3IconTexture",
+ "AchievementFrameAchievementsContainerButton3Label",
+ "AchievementFrameAchievementsContainerButton3Objectives",
+ "AchievementFrameAchievementsContainerButton3PlusMinus",
+ "AchievementFrameAchievementsContainerButton3Reward",
+ "AchievementFrameAchievementsContainerButton3RewardBackground",
+ "AchievementFrameAchievementsContainerButton3Shield",
+ "AchievementFrameAchievementsContainerButton3ShieldIcon",
+ "AchievementFrameAchievementsContainerButton3ShieldPoints",
+ "AchievementFrameAchievementsContainerButton3TitleBackground",
+ "AchievementFrameAchievementsContainerButton3TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton3TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton3TopTsunami1",
+ "AchievementFrameAchievementsContainerButton3Tracked",
+ "AchievementFrameAchievementsContainerButton3TrackedText",
+ "AchievementFrameAchievementsContainerButton4",
+ "AchievementFrameAchievementsContainerButton4Background",
+ "AchievementFrameAchievementsContainerButton4BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton4BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton4BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton4Check",
+ "AchievementFrameAchievementsContainerButton4DateCompleted",
+ "AchievementFrameAchievementsContainerButton4Description",
+ "AchievementFrameAchievementsContainerButton4Glow",
+ "AchievementFrameAchievementsContainerButton4HiddenDescription",
+ "AchievementFrameAchievementsContainerButton4Highlight",
+ "AchievementFrameAchievementsContainerButton4HighlightBottom",
+ "AchievementFrameAchievementsContainerButton4HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton4HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton4HighlightLeft",
+ "AchievementFrameAchievementsContainerButton4HighlightRight",
+ "AchievementFrameAchievementsContainerButton4HighlightTop",
+ "AchievementFrameAchievementsContainerButton4HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton4HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton4Icon",
+ "AchievementFrameAchievementsContainerButton4IconBackfill",
+ "AchievementFrameAchievementsContainerButton4IconBling",
+ "AchievementFrameAchievementsContainerButton4IconOverlay",
+ "AchievementFrameAchievementsContainerButton4IconTexture",
+ "AchievementFrameAchievementsContainerButton4Label",
+ "AchievementFrameAchievementsContainerButton4Objectives",
+ "AchievementFrameAchievementsContainerButton4PlusMinus",
+ "AchievementFrameAchievementsContainerButton4Reward",
+ "AchievementFrameAchievementsContainerButton4RewardBackground",
+ "AchievementFrameAchievementsContainerButton4Shield",
+ "AchievementFrameAchievementsContainerButton4ShieldIcon",
+ "AchievementFrameAchievementsContainerButton4ShieldPoints",
+ "AchievementFrameAchievementsContainerButton4TitleBackground",
+ "AchievementFrameAchievementsContainerButton4TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton4TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton4TopTsunami1",
+ "AchievementFrameAchievementsContainerButton4Tracked",
+ "AchievementFrameAchievementsContainerButton4TrackedText",
+ "AchievementFrameAchievementsContainerButton5",
+ "AchievementFrameAchievementsContainerButton5Background",
+ "AchievementFrameAchievementsContainerButton5BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton5BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton5BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton5Check",
+ "AchievementFrameAchievementsContainerButton5DateCompleted",
+ "AchievementFrameAchievementsContainerButton5Description",
+ "AchievementFrameAchievementsContainerButton5Glow",
+ "AchievementFrameAchievementsContainerButton5HiddenDescription",
+ "AchievementFrameAchievementsContainerButton5Highlight",
+ "AchievementFrameAchievementsContainerButton5HighlightBottom",
+ "AchievementFrameAchievementsContainerButton5HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton5HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton5HighlightLeft",
+ "AchievementFrameAchievementsContainerButton5HighlightRight",
+ "AchievementFrameAchievementsContainerButton5HighlightTop",
+ "AchievementFrameAchievementsContainerButton5HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton5HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton5Icon",
+ "AchievementFrameAchievementsContainerButton5IconBackfill",
+ "AchievementFrameAchievementsContainerButton5IconBling",
+ "AchievementFrameAchievementsContainerButton5IconOverlay",
+ "AchievementFrameAchievementsContainerButton5IconTexture",
+ "AchievementFrameAchievementsContainerButton5Label",
+ "AchievementFrameAchievementsContainerButton5Objectives",
+ "AchievementFrameAchievementsContainerButton5PlusMinus",
+ "AchievementFrameAchievementsContainerButton5Reward",
+ "AchievementFrameAchievementsContainerButton5RewardBackground",
+ "AchievementFrameAchievementsContainerButton5Shield",
+ "AchievementFrameAchievementsContainerButton5ShieldIcon",
+ "AchievementFrameAchievementsContainerButton5ShieldPoints",
+ "AchievementFrameAchievementsContainerButton5TitleBackground",
+ "AchievementFrameAchievementsContainerButton5TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton5TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton5TopTsunami1",
+ "AchievementFrameAchievementsContainerButton5Tracked",
+ "AchievementFrameAchievementsContainerButton5TrackedText",
+ "AchievementFrameAchievementsContainerButton6",
+ "AchievementFrameAchievementsContainerButton6Background",
+ "AchievementFrameAchievementsContainerButton6BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton6BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton6BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton6Check",
+ "AchievementFrameAchievementsContainerButton6DateCompleted",
+ "AchievementFrameAchievementsContainerButton6Description",
+ "AchievementFrameAchievementsContainerButton6Glow",
+ "AchievementFrameAchievementsContainerButton6HiddenDescription",
+ "AchievementFrameAchievementsContainerButton6Highlight",
+ "AchievementFrameAchievementsContainerButton6HighlightBottom",
+ "AchievementFrameAchievementsContainerButton6HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton6HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton6HighlightLeft",
+ "AchievementFrameAchievementsContainerButton6HighlightRight",
+ "AchievementFrameAchievementsContainerButton6HighlightTop",
+ "AchievementFrameAchievementsContainerButton6HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton6HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton6Icon",
+ "AchievementFrameAchievementsContainerButton6IconBackfill",
+ "AchievementFrameAchievementsContainerButton6IconBling",
+ "AchievementFrameAchievementsContainerButton6IconOverlay",
+ "AchievementFrameAchievementsContainerButton6IconTexture",
+ "AchievementFrameAchievementsContainerButton6Label",
+ "AchievementFrameAchievementsContainerButton6Objectives",
+ "AchievementFrameAchievementsContainerButton6PlusMinus",
+ "AchievementFrameAchievementsContainerButton6Reward",
+ "AchievementFrameAchievementsContainerButton6RewardBackground",
+ "AchievementFrameAchievementsContainerButton6Shield",
+ "AchievementFrameAchievementsContainerButton6ShieldIcon",
+ "AchievementFrameAchievementsContainerButton6ShieldPoints",
+ "AchievementFrameAchievementsContainerButton6TitleBackground",
+ "AchievementFrameAchievementsContainerButton6TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton6TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton6TopTsunami1",
+ "AchievementFrameAchievementsContainerButton6Tracked",
+ "AchievementFrameAchievementsContainerButton6TrackedText",
+ "AchievementFrameAchievementsContainerButton7",
+ "AchievementFrameAchievementsContainerButton7Background",
+ "AchievementFrameAchievementsContainerButton7BottomLeftTsunami",
+ "AchievementFrameAchievementsContainerButton7BottomRightTsunami",
+ "AchievementFrameAchievementsContainerButton7BottomTsunami1",
+ "AchievementFrameAchievementsContainerButton7Check",
+ "AchievementFrameAchievementsContainerButton7DateCompleted",
+ "AchievementFrameAchievementsContainerButton7Description",
+ "AchievementFrameAchievementsContainerButton7Glow",
+ "AchievementFrameAchievementsContainerButton7HiddenDescription",
+ "AchievementFrameAchievementsContainerButton7Highlight",
+ "AchievementFrameAchievementsContainerButton7HighlightBottom",
+ "AchievementFrameAchievementsContainerButton7HighlightBottomLeft",
+ "AchievementFrameAchievementsContainerButton7HighlightBottomRight",
+ "AchievementFrameAchievementsContainerButton7HighlightLeft",
+ "AchievementFrameAchievementsContainerButton7HighlightRight",
+ "AchievementFrameAchievementsContainerButton7HighlightTop",
+ "AchievementFrameAchievementsContainerButton7HighlightTopLeft",
+ "AchievementFrameAchievementsContainerButton7HighlightTopRight",
+ "AchievementFrameAchievementsContainerButton7Icon",
+ "AchievementFrameAchievementsContainerButton7IconBackfill",
+ "AchievementFrameAchievementsContainerButton7IconBling",
+ "AchievementFrameAchievementsContainerButton7IconOverlay",
+ "AchievementFrameAchievementsContainerButton7IconTexture",
+ "AchievementFrameAchievementsContainerButton7Label",
+ "AchievementFrameAchievementsContainerButton7Objectives",
+ "AchievementFrameAchievementsContainerButton7PlusMinus",
+ "AchievementFrameAchievementsContainerButton7Reward",
+ "AchievementFrameAchievementsContainerButton7RewardBackground",
+ "AchievementFrameAchievementsContainerButton7Shield",
+ "AchievementFrameAchievementsContainerButton7ShieldIcon",
+ "AchievementFrameAchievementsContainerButton7ShieldPoints",
+ "AchievementFrameAchievementsContainerButton7TitleBackground",
+ "AchievementFrameAchievementsContainerButton7TopLeftTsunami",
+ "AchievementFrameAchievementsContainerButton7TopRightTsunami",
+ "AchievementFrameAchievementsContainerButton7TopTsunami1",
+ "AchievementFrameAchievementsContainerButton7Tracked",
+ "AchievementFrameAchievementsContainerButton7TrackedText",
+ "AchievementFrameAchievementsContainerScrollBar",
+ "AchievementFrameAchievementsContainerScrollBarBG",
+ "AchievementFrameAchievementsContainerScrollBarBottom",
+ "AchievementFrameAchievementsContainerScrollBarMiddle",
+ "AchievementFrameAchievementsContainerScrollBarScrollDownButton",
+ "AchievementFrameAchievementsContainerScrollBarScrollUpButton",
+ "AchievementFrameAchievementsContainerScrollBarThumbTexture",
+ "AchievementFrameAchievementsContainerScrollBarTop",
+ "AchievementFrameAchievementsContainerScrollChild",
+ "AchievementFrameAchievementsFeatOfStrengthText",
+ "AchievementFrameAchievementsObjectives",
+ "AchievementFrameAchievements_AdjustSelection",
+ "AchievementFrameAchievements_ClearSelection",
+ "AchievementFrameAchievements_FindSelection",
+ "AchievementFrameAchievements_ForceUpdate",
+ "AchievementFrameAchievements_OnEvent",
+ "AchievementFrameAchievements_OnLoad",
+ "AchievementFrameAchievements_OnShow",
+ "AchievementFrameAchievements_SelectButton",
+ "AchievementFrameAchievements_Update",
+ "AchievementFrameBackground",
+ "AchievementFrameBaseTab_OnClick",
+ "AchievementFrameCategories",
+ "AchievementFrameCategoriesBG",
+ "AchievementFrameCategoriesContainer",
+ "AchievementFrameCategoriesContainerButton1",
+ "AchievementFrameCategoriesContainerButton10",
+ "AchievementFrameCategoriesContainerButton10Background",
+ "AchievementFrameCategoriesContainerButton10Label",
+ "AchievementFrameCategoriesContainerButton11",
+ "AchievementFrameCategoriesContainerButton11Background",
+ "AchievementFrameCategoriesContainerButton11Label",
+ "AchievementFrameCategoriesContainerButton12",
+ "AchievementFrameCategoriesContainerButton12Background",
+ "AchievementFrameCategoriesContainerButton12Label",
+ "AchievementFrameCategoriesContainerButton13",
+ "AchievementFrameCategoriesContainerButton13Background",
+ "AchievementFrameCategoriesContainerButton13Label",
+ "AchievementFrameCategoriesContainerButton14",
+ "AchievementFrameCategoriesContainerButton14Background",
+ "AchievementFrameCategoriesContainerButton14Label",
+ "AchievementFrameCategoriesContainerButton15",
+ "AchievementFrameCategoriesContainerButton15Background",
+ "AchievementFrameCategoriesContainerButton15Label",
+ "AchievementFrameCategoriesContainerButton16",
+ "AchievementFrameCategoriesContainerButton16Background",
+ "AchievementFrameCategoriesContainerButton16Label",
+ "AchievementFrameCategoriesContainerButton17",
+ "AchievementFrameCategoriesContainerButton17Background",
+ "AchievementFrameCategoriesContainerButton17Label",
+ "AchievementFrameCategoriesContainerButton18",
+ "AchievementFrameCategoriesContainerButton18Background",
+ "AchievementFrameCategoriesContainerButton18Label",
+ "AchievementFrameCategoriesContainerButton19",
+ "AchievementFrameCategoriesContainerButton19Background",
+ "AchievementFrameCategoriesContainerButton19Label",
+ "AchievementFrameCategoriesContainerButton1Background",
+ "AchievementFrameCategoriesContainerButton1Label",
+ "AchievementFrameCategoriesContainerButton2",
+ "AchievementFrameCategoriesContainerButton20",
+ "AchievementFrameCategoriesContainerButton20Background",
+ "AchievementFrameCategoriesContainerButton20Label",
+ "AchievementFrameCategoriesContainerButton2Background",
+ "AchievementFrameCategoriesContainerButton2Label",
+ "AchievementFrameCategoriesContainerButton3",
+ "AchievementFrameCategoriesContainerButton3Background",
+ "AchievementFrameCategoriesContainerButton3Label",
+ "AchievementFrameCategoriesContainerButton4",
+ "AchievementFrameCategoriesContainerButton4Background",
+ "AchievementFrameCategoriesContainerButton4Label",
+ "AchievementFrameCategoriesContainerButton5",
+ "AchievementFrameCategoriesContainerButton5Background",
+ "AchievementFrameCategoriesContainerButton5Label",
+ "AchievementFrameCategoriesContainerButton6",
+ "AchievementFrameCategoriesContainerButton6Background",
+ "AchievementFrameCategoriesContainerButton6Label",
+ "AchievementFrameCategoriesContainerButton7",
+ "AchievementFrameCategoriesContainerButton7Background",
+ "AchievementFrameCategoriesContainerButton7Label",
+ "AchievementFrameCategoriesContainerButton8",
+ "AchievementFrameCategoriesContainerButton8Background",
+ "AchievementFrameCategoriesContainerButton8Label",
+ "AchievementFrameCategoriesContainerButton9",
+ "AchievementFrameCategoriesContainerButton9Background",
+ "AchievementFrameCategoriesContainerButton9Label",
+ "AchievementFrameCategoriesContainerScrollBar",
+ "AchievementFrameCategoriesContainerScrollBarBG",
+ "AchievementFrameCategoriesContainerScrollBarBottom",
+ "AchievementFrameCategoriesContainerScrollBarMiddle",
+ "AchievementFrameCategoriesContainerScrollBarScrollDownButton",
+ "AchievementFrameCategoriesContainerScrollBarScrollUpButton",
+ "AchievementFrameCategoriesContainerScrollBarThumbTexture",
+ "AchievementFrameCategoriesContainerScrollBarTop",
+ "AchievementFrameCategoriesContainerScrollChild",
+ "AchievementFrameCategories_ClearSelection",
+ "AchievementFrameCategories_DisplayButton",
+ "AchievementFrameCategories_GetCategoryList",
+ "AchievementFrameCategories_OnEvent",
+ "AchievementFrameCategories_OnLoad",
+ "AchievementFrameCategories_OnShow",
+ "AchievementFrameCategories_SelectButton",
+ "AchievementFrameCategories_Update",
+ "AchievementFrameCategories_UpdateTooltip",
+ "AchievementFrameCategory_FeatOfStrengthTooltip",
+ "AchievementFrameCategory_StatusBarTooltip",
+ "AchievementFrameCloseButton",
+ "AchievementFrameComparison",
+ "AchievementFrameComparisonBackground",
+ "AchievementFrameComparisonContainer",
+ "AchievementFrameComparisonContainerButton1",
+ "AchievementFrameComparisonContainerButton10",
+ "AchievementFrameComparisonContainerButton10Friend",
+ "AchievementFrameComparisonContainerButton10FriendBackground",
+ "AchievementFrameComparisonContainerButton10FriendGlow",
+ "AchievementFrameComparisonContainerButton10FriendIcon",
+ "AchievementFrameComparisonContainerButton10FriendIconBling",
+ "AchievementFrameComparisonContainerButton10FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton10FriendIconTexture",
+ "AchievementFrameComparisonContainerButton10FriendShield",
+ "AchievementFrameComparisonContainerButton10FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton10FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton10FriendStatus",
+ "AchievementFrameComparisonContainerButton10FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton10Player",
+ "AchievementFrameComparisonContainerButton10PlayerBackground",
+ "AchievementFrameComparisonContainerButton10PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton10PlayerDescription",
+ "AchievementFrameComparisonContainerButton10PlayerGlow",
+ "AchievementFrameComparisonContainerButton10PlayerIcon",
+ "AchievementFrameComparisonContainerButton10PlayerIconBling",
+ "AchievementFrameComparisonContainerButton10PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton10PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton10PlayerLabel",
+ "AchievementFrameComparisonContainerButton10PlayerShield",
+ "AchievementFrameComparisonContainerButton10PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton10PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton10PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton1Friend",
+ "AchievementFrameComparisonContainerButton1FriendBackground",
+ "AchievementFrameComparisonContainerButton1FriendGlow",
+ "AchievementFrameComparisonContainerButton1FriendIcon",
+ "AchievementFrameComparisonContainerButton1FriendIconBling",
+ "AchievementFrameComparisonContainerButton1FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton1FriendIconTexture",
+ "AchievementFrameComparisonContainerButton1FriendShield",
+ "AchievementFrameComparisonContainerButton1FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton1FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton1FriendStatus",
+ "AchievementFrameComparisonContainerButton1FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton1Player",
+ "AchievementFrameComparisonContainerButton1PlayerBackground",
+ "AchievementFrameComparisonContainerButton1PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton1PlayerDescription",
+ "AchievementFrameComparisonContainerButton1PlayerGlow",
+ "AchievementFrameComparisonContainerButton1PlayerIcon",
+ "AchievementFrameComparisonContainerButton1PlayerIconBling",
+ "AchievementFrameComparisonContainerButton1PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton1PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton1PlayerLabel",
+ "AchievementFrameComparisonContainerButton1PlayerShield",
+ "AchievementFrameComparisonContainerButton1PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton1PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton1PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton2",
+ "AchievementFrameComparisonContainerButton2Friend",
+ "AchievementFrameComparisonContainerButton2FriendBackground",
+ "AchievementFrameComparisonContainerButton2FriendGlow",
+ "AchievementFrameComparisonContainerButton2FriendIcon",
+ "AchievementFrameComparisonContainerButton2FriendIconBling",
+ "AchievementFrameComparisonContainerButton2FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton2FriendIconTexture",
+ "AchievementFrameComparisonContainerButton2FriendShield",
+ "AchievementFrameComparisonContainerButton2FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton2FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton2FriendStatus",
+ "AchievementFrameComparisonContainerButton2FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton2Player",
+ "AchievementFrameComparisonContainerButton2PlayerBackground",
+ "AchievementFrameComparisonContainerButton2PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton2PlayerDescription",
+ "AchievementFrameComparisonContainerButton2PlayerGlow",
+ "AchievementFrameComparisonContainerButton2PlayerIcon",
+ "AchievementFrameComparisonContainerButton2PlayerIconBling",
+ "AchievementFrameComparisonContainerButton2PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton2PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton2PlayerLabel",
+ "AchievementFrameComparisonContainerButton2PlayerShield",
+ "AchievementFrameComparisonContainerButton2PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton2PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton2PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton3",
+ "AchievementFrameComparisonContainerButton3Friend",
+ "AchievementFrameComparisonContainerButton3FriendBackground",
+ "AchievementFrameComparisonContainerButton3FriendGlow",
+ "AchievementFrameComparisonContainerButton3FriendIcon",
+ "AchievementFrameComparisonContainerButton3FriendIconBling",
+ "AchievementFrameComparisonContainerButton3FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton3FriendIconTexture",
+ "AchievementFrameComparisonContainerButton3FriendShield",
+ "AchievementFrameComparisonContainerButton3FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton3FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton3FriendStatus",
+ "AchievementFrameComparisonContainerButton3FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton3Player",
+ "AchievementFrameComparisonContainerButton3PlayerBackground",
+ "AchievementFrameComparisonContainerButton3PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton3PlayerDescription",
+ "AchievementFrameComparisonContainerButton3PlayerGlow",
+ "AchievementFrameComparisonContainerButton3PlayerIcon",
+ "AchievementFrameComparisonContainerButton3PlayerIconBling",
+ "AchievementFrameComparisonContainerButton3PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton3PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton3PlayerLabel",
+ "AchievementFrameComparisonContainerButton3PlayerShield",
+ "AchievementFrameComparisonContainerButton3PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton3PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton3PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton4",
+ "AchievementFrameComparisonContainerButton4Friend",
+ "AchievementFrameComparisonContainerButton4FriendBackground",
+ "AchievementFrameComparisonContainerButton4FriendGlow",
+ "AchievementFrameComparisonContainerButton4FriendIcon",
+ "AchievementFrameComparisonContainerButton4FriendIconBling",
+ "AchievementFrameComparisonContainerButton4FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton4FriendIconTexture",
+ "AchievementFrameComparisonContainerButton4FriendShield",
+ "AchievementFrameComparisonContainerButton4FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton4FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton4FriendStatus",
+ "AchievementFrameComparisonContainerButton4FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton4Player",
+ "AchievementFrameComparisonContainerButton4PlayerBackground",
+ "AchievementFrameComparisonContainerButton4PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton4PlayerDescription",
+ "AchievementFrameComparisonContainerButton4PlayerGlow",
+ "AchievementFrameComparisonContainerButton4PlayerIcon",
+ "AchievementFrameComparisonContainerButton4PlayerIconBling",
+ "AchievementFrameComparisonContainerButton4PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton4PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton4PlayerLabel",
+ "AchievementFrameComparisonContainerButton4PlayerShield",
+ "AchievementFrameComparisonContainerButton4PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton4PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton4PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton5",
+ "AchievementFrameComparisonContainerButton5Friend",
+ "AchievementFrameComparisonContainerButton5FriendBackground",
+ "AchievementFrameComparisonContainerButton5FriendGlow",
+ "AchievementFrameComparisonContainerButton5FriendIcon",
+ "AchievementFrameComparisonContainerButton5FriendIconBling",
+ "AchievementFrameComparisonContainerButton5FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton5FriendIconTexture",
+ "AchievementFrameComparisonContainerButton5FriendShield",
+ "AchievementFrameComparisonContainerButton5FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton5FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton5FriendStatus",
+ "AchievementFrameComparisonContainerButton5FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton5Player",
+ "AchievementFrameComparisonContainerButton5PlayerBackground",
+ "AchievementFrameComparisonContainerButton5PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton5PlayerDescription",
+ "AchievementFrameComparisonContainerButton5PlayerGlow",
+ "AchievementFrameComparisonContainerButton5PlayerIcon",
+ "AchievementFrameComparisonContainerButton5PlayerIconBling",
+ "AchievementFrameComparisonContainerButton5PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton5PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton5PlayerLabel",
+ "AchievementFrameComparisonContainerButton5PlayerShield",
+ "AchievementFrameComparisonContainerButton5PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton5PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton5PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton6",
+ "AchievementFrameComparisonContainerButton6Friend",
+ "AchievementFrameComparisonContainerButton6FriendBackground",
+ "AchievementFrameComparisonContainerButton6FriendGlow",
+ "AchievementFrameComparisonContainerButton6FriendIcon",
+ "AchievementFrameComparisonContainerButton6FriendIconBling",
+ "AchievementFrameComparisonContainerButton6FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton6FriendIconTexture",
+ "AchievementFrameComparisonContainerButton6FriendShield",
+ "AchievementFrameComparisonContainerButton6FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton6FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton6FriendStatus",
+ "AchievementFrameComparisonContainerButton6FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton6Player",
+ "AchievementFrameComparisonContainerButton6PlayerBackground",
+ "AchievementFrameComparisonContainerButton6PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton6PlayerDescription",
+ "AchievementFrameComparisonContainerButton6PlayerGlow",
+ "AchievementFrameComparisonContainerButton6PlayerIcon",
+ "AchievementFrameComparisonContainerButton6PlayerIconBling",
+ "AchievementFrameComparisonContainerButton6PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton6PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton6PlayerLabel",
+ "AchievementFrameComparisonContainerButton6PlayerShield",
+ "AchievementFrameComparisonContainerButton6PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton6PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton6PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton7",
+ "AchievementFrameComparisonContainerButton7Friend",
+ "AchievementFrameComparisonContainerButton7FriendBackground",
+ "AchievementFrameComparisonContainerButton7FriendGlow",
+ "AchievementFrameComparisonContainerButton7FriendIcon",
+ "AchievementFrameComparisonContainerButton7FriendIconBling",
+ "AchievementFrameComparisonContainerButton7FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton7FriendIconTexture",
+ "AchievementFrameComparisonContainerButton7FriendShield",
+ "AchievementFrameComparisonContainerButton7FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton7FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton7FriendStatus",
+ "AchievementFrameComparisonContainerButton7FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton7Player",
+ "AchievementFrameComparisonContainerButton7PlayerBackground",
+ "AchievementFrameComparisonContainerButton7PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton7PlayerDescription",
+ "AchievementFrameComparisonContainerButton7PlayerGlow",
+ "AchievementFrameComparisonContainerButton7PlayerIcon",
+ "AchievementFrameComparisonContainerButton7PlayerIconBling",
+ "AchievementFrameComparisonContainerButton7PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton7PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton7PlayerLabel",
+ "AchievementFrameComparisonContainerButton7PlayerShield",
+ "AchievementFrameComparisonContainerButton7PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton7PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton7PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton8",
+ "AchievementFrameComparisonContainerButton8Friend",
+ "AchievementFrameComparisonContainerButton8FriendBackground",
+ "AchievementFrameComparisonContainerButton8FriendGlow",
+ "AchievementFrameComparisonContainerButton8FriendIcon",
+ "AchievementFrameComparisonContainerButton8FriendIconBling",
+ "AchievementFrameComparisonContainerButton8FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton8FriendIconTexture",
+ "AchievementFrameComparisonContainerButton8FriendShield",
+ "AchievementFrameComparisonContainerButton8FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton8FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton8FriendStatus",
+ "AchievementFrameComparisonContainerButton8FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton8Player",
+ "AchievementFrameComparisonContainerButton8PlayerBackground",
+ "AchievementFrameComparisonContainerButton8PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton8PlayerDescription",
+ "AchievementFrameComparisonContainerButton8PlayerGlow",
+ "AchievementFrameComparisonContainerButton8PlayerIcon",
+ "AchievementFrameComparisonContainerButton8PlayerIconBling",
+ "AchievementFrameComparisonContainerButton8PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton8PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton8PlayerLabel",
+ "AchievementFrameComparisonContainerButton8PlayerShield",
+ "AchievementFrameComparisonContainerButton8PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton8PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton8PlayerTitleBackground",
+ "AchievementFrameComparisonContainerButton9",
+ "AchievementFrameComparisonContainerButton9Friend",
+ "AchievementFrameComparisonContainerButton9FriendBackground",
+ "AchievementFrameComparisonContainerButton9FriendGlow",
+ "AchievementFrameComparisonContainerButton9FriendIcon",
+ "AchievementFrameComparisonContainerButton9FriendIconBling",
+ "AchievementFrameComparisonContainerButton9FriendIconOverlay",
+ "AchievementFrameComparisonContainerButton9FriendIconTexture",
+ "AchievementFrameComparisonContainerButton9FriendShield",
+ "AchievementFrameComparisonContainerButton9FriendShieldIcon",
+ "AchievementFrameComparisonContainerButton9FriendShieldPoints",
+ "AchievementFrameComparisonContainerButton9FriendStatus",
+ "AchievementFrameComparisonContainerButton9FriendTitleBackground",
+ "AchievementFrameComparisonContainerButton9Player",
+ "AchievementFrameComparisonContainerButton9PlayerBackground",
+ "AchievementFrameComparisonContainerButton9PlayerDateCompleted",
+ "AchievementFrameComparisonContainerButton9PlayerDescription",
+ "AchievementFrameComparisonContainerButton9PlayerGlow",
+ "AchievementFrameComparisonContainerButton9PlayerIcon",
+ "AchievementFrameComparisonContainerButton9PlayerIconBling",
+ "AchievementFrameComparisonContainerButton9PlayerIconOverlay",
+ "AchievementFrameComparisonContainerButton9PlayerIconTexture",
+ "AchievementFrameComparisonContainerButton9PlayerLabel",
+ "AchievementFrameComparisonContainerButton9PlayerShield",
+ "AchievementFrameComparisonContainerButton9PlayerShieldIcon",
+ "AchievementFrameComparisonContainerButton9PlayerShieldPoints",
+ "AchievementFrameComparisonContainerButton9PlayerTitleBackground",
+ "AchievementFrameComparisonContainerScrollBar",
+ "AchievementFrameComparisonContainerScrollBarBG",
+ "AchievementFrameComparisonContainerScrollBarBottom",
+ "AchievementFrameComparisonContainerScrollBarMiddle",
+ "AchievementFrameComparisonContainerScrollBarScrollDownButton",
+ "AchievementFrameComparisonContainerScrollBarScrollUpButton",
+ "AchievementFrameComparisonContainerScrollBarThumbTexture",
+ "AchievementFrameComparisonContainerScrollBarTop",
+ "AchievementFrameComparisonContainerScrollChild",
+ "AchievementFrameComparisonContainer_OnLoad",
+ "AchievementFrameComparisonDark",
+ "AchievementFrameComparisonHeader",
+ "AchievementFrameComparisonHeaderBG",
+ "AchievementFrameComparisonHeaderName",
+ "AchievementFrameComparisonHeaderPoints",
+ "AchievementFrameComparisonHeaderPortrait",
+ "AchievementFrameComparisonHeaderShield",
+ "AchievementFrameComparisonStat_OnLoad",
+ "AchievementFrameComparisonStatsContainer",
+ "AchievementFrameComparisonStatsContainerButton1",
+ "AchievementFrameComparisonStatsContainerButton10",
+ "AchievementFrameComparisonStatsContainerButton10BG",
+ "AchievementFrameComparisonStatsContainerButton10ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton10HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton10HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton10HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton10HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton10HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton10HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton10Mouseover",
+ "AchievementFrameComparisonStatsContainerButton10Text",
+ "AchievementFrameComparisonStatsContainerButton10Title",
+ "AchievementFrameComparisonStatsContainerButton10Value",
+ "AchievementFrameComparisonStatsContainerButton11",
+ "AchievementFrameComparisonStatsContainerButton11BG",
+ "AchievementFrameComparisonStatsContainerButton11ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton11HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton11HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton11HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton11HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton11HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton11HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton11Mouseover",
+ "AchievementFrameComparisonStatsContainerButton11Text",
+ "AchievementFrameComparisonStatsContainerButton11Title",
+ "AchievementFrameComparisonStatsContainerButton11Value",
+ "AchievementFrameComparisonStatsContainerButton12",
+ "AchievementFrameComparisonStatsContainerButton12BG",
+ "AchievementFrameComparisonStatsContainerButton12ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton12HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton12HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton12HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton12HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton12HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton12HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton12Mouseover",
+ "AchievementFrameComparisonStatsContainerButton12Text",
+ "AchievementFrameComparisonStatsContainerButton12Title",
+ "AchievementFrameComparisonStatsContainerButton12Value",
+ "AchievementFrameComparisonStatsContainerButton13",
+ "AchievementFrameComparisonStatsContainerButton13BG",
+ "AchievementFrameComparisonStatsContainerButton13ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton13HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton13HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton13HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton13HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton13HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton13HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton13Mouseover",
+ "AchievementFrameComparisonStatsContainerButton13Text",
+ "AchievementFrameComparisonStatsContainerButton13Title",
+ "AchievementFrameComparisonStatsContainerButton13Value",
+ "AchievementFrameComparisonStatsContainerButton14",
+ "AchievementFrameComparisonStatsContainerButton14BG",
+ "AchievementFrameComparisonStatsContainerButton14ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton14HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton14HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton14HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton14HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton14HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton14HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton14Mouseover",
+ "AchievementFrameComparisonStatsContainerButton14Text",
+ "AchievementFrameComparisonStatsContainerButton14Title",
+ "AchievementFrameComparisonStatsContainerButton14Value",
+ "AchievementFrameComparisonStatsContainerButton15",
+ "AchievementFrameComparisonStatsContainerButton15BG",
+ "AchievementFrameComparisonStatsContainerButton15ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton15HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton15HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton15HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton15HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton15HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton15HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton15Mouseover",
+ "AchievementFrameComparisonStatsContainerButton15Text",
+ "AchievementFrameComparisonStatsContainerButton15Title",
+ "AchievementFrameComparisonStatsContainerButton15Value",
+ "AchievementFrameComparisonStatsContainerButton16",
+ "AchievementFrameComparisonStatsContainerButton16BG",
+ "AchievementFrameComparisonStatsContainerButton16ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton16HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton16HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton16HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton16HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton16HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton16HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton16Mouseover",
+ "AchievementFrameComparisonStatsContainerButton16Text",
+ "AchievementFrameComparisonStatsContainerButton16Title",
+ "AchievementFrameComparisonStatsContainerButton16Value",
+ "AchievementFrameComparisonStatsContainerButton17",
+ "AchievementFrameComparisonStatsContainerButton17BG",
+ "AchievementFrameComparisonStatsContainerButton17ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton17HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton17HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton17HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton17HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton17HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton17HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton17Mouseover",
+ "AchievementFrameComparisonStatsContainerButton17Text",
+ "AchievementFrameComparisonStatsContainerButton17Title",
+ "AchievementFrameComparisonStatsContainerButton17Value",
+ "AchievementFrameComparisonStatsContainerButton18",
+ "AchievementFrameComparisonStatsContainerButton18BG",
+ "AchievementFrameComparisonStatsContainerButton18ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton18HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton18HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton18HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton18HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton18HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton18HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton18Mouseover",
+ "AchievementFrameComparisonStatsContainerButton18Text",
+ "AchievementFrameComparisonStatsContainerButton18Title",
+ "AchievementFrameComparisonStatsContainerButton18Value",
+ "AchievementFrameComparisonStatsContainerButton19",
+ "AchievementFrameComparisonStatsContainerButton19BG",
+ "AchievementFrameComparisonStatsContainerButton19ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton19HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton19HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton19HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton19HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton19HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton19HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton19Mouseover",
+ "AchievementFrameComparisonStatsContainerButton19Text",
+ "AchievementFrameComparisonStatsContainerButton19Title",
+ "AchievementFrameComparisonStatsContainerButton19Value",
+ "AchievementFrameComparisonStatsContainerButton1BG",
+ "AchievementFrameComparisonStatsContainerButton1ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton1HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton1HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton1HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton1HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton1HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton1HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton1Mouseover",
+ "AchievementFrameComparisonStatsContainerButton1Text",
+ "AchievementFrameComparisonStatsContainerButton1Title",
+ "AchievementFrameComparisonStatsContainerButton1Value",
+ "AchievementFrameComparisonStatsContainerButton2",
+ "AchievementFrameComparisonStatsContainerButton20",
+ "AchievementFrameComparisonStatsContainerButton20BG",
+ "AchievementFrameComparisonStatsContainerButton20ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton20HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton20HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton20HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton20HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton20HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton20HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton20Mouseover",
+ "AchievementFrameComparisonStatsContainerButton20Text",
+ "AchievementFrameComparisonStatsContainerButton20Title",
+ "AchievementFrameComparisonStatsContainerButton20Value",
+ "AchievementFrameComparisonStatsContainerButton2BG",
+ "AchievementFrameComparisonStatsContainerButton2ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton2HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton2HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton2HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton2HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton2HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton2HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton2Mouseover",
+ "AchievementFrameComparisonStatsContainerButton2Text",
+ "AchievementFrameComparisonStatsContainerButton2Title",
+ "AchievementFrameComparisonStatsContainerButton2Value",
+ "AchievementFrameComparisonStatsContainerButton3",
+ "AchievementFrameComparisonStatsContainerButton3BG",
+ "AchievementFrameComparisonStatsContainerButton3ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton3HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton3HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton3HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton3HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton3HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton3HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton3Mouseover",
+ "AchievementFrameComparisonStatsContainerButton3Text",
+ "AchievementFrameComparisonStatsContainerButton3Title",
+ "AchievementFrameComparisonStatsContainerButton3Value",
+ "AchievementFrameComparisonStatsContainerButton4",
+ "AchievementFrameComparisonStatsContainerButton4BG",
+ "AchievementFrameComparisonStatsContainerButton4ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton4HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton4HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton4HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton4HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton4HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton4HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton4Mouseover",
+ "AchievementFrameComparisonStatsContainerButton4Text",
+ "AchievementFrameComparisonStatsContainerButton4Title",
+ "AchievementFrameComparisonStatsContainerButton4Value",
+ "AchievementFrameComparisonStatsContainerButton5",
+ "AchievementFrameComparisonStatsContainerButton5BG",
+ "AchievementFrameComparisonStatsContainerButton5ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton5HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton5HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton5HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton5HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton5HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton5HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton5Mouseover",
+ "AchievementFrameComparisonStatsContainerButton5Text",
+ "AchievementFrameComparisonStatsContainerButton5Title",
+ "AchievementFrameComparisonStatsContainerButton5Value",
+ "AchievementFrameComparisonStatsContainerButton6",
+ "AchievementFrameComparisonStatsContainerButton6BG",
+ "AchievementFrameComparisonStatsContainerButton6ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton6HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton6HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton6HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton6HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton6HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton6HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton6Mouseover",
+ "AchievementFrameComparisonStatsContainerButton6Text",
+ "AchievementFrameComparisonStatsContainerButton6Title",
+ "AchievementFrameComparisonStatsContainerButton6Value",
+ "AchievementFrameComparisonStatsContainerButton7",
+ "AchievementFrameComparisonStatsContainerButton7BG",
+ "AchievementFrameComparisonStatsContainerButton7ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton7HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton7HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton7HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton7HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton7HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton7HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton7Mouseover",
+ "AchievementFrameComparisonStatsContainerButton7Text",
+ "AchievementFrameComparisonStatsContainerButton7Title",
+ "AchievementFrameComparisonStatsContainerButton7Value",
+ "AchievementFrameComparisonStatsContainerButton8",
+ "AchievementFrameComparisonStatsContainerButton8BG",
+ "AchievementFrameComparisonStatsContainerButton8ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton8HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton8HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton8HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton8HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton8HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton8HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton8Mouseover",
+ "AchievementFrameComparisonStatsContainerButton8Text",
+ "AchievementFrameComparisonStatsContainerButton8Title",
+ "AchievementFrameComparisonStatsContainerButton8Value",
+ "AchievementFrameComparisonStatsContainerButton9",
+ "AchievementFrameComparisonStatsContainerButton9BG",
+ "AchievementFrameComparisonStatsContainerButton9ComparisonValue",
+ "AchievementFrameComparisonStatsContainerButton9HeaderLeft",
+ "AchievementFrameComparisonStatsContainerButton9HeaderLeft2",
+ "AchievementFrameComparisonStatsContainerButton9HeaderMiddle",
+ "AchievementFrameComparisonStatsContainerButton9HeaderMiddle2",
+ "AchievementFrameComparisonStatsContainerButton9HeaderRight",
+ "AchievementFrameComparisonStatsContainerButton9HeaderRight2",
+ "AchievementFrameComparisonStatsContainerButton9Mouseover",
+ "AchievementFrameComparisonStatsContainerButton9Text",
+ "AchievementFrameComparisonStatsContainerButton9Title",
+ "AchievementFrameComparisonStatsContainerButton9Value",
+ "AchievementFrameComparisonStatsContainerScrollBar",
+ "AchievementFrameComparisonStatsContainerScrollBarBG",
+ "AchievementFrameComparisonStatsContainerScrollBarBottom",
+ "AchievementFrameComparisonStatsContainerScrollBarMiddle",
+ "AchievementFrameComparisonStatsContainerScrollBarScrollDownButton",
+ "AchievementFrameComparisonStatsContainerScrollBarScrollUpButton",
+ "AchievementFrameComparisonStatsContainerScrollBarThumbTexture",
+ "AchievementFrameComparisonStatsContainerScrollBarTop",
+ "AchievementFrameComparisonStatsContainerScrollChild",
+ "AchievementFrameComparisonStatsContainer_OnLoad",
+ "AchievementFrameComparisonStats_SetHeader",
+ "AchievementFrameComparisonStats_SetStat",
+ "AchievementFrameComparisonSummary",
+ "AchievementFrameComparisonSummaryFriend",
+ "AchievementFrameComparisonSummaryFriendBackground",
+ "AchievementFrameComparisonSummaryFriendStatusBar",
+ "AchievementFrameComparisonSummaryFriendStatusBarBar",
+ "AchievementFrameComparisonSummaryFriendStatusBarFillBar",
+ "AchievementFrameComparisonSummaryFriendStatusBarLeft",
+ "AchievementFrameComparisonSummaryFriendStatusBarMiddle",
+ "AchievementFrameComparisonSummaryFriendStatusBarRight",
+ "AchievementFrameComparisonSummaryFriendStatusBarText",
+ "AchievementFrameComparisonSummaryFriendStatusBarTitle",
+ "AchievementFrameComparisonSummaryPlayer",
+ "AchievementFrameComparisonSummaryPlayerBackground",
+ "AchievementFrameComparisonSummaryPlayerStatusBar",
+ "AchievementFrameComparisonSummaryPlayerStatusBarBar",
+ "AchievementFrameComparisonSummaryPlayerStatusBarFillBar",
+ "AchievementFrameComparisonSummaryPlayerStatusBarLeft",
+ "AchievementFrameComparisonSummaryPlayerStatusBarMiddle",
+ "AchievementFrameComparisonSummaryPlayerStatusBarRight",
+ "AchievementFrameComparisonSummaryPlayerStatusBarText",
+ "AchievementFrameComparisonSummaryPlayerStatusBarTitle",
+ "AchievementFrameComparisonTab_OnClick",
+ "AchievementFrameComparisonWatermark",
+ "AchievementFrameComparison_ClearSelection",
+ "AchievementFrameComparison_DisplayAchievement",
+ "AchievementFrameComparison_ForceUpdate",
+ "AchievementFrameComparison_OnEvent",
+ "AchievementFrameComparison_OnHide",
+ "AchievementFrameComparison_OnLoad",
+ "AchievementFrameComparison_OnShow",
+ "AchievementFrameComparison_SetUnit",
+ "AchievementFrameComparison_Update",
+ "AchievementFrameComparison_UpdateStats",
+ "AchievementFrameComparison_UpdateStatusBars",
+ "AchievementFrameFilterDropDown",
+ "AchievementFrameFilterDropDownButton",
+ "AchievementFrameFilterDropDownButtonDisabledTexture",
+ "AchievementFrameFilterDropDownButtonHighlightTexture",
+ "AchievementFrameFilterDropDownButtonNormalTexture",
+ "AchievementFrameFilterDropDownButtonPushedTexture",
+ "AchievementFrameFilterDropDownButton_OnClick",
+ "AchievementFrameFilterDropDownText",
+ "AchievementFrameFilterDropDown_Initialize",
+ "AchievementFrameFilterDropDown_OnLoad",
+ "AchievementFrameFilters",
+ "AchievementFrameHeader",
+ "AchievementFrameHeaderLeft",
+ "AchievementFrameHeaderPointBorder",
+ "AchievementFrameHeaderPoints",
+ "AchievementFrameHeaderRight",
+ "AchievementFrameHeaderRightDDLInset",
+ "AchievementFrameHeaderShield",
+ "AchievementFrameHeaderTitle",
+ "AchievementFrameMetalBorderBottom",
+ "AchievementFrameMetalBorderBottomLeft",
+ "AchievementFrameMetalBorderBottomRight",
+ "AchievementFrameMetalBorderLeft",
+ "AchievementFrameMetalBorderRight",
+ "AchievementFrameMetalBorderTop",
+ "AchievementFrameMetalBorderTopLeft",
+ "AchievementFrameMetalBorderTopRight",
+ "AchievementFrameMiniAchievement1",
+ "AchievementFrameStats",
+ "AchievementFrameStatsBG",
+ "AchievementFrameStatsContainer",
+ "AchievementFrameStatsContainerButton1",
+ "AchievementFrameStatsContainerButton10",
+ "AchievementFrameStatsContainerButton10BG",
+ "AchievementFrameStatsContainerButton10HeaderLeft",
+ "AchievementFrameStatsContainerButton10HeaderMiddle",
+ "AchievementFrameStatsContainerButton10HeaderRight",
+ "AchievementFrameStatsContainerButton10Title",
+ "AchievementFrameStatsContainerButton10Value",
+ "AchievementFrameStatsContainerButton11",
+ "AchievementFrameStatsContainerButton11BG",
+ "AchievementFrameStatsContainerButton11HeaderLeft",
+ "AchievementFrameStatsContainerButton11HeaderMiddle",
+ "AchievementFrameStatsContainerButton11HeaderRight",
+ "AchievementFrameStatsContainerButton11Title",
+ "AchievementFrameStatsContainerButton11Value",
+ "AchievementFrameStatsContainerButton12",
+ "AchievementFrameStatsContainerButton12BG",
+ "AchievementFrameStatsContainerButton12HeaderLeft",
+ "AchievementFrameStatsContainerButton12HeaderMiddle",
+ "AchievementFrameStatsContainerButton12HeaderRight",
+ "AchievementFrameStatsContainerButton12Title",
+ "AchievementFrameStatsContainerButton12Value",
+ "AchievementFrameStatsContainerButton13",
+ "AchievementFrameStatsContainerButton13BG",
+ "AchievementFrameStatsContainerButton13HeaderLeft",
+ "AchievementFrameStatsContainerButton13HeaderMiddle",
+ "AchievementFrameStatsContainerButton13HeaderRight",
+ "AchievementFrameStatsContainerButton13Title",
+ "AchievementFrameStatsContainerButton13Value",
+ "AchievementFrameStatsContainerButton14",
+ "AchievementFrameStatsContainerButton14BG",
+ "AchievementFrameStatsContainerButton14HeaderLeft",
+ "AchievementFrameStatsContainerButton14HeaderMiddle",
+ "AchievementFrameStatsContainerButton14HeaderRight",
+ "AchievementFrameStatsContainerButton14Title",
+ "AchievementFrameStatsContainerButton14Value",
+ "AchievementFrameStatsContainerButton15",
+ "AchievementFrameStatsContainerButton15BG",
+ "AchievementFrameStatsContainerButton15HeaderLeft",
+ "AchievementFrameStatsContainerButton15HeaderMiddle",
+ "AchievementFrameStatsContainerButton15HeaderRight",
+ "AchievementFrameStatsContainerButton15Title",
+ "AchievementFrameStatsContainerButton15Value",
+ "AchievementFrameStatsContainerButton16",
+ "AchievementFrameStatsContainerButton16BG",
+ "AchievementFrameStatsContainerButton16HeaderLeft",
+ "AchievementFrameStatsContainerButton16HeaderMiddle",
+ "AchievementFrameStatsContainerButton16HeaderRight",
+ "AchievementFrameStatsContainerButton16Title",
+ "AchievementFrameStatsContainerButton16Value",
+ "AchievementFrameStatsContainerButton17",
+ "AchievementFrameStatsContainerButton17BG",
+ "AchievementFrameStatsContainerButton17HeaderLeft",
+ "AchievementFrameStatsContainerButton17HeaderMiddle",
+ "AchievementFrameStatsContainerButton17HeaderRight",
+ "AchievementFrameStatsContainerButton17Title",
+ "AchievementFrameStatsContainerButton17Value",
+ "AchievementFrameStatsContainerButton18",
+ "AchievementFrameStatsContainerButton18BG",
+ "AchievementFrameStatsContainerButton18HeaderLeft",
+ "AchievementFrameStatsContainerButton18HeaderMiddle",
+ "AchievementFrameStatsContainerButton18HeaderRight",
+ "AchievementFrameStatsContainerButton18Title",
+ "AchievementFrameStatsContainerButton18Value",
+ "AchievementFrameStatsContainerButton19",
+ "AchievementFrameStatsContainerButton19BG",
+ "AchievementFrameStatsContainerButton19HeaderLeft",
+ "AchievementFrameStatsContainerButton19HeaderMiddle",
+ "AchievementFrameStatsContainerButton19HeaderRight",
+ "AchievementFrameStatsContainerButton19Title",
+ "AchievementFrameStatsContainerButton19Value",
+ "AchievementFrameStatsContainerButton1BG",
+ "AchievementFrameStatsContainerButton1HeaderLeft",
+ "AchievementFrameStatsContainerButton1HeaderMiddle",
+ "AchievementFrameStatsContainerButton1HeaderRight",
+ "AchievementFrameStatsContainerButton1Title",
+ "AchievementFrameStatsContainerButton1Value",
+ "AchievementFrameStatsContainerButton2",
+ "AchievementFrameStatsContainerButton20",
+ "AchievementFrameStatsContainerButton20BG",
+ "AchievementFrameStatsContainerButton20HeaderLeft",
+ "AchievementFrameStatsContainerButton20HeaderMiddle",
+ "AchievementFrameStatsContainerButton20HeaderRight",
+ "AchievementFrameStatsContainerButton20Title",
+ "AchievementFrameStatsContainerButton20Value",
+ "AchievementFrameStatsContainerButton2BG",
+ "AchievementFrameStatsContainerButton2HeaderLeft",
+ "AchievementFrameStatsContainerButton2HeaderMiddle",
+ "AchievementFrameStatsContainerButton2HeaderRight",
+ "AchievementFrameStatsContainerButton2Title",
+ "AchievementFrameStatsContainerButton2Value",
+ "AchievementFrameStatsContainerButton3",
+ "AchievementFrameStatsContainerButton3BG",
+ "AchievementFrameStatsContainerButton3HeaderLeft",
+ "AchievementFrameStatsContainerButton3HeaderMiddle",
+ "AchievementFrameStatsContainerButton3HeaderRight",
+ "AchievementFrameStatsContainerButton3Title",
+ "AchievementFrameStatsContainerButton3Value",
+ "AchievementFrameStatsContainerButton4",
+ "AchievementFrameStatsContainerButton4BG",
+ "AchievementFrameStatsContainerButton4HeaderLeft",
+ "AchievementFrameStatsContainerButton4HeaderMiddle",
+ "AchievementFrameStatsContainerButton4HeaderRight",
+ "AchievementFrameStatsContainerButton4Title",
+ "AchievementFrameStatsContainerButton4Value",
+ "AchievementFrameStatsContainerButton5",
+ "AchievementFrameStatsContainerButton5BG",
+ "AchievementFrameStatsContainerButton5HeaderLeft",
+ "AchievementFrameStatsContainerButton5HeaderMiddle",
+ "AchievementFrameStatsContainerButton5HeaderRight",
+ "AchievementFrameStatsContainerButton5Title",
+ "AchievementFrameStatsContainerButton5Value",
+ "AchievementFrameStatsContainerButton6",
+ "AchievementFrameStatsContainerButton6BG",
+ "AchievementFrameStatsContainerButton6HeaderLeft",
+ "AchievementFrameStatsContainerButton6HeaderMiddle",
+ "AchievementFrameStatsContainerButton6HeaderRight",
+ "AchievementFrameStatsContainerButton6Title",
+ "AchievementFrameStatsContainerButton6Value",
+ "AchievementFrameStatsContainerButton7",
+ "AchievementFrameStatsContainerButton7BG",
+ "AchievementFrameStatsContainerButton7HeaderLeft",
+ "AchievementFrameStatsContainerButton7HeaderMiddle",
+ "AchievementFrameStatsContainerButton7HeaderRight",
+ "AchievementFrameStatsContainerButton7Title",
+ "AchievementFrameStatsContainerButton7Value",
+ "AchievementFrameStatsContainerButton8",
+ "AchievementFrameStatsContainerButton8BG",
+ "AchievementFrameStatsContainerButton8HeaderLeft",
+ "AchievementFrameStatsContainerButton8HeaderMiddle",
+ "AchievementFrameStatsContainerButton8HeaderRight",
+ "AchievementFrameStatsContainerButton8Title",
+ "AchievementFrameStatsContainerButton8Value",
+ "AchievementFrameStatsContainerButton9",
+ "AchievementFrameStatsContainerButton9BG",
+ "AchievementFrameStatsContainerButton9HeaderLeft",
+ "AchievementFrameStatsContainerButton9HeaderMiddle",
+ "AchievementFrameStatsContainerButton9HeaderRight",
+ "AchievementFrameStatsContainerButton9Title",
+ "AchievementFrameStatsContainerButton9Value",
+ "AchievementFrameStatsContainerScrollBar",
+ "AchievementFrameStatsContainerScrollBarBG",
+ "AchievementFrameStatsContainerScrollBarBottom",
+ "AchievementFrameStatsContainerScrollBarMiddle",
+ "AchievementFrameStatsContainerScrollBarScrollDownButton",
+ "AchievementFrameStatsContainerScrollBarScrollUpButton",
+ "AchievementFrameStatsContainerScrollBarThumbTexture",
+ "AchievementFrameStatsContainerScrollBarTop",
+ "AchievementFrameStatsContainerScrollChild",
+ "AchievementFrameStats_OnEvent",
+ "AchievementFrameStats_OnLoad",
+ "AchievementFrameStats_SetHeader",
+ "AchievementFrameStats_SetStat",
+ "AchievementFrameStats_Update",
+ "AchievementFrameSummary",
+ "AchievementFrameSummaryAchievement_OnClick",
+ "AchievementFrameSummaryAchievement_OnEnter",
+ "AchievementFrameSummaryAchievement_OnLoad",
+ "AchievementFrameSummaryAchievements",
+ "AchievementFrameSummaryAchievementsEmptyText",
+ "AchievementFrameSummaryAchievementsHeader",
+ "AchievementFrameSummaryAchievementsHeaderHeader",
+ "AchievementFrameSummaryAchievementsHeaderTitle",
+ "AchievementFrameSummaryBackground",
+ "AchievementFrameSummaryCategories",
+ "AchievementFrameSummaryCategoriesCategory1",
+ "AchievementFrameSummaryCategoriesCategory1Bar",
+ "AchievementFrameSummaryCategoriesCategory1Button",
+ "AchievementFrameSummaryCategoriesCategory1ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory1ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory1ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory1ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory1FillBar",
+ "AchievementFrameSummaryCategoriesCategory1Label",
+ "AchievementFrameSummaryCategoriesCategory1Left",
+ "AchievementFrameSummaryCategoriesCategory1Middle",
+ "AchievementFrameSummaryCategoriesCategory1Right",
+ "AchievementFrameSummaryCategoriesCategory1Text",
+ "AchievementFrameSummaryCategoriesCategory2",
+ "AchievementFrameSummaryCategoriesCategory2Bar",
+ "AchievementFrameSummaryCategoriesCategory2Button",
+ "AchievementFrameSummaryCategoriesCategory2ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory2ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory2ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory2ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory2FillBar",
+ "AchievementFrameSummaryCategoriesCategory2Label",
+ "AchievementFrameSummaryCategoriesCategory2Left",
+ "AchievementFrameSummaryCategoriesCategory2Middle",
+ "AchievementFrameSummaryCategoriesCategory2Right",
+ "AchievementFrameSummaryCategoriesCategory2Text",
+ "AchievementFrameSummaryCategoriesCategory3",
+ "AchievementFrameSummaryCategoriesCategory3Bar",
+ "AchievementFrameSummaryCategoriesCategory3Button",
+ "AchievementFrameSummaryCategoriesCategory3ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory3ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory3ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory3ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory3FillBar",
+ "AchievementFrameSummaryCategoriesCategory3Label",
+ "AchievementFrameSummaryCategoriesCategory3Left",
+ "AchievementFrameSummaryCategoriesCategory3Middle",
+ "AchievementFrameSummaryCategoriesCategory3Right",
+ "AchievementFrameSummaryCategoriesCategory3Text",
+ "AchievementFrameSummaryCategoriesCategory4",
+ "AchievementFrameSummaryCategoriesCategory4Bar",
+ "AchievementFrameSummaryCategoriesCategory4Button",
+ "AchievementFrameSummaryCategoriesCategory4ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory4ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory4ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory4ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory4FillBar",
+ "AchievementFrameSummaryCategoriesCategory4Label",
+ "AchievementFrameSummaryCategoriesCategory4Left",
+ "AchievementFrameSummaryCategoriesCategory4Middle",
+ "AchievementFrameSummaryCategoriesCategory4Right",
+ "AchievementFrameSummaryCategoriesCategory4Text",
+ "AchievementFrameSummaryCategoriesCategory5",
+ "AchievementFrameSummaryCategoriesCategory5Bar",
+ "AchievementFrameSummaryCategoriesCategory5Button",
+ "AchievementFrameSummaryCategoriesCategory5ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory5ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory5ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory5ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory5FillBar",
+ "AchievementFrameSummaryCategoriesCategory5Label",
+ "AchievementFrameSummaryCategoriesCategory5Left",
+ "AchievementFrameSummaryCategoriesCategory5Middle",
+ "AchievementFrameSummaryCategoriesCategory5Right",
+ "AchievementFrameSummaryCategoriesCategory5Text",
+ "AchievementFrameSummaryCategoriesCategory6",
+ "AchievementFrameSummaryCategoriesCategory6Bar",
+ "AchievementFrameSummaryCategoriesCategory6Button",
+ "AchievementFrameSummaryCategoriesCategory6ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory6ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory6ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory6ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory6FillBar",
+ "AchievementFrameSummaryCategoriesCategory6Label",
+ "AchievementFrameSummaryCategoriesCategory6Left",
+ "AchievementFrameSummaryCategoriesCategory6Middle",
+ "AchievementFrameSummaryCategoriesCategory6Right",
+ "AchievementFrameSummaryCategoriesCategory6Text",
+ "AchievementFrameSummaryCategoriesCategory7",
+ "AchievementFrameSummaryCategoriesCategory7Bar",
+ "AchievementFrameSummaryCategoriesCategory7Button",
+ "AchievementFrameSummaryCategoriesCategory7ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory7ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory7ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory7ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory7FillBar",
+ "AchievementFrameSummaryCategoriesCategory7Label",
+ "AchievementFrameSummaryCategoriesCategory7Left",
+ "AchievementFrameSummaryCategoriesCategory7Middle",
+ "AchievementFrameSummaryCategoriesCategory7Right",
+ "AchievementFrameSummaryCategoriesCategory7Text",
+ "AchievementFrameSummaryCategoriesCategory8",
+ "AchievementFrameSummaryCategoriesCategory8Bar",
+ "AchievementFrameSummaryCategoriesCategory8Button",
+ "AchievementFrameSummaryCategoriesCategory8ButtonHighlight",
+ "AchievementFrameSummaryCategoriesCategory8ButtonHighlightLeft",
+ "AchievementFrameSummaryCategoriesCategory8ButtonHighlightMiddle",
+ "AchievementFrameSummaryCategoriesCategory8ButtonHighlightRight",
+ "AchievementFrameSummaryCategoriesCategory8FillBar",
+ "AchievementFrameSummaryCategoriesCategory8Label",
+ "AchievementFrameSummaryCategoriesCategory8Left",
+ "AchievementFrameSummaryCategoriesCategory8Middle",
+ "AchievementFrameSummaryCategoriesCategory8Right",
+ "AchievementFrameSummaryCategoriesCategory8Text",
+ "AchievementFrameSummaryCategoriesHeader",
+ "AchievementFrameSummaryCategoriesHeaderTexture",
+ "AchievementFrameSummaryCategoriesHeaderTitle",
+ "AchievementFrameSummaryCategoriesStatusBar",
+ "AchievementFrameSummaryCategoriesStatusBarBar",
+ "AchievementFrameSummaryCategoriesStatusBarFillBar",
+ "AchievementFrameSummaryCategoriesStatusBarLeft",
+ "AchievementFrameSummaryCategoriesStatusBarMiddle",
+ "AchievementFrameSummaryCategoriesStatusBarRight",
+ "AchievementFrameSummaryCategoriesStatusBarText",
+ "AchievementFrameSummaryCategoriesStatusBarTitle",
+ "AchievementFrameSummaryCategoriesStatusBar_Update",
+ "AchievementFrameSummaryCategoryButton_OnClick",
+ "AchievementFrameSummaryCategory_OnEvent",
+ "AchievementFrameSummaryCategory_OnHide",
+ "AchievementFrameSummaryCategory_OnLoad",
+ "AchievementFrameSummaryCategory_OnShow",
+ "AchievementFrameSummary_LocalizeButton",
+ "AchievementFrameSummary_OnShow",
+ "AchievementFrameSummary_Update",
+ "AchievementFrameSummary_UpdateAchievements",
+ "AchievementFrameTab1",
+ "AchievementFrameTab1Left",
+ "AchievementFrameTab1LeftDisabled",
+ "AchievementFrameTab1LeftHighlight",
+ "AchievementFrameTab1Middle",
+ "AchievementFrameTab1MiddleDisabled",
+ "AchievementFrameTab1MiddleHighlight",
+ "AchievementFrameTab1Right",
+ "AchievementFrameTab1RightDisabled",
+ "AchievementFrameTab1RightHighlight",
+ "AchievementFrameTab1Text",
+ "AchievementFrameTab2",
+ "AchievementFrameTab2Left",
+ "AchievementFrameTab2LeftDisabled",
+ "AchievementFrameTab2LeftHighlight",
+ "AchievementFrameTab2Middle",
+ "AchievementFrameTab2MiddleDisabled",
+ "AchievementFrameTab2MiddleHighlight",
+ "AchievementFrameTab2Right",
+ "AchievementFrameTab2RightDisabled",
+ "AchievementFrameTab2RightHighlight",
+ "AchievementFrameTab2Text",
+ "AchievementFrameWaterMark",
+ "AchievementFrameWoodBorderBottomLeft",
+ "AchievementFrameWoodBorderBottomRight",
+ "AchievementFrameWoodBorderTopLeft",
+ "AchievementFrameWoodBorderTopRight",
+ "AchievementFrame_ClearTextures",
+ "AchievementFrame_DisplayComparison",
+ "AchievementFrame_ForceUpdate",
+ "AchievementFrame_GetCategoryNumAchievements_Complete",
+ "AchievementFrame_GetCategoryNumAchievements_Incomplete",
+ "AchievementFrame_GetCategoryTotalNumAchievements",
+ "AchievementFrame_IsComparison",
+ "AchievementFrame_IsFeatOfStrength",
+ "AchievementFrame_LoadTextures",
+ "AchievementFrame_LoadUI",
+ "AchievementFrame_LocalizeCriteria",
+ "AchievementFrame_OnHide",
+ "AchievementFrame_OnLoad",
+ "AchievementFrame_OnShow",
+ "AchievementFrame_SelectAchievement",
+ "AchievementFrame_SelectSummaryStatistic",
+ "AchievementFrame_SetFilter",
+ "AchievementFrame_ShowSubFrame",
+ "AchievementFrame_ToggleAchievementFrame",
+ "AchievementIcon_Desaturate",
+ "AchievementIcon_OnLoad",
+ "AchievementIcon_Saturate",
+ "AchievementMicroButton",
+ "AchievementMicroButton_OnEvent",
+ "AchievementObjectives_DisplayCriteria",
+ "AchievementObjectives_DisplayProgressiveAchievement",
+ "AchievementPointsFont",
+ "AchievementPointsFontSmall",
+ "AchievementShield_Desaturate",
+ "AchievementShield_OnLoad",
+ "AchievementShield_Saturate",
+ "AchievementShield_SetPoints",
+ "AchievementStatButton_OnClick",
+ "AchievementStatButton_OnLoad",
+ "ActionBarDownButton",
+ "ActionBarUpButton",
+ "ActionBar_PageDown",
+ "ActionBar_PageUp",
+ "ActionBarsPanelOptions",
+ "ActionButton1",
+ "ActionButton10",
+ "ActionButton10Border",
+ "ActionButton10Cooldown",
+ "ActionButton10Count",
+ "ActionButton10Flash",
+ "ActionButton10HotKey",
+ "ActionButton10Icon",
+ "ActionButton10Name",
+ "ActionButton10NormalTexture",
+ "ActionButton11",
+ "ActionButton11Border",
+ "ActionButton11Cooldown",
+ "ActionButton11Count",
+ "ActionButton11Flash",
+ "ActionButton11HotKey",
+ "ActionButton11Icon",
+ "ActionButton11Name",
+ "ActionButton11NormalTexture",
+ "ActionButton12",
+ "ActionButton12Border",
+ "ActionButton12Cooldown",
+ "ActionButton12Count",
+ "ActionButton12Flash",
+ "ActionButton12HotKey",
+ "ActionButton12Icon",
+ "ActionButton12Name",
+ "ActionButton12NormalTexture",
+ "ActionButton1Border",
+ "ActionButton1Cooldown",
+ "ActionButton1Count",
+ "ActionButton1Flash",
+ "ActionButton1HotKey",
+ "ActionButton1Icon",
+ "ActionButton1Name",
+ "ActionButton1NormalTexture",
+ "ActionButton2",
+ "ActionButton2Border",
+ "ActionButton2Cooldown",
+ "ActionButton2Count",
+ "ActionButton2Flash",
+ "ActionButton2HotKey",
+ "ActionButton2Icon",
+ "ActionButton2Name",
+ "ActionButton2NormalTexture",
+ "ActionButton3",
+ "ActionButton3Border",
+ "ActionButton3Cooldown",
+ "ActionButton3Count",
+ "ActionButton3Flash",
+ "ActionButton3HotKey",
+ "ActionButton3Icon",
+ "ActionButton3Name",
+ "ActionButton3NormalTexture",
+ "ActionButton4",
+ "ActionButton4Border",
+ "ActionButton4Cooldown",
+ "ActionButton4Count",
+ "ActionButton4Flash",
+ "ActionButton4HotKey",
+ "ActionButton4Icon",
+ "ActionButton4Name",
+ "ActionButton4NormalTexture",
+ "ActionButton5",
+ "ActionButton5Border",
+ "ActionButton5Cooldown",
+ "ActionButton5Count",
+ "ActionButton5Flash",
+ "ActionButton5HotKey",
+ "ActionButton5Icon",
+ "ActionButton5Name",
+ "ActionButton5NormalTexture",
+ "ActionButton6",
+ "ActionButton6Border",
+ "ActionButton6Cooldown",
+ "ActionButton6Count",
+ "ActionButton6Flash",
+ "ActionButton6HotKey",
+ "ActionButton6Icon",
+ "ActionButton6Name",
+ "ActionButton6NormalTexture",
+ "ActionButton7",
+ "ActionButton7Border",
+ "ActionButton7Cooldown",
+ "ActionButton7Count",
+ "ActionButton7Flash",
+ "ActionButton7HotKey",
+ "ActionButton7Icon",
+ "ActionButton7Name",
+ "ActionButton7NormalTexture",
+ "ActionButton8",
+ "ActionButton8Border",
+ "ActionButton8Cooldown",
+ "ActionButton8Count",
+ "ActionButton8Flash",
+ "ActionButton8HotKey",
+ "ActionButton8Icon",
+ "ActionButton8Name",
+ "ActionButton8NormalTexture",
+ "ActionButton9",
+ "ActionButton9Border",
+ "ActionButton9Cooldown",
+ "ActionButton9Count",
+ "ActionButton9Flash",
+ "ActionButton9HotKey",
+ "ActionButton9Icon",
+ "ActionButton9Name",
+ "ActionButton9NormalTexture",
+ "ActionButtonDown",
+ "ActionButtonUp",
+ "ActionButton_CalculateAction",
+ "ActionButton_GetPagedID",
+ "ActionButton_HideGrid",
+ "ActionButton_IsFlashing",
+ "ActionButton_OnEvent",
+ "ActionButton_OnLoad",
+ "ActionButton_OnUpdate",
+ "ActionButton_SetTooltip",
+ "ActionButton_ShowGrid",
+ "ActionButton_StartFlash",
+ "ActionButton_StopFlash",
+ "ActionButton_Update",
+ "ActionButton_UpdateAction",
+ "ActionButton_UpdateCooldown",
+ "ActionButton_UpdateCount",
+ "ActionButton_UpdateFlash",
+ "ActionButton_UpdateHotkeys",
+ "ActionButton_UpdateState",
+ "ActionButton_UpdateUsable",
+ "ActionHasRange",
+ "ActionStatus",
+ "ActionStatusText",
+ "ActionStatus_DisplayMessage",
+ "ActionStatus_OnEvent",
+ "ActionStatus_OnLoad",
+ "ActionStatus_OnUpdate",
+ "ActorPoolMixin",
+ "ActorPool_Hide",
+ "ActorPool_HideAndClearModel",
+ "AddChatWindowChannel",
+ "AddChatWindowMessages",
+ "AddFriend",
+ "AddFriendEntryFrame",
+ "AddFriendEntryFrameAcceptButton",
+ "AddFriendEntryFrameAcceptButtonLeft",
+ "AddFriendEntryFrameAcceptButtonMiddle",
+ "AddFriendEntryFrameAcceptButtonRight",
+ "AddFriendEntryFrameAcceptButtonText",
+ "AddFriendEntryFrameCancelButton",
+ "AddFriendEntryFrameCancelButtonLeft",
+ "AddFriendEntryFrameCancelButtonMiddle",
+ "AddFriendEntryFrameCancelButtonRight",
+ "AddFriendEntryFrameCancelButtonText",
+ "AddFriendEntryFrameInfoButton",
+ "AddFriendEntryFrameInfoButtonTexture",
+ "AddFriendEntryFrameLeftDescription",
+ "AddFriendEntryFrameLeftFriend",
+ "AddFriendEntryFrameLeftIcon",
+ "AddFriendEntryFrameLeftTitle",
+ "AddFriendEntryFrameOrLabel",
+ "AddFriendEntryFrameRightDescription",
+ "AddFriendEntryFrameRightFriend",
+ "AddFriendEntryFrameRightIcon",
+ "AddFriendEntryFrameRightTitle",
+ "AddFriendEntryFrameTopTitle",
+ "AddFriendEntryFrame_Collapse",
+ "AddFriendEntryFrame_Expand",
+ "AddFriendFrame",
+ "AddFriendFrame_Accept",
+ "AddFriendFrame_OnShow",
+ "AddFriendFrame_ShowEntry",
+ "AddFriendFrame_ShowInfo",
+ "AddFriendInfoFrame",
+ "AddFriendInfoFrameContinueButton",
+ "AddFriendInfoFrameContinueButtonLeft",
+ "AddFriendInfoFrameContinueButtonMiddle",
+ "AddFriendInfoFrameContinueButtonRight",
+ "AddFriendInfoFrameContinueButtonText",
+ "AddFriendInfoFrameFactionIcon",
+ "AddFriendInfoFrameLeftFriend",
+ "AddFriendInfoFrameLeftTitle",
+ "AddFriendInfoFrameRightFriend",
+ "AddFriendInfoFrameRightTitle",
+ "AddFriendNameEditBox",
+ "AddFriendNameEditBoxFill",
+ "AddFriendNameEditBoxLeft",
+ "AddFriendNameEditBoxMiddle",
+ "AddFriendNameEditBoxRight",
+ "AddFriendNameEditBox_OnTextChanged",
+ "AddFriendNoteEditBox",
+ "AddFriendNoteEditBoxFill",
+ "AddFriendNoteFrame",
+ "AddFriendNoteFrameBottom",
+ "AddFriendNoteFrameBottomLeft",
+ "AddFriendNoteFrameBottomRight",
+ "AddFriendNoteFrameLeft",
+ "AddFriendNoteFrameMiddle",
+ "AddFriendNoteFrameRight",
+ "AddFriendNoteFrameScrollFrame",
+ "AddFriendNoteFrameScrollFrameFocusButton",
+ "AddFriendNoteFrameScrollFrameScrollBar",
+ "AddFriendNoteFrameScrollFrameScrollBarScrollDownButton",
+ "AddFriendNoteFrameScrollFrameScrollBarScrollUpButton",
+ "AddFriendNoteFrameScrollFrameScrollBarThumbTexture",
+ "AddFriendNoteFrameTop",
+ "AddFriendNoteFrameTopLeft",
+ "AddFriendNoteFrameTopRight",
+ "AddIgnore",
+ "AddMute",
+ "AddOrDelIgnore",
+ "AddOrDelMute",
+ "AddOrRemoveFriend",
+ "AddPreviewTalentPoints",
+ "AddQuestWatch",
+ "AddSkillUp",
+ "AddToAutoHide",
+ "AddTrackedAchievement",
+ "AddTradeMoney",
+ "AlertFrame",
+ "AlertFrame_AnimateIn",
+ "AlertFrame_FixAnchors",
+ "AlertFrame_OnEvent",
+ "AlertFrame_OnLoad",
+ "AlertFrame_ResumeOutAnimation",
+ "AlertFrame_StopOutAnimation",
+ "AltCurrencyFrame_PointsUpdate",
+ "AltCurrencyFrame_Update",
+ "AlternatePowerBar_Initialize",
+ "AlternatePowerBar_OnEvent",
+ "AlternatePowerBar_OnLoad",
+ "AlternatePowerBar_OnUpdate",
+ "AlternatePowerBar_UpdateMaxValues",
+ "AlternatePowerBar_UpdatePowerType",
+ "AlternatePowerBar_UpdateValue",
+ "AlwaysUpFrame1",
+ "AlwaysUpFrame1Text",
+ "AlwaysUpFrame2",
+ "AlwaysUpFrame2DynamicIconButton",
+ "AlwaysUpFrame2Text",
+ "AlwaysUpFrame3DynamicIconButton",
+ "AnimTimerFrame",
+ "AnimTimerFrameCountdownAnimGroup",
+ "AnimateTexCoords",
+ "AnimatedShine_OnUpdate",
+ "AnimatedShine_Start",
+ "AnimatedShine_Stop",
+ "AppendToFile",
+ "ApplyBarberShopStyle",
+ "ApplyUnitButtonConfiguration",
+ "ArenaButton_OnClick",
+ "ArenaEnemyBackground",
+ "ArenaEnemyBackground_SetOpacity",
+ "ArenaEnemyDropDown_Initialize",
+ "ArenaEnemyFrame1",
+ "ArenaEnemyFrame1Background",
+ "ArenaEnemyFrame1CastingBar",
+ "ArenaEnemyFrame1CastingBarBorderShield",
+ "ArenaEnemyFrame1CastingBarFlash",
+ "ArenaEnemyFrame1CastingBarIcon",
+ "ArenaEnemyFrame1CastingBarSpark",
+ "ArenaEnemyFrame1CastingBarText",
+ "ArenaEnemyFrame1ClassPortrait",
+ "ArenaEnemyFrame1Disconnect",
+ "ArenaEnemyFrame1DropDown",
+ "ArenaEnemyFrame1DropDownButton",
+ "ArenaEnemyFrame1DropDownButtonDisabledTexture",
+ "ArenaEnemyFrame1DropDownButtonHighlightTexture",
+ "ArenaEnemyFrame1DropDownButtonNormalTexture",
+ "ArenaEnemyFrame1DropDownButtonPushedTexture",
+ "ArenaEnemyFrame1DropDownLeft",
+ "ArenaEnemyFrame1DropDownMiddle",
+ "ArenaEnemyFrame1DropDownRight",
+ "ArenaEnemyFrame1DropDownText",
+ "ArenaEnemyFrame1Flash",
+ "ArenaEnemyFrame1HealthBar",
+ "ArenaEnemyFrame1HealthBarText",
+ "ArenaEnemyFrame1ManaBar",
+ "ArenaEnemyFrame1ManaBarText",
+ "ArenaEnemyFrame1Name",
+ "ArenaEnemyFrame1PetFrame",
+ "ArenaEnemyFrame1PetFrameDropDown",
+ "ArenaEnemyFrame1PetFrameDropDownButton",
+ "ArenaEnemyFrame1PetFrameDropDownButtonDisabledTexture",
+ "ArenaEnemyFrame1PetFrameDropDownButtonHighlightTexture",
+ "ArenaEnemyFrame1PetFrameDropDownButtonNormalTexture",
+ "ArenaEnemyFrame1PetFrameDropDownButtonPushedTexture",
+ "ArenaEnemyFrame1PetFrameDropDownLeft",
+ "ArenaEnemyFrame1PetFrameDropDownMiddle",
+ "ArenaEnemyFrame1PetFrameDropDownRight",
+ "ArenaEnemyFrame1PetFrameDropDownText",
+ "ArenaEnemyFrame1PetFrameFlash",
+ "ArenaEnemyFrame1PetFrameHealthBar",
+ "ArenaEnemyFrame1PetFrameManaBar",
+ "ArenaEnemyFrame1PetFrameName",
+ "ArenaEnemyFrame1PetFramePortrait",
+ "ArenaEnemyFrame1PetFrameTexture",
+ "ArenaEnemyFrame1Status",
+ "ArenaEnemyFrame1Texture",
+ "ArenaEnemyFrame2",
+ "ArenaEnemyFrame2Background",
+ "ArenaEnemyFrame2CastingBar",
+ "ArenaEnemyFrame2CastingBarBorderShield",
+ "ArenaEnemyFrame2CastingBarFlash",
+ "ArenaEnemyFrame2CastingBarIcon",
+ "ArenaEnemyFrame2CastingBarSpark",
+ "ArenaEnemyFrame2CastingBarText",
+ "ArenaEnemyFrame2ClassPortrait",
+ "ArenaEnemyFrame2Disconnect",
+ "ArenaEnemyFrame2DropDown",
+ "ArenaEnemyFrame2DropDownButton",
+ "ArenaEnemyFrame2DropDownButtonDisabledTexture",
+ "ArenaEnemyFrame2DropDownButtonHighlightTexture",
+ "ArenaEnemyFrame2DropDownButtonNormalTexture",
+ "ArenaEnemyFrame2DropDownButtonPushedTexture",
+ "ArenaEnemyFrame2DropDownLeft",
+ "ArenaEnemyFrame2DropDownMiddle",
+ "ArenaEnemyFrame2DropDownRight",
+ "ArenaEnemyFrame2DropDownText",
+ "ArenaEnemyFrame2Flash",
+ "ArenaEnemyFrame2HealthBar",
+ "ArenaEnemyFrame2HealthBarText",
+ "ArenaEnemyFrame2ManaBar",
+ "ArenaEnemyFrame2ManaBarText",
+ "ArenaEnemyFrame2Name",
+ "ArenaEnemyFrame2PetFrame",
+ "ArenaEnemyFrame2PetFrameDropDown",
+ "ArenaEnemyFrame2PetFrameDropDownButton",
+ "ArenaEnemyFrame2PetFrameDropDownButtonDisabledTexture",
+ "ArenaEnemyFrame2PetFrameDropDownButtonHighlightTexture",
+ "ArenaEnemyFrame2PetFrameDropDownButtonNormalTexture",
+ "ArenaEnemyFrame2PetFrameDropDownButtonPushedTexture",
+ "ArenaEnemyFrame2PetFrameDropDownLeft",
+ "ArenaEnemyFrame2PetFrameDropDownMiddle",
+ "ArenaEnemyFrame2PetFrameDropDownRight",
+ "ArenaEnemyFrame2PetFrameDropDownText",
+ "ArenaEnemyFrame2PetFrameFlash",
+ "ArenaEnemyFrame2PetFrameHealthBar",
+ "ArenaEnemyFrame2PetFrameManaBar",
+ "ArenaEnemyFrame2PetFrameName",
+ "ArenaEnemyFrame2PetFramePortrait",
+ "ArenaEnemyFrame2PetFrameTexture",
+ "ArenaEnemyFrame2Status",
+ "ArenaEnemyFrame2Texture",
+ "ArenaEnemyFrame3",
+ "ArenaEnemyFrame3Background",
+ "ArenaEnemyFrame3CastingBar",
+ "ArenaEnemyFrame3CastingBarBorderShield",
+ "ArenaEnemyFrame3CastingBarFlash",
+ "ArenaEnemyFrame3CastingBarIcon",
+ "ArenaEnemyFrame3CastingBarSpark",
+ "ArenaEnemyFrame3CastingBarText",
+ "ArenaEnemyFrame3ClassPortrait",
+ "ArenaEnemyFrame3Disconnect",
+ "ArenaEnemyFrame3DropDown",
+ "ArenaEnemyFrame3DropDownButton",
+ "ArenaEnemyFrame3DropDownButtonDisabledTexture",
+ "ArenaEnemyFrame3DropDownButtonHighlightTexture",
+ "ArenaEnemyFrame3DropDownButtonNormalTexture",
+ "ArenaEnemyFrame3DropDownButtonPushedTexture",
+ "ArenaEnemyFrame3DropDownLeft",
+ "ArenaEnemyFrame3DropDownMiddle",
+ "ArenaEnemyFrame3DropDownRight",
+ "ArenaEnemyFrame3DropDownText",
+ "ArenaEnemyFrame3Flash",
+ "ArenaEnemyFrame3HealthBar",
+ "ArenaEnemyFrame3HealthBarText",
+ "ArenaEnemyFrame3ManaBar",
+ "ArenaEnemyFrame3ManaBarText",
+ "ArenaEnemyFrame3Name",
+ "ArenaEnemyFrame3PetFrame",
+ "ArenaEnemyFrame3PetFrameDropDown",
+ "ArenaEnemyFrame3PetFrameDropDownButton",
+ "ArenaEnemyFrame3PetFrameDropDownButtonDisabledTexture",
+ "ArenaEnemyFrame3PetFrameDropDownButtonHighlightTexture",
+ "ArenaEnemyFrame3PetFrameDropDownButtonNormalTexture",
+ "ArenaEnemyFrame3PetFrameDropDownButtonPushedTexture",
+ "ArenaEnemyFrame3PetFrameDropDownLeft",
+ "ArenaEnemyFrame3PetFrameDropDownMiddle",
+ "ArenaEnemyFrame3PetFrameDropDownRight",
+ "ArenaEnemyFrame3PetFrameDropDownText",
+ "ArenaEnemyFrame3PetFrameFlash",
+ "ArenaEnemyFrame3PetFrameHealthBar",
+ "ArenaEnemyFrame3PetFrameManaBar",
+ "ArenaEnemyFrame3PetFrameName",
+ "ArenaEnemyFrame3PetFramePortrait",
+ "ArenaEnemyFrame3PetFrameTexture",
+ "ArenaEnemyFrame3Status",
+ "ArenaEnemyFrame3Texture",
+ "ArenaEnemyFrame4",
+ "ArenaEnemyFrame4Background",
+ "ArenaEnemyFrame4CastingBar",
+ "ArenaEnemyFrame4CastingBarBorderShield",
+ "ArenaEnemyFrame4CastingBarFlash",
+ "ArenaEnemyFrame4CastingBarIcon",
+ "ArenaEnemyFrame4CastingBarSpark",
+ "ArenaEnemyFrame4CastingBarText",
+ "ArenaEnemyFrame4ClassPortrait",
+ "ArenaEnemyFrame4Disconnect",
+ "ArenaEnemyFrame4DropDown",
+ "ArenaEnemyFrame4DropDownButton",
+ "ArenaEnemyFrame4DropDownButtonDisabledTexture",
+ "ArenaEnemyFrame4DropDownButtonHighlightTexture",
+ "ArenaEnemyFrame4DropDownButtonNormalTexture",
+ "ArenaEnemyFrame4DropDownButtonPushedTexture",
+ "ArenaEnemyFrame4DropDownLeft",
+ "ArenaEnemyFrame4DropDownMiddle",
+ "ArenaEnemyFrame4DropDownRight",
+ "ArenaEnemyFrame4DropDownText",
+ "ArenaEnemyFrame4Flash",
+ "ArenaEnemyFrame4HealthBar",
+ "ArenaEnemyFrame4HealthBarText",
+ "ArenaEnemyFrame4ManaBar",
+ "ArenaEnemyFrame4ManaBarText",
+ "ArenaEnemyFrame4Name",
+ "ArenaEnemyFrame4PetFrame",
+ "ArenaEnemyFrame4PetFrameDropDown",
+ "ArenaEnemyFrame4PetFrameDropDownButton",
+ "ArenaEnemyFrame4PetFrameDropDownButtonDisabledTexture",
+ "ArenaEnemyFrame4PetFrameDropDownButtonHighlightTexture",
+ "ArenaEnemyFrame4PetFrameDropDownButtonNormalTexture",
+ "ArenaEnemyFrame4PetFrameDropDownButtonPushedTexture",
+ "ArenaEnemyFrame4PetFrameDropDownLeft",
+ "ArenaEnemyFrame4PetFrameDropDownMiddle",
+ "ArenaEnemyFrame4PetFrameDropDownRight",
+ "ArenaEnemyFrame4PetFrameDropDownText",
+ "ArenaEnemyFrame4PetFrameFlash",
+ "ArenaEnemyFrame4PetFrameHealthBar",
+ "ArenaEnemyFrame4PetFrameManaBar",
+ "ArenaEnemyFrame4PetFrameName",
+ "ArenaEnemyFrame4PetFramePortrait",
+ "ArenaEnemyFrame4PetFrameTexture",
+ "ArenaEnemyFrame4Status",
+ "ArenaEnemyFrame4Texture",
+ "ArenaEnemyFrame5",
+ "ArenaEnemyFrame5Background",
+ "ArenaEnemyFrame5CastingBar",
+ "ArenaEnemyFrame5CastingBarBorderShield",
+ "ArenaEnemyFrame5CastingBarFlash",
+ "ArenaEnemyFrame5CastingBarIcon",
+ "ArenaEnemyFrame5CastingBarSpark",
+ "ArenaEnemyFrame5CastingBarText",
+ "ArenaEnemyFrame5ClassPortrait",
+ "ArenaEnemyFrame5Disconnect",
+ "ArenaEnemyFrame5DropDown",
+ "ArenaEnemyFrame5DropDownButton",
+ "ArenaEnemyFrame5DropDownButtonDisabledTexture",
+ "ArenaEnemyFrame5DropDownButtonHighlightTexture",
+ "ArenaEnemyFrame5DropDownButtonNormalTexture",
+ "ArenaEnemyFrame5DropDownButtonPushedTexture",
+ "ArenaEnemyFrame5DropDownLeft",
+ "ArenaEnemyFrame5DropDownMiddle",
+ "ArenaEnemyFrame5DropDownRight",
+ "ArenaEnemyFrame5DropDownText",
+ "ArenaEnemyFrame5Flash",
+ "ArenaEnemyFrame5HealthBar",
+ "ArenaEnemyFrame5HealthBarText",
+ "ArenaEnemyFrame5ManaBar",
+ "ArenaEnemyFrame5ManaBarText",
+ "ArenaEnemyFrame5Name",
+ "ArenaEnemyFrame5PetFrame",
+ "ArenaEnemyFrame5PetFrameDropDown",
+ "ArenaEnemyFrame5PetFrameDropDownButton",
+ "ArenaEnemyFrame5PetFrameDropDownButtonDisabledTexture",
+ "ArenaEnemyFrame5PetFrameDropDownButtonHighlightTexture",
+ "ArenaEnemyFrame5PetFrameDropDownButtonNormalTexture",
+ "ArenaEnemyFrame5PetFrameDropDownButtonPushedTexture",
+ "ArenaEnemyFrame5PetFrameDropDownLeft",
+ "ArenaEnemyFrame5PetFrameDropDownMiddle",
+ "ArenaEnemyFrame5PetFrameDropDownRight",
+ "ArenaEnemyFrame5PetFrameDropDownText",
+ "ArenaEnemyFrame5PetFrameFlash",
+ "ArenaEnemyFrame5PetFrameHealthBar",
+ "ArenaEnemyFrame5PetFrameManaBar",
+ "ArenaEnemyFrame5PetFrameName",
+ "ArenaEnemyFrame5PetFramePortrait",
+ "ArenaEnemyFrame5PetFrameTexture",
+ "ArenaEnemyFrame5Status",
+ "ArenaEnemyFrame5Texture",
+ "ArenaEnemyFrame_Lock",
+ "ArenaEnemyFrame_OnEvent",
+ "ArenaEnemyFrame_OnLoad",
+ "ArenaEnemyFrame_SetMysteryPlayer",
+ "ArenaEnemyFrame_Unlock",
+ "ArenaEnemyFrame_UpdatePet",
+ "ArenaEnemyFrame_UpdatePlayer",
+ "ArenaEnemyFrames",
+ "ArenaEnemyFrames_Disable",
+ "ArenaEnemyFrames_Enable",
+ "ArenaEnemyFrames_OnEvent",
+ "ArenaEnemyFrames_OnHide",
+ "ArenaEnemyFrames_OnLoad",
+ "ArenaEnemyFrames_OnShow",
+ "ArenaEnemyFrames_UpdateVisible",
+ "ArenaEnemyFrames_UpdateWatchFrame",
+ "ArenaEnemyPetDropDown_Initialize",
+ "ArenaEnemyPetFrame_OnEvent",
+ "ArenaEnemyPetFrame_OnLoad",
+ "ArenaFrame",
+ "ArenaFrameCancelButton",
+ "ArenaFrameCancelButtonText",
+ "ArenaFrameCloseButton",
+ "ArenaFrameDivider",
+ "ArenaFrameFrameLabel",
+ "ArenaFrameGroupJoinButton",
+ "ArenaFrameGroupJoinButtonText",
+ "ArenaFrameJoinButton",
+ "ArenaFrameJoinButtonText",
+ "ArenaFrameJoinButton_OnClick",
+ "ArenaFrameNameHeader",
+ "ArenaFrameNameHeader2",
+ "ArenaFramePortrait",
+ "ArenaFrameZoneDescription",
+ "ArenaFrame_OnEvent",
+ "ArenaFrame_OnLoad",
+ "ArenaFrame_Update",
+ "ArenaRegistrarButton1",
+ "ArenaRegistrarButton1QuestIcon",
+ "ArenaRegistrarButton2",
+ "ArenaRegistrarButton2QuestIcon",
+ "ArenaRegistrarButton3",
+ "ArenaRegistrarButton3QuestIcon",
+ "ArenaRegistrarButton4",
+ "ArenaRegistrarButton4QuestIcon",
+ "ArenaRegistrarButton5",
+ "ArenaRegistrarButton5QuestIcon",
+ "ArenaRegistrarButton6",
+ "ArenaRegistrarButton6QuestIcon",
+ "ArenaRegistrarCostLabel",
+ "ArenaRegistrarFrame",
+ "ArenaRegistrarFrameCancelButton",
+ "ArenaRegistrarFrameCancelButtonText",
+ "ArenaRegistrarFrameCloseButton",
+ "ArenaRegistrarFrameEditBox",
+ "ArenaRegistrarFrameGoodbyeButton",
+ "ArenaRegistrarFrameGoodbyeButtonText",
+ "ArenaRegistrarFrameNpcNameText",
+ "ArenaRegistrarFramePortrait",
+ "ArenaRegistrarFramePurchaseButton",
+ "ArenaRegistrarFramePurchaseButtonText",
+ "ArenaRegistrarGreetingFrame",
+ "ArenaRegistrarMoneyFrame",
+ "ArenaRegistrarMoneyFrameCopperButton",
+ "ArenaRegistrarMoneyFrameCopperButtonText",
+ "ArenaRegistrarMoneyFrameGoldButton",
+ "ArenaRegistrarMoneyFrameGoldButtonText",
+ "ArenaRegistrarMoneyFrameSilverButton",
+ "ArenaRegistrarMoneyFrameSilverButtonText",
+ "ArenaRegistrarNpcNameFrame",
+ "ArenaRegistrarPurchaseFrame",
+ "ArenaRegistrarPurchaseText",
+ "ArenaRegistrarText",
+ "ArenaRegistrar_OnEvent",
+ "ArenaRegistrar_OnLoad",
+ "ArenaRegistrar_OnShow",
+ "ArenaRegistrar_ShowPurchaseFrame",
+ "ArenaRegistrar_TurnInPetition",
+ "ArenaRegistrar_UpdatePrice",
+ "ArenaTeamDisband",
+ "ArenaTeamInviteByName",
+ "ArenaTeamLeave",
+ "ArenaTeamRoster",
+ "ArenaTeamSetLeaderByName",
+ "ArenaTeamUninviteByName",
+ "ArenaTeam_GetTeamSizeID",
+ "ArenaZone1",
+ "ArenaZone1Highlight",
+ "ArenaZone1Status",
+ "ArenaZone1Text",
+ "ArenaZone2",
+ "ArenaZone2Highlight",
+ "ArenaZone2Status",
+ "ArenaZone2Text",
+ "ArenaZone3",
+ "ArenaZone3Highlight",
+ "ArenaZone3Status",
+ "ArenaZone3Text",
+ "ArenaZone4",
+ "ArenaZone4Highlight",
+ "ArenaZone4Status",
+ "ArenaZone4Text",
+ "ArenaZone5",
+ "ArenaZone5Highlight",
+ "ArenaZone5Status",
+ "ArenaZone5Text",
+ "ArenaZone6",
+ "ArenaZone6Highlight",
+ "ArenaZone6Status",
+ "ArenaZone6Text",
+ "Arena_LoadUI",
+ "AscendStop",
+ "AssistUnit",
+ "AttackTarget",
+ "AuctionDressUpBackgroundBot",
+ "AuctionDressUpBackgroundTop",
+ "AuctionDressUpFrame",
+ "AuctionDressUpFrameCloseButton",
+ "AuctionDressUpFrameResetButton",
+ "AuctionDressUpFrameResetButtonText",
+ "AuctionDressUpFrameTop",
+ "AuctionDressUpFrame_OnHide",
+ "AuctionDressUpFrame_OnShow",
+ "AuctionDressUpModel",
+ "AuctionDressUpModelRotateLeftButton",
+ "AuctionDressUpModelRotateRightButton",
+ "AuctionFilterButton1",
+ "AuctionFilterButton10",
+ "AuctionFilterButton10Lines",
+ "AuctionFilterButton10NormalText",
+ "AuctionFilterButton10NormalTexture",
+ "AuctionFilterButton11",
+ "AuctionFilterButton11Lines",
+ "AuctionFilterButton11NormalText",
+ "AuctionFilterButton11NormalTexture",
+ "AuctionFilterButton12",
+ "AuctionFilterButton12Lines",
+ "AuctionFilterButton12NormalText",
+ "AuctionFilterButton12NormalTexture",
+ "AuctionFilterButton13",
+ "AuctionFilterButton13Lines",
+ "AuctionFilterButton13NormalText",
+ "AuctionFilterButton13NormalTexture",
+ "AuctionFilterButton14",
+ "AuctionFilterButton14Lines",
+ "AuctionFilterButton14NormalText",
+ "AuctionFilterButton14NormalTexture",
+ "AuctionFilterButton15",
+ "AuctionFilterButton15Lines",
+ "AuctionFilterButton15NormalText",
+ "AuctionFilterButton15NormalTexture",
+ "AuctionFilterButton1Lines",
+ "AuctionFilterButton1NormalText",
+ "AuctionFilterButton1NormalTexture",
+ "AuctionFilterButton2",
+ "AuctionFilterButton2Lines",
+ "AuctionFilterButton2NormalText",
+ "AuctionFilterButton2NormalTexture",
+ "AuctionFilterButton3",
+ "AuctionFilterButton3Lines",
+ "AuctionFilterButton3NormalText",
+ "AuctionFilterButton3NormalTexture",
+ "AuctionFilterButton4",
+ "AuctionFilterButton4Lines",
+ "AuctionFilterButton4NormalText",
+ "AuctionFilterButton4NormalTexture",
+ "AuctionFilterButton5",
+ "AuctionFilterButton5Lines",
+ "AuctionFilterButton5NormalText",
+ "AuctionFilterButton5NormalTexture",
+ "AuctionFilterButton6",
+ "AuctionFilterButton6Lines",
+ "AuctionFilterButton6NormalText",
+ "AuctionFilterButton6NormalTexture",
+ "AuctionFilterButton7",
+ "AuctionFilterButton7Lines",
+ "AuctionFilterButton7NormalText",
+ "AuctionFilterButton7NormalTexture",
+ "AuctionFilterButton8",
+ "AuctionFilterButton8Lines",
+ "AuctionFilterButton8NormalText",
+ "AuctionFilterButton8NormalTexture",
+ "AuctionFilterButton9",
+ "AuctionFilterButton9Lines",
+ "AuctionFilterButton9NormalText",
+ "AuctionFilterButton9NormalTexture",
+ "AuctionFrame",
+ "AuctionFrameAuctions",
+ "AuctionFrameAuctions_OnEvent",
+ "AuctionFrameAuctions_OnLoad",
+ "AuctionFrameAuctions_OnShow",
+ "AuctionFrameAuctions_Update",
+ "AuctionFrameBid",
+ "AuctionFrameBid_OnEvent",
+ "AuctionFrameBid_OnLoad",
+ "AuctionFrameBid_OnShow",
+ "AuctionFrameBid_Update",
+ "AuctionFrameBot",
+ "AuctionFrameBotLeft",
+ "AuctionFrameBotRight",
+ "AuctionFrameBrowse",
+ "AuctionFrameBrowse_InitClasses",
+ "AuctionFrameBrowse_OnEvent",
+ "AuctionFrameBrowse_OnLoad",
+ "AuctionFrameBrowse_OnShow",
+ "AuctionFrameBrowse_Reset",
+ "AuctionFrameBrowse_Search",
+ "AuctionFrameBrowse_Update",
+ "AuctionFrameBrowse_UpdateArrows",
+ "AuctionFrameCloseButton",
+ "AuctionFrameFilter_OnClick",
+ "AuctionFrameFilters_Update",
+ "AuctionFrameFilters_UpdateClasses",
+ "AuctionFrameFilters_UpdateInvTypes",
+ "AuctionFrameFilters_UpdateSubClasses",
+ "AuctionFrameItem_OnEnter",
+ "AuctionFrameMoneyFrame",
+ "AuctionFrameMoneyFrameCopperButton",
+ "AuctionFrameMoneyFrameCopperButtonText",
+ "AuctionFrameMoneyFrameGoldButton",
+ "AuctionFrameMoneyFrameGoldButtonText",
+ "AuctionFrameMoneyFrameSilverButton",
+ "AuctionFrameMoneyFrameSilverButtonText",
+ "AuctionFrameTab1",
+ "AuctionFrameTab1HighlightTexture",
+ "AuctionFrameTab1Left",
+ "AuctionFrameTab1LeftDisabled",
+ "AuctionFrameTab1Middle",
+ "AuctionFrameTab1MiddleDisabled",
+ "AuctionFrameTab1Right",
+ "AuctionFrameTab1RightDisabled",
+ "AuctionFrameTab1Text",
+ "AuctionFrameTab2",
+ "AuctionFrameTab2HighlightTexture",
+ "AuctionFrameTab2Left",
+ "AuctionFrameTab2LeftDisabled",
+ "AuctionFrameTab2Middle",
+ "AuctionFrameTab2MiddleDisabled",
+ "AuctionFrameTab2Right",
+ "AuctionFrameTab2RightDisabled",
+ "AuctionFrameTab2Text",
+ "AuctionFrameTab3",
+ "AuctionFrameTab3HighlightTexture",
+ "AuctionFrameTab3Left",
+ "AuctionFrameTab3LeftDisabled",
+ "AuctionFrameTab3Middle",
+ "AuctionFrameTab3MiddleDisabled",
+ "AuctionFrameTab3Right",
+ "AuctionFrameTab3RightDisabled",
+ "AuctionFrameTab3Text",
+ "AuctionFrameTab_OnClick",
+ "AuctionFrameTop",
+ "AuctionFrameTopLeft",
+ "AuctionFrameTopRight",
+ "AuctionFrame_GetTimeLeftText",
+ "AuctionFrame_GetTimeLeftTooltipText",
+ "AuctionFrame_Hide",
+ "AuctionFrame_LoadUI",
+ "AuctionFrame_OnClickSortColumn",
+ "AuctionFrame_OnLoad",
+ "AuctionFrame_OnShow",
+ "AuctionFrame_SetSort",
+ "AuctionFrame_Show",
+ "AuctionPortraitTexture",
+ "AuctionProgressBar",
+ "AuctionProgressBarBorder",
+ "AuctionProgressBarBorderShield",
+ "AuctionProgressBarFlash",
+ "AuctionProgressBarIcon",
+ "AuctionProgressBarSpark",
+ "AuctionProgressBarText",
+ "AuctionProgressFrame",
+ "AuctionProgressFrameCancelButton",
+ "AuctionProgressFrameFill",
+ "AuctionProgressFrameLeft",
+ "AuctionProgressFrameMiddle",
+ "AuctionProgressFrameRight",
+ "AuctionProgressFrame_OnUpdate",
+ "AuctionSellItemButton_OnClick",
+ "AuctionSellItemButton_OnEvent",
+ "AuctionSort",
+ "AuctionsBidSort",
+ "AuctionsBidSortArrow",
+ "AuctionsBidSortLeft",
+ "AuctionsBidSortMiddle",
+ "AuctionsBidSortRight",
+ "AuctionsBidSortText",
+ "AuctionsBlockFrame",
+ "AuctionsButton1",
+ "AuctionsButton1BuyoutFrame",
+ "AuctionsButton1BuyoutFrameMoney",
+ "AuctionsButton1BuyoutFrameMoneyCopperButton",
+ "AuctionsButton1BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton1BuyoutFrameMoneyGoldButton",
+ "AuctionsButton1BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton1BuyoutFrameMoneySilverButton",
+ "AuctionsButton1BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton1BuyoutFrameText",
+ "AuctionsButton1ClosingTime",
+ "AuctionsButton1ClosingTimeText",
+ "AuctionsButton1HighBidder",
+ "AuctionsButton1Highlight",
+ "AuctionsButton1Item",
+ "AuctionsButton1ItemCount",
+ "AuctionsButton1ItemIconTexture",
+ "AuctionsButton1ItemNormalTexture",
+ "AuctionsButton1ItemStock",
+ "AuctionsButton1Left",
+ "AuctionsButton1MoneyFrame",
+ "AuctionsButton1MoneyFrameCopperButton",
+ "AuctionsButton1MoneyFrameCopperButtonText",
+ "AuctionsButton1MoneyFrameGoldButton",
+ "AuctionsButton1MoneyFrameGoldButtonText",
+ "AuctionsButton1MoneyFrameLabel",
+ "AuctionsButton1MoneyFrameSilverButton",
+ "AuctionsButton1MoneyFrameSilverButtonText",
+ "AuctionsButton1Name",
+ "AuctionsButton1Right",
+ "AuctionsButton2",
+ "AuctionsButton2BuyoutFrame",
+ "AuctionsButton2BuyoutFrameMoney",
+ "AuctionsButton2BuyoutFrameMoneyCopperButton",
+ "AuctionsButton2BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton2BuyoutFrameMoneyGoldButton",
+ "AuctionsButton2BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton2BuyoutFrameMoneySilverButton",
+ "AuctionsButton2BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton2BuyoutFrameText",
+ "AuctionsButton2ClosingTime",
+ "AuctionsButton2ClosingTimeText",
+ "AuctionsButton2HighBidder",
+ "AuctionsButton2Highlight",
+ "AuctionsButton2Item",
+ "AuctionsButton2ItemCount",
+ "AuctionsButton2ItemIconTexture",
+ "AuctionsButton2ItemNormalTexture",
+ "AuctionsButton2ItemStock",
+ "AuctionsButton2Left",
+ "AuctionsButton2MoneyFrame",
+ "AuctionsButton2MoneyFrameCopperButton",
+ "AuctionsButton2MoneyFrameCopperButtonText",
+ "AuctionsButton2MoneyFrameGoldButton",
+ "AuctionsButton2MoneyFrameGoldButtonText",
+ "AuctionsButton2MoneyFrameLabel",
+ "AuctionsButton2MoneyFrameSilverButton",
+ "AuctionsButton2MoneyFrameSilverButtonText",
+ "AuctionsButton2Name",
+ "AuctionsButton2Right",
+ "AuctionsButton3",
+ "AuctionsButton3BuyoutFrame",
+ "AuctionsButton3BuyoutFrameMoney",
+ "AuctionsButton3BuyoutFrameMoneyCopperButton",
+ "AuctionsButton3BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton3BuyoutFrameMoneyGoldButton",
+ "AuctionsButton3BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton3BuyoutFrameMoneySilverButton",
+ "AuctionsButton3BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton3BuyoutFrameText",
+ "AuctionsButton3ClosingTime",
+ "AuctionsButton3ClosingTimeText",
+ "AuctionsButton3HighBidder",
+ "AuctionsButton3Highlight",
+ "AuctionsButton3Item",
+ "AuctionsButton3ItemCount",
+ "AuctionsButton3ItemIconTexture",
+ "AuctionsButton3ItemNormalTexture",
+ "AuctionsButton3ItemStock",
+ "AuctionsButton3Left",
+ "AuctionsButton3MoneyFrame",
+ "AuctionsButton3MoneyFrameCopperButton",
+ "AuctionsButton3MoneyFrameCopperButtonText",
+ "AuctionsButton3MoneyFrameGoldButton",
+ "AuctionsButton3MoneyFrameGoldButtonText",
+ "AuctionsButton3MoneyFrameLabel",
+ "AuctionsButton3MoneyFrameSilverButton",
+ "AuctionsButton3MoneyFrameSilverButtonText",
+ "AuctionsButton3Name",
+ "AuctionsButton3Right",
+ "AuctionsButton4",
+ "AuctionsButton4BuyoutFrame",
+ "AuctionsButton4BuyoutFrameMoney",
+ "AuctionsButton4BuyoutFrameMoneyCopperButton",
+ "AuctionsButton4BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton4BuyoutFrameMoneyGoldButton",
+ "AuctionsButton4BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton4BuyoutFrameMoneySilverButton",
+ "AuctionsButton4BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton4BuyoutFrameText",
+ "AuctionsButton4ClosingTime",
+ "AuctionsButton4ClosingTimeText",
+ "AuctionsButton4HighBidder",
+ "AuctionsButton4Highlight",
+ "AuctionsButton4Item",
+ "AuctionsButton4ItemCount",
+ "AuctionsButton4ItemIconTexture",
+ "AuctionsButton4ItemNormalTexture",
+ "AuctionsButton4ItemStock",
+ "AuctionsButton4Left",
+ "AuctionsButton4MoneyFrame",
+ "AuctionsButton4MoneyFrameCopperButton",
+ "AuctionsButton4MoneyFrameCopperButtonText",
+ "AuctionsButton4MoneyFrameGoldButton",
+ "AuctionsButton4MoneyFrameGoldButtonText",
+ "AuctionsButton4MoneyFrameLabel",
+ "AuctionsButton4MoneyFrameSilverButton",
+ "AuctionsButton4MoneyFrameSilverButtonText",
+ "AuctionsButton4Name",
+ "AuctionsButton4Right",
+ "AuctionsButton5",
+ "AuctionsButton5BuyoutFrame",
+ "AuctionsButton5BuyoutFrameMoney",
+ "AuctionsButton5BuyoutFrameMoneyCopperButton",
+ "AuctionsButton5BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton5BuyoutFrameMoneyGoldButton",
+ "AuctionsButton5BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton5BuyoutFrameMoneySilverButton",
+ "AuctionsButton5BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton5BuyoutFrameText",
+ "AuctionsButton5ClosingTime",
+ "AuctionsButton5ClosingTimeText",
+ "AuctionsButton5HighBidder",
+ "AuctionsButton5Highlight",
+ "AuctionsButton5Item",
+ "AuctionsButton5ItemCount",
+ "AuctionsButton5ItemIconTexture",
+ "AuctionsButton5ItemNormalTexture",
+ "AuctionsButton5ItemStock",
+ "AuctionsButton5Left",
+ "AuctionsButton5MoneyFrame",
+ "AuctionsButton5MoneyFrameCopperButton",
+ "AuctionsButton5MoneyFrameCopperButtonText",
+ "AuctionsButton5MoneyFrameGoldButton",
+ "AuctionsButton5MoneyFrameGoldButtonText",
+ "AuctionsButton5MoneyFrameLabel",
+ "AuctionsButton5MoneyFrameSilverButton",
+ "AuctionsButton5MoneyFrameSilverButtonText",
+ "AuctionsButton5Name",
+ "AuctionsButton5Right",
+ "AuctionsButton6",
+ "AuctionsButton6BuyoutFrame",
+ "AuctionsButton6BuyoutFrameMoney",
+ "AuctionsButton6BuyoutFrameMoneyCopperButton",
+ "AuctionsButton6BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton6BuyoutFrameMoneyGoldButton",
+ "AuctionsButton6BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton6BuyoutFrameMoneySilverButton",
+ "AuctionsButton6BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton6BuyoutFrameText",
+ "AuctionsButton6ClosingTime",
+ "AuctionsButton6ClosingTimeText",
+ "AuctionsButton6HighBidder",
+ "AuctionsButton6Highlight",
+ "AuctionsButton6Item",
+ "AuctionsButton6ItemCount",
+ "AuctionsButton6ItemIconTexture",
+ "AuctionsButton6ItemNormalTexture",
+ "AuctionsButton6ItemStock",
+ "AuctionsButton6Left",
+ "AuctionsButton6MoneyFrame",
+ "AuctionsButton6MoneyFrameCopperButton",
+ "AuctionsButton6MoneyFrameCopperButtonText",
+ "AuctionsButton6MoneyFrameGoldButton",
+ "AuctionsButton6MoneyFrameGoldButtonText",
+ "AuctionsButton6MoneyFrameLabel",
+ "AuctionsButton6MoneyFrameSilverButton",
+ "AuctionsButton6MoneyFrameSilverButtonText",
+ "AuctionsButton6Name",
+ "AuctionsButton6Right",
+ "AuctionsButton7",
+ "AuctionsButton7BuyoutFrame",
+ "AuctionsButton7BuyoutFrameMoney",
+ "AuctionsButton7BuyoutFrameMoneyCopperButton",
+ "AuctionsButton7BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton7BuyoutFrameMoneyGoldButton",
+ "AuctionsButton7BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton7BuyoutFrameMoneySilverButton",
+ "AuctionsButton7BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton7BuyoutFrameText",
+ "AuctionsButton7ClosingTime",
+ "AuctionsButton7ClosingTimeText",
+ "AuctionsButton7HighBidder",
+ "AuctionsButton7Highlight",
+ "AuctionsButton7Item",
+ "AuctionsButton7ItemCount",
+ "AuctionsButton7ItemIconTexture",
+ "AuctionsButton7ItemNormalTexture",
+ "AuctionsButton7ItemStock",
+ "AuctionsButton7Left",
+ "AuctionsButton7MoneyFrame",
+ "AuctionsButton7MoneyFrameCopperButton",
+ "AuctionsButton7MoneyFrameCopperButtonText",
+ "AuctionsButton7MoneyFrameGoldButton",
+ "AuctionsButton7MoneyFrameGoldButtonText",
+ "AuctionsButton7MoneyFrameLabel",
+ "AuctionsButton7MoneyFrameSilverButton",
+ "AuctionsButton7MoneyFrameSilverButtonText",
+ "AuctionsButton7Name",
+ "AuctionsButton7Right",
+ "AuctionsButton8",
+ "AuctionsButton8BuyoutFrame",
+ "AuctionsButton8BuyoutFrameMoney",
+ "AuctionsButton8BuyoutFrameMoneyCopperButton",
+ "AuctionsButton8BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton8BuyoutFrameMoneyGoldButton",
+ "AuctionsButton8BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton8BuyoutFrameMoneySilverButton",
+ "AuctionsButton8BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton8BuyoutFrameText",
+ "AuctionsButton8ClosingTime",
+ "AuctionsButton8ClosingTimeText",
+ "AuctionsButton8HighBidder",
+ "AuctionsButton8Highlight",
+ "AuctionsButton8Item",
+ "AuctionsButton8ItemCount",
+ "AuctionsButton8ItemIconTexture",
+ "AuctionsButton8ItemNormalTexture",
+ "AuctionsButton8ItemStock",
+ "AuctionsButton8Left",
+ "AuctionsButton8MoneyFrame",
+ "AuctionsButton8MoneyFrameCopperButton",
+ "AuctionsButton8MoneyFrameCopperButtonText",
+ "AuctionsButton8MoneyFrameGoldButton",
+ "AuctionsButton8MoneyFrameGoldButtonText",
+ "AuctionsButton8MoneyFrameLabel",
+ "AuctionsButton8MoneyFrameSilverButton",
+ "AuctionsButton8MoneyFrameSilverButtonText",
+ "AuctionsButton8Name",
+ "AuctionsButton8Right",
+ "AuctionsButton9",
+ "AuctionsButton9BuyoutFrame",
+ "AuctionsButton9BuyoutFrameMoney",
+ "AuctionsButton9BuyoutFrameMoneyCopperButton",
+ "AuctionsButton9BuyoutFrameMoneyCopperButtonText",
+ "AuctionsButton9BuyoutFrameMoneyGoldButton",
+ "AuctionsButton9BuyoutFrameMoneyGoldButtonText",
+ "AuctionsButton9BuyoutFrameMoneySilverButton",
+ "AuctionsButton9BuyoutFrameMoneySilverButtonText",
+ "AuctionsButton9BuyoutFrameText",
+ "AuctionsButton9ClosingTime",
+ "AuctionsButton9ClosingTimeText",
+ "AuctionsButton9HighBidder",
+ "AuctionsButton9Highlight",
+ "AuctionsButton9Item",
+ "AuctionsButton9ItemCount",
+ "AuctionsButton9ItemIconTexture",
+ "AuctionsButton9ItemNormalTexture",
+ "AuctionsButton9ItemStock",
+ "AuctionsButton9Left",
+ "AuctionsButton9MoneyFrame",
+ "AuctionsButton9MoneyFrameCopperButton",
+ "AuctionsButton9MoneyFrameCopperButtonText",
+ "AuctionsButton9MoneyFrameGoldButton",
+ "AuctionsButton9MoneyFrameGoldButtonText",
+ "AuctionsButton9MoneyFrameLabel",
+ "AuctionsButton9MoneyFrameSilverButton",
+ "AuctionsButton9MoneyFrameSilverButtonText",
+ "AuctionsButton9Name",
+ "AuctionsButton9Right",
+ "AuctionsButton_OnClick",
+ "AuctionsBuyoutError",
+ "AuctionsBuyoutText",
+ "AuctionsCancelAuctionButton",
+ "AuctionsCancelAuctionButtonLeft",
+ "AuctionsCancelAuctionButtonMiddle",
+ "AuctionsCancelAuctionButtonRight",
+ "AuctionsCancelAuctionButtonText",
+ "AuctionsCloseButton",
+ "AuctionsCloseButtonText",
+ "AuctionsCreateAuctionButton",
+ "AuctionsCreateAuctionButtonLeft",
+ "AuctionsCreateAuctionButtonMiddle",
+ "AuctionsCreateAuctionButtonRight",
+ "AuctionsCreateAuctionButtonText",
+ "AuctionsCreateAuctionButton_OnClick",
+ "AuctionsDepositMoneyFrame",
+ "AuctionsDepositMoneyFrameCopperButton",
+ "AuctionsDepositMoneyFrameCopperButtonText",
+ "AuctionsDepositMoneyFrameGoldButton",
+ "AuctionsDepositMoneyFrameGoldButtonText",
+ "AuctionsDepositMoneyFrameSilverButton",
+ "AuctionsDepositMoneyFrameSilverButtonText",
+ "AuctionsDepositText",
+ "AuctionsDurationSort",
+ "AuctionsDurationSortArrow",
+ "AuctionsDurationSortLeft",
+ "AuctionsDurationSortMiddle",
+ "AuctionsDurationSortRight",
+ "AuctionsDurationSortText",
+ "AuctionsFrameAuctions_ValidateAuction",
+ "AuctionsHighBidderSort",
+ "AuctionsHighBidderSortArrow",
+ "AuctionsHighBidderSortLeft",
+ "AuctionsHighBidderSortMiddle",
+ "AuctionsHighBidderSortRight",
+ "AuctionsHighBidderSortText",
+ "AuctionsItemButton",
+ "AuctionsItemButtonCount",
+ "AuctionsItemButtonName",
+ "AuctionsItemText",
+ "AuctionsNumStacksEntry",
+ "AuctionsNumStacksEntryLeft",
+ "AuctionsNumStacksEntryMiddle",
+ "AuctionsNumStacksEntryRight",
+ "AuctionsNumStacksMaxButton",
+ "AuctionsNumStacksMaxButtonLeft",
+ "AuctionsNumStacksMaxButtonMiddle",
+ "AuctionsNumStacksMaxButtonRight",
+ "AuctionsNumStacksMaxButtonText",
+ "AuctionsQualitySort",
+ "AuctionsQualitySortArrow",
+ "AuctionsQualitySortLeft",
+ "AuctionsQualitySortMiddle",
+ "AuctionsQualitySortRight",
+ "AuctionsQualitySortText",
+ "AuctionsScrollFrame",
+ "AuctionsScrollFrameScrollBar",
+ "AuctionsScrollFrameScrollBarScrollDownButton",
+ "AuctionsScrollFrameScrollBarScrollUpButton",
+ "AuctionsScrollFrameScrollBarThumbTexture",
+ "AuctionsScrollFrameScrollChildFrame",
+ "AuctionsSearchCountText",
+ "AuctionsStackSizeEntry",
+ "AuctionsStackSizeEntryLeft",
+ "AuctionsStackSizeEntryMiddle",
+ "AuctionsStackSizeEntryRight",
+ "AuctionsStackSizeMaxButton",
+ "AuctionsStackSizeMaxButtonLeft",
+ "AuctionsStackSizeMaxButtonMiddle",
+ "AuctionsStackSizeMaxButtonRight",
+ "AuctionsStackSizeMaxButtonText",
+ "AuctionsTabText",
+ "AuctionsTitle",
+ "AudioOptionsFrame",
+ "AudioOptionsFrameCancel",
+ "AudioOptionsFrameCancelText",
+ "AudioOptionsFrameCancel_OnClick",
+ "AudioOptionsFrameCategoryFrame",
+ "AudioOptionsFrameCategoryFrameBottom",
+ "AudioOptionsFrameCategoryFrameBottomLeft",
+ "AudioOptionsFrameCategoryFrameBottomRight",
+ "AudioOptionsFrameCategoryFrameButton1",
+ "AudioOptionsFrameCategoryFrameButton10",
+ "AudioOptionsFrameCategoryFrameButton10Text",
+ "AudioOptionsFrameCategoryFrameButton10Toggle",
+ "AudioOptionsFrameCategoryFrameButton10ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton10ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton10TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton11",
+ "AudioOptionsFrameCategoryFrameButton11Text",
+ "AudioOptionsFrameCategoryFrameButton11Toggle",
+ "AudioOptionsFrameCategoryFrameButton11ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton11ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton11TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton12",
+ "AudioOptionsFrameCategoryFrameButton12Text",
+ "AudioOptionsFrameCategoryFrameButton12Toggle",
+ "AudioOptionsFrameCategoryFrameButton12ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton12ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton12TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton13",
+ "AudioOptionsFrameCategoryFrameButton13Text",
+ "AudioOptionsFrameCategoryFrameButton13Toggle",
+ "AudioOptionsFrameCategoryFrameButton13ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton13ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton13TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton14",
+ "AudioOptionsFrameCategoryFrameButton14Text",
+ "AudioOptionsFrameCategoryFrameButton14Toggle",
+ "AudioOptionsFrameCategoryFrameButton14ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton14ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton14TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton15",
+ "AudioOptionsFrameCategoryFrameButton15Text",
+ "AudioOptionsFrameCategoryFrameButton15Toggle",
+ "AudioOptionsFrameCategoryFrameButton15ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton15ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton15TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton16",
+ "AudioOptionsFrameCategoryFrameButton16Text",
+ "AudioOptionsFrameCategoryFrameButton16Toggle",
+ "AudioOptionsFrameCategoryFrameButton16ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton16ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton16TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton17",
+ "AudioOptionsFrameCategoryFrameButton17Text",
+ "AudioOptionsFrameCategoryFrameButton17Toggle",
+ "AudioOptionsFrameCategoryFrameButton17ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton17ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton17TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton18",
+ "AudioOptionsFrameCategoryFrameButton18Text",
+ "AudioOptionsFrameCategoryFrameButton18Toggle",
+ "AudioOptionsFrameCategoryFrameButton18ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton18ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton18TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton19",
+ "AudioOptionsFrameCategoryFrameButton19Text",
+ "AudioOptionsFrameCategoryFrameButton19Toggle",
+ "AudioOptionsFrameCategoryFrameButton19ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton19ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton19TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton1Text",
+ "AudioOptionsFrameCategoryFrameButton1Toggle",
+ "AudioOptionsFrameCategoryFrameButton1ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton1ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton1TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton2",
+ "AudioOptionsFrameCategoryFrameButton20",
+ "AudioOptionsFrameCategoryFrameButton20Text",
+ "AudioOptionsFrameCategoryFrameButton20Toggle",
+ "AudioOptionsFrameCategoryFrameButton20ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton20ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton20TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton21",
+ "AudioOptionsFrameCategoryFrameButton21Text",
+ "AudioOptionsFrameCategoryFrameButton21Toggle",
+ "AudioOptionsFrameCategoryFrameButton21ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton21ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton21TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton22",
+ "AudioOptionsFrameCategoryFrameButton22Text",
+ "AudioOptionsFrameCategoryFrameButton22Toggle",
+ "AudioOptionsFrameCategoryFrameButton22ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton22ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton22TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton23",
+ "AudioOptionsFrameCategoryFrameButton23Text",
+ "AudioOptionsFrameCategoryFrameButton23Toggle",
+ "AudioOptionsFrameCategoryFrameButton23ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton23ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton23TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton2Text",
+ "AudioOptionsFrameCategoryFrameButton2Toggle",
+ "AudioOptionsFrameCategoryFrameButton2ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton2ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton2TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton3",
+ "AudioOptionsFrameCategoryFrameButton3Text",
+ "AudioOptionsFrameCategoryFrameButton3Toggle",
+ "AudioOptionsFrameCategoryFrameButton3ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton3ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton3TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton4",
+ "AudioOptionsFrameCategoryFrameButton4Text",
+ "AudioOptionsFrameCategoryFrameButton4Toggle",
+ "AudioOptionsFrameCategoryFrameButton4ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton4ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton4TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton5",
+ "AudioOptionsFrameCategoryFrameButton5Text",
+ "AudioOptionsFrameCategoryFrameButton5Toggle",
+ "AudioOptionsFrameCategoryFrameButton5ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton5ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton5TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton6",
+ "AudioOptionsFrameCategoryFrameButton6Text",
+ "AudioOptionsFrameCategoryFrameButton6Toggle",
+ "AudioOptionsFrameCategoryFrameButton6ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton6ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton6TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton7",
+ "AudioOptionsFrameCategoryFrameButton7Text",
+ "AudioOptionsFrameCategoryFrameButton7Toggle",
+ "AudioOptionsFrameCategoryFrameButton7ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton7ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton7TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton8",
+ "AudioOptionsFrameCategoryFrameButton8Text",
+ "AudioOptionsFrameCategoryFrameButton8Toggle",
+ "AudioOptionsFrameCategoryFrameButton8ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton8ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton8TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameButton9",
+ "AudioOptionsFrameCategoryFrameButton9Text",
+ "AudioOptionsFrameCategoryFrameButton9Toggle",
+ "AudioOptionsFrameCategoryFrameButton9ToggleHighlightTexture",
+ "AudioOptionsFrameCategoryFrameButton9ToggleNormalTexture",
+ "AudioOptionsFrameCategoryFrameButton9TogglePushedTexture",
+ "AudioOptionsFrameCategoryFrameLeft",
+ "AudioOptionsFrameCategoryFrameList",
+ "AudioOptionsFrameCategoryFrameListScrollBar",
+ "AudioOptionsFrameCategoryFrameListScrollBarScrollDownButton",
+ "AudioOptionsFrameCategoryFrameListScrollBarScrollUpButton",
+ "AudioOptionsFrameCategoryFrameListScrollBarThumbTexture",
+ "AudioOptionsFrameCategoryFrameListScrollChildFrame",
+ "AudioOptionsFrameCategoryFrameRight",
+ "AudioOptionsFrameCategoryFrameTop",
+ "AudioOptionsFrameCategoryFrameTopLeft",
+ "AudioOptionsFrameCategoryFrameTopRight",
+ "AudioOptionsFrameDefault_OnClick",
+ "AudioOptionsFrameDefaults",
+ "AudioOptionsFrameHeader",
+ "AudioOptionsFrameHeaderText",
+ "AudioOptionsFrameOkay",
+ "AudioOptionsFrameOkayText",
+ "AudioOptionsFrameOkay_OnClick",
+ "AudioOptionsFramePanelContainer",
+ "AudioOptionsFrame_AudioRestart",
+ "AudioOptionsFrame_OnEvent",
+ "AudioOptionsFrame_OnHide",
+ "AudioOptionsFrame_OnLoad",
+ "AudioOptionsFrame_SetAllToDefaults",
+ "AudioOptionsFrame_SetCurrentToDefaults",
+ "AudioOptionsFrame_Toggle",
+ "AudioOptionsPanel_CheckButton_OnClick",
+ "AudioOptionsSoundPanel",
+ "AudioOptionsSoundPanelAmbienceVolume",
+ "AudioOptionsSoundPanelAmbienceVolumeHigh",
+ "AudioOptionsSoundPanelAmbienceVolumeLabel",
+ "AudioOptionsSoundPanelAmbienceVolumeLow",
+ "AudioOptionsSoundPanelAmbienceVolumeText",
+ "AudioOptionsSoundPanelAmbienceVolumeThumb",
+ "AudioOptionsSoundPanelAmbientSounds",
+ "AudioOptionsSoundPanelAmbientSoundsText",
+ "AudioOptionsSoundPanelEmoteSounds",
+ "AudioOptionsSoundPanelEmoteSoundsText",
+ "AudioOptionsSoundPanelEnableDSPs",
+ "AudioOptionsSoundPanelEnableDSPsText",
+ "AudioOptionsSoundPanelEnableSound",
+ "AudioOptionsSoundPanelEnableSoundText",
+ "AudioOptionsSoundPanelErrorSpeech",
+ "AudioOptionsSoundPanelErrorSpeechText",
+ "AudioOptionsSoundPanelHRTF",
+ "AudioOptionsSoundPanelHRTFText",
+ "AudioOptionsSoundPanelHardware",
+ "AudioOptionsSoundPanelHardwareDropDown",
+ "AudioOptionsSoundPanelHardwareDropDownButton",
+ "AudioOptionsSoundPanelHardwareDropDownButtonDisabledTexture",
+ "AudioOptionsSoundPanelHardwareDropDownButtonHighlightTexture",
+ "AudioOptionsSoundPanelHardwareDropDownButtonNormalTexture",
+ "AudioOptionsSoundPanelHardwareDropDownButtonPushedTexture",
+ "AudioOptionsSoundPanelHardwareDropDownLabel",
+ "AudioOptionsSoundPanelHardwareDropDownLeft",
+ "AudioOptionsSoundPanelHardwareDropDownMiddle",
+ "AudioOptionsSoundPanelHardwareDropDownRight",
+ "AudioOptionsSoundPanelHardwareDropDownText",
+ "AudioOptionsSoundPanelHardwareDropDown_Initialize",
+ "AudioOptionsSoundPanelHardwareDropDown_OnClick",
+ "AudioOptionsSoundPanelHardwareDropDown_OnLoad",
+ "AudioOptionsSoundPanelHardwareTitle",
+ "AudioOptionsSoundPanelLoopMusic",
+ "AudioOptionsSoundPanelLoopMusicText",
+ "AudioOptionsSoundPanelMasterVolume",
+ "AudioOptionsSoundPanelMasterVolumeHigh",
+ "AudioOptionsSoundPanelMasterVolumeLabel",
+ "AudioOptionsSoundPanelMasterVolumeLow",
+ "AudioOptionsSoundPanelMasterVolumeText",
+ "AudioOptionsSoundPanelMasterVolumeThumb",
+ "AudioOptionsSoundPanelMusic",
+ "AudioOptionsSoundPanelMusicText",
+ "AudioOptionsSoundPanelMusicVolume",
+ "AudioOptionsSoundPanelMusicVolumeHigh",
+ "AudioOptionsSoundPanelMusicVolumeLabel",
+ "AudioOptionsSoundPanelMusicVolumeLow",
+ "AudioOptionsSoundPanelMusicVolumeText",
+ "AudioOptionsSoundPanelMusicVolumeThumb",
+ "AudioOptionsSoundPanelPetSounds",
+ "AudioOptionsSoundPanelPetSoundsText",
+ "AudioOptionsSoundPanelPlayback",
+ "AudioOptionsSoundPanelPlaybackTitle",
+ "AudioOptionsSoundPanelReverb",
+ "AudioOptionsSoundPanelReverbText",
+ "AudioOptionsSoundPanelSoundChannels",
+ "AudioOptionsSoundPanelSoundChannelsHigh",
+ "AudioOptionsSoundPanelSoundChannelsLow",
+ "AudioOptionsSoundPanelSoundChannelsText",
+ "AudioOptionsSoundPanelSoundChannelsThumb",
+ "AudioOptionsSoundPanelSoundEffects",
+ "AudioOptionsSoundPanelSoundEffectsText",
+ "AudioOptionsSoundPanelSoundInBG",
+ "AudioOptionsSoundPanelSoundInBGText",
+ "AudioOptionsSoundPanelSoundQuality",
+ "AudioOptionsSoundPanelSoundQualityHigh",
+ "AudioOptionsSoundPanelSoundQualityLow",
+ "AudioOptionsSoundPanelSoundQualityText",
+ "AudioOptionsSoundPanelSoundQualityThumb",
+ "AudioOptionsSoundPanelSoundVolume",
+ "AudioOptionsSoundPanelSoundVolumeHigh",
+ "AudioOptionsSoundPanelSoundVolumeLabel",
+ "AudioOptionsSoundPanelSoundVolumeLow",
+ "AudioOptionsSoundPanelSoundVolumeText",
+ "AudioOptionsSoundPanelSoundVolumeThumb",
+ "AudioOptionsSoundPanelSubText",
+ "AudioOptionsSoundPanelTitle",
+ "AudioOptionsSoundPanelUseHardware",
+ "AudioOptionsSoundPanelUseHardwareText",
+ "AudioOptionsSoundPanelVolume",
+ "AudioOptionsSoundPanelVolumeTitle",
+ "AudioOptionsSoundPanel_OnLoad",
+ "AudioOptionsVoicePanel",
+ "AudioOptionsVoicePanelAmbienceFade",
+ "AudioOptionsVoicePanelAmbienceFadeHigh",
+ "AudioOptionsVoicePanelAmbienceFadeLabel",
+ "AudioOptionsVoicePanelAmbienceFadeLow",
+ "AudioOptionsVoicePanelAmbienceFadeText",
+ "AudioOptionsVoicePanelAmbienceFadeThumb",
+ "AudioOptionsVoicePanelAudio",
+ "AudioOptionsVoicePanelAudioDescription",
+ "AudioOptionsVoicePanelAudioLabel",
+ "AudioOptionsVoicePanelAudioNormal",
+ "AudioOptionsVoicePanelAudioOff",
+ "AudioOptionsVoicePanelBinding",
+ "AudioOptionsVoicePanelBindingOutput",
+ "AudioOptionsVoicePanelBindingOutputText",
+ "AudioOptionsVoicePanelBindingOutputTextConflict",
+ "AudioOptionsVoicePanelBindingOutput_OnUpdate",
+ "AudioOptionsVoicePanelBindingTitle",
+ "AudioOptionsVoicePanelBindingType_Update",
+ "AudioOptionsVoicePanelChatMode1",
+ "AudioOptionsVoicePanelChatMode1KeyBindingButton",
+ "AudioOptionsVoicePanelChatMode1KeyBindingButtonHiddenText",
+ "AudioOptionsVoicePanelChatMode1KeyBindingButtonText",
+ "AudioOptionsVoicePanelChatMode1Label",
+ "AudioOptionsVoicePanelChatMode2",
+ "AudioOptionsVoicePanelChatModeDropDown",
+ "AudioOptionsVoicePanelChatModeDropDownButton",
+ "AudioOptionsVoicePanelChatModeDropDownButtonDisabledTexture",
+ "AudioOptionsVoicePanelChatModeDropDownButtonHighlightTexture",
+ "AudioOptionsVoicePanelChatModeDropDownButtonNormalTexture",
+ "AudioOptionsVoicePanelChatModeDropDownButtonPushedTexture",
+ "AudioOptionsVoicePanelChatModeDropDownLabel",
+ "AudioOptionsVoicePanelChatModeDropDownLeft",
+ "AudioOptionsVoicePanelChatModeDropDownMiddle",
+ "AudioOptionsVoicePanelChatModeDropDownRight",
+ "AudioOptionsVoicePanelChatModeDropDownText",
+ "AudioOptionsVoicePanelChatModeDropDown_Initialize",
+ "AudioOptionsVoicePanelChatModeDropDown_OnClick",
+ "AudioOptionsVoicePanelChatModeDropDown_OnLoad",
+ "AudioOptionsVoicePanelDisabledMessage",
+ "AudioOptionsVoicePanelDisabledMessageText",
+ "AudioOptionsVoicePanelEnableMicrophone",
+ "AudioOptionsVoicePanelEnableMicrophoneText",
+ "AudioOptionsVoicePanelEnableMicrophone_UpdateControls",
+ "AudioOptionsVoicePanelEnableVoice",
+ "AudioOptionsVoicePanelEnableVoiceText",
+ "AudioOptionsVoicePanelEnableVoice_UpdateControls",
+ "AudioOptionsVoicePanelInputDeviceDropDown",
+ "AudioOptionsVoicePanelInputDeviceDropDownButton",
+ "AudioOptionsVoicePanelInputDeviceDropDownButtonDisabledTexture",
+ "AudioOptionsVoicePanelInputDeviceDropDownButtonHighlightTexture",
+ "AudioOptionsVoicePanelInputDeviceDropDownButtonNormalTexture",
+ "AudioOptionsVoicePanelInputDeviceDropDownButtonPushedTexture",
+ "AudioOptionsVoicePanelInputDeviceDropDownLeft",
+ "AudioOptionsVoicePanelInputDeviceDropDownMiddle",
+ "AudioOptionsVoicePanelInputDeviceDropDownRight",
+ "AudioOptionsVoicePanelInputDeviceDropDownText",
+ "AudioOptionsVoicePanelInputDeviceDropDown_Initialize",
+ "AudioOptionsVoicePanelInputDeviceDropDown_OnClick",
+ "AudioOptionsVoicePanelInputDeviceDropDown_OnLoad",
+ "AudioOptionsVoicePanelKeyBindingButton_BindButton",
+ "AudioOptionsVoicePanelKeyBindingButton_CancelBinding",
+ "AudioOptionsVoicePanelKeyBindingButton_OnClick",
+ "AudioOptionsVoicePanelKeyBindingButton_OnEnter",
+ "AudioOptionsVoicePanelKeyBindingButton_OnKeyDown",
+ "AudioOptionsVoicePanelKeyBindingButton_OnKeyUp",
+ "AudioOptionsVoicePanelKeyBindingButton_Refresh",
+ "AudioOptionsVoicePanelKeyBindingButton_SetTooltip",
+ "AudioOptionsVoicePanelListening",
+ "AudioOptionsVoicePanelListeningTitle",
+ "AudioOptionsVoicePanelMicTest",
+ "AudioOptionsVoicePanelMicTestText",
+ "AudioOptionsVoicePanelMicTestTitle",
+ "AudioOptionsVoicePanelMicrophoneVolume",
+ "AudioOptionsVoicePanelMicrophoneVolumeHigh",
+ "AudioOptionsVoicePanelMicrophoneVolumeLabel",
+ "AudioOptionsVoicePanelMicrophoneVolumeLow",
+ "AudioOptionsVoicePanelMicrophoneVolumeText",
+ "AudioOptionsVoicePanelMicrophoneVolumeThumb",
+ "AudioOptionsVoicePanelMusicFade",
+ "AudioOptionsVoicePanelMusicFadeHigh",
+ "AudioOptionsVoicePanelMusicFadeLabel",
+ "AudioOptionsVoicePanelMusicFadeLow",
+ "AudioOptionsVoicePanelMusicFadeText",
+ "AudioOptionsVoicePanelMusicFadeThumb",
+ "AudioOptionsVoicePanelOutputDeviceDropDown",
+ "AudioOptionsVoicePanelOutputDeviceDropDownButton",
+ "AudioOptionsVoicePanelOutputDeviceDropDownButtonDisabledTexture",
+ "AudioOptionsVoicePanelOutputDeviceDropDownButtonHighlightTexture",
+ "AudioOptionsVoicePanelOutputDeviceDropDownButtonNormalTexture",
+ "AudioOptionsVoicePanelOutputDeviceDropDownButtonPushedTexture",
+ "AudioOptionsVoicePanelOutputDeviceDropDownLabel",
+ "AudioOptionsVoicePanelOutputDeviceDropDownLeft",
+ "AudioOptionsVoicePanelOutputDeviceDropDownMiddle",
+ "AudioOptionsVoicePanelOutputDeviceDropDownRight",
+ "AudioOptionsVoicePanelOutputDeviceDropDownText",
+ "AudioOptionsVoicePanelOutputDeviceDropDown_Initialize",
+ "AudioOptionsVoicePanelOutputDeviceDropDown_OnClick",
+ "AudioOptionsVoicePanelOutputDeviceDropDown_OnEvent",
+ "AudioOptionsVoicePanelOutputDeviceDropDown_OnLoad",
+ "AudioOptionsVoicePanelPushToTalkSound",
+ "AudioOptionsVoicePanelPushToTalkSoundText",
+ "AudioOptionsVoicePanelSoundFade",
+ "AudioOptionsVoicePanelSoundFadeHigh",
+ "AudioOptionsVoicePanelSoundFadeLabel",
+ "AudioOptionsVoicePanelSoundFadeLow",
+ "AudioOptionsVoicePanelSoundFadeText",
+ "AudioOptionsVoicePanelSoundFadeThumb",
+ "AudioOptionsVoicePanelSpeakerVolume",
+ "AudioOptionsVoicePanelSpeakerVolumeHigh",
+ "AudioOptionsVoicePanelSpeakerVolumeLabel",
+ "AudioOptionsVoicePanelSpeakerVolumeLow",
+ "AudioOptionsVoicePanelSpeakerVolumeText",
+ "AudioOptionsVoicePanelSpeakerVolumeThumb",
+ "AudioOptionsVoicePanelSubText",
+ "AudioOptionsVoicePanelTalking",
+ "AudioOptionsVoicePanelTalkingTitle",
+ "AudioOptionsVoicePanelTitle",
+ "AudioOptionsVoicePanelVoiceActivateSlider",
+ "AudioOptionsVoicePanelVoiceActivateSliderHigh",
+ "AudioOptionsVoicePanelVoiceActivateSliderLow",
+ "AudioOptionsVoicePanelVoiceActivateSliderText",
+ "AudioOptionsVoicePanelVoiceActivateSliderThumb",
+ "AudioOptionsVoicePanel_DisableMicrophoneControls",
+ "AudioOptionsVoicePanel_EnableMicrophoneControls",
+ "AudioOptionsVoicePanel_OnEvent",
+ "AudioOptionsVoicePanel_OnHide",
+ "AudioOptionsVoicePanel_OnLoad",
+ "AudioOptionsVoicePanel_OnShow",
+ "AudioOptionsVoicePanel_Refresh",
+ "AudioOptionsVoicePanel_SetInputDevice",
+ "AudioOptionsVoicePanel_SetOutputDevice",
+ "AuraButton_OnUpdate",
+ "AuraButton_Update",
+ "AuraButton_UpdateDuration",
+ "AutoCastShine_AutoCastStart",
+ "AutoCastShine_AutoCastStop",
+ "AutoCastShine_OnLoad",
+ "AutoCastShine_OnUpdate",
+ "AutoCompleteBox",
+ "AutoCompleteButton1",
+ "AutoCompleteButton1Text",
+ "AutoCompleteButton2",
+ "AutoCompleteButton2Text",
+ "AutoCompleteButton3",
+ "AutoCompleteButton3Text",
+ "AutoCompleteButton4",
+ "AutoCompleteButton4Text",
+ "AutoCompleteButton5",
+ "AutoCompleteButton5Text",
+ "AutoCompleteButton_OnClick",
+ "AutoCompleteEditBox_AddHighlightedText",
+ "AutoCompleteEditBox_OnChar",
+ "AutoCompleteEditBox_OnEditFocusLost",
+ "AutoCompleteEditBox_OnEnterPressed",
+ "AutoCompleteEditBox_OnEscapePressed",
+ "AutoCompleteEditBox_OnTabPressed",
+ "AutoCompleteEditBox_OnTextChanged",
+ "AutoCompleteInfoDelayer",
+ "AutoCompleteInstructions",
+ "AutoComplete_GetNumResults",
+ "AutoComplete_GetSelectedIndex",
+ "AutoComplete_HideIfAttachedTo",
+ "AutoComplete_OnLoad",
+ "AutoComplete_SetSelectedIndex",
+ "AutoComplete_Update",
+ "AutoComplete_UpdateResults",
+ "AutoEquipCursorItem",
+ "AutoFollowStatus",
+ "AutoFollowStatusText",
+ "AutoFollowStatus_OnEvent",
+ "AutoFollowStatus_OnLoad",
+ "AutoFollowStatus_OnUpdate",
+ "AutoLootMailItem",
+ "AutoStoreGuildBankItem",
+ "AvailableQuestsText",
+ "AvailableServicesText",
+ "AzerothButton",
+ "AzerothButtonHighlight",
+ "BAD_BOY_UNITS",
+ "BATTLEFIELD_TIMER_THRESHOLDS",
+ "BG_VEHICLES",
+ "BNAcceptFriendInvite",
+ "BNConnected",
+ "BNConversationButton_OnClick",
+ "BNConversationButton_OnEnter",
+ "BNConversationButton_OnEvent",
+ "BNConversationButton_OnLeave",
+ "BNConversationButton_OnLoad",
+ "BNConversationButton_UpdateAttachmentPoint",
+ "BNConversationButton_UpdateEnabledState",
+ "BNConversationButton_UpdateTarget",
+ "BNConversationInviteDialog",
+ "BNConversationInviteDialogCancelButton",
+ "BNConversationInviteDialogCancelButtonText",
+ "BNConversationInviteDialogHeader",
+ "BNConversationInviteDialogHeaderText",
+ "BNConversationInviteDialogInstructionText",
+ "BNConversationInviteDialogInviteButton",
+ "BNConversationInviteDialogInviteButtonText",
+ "BNConversationInviteDialogInviteButton_OnClick",
+ "BNConversationInviteDialogList",
+ "BNConversationInviteDialogListFriend1",
+ "BNConversationInviteDialogListFriend1Text",
+ "BNConversationInviteDialogListFriend2",
+ "BNConversationInviteDialogListFriend2Text",
+ "BNConversationInviteDialogListFriend3",
+ "BNConversationInviteDialogListFriend3Text",
+ "BNConversationInviteDialogListFriend4",
+ "BNConversationInviteDialogListFriend4Text",
+ "BNConversationInviteDialogListFriend5",
+ "BNConversationInviteDialogListFriend5Text",
+ "BNConversationInviteDialogListFriend6",
+ "BNConversationInviteDialogListFriend6Text",
+ "BNConversationInviteDialogListFriend7",
+ "BNConversationInviteDialogListFriend7Text",
+ "BNConversationInviteDialogListScrollFrame",
+ "BNConversationInviteDialogListScrollFrameScrollBar",
+ "BNConversationInviteDialogListScrollFrameScrollBarScrollDownButton",
+ "BNConversationInviteDialogListScrollFrameScrollBarScrollUpButton",
+ "BNConversationInviteDialogListScrollFrameScrollBarThumbTexture",
+ "BNConversationInviteDialogListScrollFrameScrollChildFrame",
+ "BNConversationInviteDialog_OnEvent",
+ "BNConversationInviteDialog_OnLoad",
+ "BNConversationInviteListCheckButton_OnClick",
+ "BNConversationInvite_Deselect",
+ "BNConversationInvite_Lock",
+ "BNConversationInvite_LockActions",
+ "BNConversationInvite_NewConversation",
+ "BNConversationInvite_Reset",
+ "BNConversationInvite_Select",
+ "BNConversationInvite_SelectPlayers",
+ "BNConversationInvite_SetMinMaxInvites",
+ "BNConversationInvite_SetMode",
+ "BNConversationInvite_Unlock",
+ "BNConversationInvite_UnlockActions",
+ "BNConversationInvite_Update",
+ "BNConversationInvite_UpdateInviteButtonState",
+ "BNConversation_DisplayConversationTooltip",
+ "BNCreateConversation",
+ "BNDeclineFriendInvite",
+ "BNFeaturesEnabled",
+ "BNFeaturesEnabledAndConnected",
+ "BNGetBlockedInfo",
+ "BNGetBlockedToonInfo",
+ "BNGetConversationInfo",
+ "BNGetConversationMemberInfo",
+ "BNGetCustomMessageTable",
+ "BNGetFOFInfo",
+ "BNGetFriendInfo",
+ "BNGetFriendInfoByID",
+ "BNGetFriendInviteInfo",
+ "BNGetFriendToonInfo",
+ "BNGetInfo",
+ "BNGetMatureLanguageFilter",
+ "BNGetMaxPlayersInConversation",
+ "BNGetNumBlocked",
+ "BNGetNumBlockedToons",
+ "BNGetNumConversationMembers",
+ "BNGetNumFOF",
+ "BNGetNumFriendInvites",
+ "BNGetNumFriendToons",
+ "BNGetNumFriends",
+ "BNGetSelectedBlock",
+ "BNGetSelectedFriend",
+ "BNGetSelectedToonBlock",
+ "BNGetToonInfo",
+ "BNInviteToConversation",
+ "BNIsBlocked",
+ "BNIsFriend",
+ "BNIsSelf",
+ "BNIsToonBlocked",
+ "BNLeaveConversation",
+ "BNListConversation",
+ "BNRemoveFriend",
+ "BNReportFriendInvite",
+ "BNReportPlayer",
+ "BNRequestFOFInfo",
+ "BNSendConversationMessage",
+ "BNSendFriendInvite",
+ "BNSendFriendInviteByID",
+ "BNSendWhisper",
+ "BNSetAFK",
+ "BNSetBlocked",
+ "BNSetCustomMessage",
+ "BNSetDND",
+ "BNSetFocus",
+ "BNSetFriendNote",
+ "BNSetMatureLanguageFilter",
+ "BNSetSelectedBlock",
+ "BNSetSelectedFriend",
+ "BNSetSelectedToonBlock",
+ "BNSetToonBlocked",
+ "BNToastFrame",
+ "BNToastFrameAnimIn",
+ "BNToastFrameBottomLine",
+ "BNToastFrameClickFrame",
+ "BNToastFrameCloseButton",
+ "BNToastFrameDoubleLine",
+ "BNToastFrameGlowFrame",
+ "BNToastFrameGlowFrameGlow",
+ "BNToastFrameGlowFrameGlowAnimIn",
+ "BNToastFrameIconTexture",
+ "BNToastFrameTopLine",
+ "BNToastFrameWaitAndAnimOut",
+ "BNToastFrame_AddToast",
+ "BNToastFrame_Close",
+ "BNToastFrame_OnClick",
+ "BNToastFrame_OnEvent",
+ "BNToastFrame_OnUpdate",
+ "BNToastFrame_RemoveToast",
+ "BNToastFrame_Show",
+ "BNToastFrame_UpdateAnchor",
+ "BNetEventFrame",
+ "BNetReportFrame",
+ "BNetReportFrameCancelButton",
+ "BNetReportFrameCancelButtonLeft",
+ "BNetReportFrameCancelButtonMiddle",
+ "BNetReportFrameCancelButtonRight",
+ "BNetReportFrameCancelButtonText",
+ "BNetReportFrameComment",
+ "BNetReportFrameCommentBottom",
+ "BNetReportFrameCommentBottomLeft",
+ "BNetReportFrameCommentBottomRight",
+ "BNetReportFrameCommentBox",
+ "BNetReportFrameCommentBoxFill",
+ "BNetReportFrameCommentLeft",
+ "BNetReportFrameCommentMiddle",
+ "BNetReportFrameCommentRight",
+ "BNetReportFrameCommentScrollFrame",
+ "BNetReportFrameCommentScrollFrameFocusButton",
+ "BNetReportFrameCommentScrollFrameScrollBar",
+ "BNetReportFrameCommentScrollFrameScrollBarScrollDownButton",
+ "BNetReportFrameCommentScrollFrameScrollBarScrollUpButton",
+ "BNetReportFrameCommentScrollFrameScrollBarThumbTexture",
+ "BNetReportFrameCommentTop",
+ "BNetReportFrameCommentTopLeft",
+ "BNetReportFrameCommentTopRight",
+ "BNetReportFrameName",
+ "BNetReportFrameReportButton",
+ "BNetReportFrameReportButtonLeft",
+ "BNetReportFrameReportButtonMiddle",
+ "BNetReportFrameReportButtonRight",
+ "BNetReportFrameReportButtonText",
+ "BNetReportFrameTitle",
+ "BNet_ConfirmReport",
+ "BNet_DisableToasts",
+ "BNet_EnableToasts",
+ "BNet_GetPresenceID",
+ "BNet_InitiateReport",
+ "BNet_OnEvent",
+ "BNet_OnLoad",
+ "BNet_SendReport",
+ "BNet_SetToastDuration",
+ "BNet_UpdateToastEvent",
+ "BackpackButton_OnClick",
+ "BackpackButton_OnModifiedClick",
+ "BackpackButton_UpdateChecked",
+ "BackpackTokenButton_OnClick",
+ "BackpackTokenFrame",
+ "BackpackTokenFrameToken1",
+ "BackpackTokenFrameToken1Count",
+ "BackpackTokenFrameToken1Icon",
+ "BackpackTokenFrameToken2",
+ "BackpackTokenFrameToken2Count",
+ "BackpackTokenFrameToken2Icon",
+ "BackpackTokenFrameToken3",
+ "BackpackTokenFrameToken3Count",
+ "BackpackTokenFrameToken3Icon",
+ "BackpackTokenFrame_IsShown",
+ "BackpackTokenFrame_Update",
+ "BagSlotButton_OnClick",
+ "BagSlotButton_OnDrag",
+ "BagSlotButton_OnEnter",
+ "BagSlotButton_OnModifiedClick",
+ "BagSlotButton_UpdateChecked",
+ "BankButtonIDToInvSlotID",
+ "BankCloseButton",
+ "BankFrame",
+ "BankFrameBag1",
+ "BankFrameBag1Cooldown",
+ "BankFrameBag1Count",
+ "BankFrameBag1HighlightFrame",
+ "BankFrameBag1HighlightFrameTexture",
+ "BankFrameBag1IconTexture",
+ "BankFrameBag1NormalTexture",
+ "BankFrameBag1Stock",
+ "BankFrameBag2",
+ "BankFrameBag2Cooldown",
+ "BankFrameBag2Count",
+ "BankFrameBag2HighlightFrame",
+ "BankFrameBag2HighlightFrameTexture",
+ "BankFrameBag2IconTexture",
+ "BankFrameBag2NormalTexture",
+ "BankFrameBag2Stock",
+ "BankFrameBag3",
+ "BankFrameBag3Cooldown",
+ "BankFrameBag3Count",
+ "BankFrameBag3HighlightFrame",
+ "BankFrameBag3HighlightFrameTexture",
+ "BankFrameBag3IconTexture",
+ "BankFrameBag3NormalTexture",
+ "BankFrameBag3Stock",
+ "BankFrameBag4",
+ "BankFrameBag4Cooldown",
+ "BankFrameBag4Count",
+ "BankFrameBag4HighlightFrame",
+ "BankFrameBag4HighlightFrameTexture",
+ "BankFrameBag4IconTexture",
+ "BankFrameBag4NormalTexture",
+ "BankFrameBag4Stock",
+ "BankFrameBag5",
+ "BankFrameBag5Cooldown",
+ "BankFrameBag5Count",
+ "BankFrameBag5HighlightFrame",
+ "BankFrameBag5HighlightFrameTexture",
+ "BankFrameBag5IconTexture",
+ "BankFrameBag5NormalTexture",
+ "BankFrameBag5Stock",
+ "BankFrameBag6",
+ "BankFrameBag6Cooldown",
+ "BankFrameBag6Count",
+ "BankFrameBag6HighlightFrame",
+ "BankFrameBag6HighlightFrameTexture",
+ "BankFrameBag6IconTexture",
+ "BankFrameBag6NormalTexture",
+ "BankFrameBag6Stock",
+ "BankFrameBag7",
+ "BankFrameBag7Cooldown",
+ "BankFrameBag7Count",
+ "BankFrameBag7HighlightFrame",
+ "BankFrameBag7HighlightFrameTexture",
+ "BankFrameBag7IconTexture",
+ "BankFrameBag7NormalTexture",
+ "BankFrameBag7Stock",
+ "BankFrameBagButton_OnLoad",
+ "BankFrameBaseButton_OnLoad",
+ "BankFrameDetailMoneyFrame",
+ "BankFrameDetailMoneyFrameCopperButton",
+ "BankFrameDetailMoneyFrameCopperButtonText",
+ "BankFrameDetailMoneyFrameGoldButton",
+ "BankFrameDetailMoneyFrameGoldButtonText",
+ "BankFrameDetailMoneyFrameSilverButton",
+ "BankFrameDetailMoneyFrameSilverButtonText",
+ "BankFrameItem1",
+ "BankFrameItem10",
+ "BankFrameItem10Cooldown",
+ "BankFrameItem10Count",
+ "BankFrameItem10IconQuestTexture",
+ "BankFrameItem10IconTexture",
+ "BankFrameItem10NormalTexture",
+ "BankFrameItem10Stock",
+ "BankFrameItem11",
+ "BankFrameItem11Cooldown",
+ "BankFrameItem11Count",
+ "BankFrameItem11IconQuestTexture",
+ "BankFrameItem11IconTexture",
+ "BankFrameItem11NormalTexture",
+ "BankFrameItem11Stock",
+ "BankFrameItem12",
+ "BankFrameItem12Cooldown",
+ "BankFrameItem12Count",
+ "BankFrameItem12IconQuestTexture",
+ "BankFrameItem12IconTexture",
+ "BankFrameItem12NormalTexture",
+ "BankFrameItem12Stock",
+ "BankFrameItem13",
+ "BankFrameItem13Cooldown",
+ "BankFrameItem13Count",
+ "BankFrameItem13IconQuestTexture",
+ "BankFrameItem13IconTexture",
+ "BankFrameItem13NormalTexture",
+ "BankFrameItem13Stock",
+ "BankFrameItem14",
+ "BankFrameItem14Cooldown",
+ "BankFrameItem14Count",
+ "BankFrameItem14IconQuestTexture",
+ "BankFrameItem14IconTexture",
+ "BankFrameItem14NormalTexture",
+ "BankFrameItem14Stock",
+ "BankFrameItem15",
+ "BankFrameItem15Cooldown",
+ "BankFrameItem15Count",
+ "BankFrameItem15IconQuestTexture",
+ "BankFrameItem15IconTexture",
+ "BankFrameItem15NormalTexture",
+ "BankFrameItem15Stock",
+ "BankFrameItem16",
+ "BankFrameItem16Cooldown",
+ "BankFrameItem16Count",
+ "BankFrameItem16IconQuestTexture",
+ "BankFrameItem16IconTexture",
+ "BankFrameItem16NormalTexture",
+ "BankFrameItem16Stock",
+ "BankFrameItem17",
+ "BankFrameItem17Cooldown",
+ "BankFrameItem17Count",
+ "BankFrameItem17IconQuestTexture",
+ "BankFrameItem17IconTexture",
+ "BankFrameItem17NormalTexture",
+ "BankFrameItem17Stock",
+ "BankFrameItem18",
+ "BankFrameItem18Cooldown",
+ "BankFrameItem18Count",
+ "BankFrameItem18IconQuestTexture",
+ "BankFrameItem18IconTexture",
+ "BankFrameItem18NormalTexture",
+ "BankFrameItem18Stock",
+ "BankFrameItem19",
+ "BankFrameItem19Cooldown",
+ "BankFrameItem19Count",
+ "BankFrameItem19IconQuestTexture",
+ "BankFrameItem19IconTexture",
+ "BankFrameItem19NormalTexture",
+ "BankFrameItem19Stock",
+ "BankFrameItem1Cooldown",
+ "BankFrameItem1Count",
+ "BankFrameItem1IconQuestTexture",
+ "BankFrameItem1IconTexture",
+ "BankFrameItem1NormalTexture",
+ "BankFrameItem1Stock",
+ "BankFrameItem2",
+ "BankFrameItem20",
+ "BankFrameItem20Cooldown",
+ "BankFrameItem20Count",
+ "BankFrameItem20IconQuestTexture",
+ "BankFrameItem20IconTexture",
+ "BankFrameItem20NormalTexture",
+ "BankFrameItem20Stock",
+ "BankFrameItem21",
+ "BankFrameItem21Cooldown",
+ "BankFrameItem21Count",
+ "BankFrameItem21IconQuestTexture",
+ "BankFrameItem21IconTexture",
+ "BankFrameItem21NormalTexture",
+ "BankFrameItem21Stock",
+ "BankFrameItem22",
+ "BankFrameItem22Cooldown",
+ "BankFrameItem22Count",
+ "BankFrameItem22IconQuestTexture",
+ "BankFrameItem22IconTexture",
+ "BankFrameItem22NormalTexture",
+ "BankFrameItem22Stock",
+ "BankFrameItem23",
+ "BankFrameItem23Cooldown",
+ "BankFrameItem23Count",
+ "BankFrameItem23IconQuestTexture",
+ "BankFrameItem23IconTexture",
+ "BankFrameItem23NormalTexture",
+ "BankFrameItem23Stock",
+ "BankFrameItem24",
+ "BankFrameItem24Cooldown",
+ "BankFrameItem24Count",
+ "BankFrameItem24IconQuestTexture",
+ "BankFrameItem24IconTexture",
+ "BankFrameItem24NormalTexture",
+ "BankFrameItem24Stock",
+ "BankFrameItem25",
+ "BankFrameItem25Cooldown",
+ "BankFrameItem25Count",
+ "BankFrameItem25IconQuestTexture",
+ "BankFrameItem25IconTexture",
+ "BankFrameItem25NormalTexture",
+ "BankFrameItem25Stock",
+ "BankFrameItem26",
+ "BankFrameItem26Cooldown",
+ "BankFrameItem26Count",
+ "BankFrameItem26IconQuestTexture",
+ "BankFrameItem26IconTexture",
+ "BankFrameItem26NormalTexture",
+ "BankFrameItem26Stock",
+ "BankFrameItem27",
+ "BankFrameItem27Cooldown",
+ "BankFrameItem27Count",
+ "BankFrameItem27IconQuestTexture",
+ "BankFrameItem27IconTexture",
+ "BankFrameItem27NormalTexture",
+ "BankFrameItem27Stock",
+ "BankFrameItem28",
+ "BankFrameItem28Cooldown",
+ "BankFrameItem28Count",
+ "BankFrameItem28IconQuestTexture",
+ "BankFrameItem28IconTexture",
+ "BankFrameItem28NormalTexture",
+ "BankFrameItem28Stock",
+ "BankFrameItem2Cooldown",
+ "BankFrameItem2Count",
+ "BankFrameItem2IconQuestTexture",
+ "BankFrameItem2IconTexture",
+ "BankFrameItem2NormalTexture",
+ "BankFrameItem2Stock",
+ "BankFrameItem3",
+ "BankFrameItem3Cooldown",
+ "BankFrameItem3Count",
+ "BankFrameItem3IconQuestTexture",
+ "BankFrameItem3IconTexture",
+ "BankFrameItem3NormalTexture",
+ "BankFrameItem3Stock",
+ "BankFrameItem4",
+ "BankFrameItem4Cooldown",
+ "BankFrameItem4Count",
+ "BankFrameItem4IconQuestTexture",
+ "BankFrameItem4IconTexture",
+ "BankFrameItem4NormalTexture",
+ "BankFrameItem4Stock",
+ "BankFrameItem5",
+ "BankFrameItem5Cooldown",
+ "BankFrameItem5Count",
+ "BankFrameItem5IconQuestTexture",
+ "BankFrameItem5IconTexture",
+ "BankFrameItem5NormalTexture",
+ "BankFrameItem5Stock",
+ "BankFrameItem6",
+ "BankFrameItem6Cooldown",
+ "BankFrameItem6Count",
+ "BankFrameItem6IconQuestTexture",
+ "BankFrameItem6IconTexture",
+ "BankFrameItem6NormalTexture",
+ "BankFrameItem6Stock",
+ "BankFrameItem7",
+ "BankFrameItem7Cooldown",
+ "BankFrameItem7Count",
+ "BankFrameItem7IconQuestTexture",
+ "BankFrameItem7IconTexture",
+ "BankFrameItem7NormalTexture",
+ "BankFrameItem7Stock",
+ "BankFrameItem8",
+ "BankFrameItem8Cooldown",
+ "BankFrameItem8Count",
+ "BankFrameItem8IconQuestTexture",
+ "BankFrameItem8IconTexture",
+ "BankFrameItem8NormalTexture",
+ "BankFrameItem8Stock",
+ "BankFrameItem9",
+ "BankFrameItem9Cooldown",
+ "BankFrameItem9Count",
+ "BankFrameItem9IconQuestTexture",
+ "BankFrameItem9IconTexture",
+ "BankFrameItem9NormalTexture",
+ "BankFrameItem9Stock",
+ "BankFrameItemButtonBag_OnClick",
+ "BankFrameItemButtonBag_Pickup",
+ "BankFrameItemButtonGeneric_OnClick",
+ "BankFrameItemButtonGeneric_OnModifiedClick",
+ "BankFrameItemButton_OnEnter",
+ "BankFrameItemButton_OnLoad",
+ "BankFrameItemButton_Update",
+ "BankFrameItemButton_UpdateLocked",
+ "BankFrameMoneyFrame",
+ "BankFrameMoneyFrameCopperButton",
+ "BankFrameMoneyFrameCopperButtonText",
+ "BankFrameMoneyFrameGoldButton",
+ "BankFrameMoneyFrameGoldButtonText",
+ "BankFrameMoneyFrameSilverButton",
+ "BankFrameMoneyFrameSilverButtonText",
+ "BankFramePurchaseButton",
+ "BankFramePurchaseButtonText",
+ "BankFramePurchaseInfo",
+ "BankFrameSlotCost",
+ "BankFrameTitleText",
+ "BankFrame_OnEvent",
+ "BankFrame_OnHide",
+ "BankFrame_OnLoad",
+ "BankFrame_OnShow",
+ "BankFrame_UpdateCooldown",
+ "BankPortraitTexture",
+ "BarberShopBannerFrame",
+ "BarberShopBannerFrameBGTexture",
+ "BarberShopBannerFrameCaption",
+ "BarberShopFrame",
+ "BarberShopFrameBackground",
+ "BarberShopFrameCancelButton",
+ "BarberShopFrameCancelButtonText",
+ "BarberShopFrameMoneyFrame",
+ "BarberShopFrameMoneyFrameCopperButton",
+ "BarberShopFrameMoneyFrameCopperButtonText",
+ "BarberShopFrameMoneyFrameGoldButton",
+ "BarberShopFrameMoneyFrameGoldButtonText",
+ "BarberShopFrameMoneyFrameSilverButton",
+ "BarberShopFrameMoneyFrameSilverButtonText",
+ "BarberShopFrameOkayButton",
+ "BarberShopFrameOkayButtonText",
+ "BarberShopFrameResetButton",
+ "BarberShopFrameResetButtonText",
+ "BarberShopFrameSelector1",
+ "BarberShopFrameSelector1Category",
+ "BarberShopFrameSelector1Next",
+ "BarberShopFrameSelector1Prev",
+ "BarberShopFrameSelector2",
+ "BarberShopFrameSelector2Category",
+ "BarberShopFrameSelector2Next",
+ "BarberShopFrameSelector2Prev",
+ "BarberShopFrameSelector3",
+ "BarberShopFrameSelector3Category",
+ "BarberShopFrameSelector3Next",
+ "BarberShopFrameSelector3Prev",
+ "BarberShopFrameSelector4",
+ "BarberShopFrameSelector4Category",
+ "BarberShopFrameSelector4Next",
+ "BarberShopFrameSelector4Prev",
+ "BarberShopFrame_LoadUI",
+ "BarberShopReset",
+ "BarberShop_OnEvent",
+ "BarberShop_OnHide",
+ "BarberShop_OnLoad",
+ "BarberShop_OnShow",
+ "BarberShop_ResetLabelColors",
+ "BarberShop_SetLabelColor",
+ "BarberShop_ToFourAttributeFormat",
+ "BarberShop_Update",
+ "BarberShop_UpdateBanner",
+ "BarberShop_UpdateCost",
+ "BarberShop_UpdateFacialHairCustomization",
+ "BarberShop_UpdateHairCustomization",
+ "BarberShop_UpdateSelector",
+ "BasicScriptErrors",
+ "BasicScriptErrorsButton",
+ "BasicScriptErrorsText",
+ "BattlefieldButton_OnClick",
+ "BattlefieldFrame",
+ "BattlefieldFrameCancelButton",
+ "BattlefieldFrameCancelButtonText",
+ "BattlefieldFrameCloseButton",
+ "BattlefieldFrameFrameLabel",
+ "BattlefieldFrameGroupJoinButton",
+ "BattlefieldFrameGroupJoinButtonText",
+ "BattlefieldFrameInfoScrollFrame",
+ "BattlefieldFrameInfoScrollFrameChildFrame",
+ "BattlefieldFrameInfoScrollFrameChildFrameDescription",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfo",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoDescription",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoLossReward",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoLossRewardArenaAmount",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoLossRewardArenaSymbol",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoLossRewardHonorAmount",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoLossRewardHonorSymbol",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoLossRewardLabel",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoRewardsLabel",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoTitle",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoWinReward",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoWinRewardArenaAmount",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoWinRewardArenaSymbol",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoWinRewardHonorAmount",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoWinRewardHonorSymbol",
+ "BattlefieldFrameInfoScrollFrameChildFrameRewardsInfoWinRewardLabel",
+ "BattlefieldFrameInfoScrollFrameScrollBar",
+ "BattlefieldFrameInfoScrollFrameScrollBarScrollDownButton",
+ "BattlefieldFrameInfoScrollFrameScrollBarScrollUpButton",
+ "BattlefieldFrameInfoScrollFrameScrollBarThumbTexture",
+ "BattlefieldFrameJoinButton",
+ "BattlefieldFrameJoinButtonText",
+ "BattlefieldFrameJoinButton_OnClick",
+ "BattlefieldFrameNameHeader",
+ "BattlefieldFramePortrait",
+ "BattlefieldFrame_GetSelectedBattlegroundInfo",
+ "BattlefieldFrame_OnEvent",
+ "BattlefieldFrame_OnLoad",
+ "BattlefieldFrame_Update",
+ "BattlefieldFrame_UpdateRandomInfo",
+ "BattlefieldFrame_UpdateStatus",
+ "BattlefieldIconText",
+ "BattlefieldListScrollFrame",
+ "BattlefieldListScrollFrameScrollBar",
+ "BattlefieldListScrollFrameScrollBarScrollDownButton",
+ "BattlefieldListScrollFrameScrollBarScrollUpButton",
+ "BattlefieldListScrollFrameScrollBarThumbTexture",
+ "BattlefieldListScrollFrameScrollChildFrame",
+ "BattlefieldMgrEntryInviteResponse",
+ "BattlefieldMgrExitRequest",
+ "BattlefieldMgrQueueInviteResponse",
+ "BattlefieldMgrQueueRequest",
+ "BattlefieldMinimap",
+ "BattlefieldMinimap1",
+ "BattlefieldMinimap10",
+ "BattlefieldMinimap11",
+ "BattlefieldMinimap12",
+ "BattlefieldMinimap2",
+ "BattlefieldMinimap3",
+ "BattlefieldMinimap4",
+ "BattlefieldMinimap5",
+ "BattlefieldMinimap6",
+ "BattlefieldMinimap7",
+ "BattlefieldMinimap8",
+ "BattlefieldMinimap9",
+ "BattlefieldMinimapBackground",
+ "BattlefieldMinimapCloseButton",
+ "BattlefieldMinimapCorner",
+ "BattlefieldMinimapCorpse",
+ "BattlefieldMinimapFlag1",
+ "BattlefieldMinimapFlag1Texture",
+ "BattlefieldMinimapFlag2",
+ "BattlefieldMinimapFlag2Texture",
+ "BattlefieldMinimapOptions",
+ "BattlefieldMinimapParty1",
+ "BattlefieldMinimapParty1Icon",
+ "BattlefieldMinimapParty2",
+ "BattlefieldMinimapParty2Icon",
+ "BattlefieldMinimapParty3",
+ "BattlefieldMinimapParty3Icon",
+ "BattlefieldMinimapParty4",
+ "BattlefieldMinimapParty4Icon",
+ "BattlefieldMinimapRaid1",
+ "BattlefieldMinimapRaid10",
+ "BattlefieldMinimapRaid10Icon",
+ "BattlefieldMinimapRaid11",
+ "BattlefieldMinimapRaid11Icon",
+ "BattlefieldMinimapRaid12",
+ "BattlefieldMinimapRaid12Icon",
+ "BattlefieldMinimapRaid13",
+ "BattlefieldMinimapRaid13Icon",
+ "BattlefieldMinimapRaid14",
+ "BattlefieldMinimapRaid14Icon",
+ "BattlefieldMinimapRaid15",
+ "BattlefieldMinimapRaid15Icon",
+ "BattlefieldMinimapRaid16",
+ "BattlefieldMinimapRaid16Icon",
+ "BattlefieldMinimapRaid17",
+ "BattlefieldMinimapRaid17Icon",
+ "BattlefieldMinimapRaid18",
+ "BattlefieldMinimapRaid18Icon",
+ "BattlefieldMinimapRaid19",
+ "BattlefieldMinimapRaid19Icon",
+ "BattlefieldMinimapRaid1Icon",
+ "BattlefieldMinimapRaid2",
+ "BattlefieldMinimapRaid20",
+ "BattlefieldMinimapRaid20Icon",
+ "BattlefieldMinimapRaid21",
+ "BattlefieldMinimapRaid21Icon",
+ "BattlefieldMinimapRaid22",
+ "BattlefieldMinimapRaid22Icon",
+ "BattlefieldMinimapRaid23",
+ "BattlefieldMinimapRaid23Icon",
+ "BattlefieldMinimapRaid24",
+ "BattlefieldMinimapRaid24Icon",
+ "BattlefieldMinimapRaid25",
+ "BattlefieldMinimapRaid25Icon",
+ "BattlefieldMinimapRaid26",
+ "BattlefieldMinimapRaid26Icon",
+ "BattlefieldMinimapRaid27",
+ "BattlefieldMinimapRaid27Icon",
+ "BattlefieldMinimapRaid28",
+ "BattlefieldMinimapRaid28Icon",
+ "BattlefieldMinimapRaid29",
+ "BattlefieldMinimapRaid29Icon",
+ "BattlefieldMinimapRaid2Icon",
+ "BattlefieldMinimapRaid3",
+ "BattlefieldMinimapRaid30",
+ "BattlefieldMinimapRaid30Icon",
+ "BattlefieldMinimapRaid31",
+ "BattlefieldMinimapRaid31Icon",
+ "BattlefieldMinimapRaid32",
+ "BattlefieldMinimapRaid32Icon",
+ "BattlefieldMinimapRaid33",
+ "BattlefieldMinimapRaid33Icon",
+ "BattlefieldMinimapRaid34",
+ "BattlefieldMinimapRaid34Icon",
+ "BattlefieldMinimapRaid35",
+ "BattlefieldMinimapRaid35Icon",
+ "BattlefieldMinimapRaid36",
+ "BattlefieldMinimapRaid36Icon",
+ "BattlefieldMinimapRaid37",
+ "BattlefieldMinimapRaid37Icon",
+ "BattlefieldMinimapRaid38",
+ "BattlefieldMinimapRaid38Icon",
+ "BattlefieldMinimapRaid39",
+ "BattlefieldMinimapRaid39Icon",
+ "BattlefieldMinimapRaid3Icon",
+ "BattlefieldMinimapRaid4",
+ "BattlefieldMinimapRaid40",
+ "BattlefieldMinimapRaid40Icon",
+ "BattlefieldMinimapRaid4Icon",
+ "BattlefieldMinimapRaid5",
+ "BattlefieldMinimapRaid5Icon",
+ "BattlefieldMinimapRaid6",
+ "BattlefieldMinimapRaid6Icon",
+ "BattlefieldMinimapRaid7",
+ "BattlefieldMinimapRaid7Icon",
+ "BattlefieldMinimapRaid8",
+ "BattlefieldMinimapRaid8Icon",
+ "BattlefieldMinimapRaid9",
+ "BattlefieldMinimapRaid9Icon",
+ "BattlefieldMinimapTab",
+ "BattlefieldMinimapTabDropDown",
+ "BattlefieldMinimapTabDropDownButton",
+ "BattlefieldMinimapTabDropDownButtonDisabledTexture",
+ "BattlefieldMinimapTabDropDownButtonHighlightTexture",
+ "BattlefieldMinimapTabDropDownButtonNormalTexture",
+ "BattlefieldMinimapTabDropDownButtonPushedTexture",
+ "BattlefieldMinimapTabDropDownLeft",
+ "BattlefieldMinimapTabDropDownMiddle",
+ "BattlefieldMinimapTabDropDownRight",
+ "BattlefieldMinimapTabDropDownText",
+ "BattlefieldMinimapTabDropDown_Initialize",
+ "BattlefieldMinimapTabDropDown_ShowOpacity",
+ "BattlefieldMinimapTabDropDown_ToggleLock",
+ "BattlefieldMinimapTabDropDown_TogglePlayers",
+ "BattlefieldMinimapTabFlash",
+ "BattlefieldMinimapTabLeft",
+ "BattlefieldMinimapTabMiddle",
+ "BattlefieldMinimapTabRight",
+ "BattlefieldMinimapTabText",
+ "BattlefieldMinimapTab_OnClick",
+ "BattlefieldMinimapUnit_OnEnter",
+ "BattlefieldMinimap_ClearTextures",
+ "BattlefieldMinimap_CreatePOI",
+ "BattlefieldMinimap_LoadUI",
+ "BattlefieldMinimap_OnEvent",
+ "BattlefieldMinimap_OnHide",
+ "BattlefieldMinimap_OnLoad",
+ "BattlefieldMinimap_OnShow",
+ "BattlefieldMinimap_OnUpdate",
+ "BattlefieldMinimap_Toggle",
+ "BattlefieldMinimap_Update",
+ "BattlefieldMinimap_UpdateOpacity",
+ "BattlefieldTimerFrame",
+ "BattlefieldTimerFrame_OnUpdate",
+ "BattlefieldZone1",
+ "BattlefieldZone1Highlight",
+ "BattlefieldZone1Text",
+ "BattlefieldZone2",
+ "BattlefieldZone2Highlight",
+ "BattlefieldZone2Text",
+ "BattlefieldZone3",
+ "BattlefieldZone3Highlight",
+ "BattlefieldZone3Text",
+ "BattlefieldZone4",
+ "BattlefieldZone4Highlight",
+ "BattlefieldZone4Text",
+ "BattlefieldZone5",
+ "BattlefieldZone5Highlight",
+ "BattlefieldZone5Text",
+ "BattlegroundShine",
+ "BattlegroundShineFadeIn",
+ "BattlegroundShineFadeOut",
+ "BattlegroundType1",
+ "BattlegroundType1Highlight",
+ "BattlegroundType1Text",
+ "BattlegroundType2",
+ "BattlegroundType2Highlight",
+ "BattlegroundType2Text",
+ "BattlegroundType3",
+ "BattlegroundType3Highlight",
+ "BattlegroundType3Text",
+ "BattlegroundType4",
+ "BattlegroundType4Highlight",
+ "BattlegroundType4Text",
+ "BattlegroundType5",
+ "BattlegroundType5Highlight",
+ "BattlegroundType5Text",
+ "BattlenetPanelOptions",
+ "BeginTrade",
+ "BetterDate",
+ "BidBidButton",
+ "BidBidButtonText",
+ "BidBidPrice",
+ "BidBidPriceCopper",
+ "BidBidPriceCopperLeft",
+ "BidBidPriceCopperMiddle",
+ "BidBidPriceCopperRight",
+ "BidBidPriceGold",
+ "BidBidPriceGoldLeft",
+ "BidBidPriceGoldMiddle",
+ "BidBidPriceGoldRight",
+ "BidBidPriceSilver",
+ "BidBidPriceSilverLeft",
+ "BidBidPriceSilverMiddle",
+ "BidBidPriceSilverRight",
+ "BidBidSort",
+ "BidBidSortArrow",
+ "BidBidSortLeft",
+ "BidBidSortMiddle",
+ "BidBidSortRight",
+ "BidBidSortText",
+ "BidBidText",
+ "BidButton1",
+ "BidButton1BidStatus",
+ "BidButton1BuyoutMoneyFrame",
+ "BidButton1BuyoutMoneyFrameCopperButton",
+ "BidButton1BuyoutMoneyFrameCopperButtonText",
+ "BidButton1BuyoutMoneyFrameGoldButton",
+ "BidButton1BuyoutMoneyFrameGoldButtonText",
+ "BidButton1BuyoutMoneyFrameSilverButton",
+ "BidButton1BuyoutMoneyFrameSilverButtonText",
+ "BidButton1ClosingTime",
+ "BidButton1ClosingTimeText",
+ "BidButton1CurrentBidMoneyFrame",
+ "BidButton1CurrentBidMoneyFrameCopperButton",
+ "BidButton1CurrentBidMoneyFrameCopperButtonText",
+ "BidButton1CurrentBidMoneyFrameGoldButton",
+ "BidButton1CurrentBidMoneyFrameGoldButtonText",
+ "BidButton1CurrentBidMoneyFrameSilverButton",
+ "BidButton1CurrentBidMoneyFrameSilverButtonText",
+ "BidButton1Highlight",
+ "BidButton1Item",
+ "BidButton1ItemCount",
+ "BidButton1ItemIconTexture",
+ "BidButton1ItemNormalTexture",
+ "BidButton1ItemStock",
+ "BidButton1Left",
+ "BidButton1Level",
+ "BidButton1Name",
+ "BidButton1Right",
+ "BidButton2",
+ "BidButton2BidStatus",
+ "BidButton2BuyoutMoneyFrame",
+ "BidButton2BuyoutMoneyFrameCopperButton",
+ "BidButton2BuyoutMoneyFrameCopperButtonText",
+ "BidButton2BuyoutMoneyFrameGoldButton",
+ "BidButton2BuyoutMoneyFrameGoldButtonText",
+ "BidButton2BuyoutMoneyFrameSilverButton",
+ "BidButton2BuyoutMoneyFrameSilverButtonText",
+ "BidButton2ClosingTime",
+ "BidButton2ClosingTimeText",
+ "BidButton2CurrentBidMoneyFrame",
+ "BidButton2CurrentBidMoneyFrameCopperButton",
+ "BidButton2CurrentBidMoneyFrameCopperButtonText",
+ "BidButton2CurrentBidMoneyFrameGoldButton",
+ "BidButton2CurrentBidMoneyFrameGoldButtonText",
+ "BidButton2CurrentBidMoneyFrameSilverButton",
+ "BidButton2CurrentBidMoneyFrameSilverButtonText",
+ "BidButton2Highlight",
+ "BidButton2Item",
+ "BidButton2ItemCount",
+ "BidButton2ItemIconTexture",
+ "BidButton2ItemNormalTexture",
+ "BidButton2ItemStock",
+ "BidButton2Left",
+ "BidButton2Level",
+ "BidButton2Name",
+ "BidButton2Right",
+ "BidButton3",
+ "BidButton3BidStatus",
+ "BidButton3BuyoutMoneyFrame",
+ "BidButton3BuyoutMoneyFrameCopperButton",
+ "BidButton3BuyoutMoneyFrameCopperButtonText",
+ "BidButton3BuyoutMoneyFrameGoldButton",
+ "BidButton3BuyoutMoneyFrameGoldButtonText",
+ "BidButton3BuyoutMoneyFrameSilverButton",
+ "BidButton3BuyoutMoneyFrameSilverButtonText",
+ "BidButton3ClosingTime",
+ "BidButton3ClosingTimeText",
+ "BidButton3CurrentBidMoneyFrame",
+ "BidButton3CurrentBidMoneyFrameCopperButton",
+ "BidButton3CurrentBidMoneyFrameCopperButtonText",
+ "BidButton3CurrentBidMoneyFrameGoldButton",
+ "BidButton3CurrentBidMoneyFrameGoldButtonText",
+ "BidButton3CurrentBidMoneyFrameSilverButton",
+ "BidButton3CurrentBidMoneyFrameSilverButtonText",
+ "BidButton3Highlight",
+ "BidButton3Item",
+ "BidButton3ItemCount",
+ "BidButton3ItemIconTexture",
+ "BidButton3ItemNormalTexture",
+ "BidButton3ItemStock",
+ "BidButton3Left",
+ "BidButton3Level",
+ "BidButton3Name",
+ "BidButton3Right",
+ "BidButton4",
+ "BidButton4BidStatus",
+ "BidButton4BuyoutMoneyFrame",
+ "BidButton4BuyoutMoneyFrameCopperButton",
+ "BidButton4BuyoutMoneyFrameCopperButtonText",
+ "BidButton4BuyoutMoneyFrameGoldButton",
+ "BidButton4BuyoutMoneyFrameGoldButtonText",
+ "BidButton4BuyoutMoneyFrameSilverButton",
+ "BidButton4BuyoutMoneyFrameSilverButtonText",
+ "BidButton4ClosingTime",
+ "BidButton4ClosingTimeText",
+ "BidButton4CurrentBidMoneyFrame",
+ "BidButton4CurrentBidMoneyFrameCopperButton",
+ "BidButton4CurrentBidMoneyFrameCopperButtonText",
+ "BidButton4CurrentBidMoneyFrameGoldButton",
+ "BidButton4CurrentBidMoneyFrameGoldButtonText",
+ "BidButton4CurrentBidMoneyFrameSilverButton",
+ "BidButton4CurrentBidMoneyFrameSilverButtonText",
+ "BidButton4Highlight",
+ "BidButton4Item",
+ "BidButton4ItemCount",
+ "BidButton4ItemIconTexture",
+ "BidButton4ItemNormalTexture",
+ "BidButton4ItemStock",
+ "BidButton4Left",
+ "BidButton4Level",
+ "BidButton4Name",
+ "BidButton4Right",
+ "BidButton5",
+ "BidButton5BidStatus",
+ "BidButton5BuyoutMoneyFrame",
+ "BidButton5BuyoutMoneyFrameCopperButton",
+ "BidButton5BuyoutMoneyFrameCopperButtonText",
+ "BidButton5BuyoutMoneyFrameGoldButton",
+ "BidButton5BuyoutMoneyFrameGoldButtonText",
+ "BidButton5BuyoutMoneyFrameSilverButton",
+ "BidButton5BuyoutMoneyFrameSilverButtonText",
+ "BidButton5ClosingTime",
+ "BidButton5ClosingTimeText",
+ "BidButton5CurrentBidMoneyFrame",
+ "BidButton5CurrentBidMoneyFrameCopperButton",
+ "BidButton5CurrentBidMoneyFrameCopperButtonText",
+ "BidButton5CurrentBidMoneyFrameGoldButton",
+ "BidButton5CurrentBidMoneyFrameGoldButtonText",
+ "BidButton5CurrentBidMoneyFrameSilverButton",
+ "BidButton5CurrentBidMoneyFrameSilverButtonText",
+ "BidButton5Highlight",
+ "BidButton5Item",
+ "BidButton5ItemCount",
+ "BidButton5ItemIconTexture",
+ "BidButton5ItemNormalTexture",
+ "BidButton5ItemStock",
+ "BidButton5Left",
+ "BidButton5Level",
+ "BidButton5Name",
+ "BidButton5Right",
+ "BidButton6",
+ "BidButton6BidStatus",
+ "BidButton6BuyoutMoneyFrame",
+ "BidButton6BuyoutMoneyFrameCopperButton",
+ "BidButton6BuyoutMoneyFrameCopperButtonText",
+ "BidButton6BuyoutMoneyFrameGoldButton",
+ "BidButton6BuyoutMoneyFrameGoldButtonText",
+ "BidButton6BuyoutMoneyFrameSilverButton",
+ "BidButton6BuyoutMoneyFrameSilverButtonText",
+ "BidButton6ClosingTime",
+ "BidButton6ClosingTimeText",
+ "BidButton6CurrentBidMoneyFrame",
+ "BidButton6CurrentBidMoneyFrameCopperButton",
+ "BidButton6CurrentBidMoneyFrameCopperButtonText",
+ "BidButton6CurrentBidMoneyFrameGoldButton",
+ "BidButton6CurrentBidMoneyFrameGoldButtonText",
+ "BidButton6CurrentBidMoneyFrameSilverButton",
+ "BidButton6CurrentBidMoneyFrameSilverButtonText",
+ "BidButton6Highlight",
+ "BidButton6Item",
+ "BidButton6ItemCount",
+ "BidButton6ItemIconTexture",
+ "BidButton6ItemNormalTexture",
+ "BidButton6ItemStock",
+ "BidButton6Left",
+ "BidButton6Level",
+ "BidButton6Name",
+ "BidButton6Right",
+ "BidButton7",
+ "BidButton7BidStatus",
+ "BidButton7BuyoutMoneyFrame",
+ "BidButton7BuyoutMoneyFrameCopperButton",
+ "BidButton7BuyoutMoneyFrameCopperButtonText",
+ "BidButton7BuyoutMoneyFrameGoldButton",
+ "BidButton7BuyoutMoneyFrameGoldButtonText",
+ "BidButton7BuyoutMoneyFrameSilverButton",
+ "BidButton7BuyoutMoneyFrameSilverButtonText",
+ "BidButton7ClosingTime",
+ "BidButton7ClosingTimeText",
+ "BidButton7CurrentBidMoneyFrame",
+ "BidButton7CurrentBidMoneyFrameCopperButton",
+ "BidButton7CurrentBidMoneyFrameCopperButtonText",
+ "BidButton7CurrentBidMoneyFrameGoldButton",
+ "BidButton7CurrentBidMoneyFrameGoldButtonText",
+ "BidButton7CurrentBidMoneyFrameSilverButton",
+ "BidButton7CurrentBidMoneyFrameSilverButtonText",
+ "BidButton7Highlight",
+ "BidButton7Item",
+ "BidButton7ItemCount",
+ "BidButton7ItemIconTexture",
+ "BidButton7ItemNormalTexture",
+ "BidButton7ItemStock",
+ "BidButton7Left",
+ "BidButton7Level",
+ "BidButton7Name",
+ "BidButton7Right",
+ "BidButton8",
+ "BidButton8BidStatus",
+ "BidButton8BuyoutMoneyFrame",
+ "BidButton8BuyoutMoneyFrameCopperButton",
+ "BidButton8BuyoutMoneyFrameCopperButtonText",
+ "BidButton8BuyoutMoneyFrameGoldButton",
+ "BidButton8BuyoutMoneyFrameGoldButtonText",
+ "BidButton8BuyoutMoneyFrameSilverButton",
+ "BidButton8BuyoutMoneyFrameSilverButtonText",
+ "BidButton8ClosingTime",
+ "BidButton8ClosingTimeText",
+ "BidButton8CurrentBidMoneyFrame",
+ "BidButton8CurrentBidMoneyFrameCopperButton",
+ "BidButton8CurrentBidMoneyFrameCopperButtonText",
+ "BidButton8CurrentBidMoneyFrameGoldButton",
+ "BidButton8CurrentBidMoneyFrameGoldButtonText",
+ "BidButton8CurrentBidMoneyFrameSilverButton",
+ "BidButton8CurrentBidMoneyFrameSilverButtonText",
+ "BidButton8Highlight",
+ "BidButton8Item",
+ "BidButton8ItemCount",
+ "BidButton8ItemIconTexture",
+ "BidButton8ItemNormalTexture",
+ "BidButton8ItemStock",
+ "BidButton8Left",
+ "BidButton8Level",
+ "BidButton8Name",
+ "BidButton8Right",
+ "BidButton9",
+ "BidButton9BidStatus",
+ "BidButton9BuyoutMoneyFrame",
+ "BidButton9BuyoutMoneyFrameCopperButton",
+ "BidButton9BuyoutMoneyFrameCopperButtonText",
+ "BidButton9BuyoutMoneyFrameGoldButton",
+ "BidButton9BuyoutMoneyFrameGoldButtonText",
+ "BidButton9BuyoutMoneyFrameSilverButton",
+ "BidButton9BuyoutMoneyFrameSilverButtonText",
+ "BidButton9ClosingTime",
+ "BidButton9ClosingTimeText",
+ "BidButton9CurrentBidMoneyFrame",
+ "BidButton9CurrentBidMoneyFrameCopperButton",
+ "BidButton9CurrentBidMoneyFrameCopperButtonText",
+ "BidButton9CurrentBidMoneyFrameGoldButton",
+ "BidButton9CurrentBidMoneyFrameGoldButtonText",
+ "BidButton9CurrentBidMoneyFrameSilverButton",
+ "BidButton9CurrentBidMoneyFrameSilverButtonText",
+ "BidButton9Highlight",
+ "BidButton9Item",
+ "BidButton9ItemCount",
+ "BidButton9ItemIconTexture",
+ "BidButton9ItemNormalTexture",
+ "BidButton9ItemStock",
+ "BidButton9Left",
+ "BidButton9Level",
+ "BidButton9Name",
+ "BidButton9Right",
+ "BidButton_OnClick",
+ "BidBuyoutButton",
+ "BidBuyoutButtonText",
+ "BidBuyoutSort",
+ "BidBuyoutSortArrow",
+ "BidBuyoutSortLeft",
+ "BidBuyoutSortMiddle",
+ "BidBuyoutSortRight",
+ "BidBuyoutSortText",
+ "BidCloseButton",
+ "BidCloseButtonText",
+ "BidDurationSort",
+ "BidDurationSortArrow",
+ "BidDurationSortLeft",
+ "BidDurationSortMiddle",
+ "BidDurationSortRight",
+ "BidDurationSortText",
+ "BidLevelSort",
+ "BidLevelSortArrow",
+ "BidLevelSortLeft",
+ "BidLevelSortMiddle",
+ "BidLevelSortRight",
+ "BidLevelSortText",
+ "BidQualitySort",
+ "BidQualitySortArrow",
+ "BidQualitySortLeft",
+ "BidQualitySortMiddle",
+ "BidQualitySortRight",
+ "BidQualitySortText",
+ "BidScrollFrame",
+ "BidScrollFrameScrollBar",
+ "BidScrollFrameScrollBarScrollDownButton",
+ "BidScrollFrameScrollBarScrollUpButton",
+ "BidScrollFrameScrollBarThumbTexture",
+ "BidScrollFrameScrollChildFrame",
+ "BidSearchCountText",
+ "BidStatusSort",
+ "BidStatusSortArrow",
+ "BidStatusSortLeft",
+ "BidStatusSortMiddle",
+ "BidStatusSortRight",
+ "BidStatusSortText",
+ "BidTitle",
+ "BigWigs",
+ "BindEnchant",
+ "BlackoutWorld",
+ "BlizzardOptionsPanel_Cancel",
+ "BlizzardOptionsPanel_CancelControl",
+ "BlizzardOptionsPanel_CheckButton_Disable",
+ "BlizzardOptionsPanel_CheckButton_Enable",
+ "BlizzardOptionsPanel_CheckButton_OnClick",
+ "BlizzardOptionsPanel_CheckButton_Refresh",
+ "BlizzardOptionsPanel_CheckButton_SetNewValue",
+ "BlizzardOptionsPanel_Default",
+ "BlizzardOptionsPanel_DefaultControl",
+ "BlizzardOptionsPanel_DropDown_Refresh",
+ "BlizzardOptionsPanel_GetCVarDefaultSafe",
+ "BlizzardOptionsPanel_GetCVarMaxSafe",
+ "BlizzardOptionsPanel_GetCVarMinSafe",
+ "BlizzardOptionsPanel_GetCVarSafe",
+ "BlizzardOptionsPanel_Okay",
+ "BlizzardOptionsPanel_OkayControl",
+ "BlizzardOptionsPanel_OnEvent",
+ "BlizzardOptionsPanel_OnLoad",
+ "BlizzardOptionsPanel_Refresh",
+ "BlizzardOptionsPanel_RefreshControl",
+ "BlizzardOptionsPanel_RegisterControl",
+ "BlizzardOptionsPanel_SetCVarSafe",
+ "BlizzardOptionsPanel_SetupControl",
+ "BlizzardOptionsPanel_SetupDependentControl",
+ "BlizzardOptionsPanel_Slider_Disable",
+ "BlizzardOptionsPanel_Slider_Enable",
+ "BlizzardOptionsPanel_Slider_OnValueChanged",
+ "BlizzardOptionsPanel_Slider_Refresh",
+ "BlizzardOptionsPanel_UpdateCombatText",
+ "BlizzardOptionsPanel_UpdateRaidPullouts",
+ "BlizzardStopwatchOptions",
+ "Blizzard_CombatLog_ApplyFilters",
+ "Blizzard_CombatLog_CreateActionMenu",
+ "Blizzard_CombatLog_CreateFilterMenu",
+ "Blizzard_CombatLog_CreateSpellMenu",
+ "Blizzard_CombatLog_CreateTabMenu",
+ "Blizzard_CombatLog_CreateUnitMenu",
+ "Blizzard_CombatLog_CurrentSettings",
+ "Blizzard_CombatLog_DisableEvent",
+ "Blizzard_CombatLog_EnableEvent",
+ "Blizzard_CombatLog_Filter_Defaults",
+ "Blizzard_CombatLog_Filters",
+ "Blizzard_CombatLog_FormattingMenu",
+ "Blizzard_CombatLog_GenerateFullEventList",
+ "Blizzard_CombatLog_GenerateFullFlagList",
+ "Blizzard_CombatLog_HasEvent",
+ "Blizzard_CombatLog_InitializeFilters",
+ "Blizzard_CombatLog_MenuHelper",
+ "Blizzard_CombatLog_MessageTypesMenu",
+ "Blizzard_CombatLog_QuickButtonFrame_OnEvent",
+ "Blizzard_CombatLog_QuickButtonFrame_OnLoad",
+ "Blizzard_CombatLog_QuickButtonRightClick",
+ "Blizzard_CombatLog_QuickButton_OnClick",
+ "Blizzard_CombatLog_Refilter",
+ "Blizzard_CombatLog_RefilterUpdate",
+ "Blizzard_CombatLog_RefreshGlobalLinks",
+ "Blizzard_CombatLog_SpellMenuClick",
+ "Blizzard_CombatLog_UnitMenuClick",
+ "Blizzard_CombatLog_Update_QuickButtons",
+ "BonusActionBarFrame",
+ "BonusActionBarTexture0",
+ "BonusActionBarTexture1",
+ "BonusActionBar_OnEvent",
+ "BonusActionBar_OnLoad",
+ "BonusActionBar_OnUpdate",
+ "BonusActionButton1",
+ "BonusActionButton10",
+ "BonusActionButton10Border",
+ "BonusActionButton10Cooldown",
+ "BonusActionButton10Count",
+ "BonusActionButton10Flash",
+ "BonusActionButton10HotKey",
+ "BonusActionButton10Icon",
+ "BonusActionButton10Name",
+ "BonusActionButton10NormalTexture",
+ "BonusActionButton11",
+ "BonusActionButton11Border",
+ "BonusActionButton11Cooldown",
+ "BonusActionButton11Count",
+ "BonusActionButton11Flash",
+ "BonusActionButton11HotKey",
+ "BonusActionButton11Icon",
+ "BonusActionButton11Name",
+ "BonusActionButton11NormalTexture",
+ "BonusActionButton12",
+ "BonusActionButton12Border",
+ "BonusActionButton12Cooldown",
+ "BonusActionButton12Count",
+ "BonusActionButton12Flash",
+ "BonusActionButton12HotKey",
+ "BonusActionButton12Icon",
+ "BonusActionButton12Name",
+ "BonusActionButton12NormalTexture",
+ "BonusActionButton1Border",
+ "BonusActionButton1Cooldown",
+ "BonusActionButton1Count",
+ "BonusActionButton1Flash",
+ "BonusActionButton1HotKey",
+ "BonusActionButton1Icon",
+ "BonusActionButton1Name",
+ "BonusActionButton1NormalTexture",
+ "BonusActionButton2",
+ "BonusActionButton2Border",
+ "BonusActionButton2Cooldown",
+ "BonusActionButton2Count",
+ "BonusActionButton2Flash",
+ "BonusActionButton2HotKey",
+ "BonusActionButton2Icon",
+ "BonusActionButton2Name",
+ "BonusActionButton2NormalTexture",
+ "BonusActionButton3",
+ "BonusActionButton3Border",
+ "BonusActionButton3Cooldown",
+ "BonusActionButton3Count",
+ "BonusActionButton3Flash",
+ "BonusActionButton3HotKey",
+ "BonusActionButton3Icon",
+ "BonusActionButton3Name",
+ "BonusActionButton3NormalTexture",
+ "BonusActionButton4",
+ "BonusActionButton4Border",
+ "BonusActionButton4Cooldown",
+ "BonusActionButton4Count",
+ "BonusActionButton4Flash",
+ "BonusActionButton4HotKey",
+ "BonusActionButton4Icon",
+ "BonusActionButton4Name",
+ "BonusActionButton4NormalTexture",
+ "BonusActionButton5",
+ "BonusActionButton5Border",
+ "BonusActionButton5Cooldown",
+ "BonusActionButton5Count",
+ "BonusActionButton5Flash",
+ "BonusActionButton5HotKey",
+ "BonusActionButton5Icon",
+ "BonusActionButton5Name",
+ "BonusActionButton5NormalTexture",
+ "BonusActionButton6",
+ "BonusActionButton6Border",
+ "BonusActionButton6Cooldown",
+ "BonusActionButton6Count",
+ "BonusActionButton6Flash",
+ "BonusActionButton6HotKey",
+ "BonusActionButton6Icon",
+ "BonusActionButton6Name",
+ "BonusActionButton6NormalTexture",
+ "BonusActionButton7",
+ "BonusActionButton7Border",
+ "BonusActionButton7Cooldown",
+ "BonusActionButton7Count",
+ "BonusActionButton7Flash",
+ "BonusActionButton7HotKey",
+ "BonusActionButton7Icon",
+ "BonusActionButton7Name",
+ "BonusActionButton7NormalTexture",
+ "BonusActionButton8",
+ "BonusActionButton8Border",
+ "BonusActionButton8Cooldown",
+ "BonusActionButton8Count",
+ "BonusActionButton8Flash",
+ "BonusActionButton8HotKey",
+ "BonusActionButton8Icon",
+ "BonusActionButton8Name",
+ "BonusActionButton8NormalTexture",
+ "BonusActionButton9",
+ "BonusActionButton9Border",
+ "BonusActionButton9Cooldown",
+ "BonusActionButton9Count",
+ "BonusActionButton9Flash",
+ "BonusActionButton9HotKey",
+ "BonusActionButton9Icon",
+ "BonusActionButton9Name",
+ "BonusActionButton9NormalTexture",
+ "BonusActionButtonDown",
+ "BonusActionButtonUp",
+ "Boss1TargetFrame",
+ "Boss1TargetFrameBackground",
+ "Boss1TargetFrameBuffs",
+ "Boss1TargetFrameDebuffs",
+ "Boss1TargetFrameDropDown",
+ "Boss1TargetFrameDropDownButton",
+ "Boss1TargetFrameDropDownButtonDisabledTexture",
+ "Boss1TargetFrameDropDownButtonHighlightTexture",
+ "Boss1TargetFrameDropDownButtonNormalTexture",
+ "Boss1TargetFrameDropDownButtonPushedTexture",
+ "Boss1TargetFrameDropDownLeft",
+ "Boss1TargetFrameDropDownMiddle",
+ "Boss1TargetFrameDropDownRight",
+ "Boss1TargetFrameDropDownText",
+ "Boss1TargetFrameFlash",
+ "Boss1TargetFrameHealthBar",
+ "Boss1TargetFrameManaBar",
+ "Boss1TargetFrameNameBackground",
+ "Boss1TargetFrameNumericalThreat",
+ "Boss1TargetFrameNumericalThreatBG",
+ "Boss1TargetFrameNumericalThreatValue",
+ "Boss1TargetFramePortrait",
+ "Boss1TargetFrameTextureFrame",
+ "Boss1TargetFrameTextureFrameDeadText",
+ "Boss1TargetFrameTextureFrameHealthBarText",
+ "Boss1TargetFrameTextureFrameHighLevelTexture",
+ "Boss1TargetFrameTextureFrameLeaderIcon",
+ "Boss1TargetFrameTextureFrameLevelText",
+ "Boss1TargetFrameTextureFrameManaBarText",
+ "Boss1TargetFrameTextureFrameName",
+ "Boss1TargetFrameTextureFramePVPIcon",
+ "Boss1TargetFrameTextureFrameRaidTargetIcon",
+ "Boss1TargetFrameTextureFrameTexture",
+ "Boss2TargetFrame",
+ "Boss2TargetFrameBackground",
+ "Boss2TargetFrameBuffs",
+ "Boss2TargetFrameDebuffs",
+ "Boss2TargetFrameDropDown",
+ "Boss2TargetFrameDropDownButton",
+ "Boss2TargetFrameDropDownButtonDisabledTexture",
+ "Boss2TargetFrameDropDownButtonHighlightTexture",
+ "Boss2TargetFrameDropDownButtonNormalTexture",
+ "Boss2TargetFrameDropDownButtonPushedTexture",
+ "Boss2TargetFrameDropDownLeft",
+ "Boss2TargetFrameDropDownMiddle",
+ "Boss2TargetFrameDropDownRight",
+ "Boss2TargetFrameDropDownText",
+ "Boss2TargetFrameFlash",
+ "Boss2TargetFrameHealthBar",
+ "Boss2TargetFrameManaBar",
+ "Boss2TargetFrameNameBackground",
+ "Boss2TargetFrameNumericalThreat",
+ "Boss2TargetFrameNumericalThreatBG",
+ "Boss2TargetFrameNumericalThreatValue",
+ "Boss2TargetFramePortrait",
+ "Boss2TargetFrameTextureFrame",
+ "Boss2TargetFrameTextureFrameDeadText",
+ "Boss2TargetFrameTextureFrameHealthBarText",
+ "Boss2TargetFrameTextureFrameHighLevelTexture",
+ "Boss2TargetFrameTextureFrameLeaderIcon",
+ "Boss2TargetFrameTextureFrameLevelText",
+ "Boss2TargetFrameTextureFrameManaBarText",
+ "Boss2TargetFrameTextureFrameName",
+ "Boss2TargetFrameTextureFramePVPIcon",
+ "Boss2TargetFrameTextureFrameRaidTargetIcon",
+ "Boss2TargetFrameTextureFrameTexture",
+ "Boss3TargetFrame",
+ "Boss3TargetFrameBackground",
+ "Boss3TargetFrameBuffs",
+ "Boss3TargetFrameDebuffs",
+ "Boss3TargetFrameDropDown",
+ "Boss3TargetFrameDropDownButton",
+ "Boss3TargetFrameDropDownButtonDisabledTexture",
+ "Boss3TargetFrameDropDownButtonHighlightTexture",
+ "Boss3TargetFrameDropDownButtonNormalTexture",
+ "Boss3TargetFrameDropDownButtonPushedTexture",
+ "Boss3TargetFrameDropDownLeft",
+ "Boss3TargetFrameDropDownMiddle",
+ "Boss3TargetFrameDropDownRight",
+ "Boss3TargetFrameDropDownText",
+ "Boss3TargetFrameFlash",
+ "Boss3TargetFrameHealthBar",
+ "Boss3TargetFrameManaBar",
+ "Boss3TargetFrameNameBackground",
+ "Boss3TargetFrameNumericalThreat",
+ "Boss3TargetFrameNumericalThreatBG",
+ "Boss3TargetFrameNumericalThreatValue",
+ "Boss3TargetFramePortrait",
+ "Boss3TargetFrameTextureFrame",
+ "Boss3TargetFrameTextureFrameDeadText",
+ "Boss3TargetFrameTextureFrameHealthBarText",
+ "Boss3TargetFrameTextureFrameHighLevelTexture",
+ "Boss3TargetFrameTextureFrameLeaderIcon",
+ "Boss3TargetFrameTextureFrameLevelText",
+ "Boss3TargetFrameTextureFrameManaBarText",
+ "Boss3TargetFrameTextureFrameName",
+ "Boss3TargetFrameTextureFramePVPIcon",
+ "Boss3TargetFrameTextureFrameRaidTargetIcon",
+ "Boss3TargetFrameTextureFrameTexture",
+ "Boss4TargetFrame",
+ "Boss4TargetFrameBackground",
+ "Boss4TargetFrameBuffs",
+ "Boss4TargetFrameDebuffs",
+ "Boss4TargetFrameDropDown",
+ "Boss4TargetFrameDropDownButton",
+ "Boss4TargetFrameDropDownButtonDisabledTexture",
+ "Boss4TargetFrameDropDownButtonHighlightTexture",
+ "Boss4TargetFrameDropDownButtonNormalTexture",
+ "Boss4TargetFrameDropDownButtonPushedTexture",
+ "Boss4TargetFrameDropDownLeft",
+ "Boss4TargetFrameDropDownMiddle",
+ "Boss4TargetFrameDropDownRight",
+ "Boss4TargetFrameDropDownText",
+ "Boss4TargetFrameFlash",
+ "Boss4TargetFrameHealthBar",
+ "Boss4TargetFrameManaBar",
+ "Boss4TargetFrameNameBackground",
+ "Boss4TargetFrameNumericalThreat",
+ "Boss4TargetFrameNumericalThreatBG",
+ "Boss4TargetFrameNumericalThreatValue",
+ "Boss4TargetFramePortrait",
+ "Boss4TargetFrameTextureFrame",
+ "Boss4TargetFrameTextureFrameDeadText",
+ "Boss4TargetFrameTextureFrameHealthBarText",
+ "Boss4TargetFrameTextureFrameHighLevelTexture",
+ "Boss4TargetFrameTextureFrameLeaderIcon",
+ "Boss4TargetFrameTextureFrameLevelText",
+ "Boss4TargetFrameTextureFrameManaBarText",
+ "Boss4TargetFrameTextureFrameName",
+ "Boss4TargetFrameTextureFramePVPIcon",
+ "Boss4TargetFrameTextureFrameRaidTargetIcon",
+ "Boss4TargetFrameTextureFrameTexture",
+ "BossEmoteNormalHuge",
+ "BossTargetFrameDropDown_Initialize",
+ "BossTargetFrame_OnLoad",
+ "BrowseBidButton",
+ "BrowseBidButtonText",
+ "BrowseBidPrice",
+ "BrowseBidPriceCopper",
+ "BrowseBidPriceCopperLeft",
+ "BrowseBidPriceCopperMiddle",
+ "BrowseBidPriceCopperRight",
+ "BrowseBidPriceGold",
+ "BrowseBidPriceGoldLeft",
+ "BrowseBidPriceGoldMiddle",
+ "BrowseBidPriceGoldRight",
+ "BrowseBidPriceSilver",
+ "BrowseBidPriceSilverLeft",
+ "BrowseBidPriceSilverMiddle",
+ "BrowseBidPriceSilverRight",
+ "BrowseBidText",
+ "BrowseButton1",
+ "BrowseButton1BuyoutFrame",
+ "BrowseButton1BuyoutFrameMoney",
+ "BrowseButton1BuyoutFrameMoneyCopperButton",
+ "BrowseButton1BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton1BuyoutFrameMoneyGoldButton",
+ "BrowseButton1BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton1BuyoutFrameMoneySilverButton",
+ "BrowseButton1BuyoutFrameMoneySilverButtonText",
+ "BrowseButton1BuyoutFrameText",
+ "BrowseButton1ClosingTime",
+ "BrowseButton1ClosingTimeText",
+ "BrowseButton1HighBidder",
+ "BrowseButton1Highlight",
+ "BrowseButton1Item",
+ "BrowseButton1ItemCount",
+ "BrowseButton1ItemIconTexture",
+ "BrowseButton1ItemNormalTexture",
+ "BrowseButton1ItemStock",
+ "BrowseButton1Left",
+ "BrowseButton1Level",
+ "BrowseButton1MoneyFrame",
+ "BrowseButton1MoneyFrameCopperButton",
+ "BrowseButton1MoneyFrameCopperButtonText",
+ "BrowseButton1MoneyFrameGoldButton",
+ "BrowseButton1MoneyFrameGoldButtonText",
+ "BrowseButton1MoneyFrameSilverButton",
+ "BrowseButton1MoneyFrameSilverButtonText",
+ "BrowseButton1Name",
+ "BrowseButton1Right",
+ "BrowseButton1YourBidText",
+ "BrowseButton2",
+ "BrowseButton2BuyoutFrame",
+ "BrowseButton2BuyoutFrameMoney",
+ "BrowseButton2BuyoutFrameMoneyCopperButton",
+ "BrowseButton2BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton2BuyoutFrameMoneyGoldButton",
+ "BrowseButton2BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton2BuyoutFrameMoneySilverButton",
+ "BrowseButton2BuyoutFrameMoneySilverButtonText",
+ "BrowseButton2BuyoutFrameText",
+ "BrowseButton2ClosingTime",
+ "BrowseButton2ClosingTimeText",
+ "BrowseButton2HighBidder",
+ "BrowseButton2Highlight",
+ "BrowseButton2Item",
+ "BrowseButton2ItemCount",
+ "BrowseButton2ItemIconTexture",
+ "BrowseButton2ItemNormalTexture",
+ "BrowseButton2ItemStock",
+ "BrowseButton2Left",
+ "BrowseButton2Level",
+ "BrowseButton2MoneyFrame",
+ "BrowseButton2MoneyFrameCopperButton",
+ "BrowseButton2MoneyFrameCopperButtonText",
+ "BrowseButton2MoneyFrameGoldButton",
+ "BrowseButton2MoneyFrameGoldButtonText",
+ "BrowseButton2MoneyFrameSilverButton",
+ "BrowseButton2MoneyFrameSilverButtonText",
+ "BrowseButton2Name",
+ "BrowseButton2Right",
+ "BrowseButton2YourBidText",
+ "BrowseButton3",
+ "BrowseButton3BuyoutFrame",
+ "BrowseButton3BuyoutFrameMoney",
+ "BrowseButton3BuyoutFrameMoneyCopperButton",
+ "BrowseButton3BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton3BuyoutFrameMoneyGoldButton",
+ "BrowseButton3BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton3BuyoutFrameMoneySilverButton",
+ "BrowseButton3BuyoutFrameMoneySilverButtonText",
+ "BrowseButton3BuyoutFrameText",
+ "BrowseButton3ClosingTime",
+ "BrowseButton3ClosingTimeText",
+ "BrowseButton3HighBidder",
+ "BrowseButton3Highlight",
+ "BrowseButton3Item",
+ "BrowseButton3ItemCount",
+ "BrowseButton3ItemIconTexture",
+ "BrowseButton3ItemNormalTexture",
+ "BrowseButton3ItemStock",
+ "BrowseButton3Left",
+ "BrowseButton3Level",
+ "BrowseButton3MoneyFrame",
+ "BrowseButton3MoneyFrameCopperButton",
+ "BrowseButton3MoneyFrameCopperButtonText",
+ "BrowseButton3MoneyFrameGoldButton",
+ "BrowseButton3MoneyFrameGoldButtonText",
+ "BrowseButton3MoneyFrameSilverButton",
+ "BrowseButton3MoneyFrameSilverButtonText",
+ "BrowseButton3Name",
+ "BrowseButton3Right",
+ "BrowseButton3YourBidText",
+ "BrowseButton4",
+ "BrowseButton4BuyoutFrame",
+ "BrowseButton4BuyoutFrameMoney",
+ "BrowseButton4BuyoutFrameMoneyCopperButton",
+ "BrowseButton4BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton4BuyoutFrameMoneyGoldButton",
+ "BrowseButton4BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton4BuyoutFrameMoneySilverButton",
+ "BrowseButton4BuyoutFrameMoneySilverButtonText",
+ "BrowseButton4BuyoutFrameText",
+ "BrowseButton4ClosingTime",
+ "BrowseButton4ClosingTimeText",
+ "BrowseButton4HighBidder",
+ "BrowseButton4Highlight",
+ "BrowseButton4Item",
+ "BrowseButton4ItemCount",
+ "BrowseButton4ItemIconTexture",
+ "BrowseButton4ItemNormalTexture",
+ "BrowseButton4ItemStock",
+ "BrowseButton4Left",
+ "BrowseButton4Level",
+ "BrowseButton4MoneyFrame",
+ "BrowseButton4MoneyFrameCopperButton",
+ "BrowseButton4MoneyFrameCopperButtonText",
+ "BrowseButton4MoneyFrameGoldButton",
+ "BrowseButton4MoneyFrameGoldButtonText",
+ "BrowseButton4MoneyFrameSilverButton",
+ "BrowseButton4MoneyFrameSilverButtonText",
+ "BrowseButton4Name",
+ "BrowseButton4Right",
+ "BrowseButton4YourBidText",
+ "BrowseButton5",
+ "BrowseButton5BuyoutFrame",
+ "BrowseButton5BuyoutFrameMoney",
+ "BrowseButton5BuyoutFrameMoneyCopperButton",
+ "BrowseButton5BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton5BuyoutFrameMoneyGoldButton",
+ "BrowseButton5BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton5BuyoutFrameMoneySilverButton",
+ "BrowseButton5BuyoutFrameMoneySilverButtonText",
+ "BrowseButton5BuyoutFrameText",
+ "BrowseButton5ClosingTime",
+ "BrowseButton5ClosingTimeText",
+ "BrowseButton5HighBidder",
+ "BrowseButton5Highlight",
+ "BrowseButton5Item",
+ "BrowseButton5ItemCount",
+ "BrowseButton5ItemIconTexture",
+ "BrowseButton5ItemNormalTexture",
+ "BrowseButton5ItemStock",
+ "BrowseButton5Left",
+ "BrowseButton5Level",
+ "BrowseButton5MoneyFrame",
+ "BrowseButton5MoneyFrameCopperButton",
+ "BrowseButton5MoneyFrameCopperButtonText",
+ "BrowseButton5MoneyFrameGoldButton",
+ "BrowseButton5MoneyFrameGoldButtonText",
+ "BrowseButton5MoneyFrameSilverButton",
+ "BrowseButton5MoneyFrameSilverButtonText",
+ "BrowseButton5Name",
+ "BrowseButton5Right",
+ "BrowseButton5YourBidText",
+ "BrowseButton6",
+ "BrowseButton6BuyoutFrame",
+ "BrowseButton6BuyoutFrameMoney",
+ "BrowseButton6BuyoutFrameMoneyCopperButton",
+ "BrowseButton6BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton6BuyoutFrameMoneyGoldButton",
+ "BrowseButton6BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton6BuyoutFrameMoneySilverButton",
+ "BrowseButton6BuyoutFrameMoneySilverButtonText",
+ "BrowseButton6BuyoutFrameText",
+ "BrowseButton6ClosingTime",
+ "BrowseButton6ClosingTimeText",
+ "BrowseButton6HighBidder",
+ "BrowseButton6Highlight",
+ "BrowseButton6Item",
+ "BrowseButton6ItemCount",
+ "BrowseButton6ItemIconTexture",
+ "BrowseButton6ItemNormalTexture",
+ "BrowseButton6ItemStock",
+ "BrowseButton6Left",
+ "BrowseButton6Level",
+ "BrowseButton6MoneyFrame",
+ "BrowseButton6MoneyFrameCopperButton",
+ "BrowseButton6MoneyFrameCopperButtonText",
+ "BrowseButton6MoneyFrameGoldButton",
+ "BrowseButton6MoneyFrameGoldButtonText",
+ "BrowseButton6MoneyFrameSilverButton",
+ "BrowseButton6MoneyFrameSilverButtonText",
+ "BrowseButton6Name",
+ "BrowseButton6Right",
+ "BrowseButton6YourBidText",
+ "BrowseButton7",
+ "BrowseButton7BuyoutFrame",
+ "BrowseButton7BuyoutFrameMoney",
+ "BrowseButton7BuyoutFrameMoneyCopperButton",
+ "BrowseButton7BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton7BuyoutFrameMoneyGoldButton",
+ "BrowseButton7BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton7BuyoutFrameMoneySilverButton",
+ "BrowseButton7BuyoutFrameMoneySilverButtonText",
+ "BrowseButton7BuyoutFrameText",
+ "BrowseButton7ClosingTime",
+ "BrowseButton7ClosingTimeText",
+ "BrowseButton7HighBidder",
+ "BrowseButton7Highlight",
+ "BrowseButton7Item",
+ "BrowseButton7ItemCount",
+ "BrowseButton7ItemIconTexture",
+ "BrowseButton7ItemNormalTexture",
+ "BrowseButton7ItemStock",
+ "BrowseButton7Left",
+ "BrowseButton7Level",
+ "BrowseButton7MoneyFrame",
+ "BrowseButton7MoneyFrameCopperButton",
+ "BrowseButton7MoneyFrameCopperButtonText",
+ "BrowseButton7MoneyFrameGoldButton",
+ "BrowseButton7MoneyFrameGoldButtonText",
+ "BrowseButton7MoneyFrameSilverButton",
+ "BrowseButton7MoneyFrameSilverButtonText",
+ "BrowseButton7Name",
+ "BrowseButton7Right",
+ "BrowseButton7YourBidText",
+ "BrowseButton8",
+ "BrowseButton8BuyoutFrame",
+ "BrowseButton8BuyoutFrameMoney",
+ "BrowseButton8BuyoutFrameMoneyCopperButton",
+ "BrowseButton8BuyoutFrameMoneyCopperButtonText",
+ "BrowseButton8BuyoutFrameMoneyGoldButton",
+ "BrowseButton8BuyoutFrameMoneyGoldButtonText",
+ "BrowseButton8BuyoutFrameMoneySilverButton",
+ "BrowseButton8BuyoutFrameMoneySilverButtonText",
+ "BrowseButton8BuyoutFrameText",
+ "BrowseButton8ClosingTime",
+ "BrowseButton8ClosingTimeText",
+ "BrowseButton8HighBidder",
+ "BrowseButton8Highlight",
+ "BrowseButton8Item",
+ "BrowseButton8ItemCount",
+ "BrowseButton8ItemIconTexture",
+ "BrowseButton8ItemNormalTexture",
+ "BrowseButton8ItemStock",
+ "BrowseButton8Left",
+ "BrowseButton8Level",
+ "BrowseButton8MoneyFrame",
+ "BrowseButton8MoneyFrameCopperButton",
+ "BrowseButton8MoneyFrameCopperButtonText",
+ "BrowseButton8MoneyFrameGoldButton",
+ "BrowseButton8MoneyFrameGoldButtonText",
+ "BrowseButton8MoneyFrameSilverButton",
+ "BrowseButton8MoneyFrameSilverButtonText",
+ "BrowseButton8Name",
+ "BrowseButton8Right",
+ "BrowseButton8YourBidText",
+ "BrowseButton_OnClick",
+ "BrowseBuyoutButton",
+ "BrowseBuyoutButtonText",
+ "BrowseCloseButton",
+ "BrowseCloseButtonText",
+ "BrowseCurrentBidSort",
+ "BrowseCurrentBidSortArrow",
+ "BrowseCurrentBidSortLeft",
+ "BrowseCurrentBidSortMiddle",
+ "BrowseCurrentBidSortRight",
+ "BrowseCurrentBidSortText",
+ "BrowseDropDown",
+ "BrowseDropDownButton",
+ "BrowseDropDownButtonDisabledTexture",
+ "BrowseDropDownButtonHighlightTexture",
+ "BrowseDropDownButtonNormalTexture",
+ "BrowseDropDownButtonPushedTexture",
+ "BrowseDropDownLeft",
+ "BrowseDropDownMiddle",
+ "BrowseDropDownName",
+ "BrowseDropDownRight",
+ "BrowseDropDownText",
+ "BrowseDropDown_Initialize",
+ "BrowseDropDown_OnClick",
+ "BrowseDropDown_OnLoad",
+ "BrowseDurationSort",
+ "BrowseDurationSortArrow",
+ "BrowseDurationSortLeft",
+ "BrowseDurationSortMiddle",
+ "BrowseDurationSortRight",
+ "BrowseDurationSortText",
+ "BrowseFilterScrollFrame",
+ "BrowseFilterScrollFrameScrollBar",
+ "BrowseFilterScrollFrameScrollBarScrollDownButton",
+ "BrowseFilterScrollFrameScrollBarScrollUpButton",
+ "BrowseFilterScrollFrameScrollBarThumbTexture",
+ "BrowseFilterScrollFrameScrollChildFrame",
+ "BrowseHighBidderSort",
+ "BrowseHighBidderSortArrow",
+ "BrowseHighBidderSortLeft",
+ "BrowseHighBidderSortMiddle",
+ "BrowseHighBidderSortRight",
+ "BrowseHighBidderSortText",
+ "BrowseLevelHyphen",
+ "BrowseLevelSort",
+ "BrowseLevelSortArrow",
+ "BrowseLevelSortLeft",
+ "BrowseLevelSortMiddle",
+ "BrowseLevelSortRight",
+ "BrowseLevelSortText",
+ "BrowseLevelText",
+ "BrowseMaxLevel",
+ "BrowseMaxLevelLeft",
+ "BrowseMaxLevelMiddle",
+ "BrowseMaxLevelRight",
+ "BrowseMinLevel",
+ "BrowseMinLevelLeft",
+ "BrowseMinLevelMiddle",
+ "BrowseMinLevelRight",
+ "BrowseName",
+ "BrowseNameLeft",
+ "BrowseNameMiddle",
+ "BrowseNameRight",
+ "BrowseNameText",
+ "BrowseNextPageButton",
+ "BrowseNoResultsText",
+ "BrowsePrevPageButton",
+ "BrowseQualitySort",
+ "BrowseQualitySortArrow",
+ "BrowseQualitySortLeft",
+ "BrowseQualitySortMiddle",
+ "BrowseQualitySortRight",
+ "BrowseQualitySortText",
+ "BrowseResetButton",
+ "BrowseResetButtonText",
+ "BrowseResetButton_OnUpdate",
+ "BrowseScrollFrame",
+ "BrowseScrollFrameScrollBar",
+ "BrowseScrollFrameScrollBarScrollDownButton",
+ "BrowseScrollFrameScrollBarScrollUpButton",
+ "BrowseScrollFrameScrollBarThumbTexture",
+ "BrowseScrollFrameScrollChildFrame",
+ "BrowseSearchButton",
+ "BrowseSearchButtonText",
+ "BrowseSearchButton_OnUpdate",
+ "BrowseSearchCountText",
+ "BrowseSearchDotsText",
+ "BrowseTitle",
+ "BuffButton1",
+ "BuffButton1Count",
+ "BuffButton1Duration",
+ "BuffButton1Icon",
+ "BuffButton2",
+ "BuffButton2Count",
+ "BuffButton2Duration",
+ "BuffButton2Icon",
+ "BuffButton_OnClick",
+ "BuffButton_OnLoad",
+ "BuffFrame",
+ "BuffFrame_OnEvent",
+ "BuffFrame_OnLoad",
+ "BuffFrame_OnUpdate",
+ "BuffFrame_Update",
+ "BuffFrame_UpdateAllBuffAnchors",
+ "BuffFrame_UpdatePositions",
+ "BuffsPanelOptions",
+ "BuildColoredListString",
+ "BuildListString",
+ "BuildMultilineTooltip",
+ "BuildNewLineListString",
+ "ButtonInventorySlot",
+ "ButtonPulse_OnUpdate",
+ "ButtonPulse_StopPulse",
+ "BuyGuildBankTab",
+ "BuyGuildCharter",
+ "BuyMerchantItem",
+ "BuyPetition",
+ "BuySkillTier",
+ "BuyStableSlot",
+ "BuyTrainerService",
+ "BuybackFrameBotLeft",
+ "BuybackFrameBotRight",
+ "BuybackFrameTopLeft",
+ "BuybackFrameTopRight",
+ "BuybackItem",
+ "BuyoutPrice",
+ "BuyoutPriceCopper",
+ "BuyoutPriceCopperLeft",
+ "BuyoutPriceCopperMiddle",
+ "BuyoutPriceCopperRight",
+ "BuyoutPriceGold",
+ "BuyoutPriceGoldLeft",
+ "BuyoutPriceGoldMiddle",
+ "BuyoutPriceGoldRight",
+ "BuyoutPriceSilver",
+ "BuyoutPriceSilverLeft",
+ "BuyoutPriceSilverMiddle",
+ "BuyoutPriceSilverRight",
+ "CALENDAR_CREATEEVENTFRAME_TAB_LIST",
+ "CHANNELPULLOUT_FADEFRAMES",
+ "CHANNELPULLOUT_OPTIONS",
+ "CHARACTERFRAME_SUBFRAMES",
+ "CHATCONFIG_SELECTED_FILTER_COLORS",
+ "CHATCONFIG_SELECTED_FILTER_FILTERS",
+ "CHATCONFIG_SELECTED_FILTER_SETTINGS",
+ "CHAT_CATEGORY_LIST",
+ "CHAT_CHANNEL_TABBING",
+ "CHAT_CONFIG_CATEGORIES",
+ "CHAT_CONFIG_CHANNEL_LIST",
+ "CHAT_CONFIG_CHAT_CREATURE_LEFT",
+ "CHAT_CONFIG_CHAT_LEFT",
+ "CHAT_CONFIG_OTHER_COMBAT",
+ "CHAT_CONFIG_OTHER_PVP",
+ "CHAT_CONFIG_OTHER_SYSTEM",
+ "CHAT_FONT_HEIGHTS",
+ "CHAT_FRAMES",
+ "CHAT_FRAME_TEXTURES",
+ "CHAT_INVERTED_CATEGORY_LIST",
+ "CHAT_OPTIONS",
+ "CLASS_BUTTONS",
+ "CLASS_FILTERS",
+ "CLASS_ICON_TCOORDS",
+ "CLASS_SORT_ORDER",
+ "COINFRAME_BINDING_CACHE",
+ "COMBATCONFIG_COLORPICKER_FUNCTIONS",
+ "COMBATLOG",
+ "COMBATLOG_DEFAULT_COLORS",
+ "COMBATLOG_DEFAULT_SETTINGS",
+ "COMBATLOG_EVENT_LIST",
+ "COMBATLOG_FLAG_LIST",
+ "COMBAT_CONFIG_MESSAGESOURCES_BY",
+ "COMBAT_CONFIG_MESSAGESOURCES_TO",
+ "COMBAT_CONFIG_MESSAGETYPES_LEFT",
+ "COMBAT_CONFIG_MESSAGETYPES_MISC",
+ "COMBAT_CONFIG_MESSAGETYPES_RIGHT",
+ "COMBAT_CONFIG_TABS",
+ "COMBAT_CONFIG_UNIT_COLORS",
+ "COMBAT_TEXT_LOCATIONS",
+ "COMBAT_TEXT_RUNE",
+ "COMBAT_TEXT_SCROLL_FUNCTION",
+ "COMBAT_TEXT_TO_ANIMATE",
+ "COMBAT_TEXT_TYPE_INFO",
+ "COMPARISON_ACHIEVEMENT_FUNCTIONS",
+ "COMPARISON_STAT_FUNCTIONS",
+ "CURRENT_BATTLEFIELD_QUEUES",
+ "CURRENT_MAP_QUESTS",
+ "CUSTOM_CLASS_COLORS",
+ "CalculateAuctionDeposit",
+ "CalendarAddEvent",
+ "CalendarArenaTeamContextMenu",
+ "CalendarArenaTeamContextMenuButton1",
+ "CalendarArenaTeamContextMenuButton10",
+ "CalendarArenaTeamContextMenuButton10ShortcutText",
+ "CalendarArenaTeamContextMenuButton11",
+ "CalendarArenaTeamContextMenuButton11ShortcutText",
+ "CalendarArenaTeamContextMenuButton12",
+ "CalendarArenaTeamContextMenuButton12ShortcutText",
+ "CalendarArenaTeamContextMenuButton13",
+ "CalendarArenaTeamContextMenuButton13ShortcutText",
+ "CalendarArenaTeamContextMenuButton14",
+ "CalendarArenaTeamContextMenuButton14ShortcutText",
+ "CalendarArenaTeamContextMenuButton15",
+ "CalendarArenaTeamContextMenuButton15ShortcutText",
+ "CalendarArenaTeamContextMenuButton16",
+ "CalendarArenaTeamContextMenuButton16ShortcutText",
+ "CalendarArenaTeamContextMenuButton17",
+ "CalendarArenaTeamContextMenuButton17ShortcutText",
+ "CalendarArenaTeamContextMenuButton18",
+ "CalendarArenaTeamContextMenuButton18ShortcutText",
+ "CalendarArenaTeamContextMenuButton19",
+ "CalendarArenaTeamContextMenuButton19ShortcutText",
+ "CalendarArenaTeamContextMenuButton1ShortcutText",
+ "CalendarArenaTeamContextMenuButton2",
+ "CalendarArenaTeamContextMenuButton20",
+ "CalendarArenaTeamContextMenuButton20ShortcutText",
+ "CalendarArenaTeamContextMenuButton21",
+ "CalendarArenaTeamContextMenuButton21ShortcutText",
+ "CalendarArenaTeamContextMenuButton22",
+ "CalendarArenaTeamContextMenuButton22ShortcutText",
+ "CalendarArenaTeamContextMenuButton23",
+ "CalendarArenaTeamContextMenuButton23ShortcutText",
+ "CalendarArenaTeamContextMenuButton24",
+ "CalendarArenaTeamContextMenuButton24ShortcutText",
+ "CalendarArenaTeamContextMenuButton25",
+ "CalendarArenaTeamContextMenuButton25ShortcutText",
+ "CalendarArenaTeamContextMenuButton26",
+ "CalendarArenaTeamContextMenuButton26ShortcutText",
+ "CalendarArenaTeamContextMenuButton27",
+ "CalendarArenaTeamContextMenuButton27ShortcutText",
+ "CalendarArenaTeamContextMenuButton28",
+ "CalendarArenaTeamContextMenuButton28ShortcutText",
+ "CalendarArenaTeamContextMenuButton29",
+ "CalendarArenaTeamContextMenuButton29ShortcutText",
+ "CalendarArenaTeamContextMenuButton2ShortcutText",
+ "CalendarArenaTeamContextMenuButton3",
+ "CalendarArenaTeamContextMenuButton30",
+ "CalendarArenaTeamContextMenuButton30ShortcutText",
+ "CalendarArenaTeamContextMenuButton31",
+ "CalendarArenaTeamContextMenuButton31ShortcutText",
+ "CalendarArenaTeamContextMenuButton32",
+ "CalendarArenaTeamContextMenuButton32ShortcutText",
+ "CalendarArenaTeamContextMenuButton3ShortcutText",
+ "CalendarArenaTeamContextMenuButton4",
+ "CalendarArenaTeamContextMenuButton4ShortcutText",
+ "CalendarArenaTeamContextMenuButton5",
+ "CalendarArenaTeamContextMenuButton5ShortcutText",
+ "CalendarArenaTeamContextMenuButton6",
+ "CalendarArenaTeamContextMenuButton6ShortcutText",
+ "CalendarArenaTeamContextMenuButton7",
+ "CalendarArenaTeamContextMenuButton7ShortcutText",
+ "CalendarArenaTeamContextMenuButton8",
+ "CalendarArenaTeamContextMenuButton8ShortcutText",
+ "CalendarArenaTeamContextMenuButton9",
+ "CalendarArenaTeamContextMenuButton9ShortcutText",
+ "CalendarArenaTeamContextMenuButton_OnClick_CreateArenaTeamEvent",
+ "CalendarArenaTeamContextMenu_Initialize",
+ "CalendarArenaTeamContextMenu_OnEvent",
+ "CalendarArenaTeamContextMenu_OnLoad",
+ "CalendarArenaTeamContextMenu_OnShow",
+ "CalendarCanAddEvent",
+ "CalendarCanSendInvite",
+ "CalendarClassButton1",
+ "CalendarClassButton10",
+ "CalendarClassButton10Count",
+ "CalendarClassButton1Count",
+ "CalendarClassButton2",
+ "CalendarClassButton2Count",
+ "CalendarClassButton3",
+ "CalendarClassButton3Count",
+ "CalendarClassButton4",
+ "CalendarClassButton4Count",
+ "CalendarClassButton5",
+ "CalendarClassButton5Count",
+ "CalendarClassButton6",
+ "CalendarClassButton6Count",
+ "CalendarClassButton7",
+ "CalendarClassButton7Count",
+ "CalendarClassButton8",
+ "CalendarClassButton8Count",
+ "CalendarClassButton9",
+ "CalendarClassButton9Count",
+ "CalendarClassButtonContainer",
+ "CalendarClassButtonContainer_Hide",
+ "CalendarClassButtonContainer_OnLoad",
+ "CalendarClassButtonContainer_Show",
+ "CalendarClassButtonContainer_Update",
+ "CalendarClassButton_OnEnter",
+ "CalendarClassButton_OnLoad",
+ "CalendarClassTotalsButton",
+ "CalendarClassTotalsButtonBackgroundBottom",
+ "CalendarClassTotalsButtonBackgroundMiddle",
+ "CalendarClassTotalsButtonBackgroundTop",
+ "CalendarClassTotalsButton_OnEnter",
+ "CalendarClassTotalsButton_Update",
+ "CalendarClassTotalsText",
+ "CalendarCloseButton",
+ "CalendarCloseEvent",
+ "CalendarContextDeselectEvent",
+ "CalendarContextEventCanComplain",
+ "CalendarContextEventCanEdit",
+ "CalendarContextEventClipboard",
+ "CalendarContextEventComplain",
+ "CalendarContextEventCopy",
+ "CalendarContextEventGetCalendarType",
+ "CalendarContextEventPaste",
+ "CalendarContextEventRemove",
+ "CalendarContextEventSignUp",
+ "CalendarContextGetEventIndex",
+ "CalendarContextInviteAvailable",
+ "CalendarContextInviteDecline",
+ "CalendarContextInviteIsPending",
+ "CalendarContextInviteModeratorStatus",
+ "CalendarContextInviteRemove",
+ "CalendarContextInviteStatus",
+ "CalendarContextInviteTentative",
+ "CalendarContextInviteType",
+ "CalendarContextMenu",
+ "CalendarContextMenuButton1",
+ "CalendarContextMenuButton10",
+ "CalendarContextMenuButton10ShortcutText",
+ "CalendarContextMenuButton11",
+ "CalendarContextMenuButton11ShortcutText",
+ "CalendarContextMenuButton12",
+ "CalendarContextMenuButton12ShortcutText",
+ "CalendarContextMenuButton13",
+ "CalendarContextMenuButton13ShortcutText",
+ "CalendarContextMenuButton14",
+ "CalendarContextMenuButton14ShortcutText",
+ "CalendarContextMenuButton15",
+ "CalendarContextMenuButton15ShortcutText",
+ "CalendarContextMenuButton16",
+ "CalendarContextMenuButton16ShortcutText",
+ "CalendarContextMenuButton17",
+ "CalendarContextMenuButton17ShortcutText",
+ "CalendarContextMenuButton18",
+ "CalendarContextMenuButton18ShortcutText",
+ "CalendarContextMenuButton19",
+ "CalendarContextMenuButton19ShortcutText",
+ "CalendarContextMenuButton1ShortcutText",
+ "CalendarContextMenuButton2",
+ "CalendarContextMenuButton20",
+ "CalendarContextMenuButton20ShortcutText",
+ "CalendarContextMenuButton21",
+ "CalendarContextMenuButton21ShortcutText",
+ "CalendarContextMenuButton22",
+ "CalendarContextMenuButton22ShortcutText",
+ "CalendarContextMenuButton23",
+ "CalendarContextMenuButton23ShortcutText",
+ "CalendarContextMenuButton24",
+ "CalendarContextMenuButton24ShortcutText",
+ "CalendarContextMenuButton25",
+ "CalendarContextMenuButton25ShortcutText",
+ "CalendarContextMenuButton26",
+ "CalendarContextMenuButton26ShortcutText",
+ "CalendarContextMenuButton27",
+ "CalendarContextMenuButton27ShortcutText",
+ "CalendarContextMenuButton28",
+ "CalendarContextMenuButton28ShortcutText",
+ "CalendarContextMenuButton29",
+ "CalendarContextMenuButton29ShortcutText",
+ "CalendarContextMenuButton2ShortcutText",
+ "CalendarContextMenuButton3",
+ "CalendarContextMenuButton30",
+ "CalendarContextMenuButton30ShortcutText",
+ "CalendarContextMenuButton31",
+ "CalendarContextMenuButton31ShortcutText",
+ "CalendarContextMenuButton32",
+ "CalendarContextMenuButton32ShortcutText",
+ "CalendarContextMenuButton3ShortcutText",
+ "CalendarContextMenuButton4",
+ "CalendarContextMenuButton4ShortcutText",
+ "CalendarContextMenuButton5",
+ "CalendarContextMenuButton5ShortcutText",
+ "CalendarContextMenuButton6",
+ "CalendarContextMenuButton6ShortcutText",
+ "CalendarContextMenuButton7",
+ "CalendarContextMenuButton7ShortcutText",
+ "CalendarContextMenuButton8",
+ "CalendarContextMenuButton8ShortcutText",
+ "CalendarContextMenuButton9",
+ "CalendarContextMenuButton9ShortcutText",
+ "CalendarContextMenu_Hide",
+ "CalendarContextMenu_OnEvent",
+ "CalendarContextMenu_OnHide",
+ "CalendarContextMenu_OnLoad",
+ "CalendarContextMenu_Reset",
+ "CalendarContextMenu_Show",
+ "CalendarContextMenu_Toggle",
+ "CalendarContextSelectEvent",
+ "CalendarCreateEventAMPMDropDown",
+ "CalendarCreateEventAMPMDropDownButton",
+ "CalendarCreateEventAMPMDropDownButtonDisabledTexture",
+ "CalendarCreateEventAMPMDropDownButtonHighlightTexture",
+ "CalendarCreateEventAMPMDropDownButtonNormalTexture",
+ "CalendarCreateEventAMPMDropDownButtonPushedTexture",
+ "CalendarCreateEventAMPMDropDownLeft",
+ "CalendarCreateEventAMPMDropDownMiddle",
+ "CalendarCreateEventAMPMDropDownRight",
+ "CalendarCreateEventAMPMDropDownText",
+ "CalendarCreateEventAMPMDropDown_Initialize",
+ "CalendarCreateEventAMPMDropDown_OnClick",
+ "CalendarCreateEventAutoApproveCheck",
+ "CalendarCreateEventAutoApproveCheckText",
+ "CalendarCreateEventAutoApproveCheck_OnClick",
+ "CalendarCreateEventAutoApproveCheck_OnLoad",
+ "CalendarCreateEventBackground",
+ "CalendarCreateEventCloseButton",
+ "CalendarCreateEventCreateButton",
+ "CalendarCreateEventCreateButtonBorder",
+ "CalendarCreateEventCreateButtonLeft",
+ "CalendarCreateEventCreateButtonMiddle",
+ "CalendarCreateEventCreateButtonRight",
+ "CalendarCreateEventCreateButtonText",
+ "CalendarCreateEventCreateButton_OnClick",
+ "CalendarCreateEventCreateButton_OnUpdate",
+ "CalendarCreateEventCreateButton_SetText",
+ "CalendarCreateEventCreateButton_Update",
+ "CalendarCreateEventCreatorName",
+ "CalendarCreateEventCreatorName_Update",
+ "CalendarCreateEventDateLabel",
+ "CalendarCreateEventDescriptionContainer",
+ "CalendarCreateEventDescriptionEdit",
+ "CalendarCreateEventDescriptionScrollFrame",
+ "CalendarCreateEventDescriptionScrollFrameFocusButton",
+ "CalendarCreateEventDescriptionScrollFrameScrollBar",
+ "CalendarCreateEventDescriptionScrollFrameScrollBarScrollDownButton",
+ "CalendarCreateEventDescriptionScrollFrameScrollBarScrollUpButton",
+ "CalendarCreateEventDescriptionScrollFrameScrollBarThumbTexture",
+ "CalendarCreateEventDescriptionScrollFrame_OnLoad",
+ "CalendarCreateEventDivider",
+ "CalendarCreateEventFrame",
+ "CalendarCreateEventFrameButtonBackground",
+ "CalendarCreateEventFrameModalOverlay",
+ "CalendarCreateEventFrame_OnEvent",
+ "CalendarCreateEventFrame_OnHide",
+ "CalendarCreateEventFrame_OnLoad",
+ "CalendarCreateEventFrame_OnShow",
+ "CalendarCreateEventFrame_SetSelectedInvite",
+ "CalendarCreateEventFrame_Update",
+ "CalendarCreateEventHourDropDown",
+ "CalendarCreateEventHourDropDownButton",
+ "CalendarCreateEventHourDropDownButtonDisabledTexture",
+ "CalendarCreateEventHourDropDownButtonHighlightTexture",
+ "CalendarCreateEventHourDropDownButtonNormalTexture",
+ "CalendarCreateEventHourDropDownButtonPushedTexture",
+ "CalendarCreateEventHourDropDownLeft",
+ "CalendarCreateEventHourDropDownMiddle",
+ "CalendarCreateEventHourDropDownRight",
+ "CalendarCreateEventHourDropDownText",
+ "CalendarCreateEventHourDropDown_Initialize",
+ "CalendarCreateEventHourDropDown_OnClick",
+ "CalendarCreateEventIcon",
+ "CalendarCreateEventInviteButton",
+ "CalendarCreateEventInviteButtonLeft",
+ "CalendarCreateEventInviteButtonMiddle",
+ "CalendarCreateEventInviteButtonRight",
+ "CalendarCreateEventInviteButtonText",
+ "CalendarCreateEventInviteButton_OnClick",
+ "CalendarCreateEventInviteButton_OnUpdate",
+ "CalendarCreateEventInviteButton_Update",
+ "CalendarCreateEventInviteContextMenu_Initialize",
+ "CalendarCreateEventInviteEdit",
+ "CalendarCreateEventInviteEditLeft",
+ "CalendarCreateEventInviteEditMiddle",
+ "CalendarCreateEventInviteEditRight",
+ "CalendarCreateEventInviteEdit_OnEditFocusLost",
+ "CalendarCreateEventInviteEdit_OnEnterPressed",
+ "CalendarCreateEventInviteList",
+ "CalendarCreateEventInviteListButton_Click",
+ "CalendarCreateEventInviteListButton_OnClick",
+ "CalendarCreateEventInviteListClassSortButton",
+ "CalendarCreateEventInviteListClassSortButtonDirection",
+ "CalendarCreateEventInviteListNameSortButton",
+ "CalendarCreateEventInviteListNameSortButtonDirection",
+ "CalendarCreateEventInviteListScrollFrame",
+ "CalendarCreateEventInviteListScrollFrameButton1",
+ "CalendarCreateEventInviteListScrollFrameButton10",
+ "CalendarCreateEventInviteListScrollFrameButton10Class",
+ "CalendarCreateEventInviteListScrollFrameButton10ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton10Name",
+ "CalendarCreateEventInviteListScrollFrameButton10PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton10Status",
+ "CalendarCreateEventInviteListScrollFrameButton11",
+ "CalendarCreateEventInviteListScrollFrameButton11Class",
+ "CalendarCreateEventInviteListScrollFrameButton11ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton11Name",
+ "CalendarCreateEventInviteListScrollFrameButton11PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton11Status",
+ "CalendarCreateEventInviteListScrollFrameButton12",
+ "CalendarCreateEventInviteListScrollFrameButton12Class",
+ "CalendarCreateEventInviteListScrollFrameButton12ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton12Name",
+ "CalendarCreateEventInviteListScrollFrameButton12PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton12Status",
+ "CalendarCreateEventInviteListScrollFrameButton13",
+ "CalendarCreateEventInviteListScrollFrameButton13Class",
+ "CalendarCreateEventInviteListScrollFrameButton13ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton13Name",
+ "CalendarCreateEventInviteListScrollFrameButton13PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton13Status",
+ "CalendarCreateEventInviteListScrollFrameButton14",
+ "CalendarCreateEventInviteListScrollFrameButton14Class",
+ "CalendarCreateEventInviteListScrollFrameButton14ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton14Name",
+ "CalendarCreateEventInviteListScrollFrameButton14PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton14Status",
+ "CalendarCreateEventInviteListScrollFrameButton15",
+ "CalendarCreateEventInviteListScrollFrameButton15Class",
+ "CalendarCreateEventInviteListScrollFrameButton15ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton15Name",
+ "CalendarCreateEventInviteListScrollFrameButton15PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton15Status",
+ "CalendarCreateEventInviteListScrollFrameButton16",
+ "CalendarCreateEventInviteListScrollFrameButton16Class",
+ "CalendarCreateEventInviteListScrollFrameButton16ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton16Name",
+ "CalendarCreateEventInviteListScrollFrameButton16PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton16Status",
+ "CalendarCreateEventInviteListScrollFrameButton17",
+ "CalendarCreateEventInviteListScrollFrameButton17Class",
+ "CalendarCreateEventInviteListScrollFrameButton17ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton17Name",
+ "CalendarCreateEventInviteListScrollFrameButton17PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton17Status",
+ "CalendarCreateEventInviteListScrollFrameButton18",
+ "CalendarCreateEventInviteListScrollFrameButton18Class",
+ "CalendarCreateEventInviteListScrollFrameButton18ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton18Name",
+ "CalendarCreateEventInviteListScrollFrameButton18PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton18Status",
+ "CalendarCreateEventInviteListScrollFrameButton19",
+ "CalendarCreateEventInviteListScrollFrameButton19Class",
+ "CalendarCreateEventInviteListScrollFrameButton19ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton19Name",
+ "CalendarCreateEventInviteListScrollFrameButton19PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton19Status",
+ "CalendarCreateEventInviteListScrollFrameButton1Class",
+ "CalendarCreateEventInviteListScrollFrameButton1ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton1Name",
+ "CalendarCreateEventInviteListScrollFrameButton1PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton1Status",
+ "CalendarCreateEventInviteListScrollFrameButton2",
+ "CalendarCreateEventInviteListScrollFrameButton2Class",
+ "CalendarCreateEventInviteListScrollFrameButton2ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton2Name",
+ "CalendarCreateEventInviteListScrollFrameButton2PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton2Status",
+ "CalendarCreateEventInviteListScrollFrameButton3",
+ "CalendarCreateEventInviteListScrollFrameButton3Class",
+ "CalendarCreateEventInviteListScrollFrameButton3ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton3Name",
+ "CalendarCreateEventInviteListScrollFrameButton3PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton3Status",
+ "CalendarCreateEventInviteListScrollFrameButton4",
+ "CalendarCreateEventInviteListScrollFrameButton4Class",
+ "CalendarCreateEventInviteListScrollFrameButton4ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton4Name",
+ "CalendarCreateEventInviteListScrollFrameButton4PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton4Status",
+ "CalendarCreateEventInviteListScrollFrameButton5",
+ "CalendarCreateEventInviteListScrollFrameButton5Class",
+ "CalendarCreateEventInviteListScrollFrameButton5ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton5Name",
+ "CalendarCreateEventInviteListScrollFrameButton5PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton5Status",
+ "CalendarCreateEventInviteListScrollFrameButton6",
+ "CalendarCreateEventInviteListScrollFrameButton6Class",
+ "CalendarCreateEventInviteListScrollFrameButton6ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton6Name",
+ "CalendarCreateEventInviteListScrollFrameButton6PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton6Status",
+ "CalendarCreateEventInviteListScrollFrameButton7",
+ "CalendarCreateEventInviteListScrollFrameButton7Class",
+ "CalendarCreateEventInviteListScrollFrameButton7ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton7Name",
+ "CalendarCreateEventInviteListScrollFrameButton7PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton7Status",
+ "CalendarCreateEventInviteListScrollFrameButton8",
+ "CalendarCreateEventInviteListScrollFrameButton8Class",
+ "CalendarCreateEventInviteListScrollFrameButton8ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton8Name",
+ "CalendarCreateEventInviteListScrollFrameButton8PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton8Status",
+ "CalendarCreateEventInviteListScrollFrameButton9",
+ "CalendarCreateEventInviteListScrollFrameButton9Class",
+ "CalendarCreateEventInviteListScrollFrameButton9ModIcon",
+ "CalendarCreateEventInviteListScrollFrameButton9Name",
+ "CalendarCreateEventInviteListScrollFrameButton9PartyIcon",
+ "CalendarCreateEventInviteListScrollFrameButton9Status",
+ "CalendarCreateEventInviteListScrollFrameScrollBar",
+ "CalendarCreateEventInviteListScrollFrameScrollBarBG",
+ "CalendarCreateEventInviteListScrollFrameScrollBarBottom",
+ "CalendarCreateEventInviteListScrollFrameScrollBarMiddle",
+ "CalendarCreateEventInviteListScrollFrameScrollBarScrollDownButton",
+ "CalendarCreateEventInviteListScrollFrameScrollBarScrollUpButton",
+ "CalendarCreateEventInviteListScrollFrameScrollBarThumbTexture",
+ "CalendarCreateEventInviteListScrollFrameScrollBarTop",
+ "CalendarCreateEventInviteListScrollFrameScrollChild",
+ "CalendarCreateEventInviteListScrollFrame_Update",
+ "CalendarCreateEventInviteListSection",
+ "CalendarCreateEventInviteListStatusSortButton",
+ "CalendarCreateEventInviteListStatusSortButtonDirection",
+ "CalendarCreateEventInviteList_Update",
+ "CalendarCreateEventLockEventCheck",
+ "CalendarCreateEventLockEventCheckText",
+ "CalendarCreateEventLockEventCheck_OnClick",
+ "CalendarCreateEventLockEventCheck_OnLoad",
+ "CalendarCreateEventMassInviteButton",
+ "CalendarCreateEventMassInviteButtonBorder",
+ "CalendarCreateEventMassInviteButtonLeft",
+ "CalendarCreateEventMassInviteButtonMiddle",
+ "CalendarCreateEventMassInviteButtonRight",
+ "CalendarCreateEventMassInviteButtonText",
+ "CalendarCreateEventMassInviteButton_OnClick",
+ "CalendarCreateEventMassInviteButton_OnUpdate",
+ "CalendarCreateEventMassInviteButton_Update",
+ "CalendarCreateEventMinuteDropDown",
+ "CalendarCreateEventMinuteDropDownButton",
+ "CalendarCreateEventMinuteDropDownButtonDisabledTexture",
+ "CalendarCreateEventMinuteDropDownButtonHighlightTexture",
+ "CalendarCreateEventMinuteDropDownButtonNormalTexture",
+ "CalendarCreateEventMinuteDropDownButtonPushedTexture",
+ "CalendarCreateEventMinuteDropDownLeft",
+ "CalendarCreateEventMinuteDropDownMiddle",
+ "CalendarCreateEventMinuteDropDownRight",
+ "CalendarCreateEventMinuteDropDownText",
+ "CalendarCreateEventMinuteDropDown_Initialize",
+ "CalendarCreateEventMinuteDropDown_OnClick",
+ "CalendarCreateEventRaidInviteButton",
+ "CalendarCreateEventRaidInviteButtonBorder",
+ "CalendarCreateEventRaidInviteButtonLeft",
+ "CalendarCreateEventRaidInviteButtonMiddle",
+ "CalendarCreateEventRaidInviteButtonRight",
+ "CalendarCreateEventRaidInviteButtonText",
+ "CalendarCreateEventRaidInviteButton_OnClick",
+ "CalendarCreateEventRaidInviteButton_OnEnter",
+ "CalendarCreateEventRaidInviteButton_OnEvent",
+ "CalendarCreateEventRaidInviteButton_OnLoad",
+ "CalendarCreateEventRaidInviteButton_Update",
+ "CalendarCreateEventRepeatOptionDropDown",
+ "CalendarCreateEventRepeatOptionDropDownButton",
+ "CalendarCreateEventRepeatOptionDropDownButtonDisabledTexture",
+ "CalendarCreateEventRepeatOptionDropDownButtonHighlightTexture",
+ "CalendarCreateEventRepeatOptionDropDownButtonNormalTexture",
+ "CalendarCreateEventRepeatOptionDropDownButtonPushedTexture",
+ "CalendarCreateEventRepeatOptionDropDownLeft",
+ "CalendarCreateEventRepeatOptionDropDownMiddle",
+ "CalendarCreateEventRepeatOptionDropDownRight",
+ "CalendarCreateEventRepeatOptionDropDownText",
+ "CalendarCreateEventRepeatOptionDropDown_Initialize",
+ "CalendarCreateEventRepeatOptionDropDown_OnClick",
+ "CalendarCreateEventTextureName",
+ "CalendarCreateEventTexture_Update",
+ "CalendarCreateEventTitleEdit",
+ "CalendarCreateEventTitleEditLeft",
+ "CalendarCreateEventTitleEditMiddle",
+ "CalendarCreateEventTitleEditRight",
+ "CalendarCreateEventTitleEdit_OnEditFocusLost",
+ "CalendarCreateEventTitleEdit_OnTextChanged",
+ "CalendarCreateEventTitleFrame",
+ "CalendarCreateEventTitleFrameBackgroundLeft",
+ "CalendarCreateEventTitleFrameBackgroundMiddle",
+ "CalendarCreateEventTitleFrameBackgroundRight",
+ "CalendarCreateEventTitleFrameText",
+ "CalendarCreateEventTypeDropDown",
+ "CalendarCreateEventTypeDropDownButton",
+ "CalendarCreateEventTypeDropDownButtonDisabledTexture",
+ "CalendarCreateEventTypeDropDownButtonHighlightTexture",
+ "CalendarCreateEventTypeDropDownButtonNormalTexture",
+ "CalendarCreateEventTypeDropDownButtonPushedTexture",
+ "CalendarCreateEventTypeDropDownLeft",
+ "CalendarCreateEventTypeDropDownMiddle",
+ "CalendarCreateEventTypeDropDownRight",
+ "CalendarCreateEventTypeDropDownText",
+ "CalendarCreateEventTypeDropDown_InitEventTypes",
+ "CalendarCreateEventTypeDropDown_InitRepeatOptions",
+ "CalendarCreateEventTypeDropDown_Initialize",
+ "CalendarCreateEventTypeDropDown_OnClick",
+ "CalendarCreateEvent_SetAutoApprove",
+ "CalendarCreateEvent_SetEventTime",
+ "CalendarCreateEvent_SetLockEvent",
+ "CalendarCreateEvent_UpdateEventTime",
+ "CalendarCreateEvent_UpdateEventType",
+ "CalendarCreateEvent_UpdateRepeatOption",
+ "CalendarCreateEvent_UpdateTimeFormat",
+ "CalendarDayButton1",
+ "CalendarDayButton10",
+ "CalendarDayButton10DarkFrame",
+ "CalendarDayButton10DarkFrameBottom",
+ "CalendarDayButton10DarkFrameTop",
+ "CalendarDayButton10DateFrame",
+ "CalendarDayButton10DateFrameBackground",
+ "CalendarDayButton10DateFrameDate",
+ "CalendarDayButton10EventBackgroundTexture",
+ "CalendarDayButton10EventButton1",
+ "CalendarDayButton10EventButton1Black",
+ "CalendarDayButton10EventButton1Text1",
+ "CalendarDayButton10EventButton1Text2",
+ "CalendarDayButton10EventButton2",
+ "CalendarDayButton10EventButton2Black",
+ "CalendarDayButton10EventButton2Text1",
+ "CalendarDayButton10EventButton2Text2",
+ "CalendarDayButton10EventButton3",
+ "CalendarDayButton10EventButton3Black",
+ "CalendarDayButton10EventButton3Text1",
+ "CalendarDayButton10EventButton3Text2",
+ "CalendarDayButton10EventButton4",
+ "CalendarDayButton10EventButton4Black",
+ "CalendarDayButton10EventButton4Text1",
+ "CalendarDayButton10EventButton4Text2",
+ "CalendarDayButton10EventTexture",
+ "CalendarDayButton10MoreEventsButton",
+ "CalendarDayButton10OverlayFrame",
+ "CalendarDayButton10OverlayFrameTexture",
+ "CalendarDayButton10PendingInviteTexture",
+ "CalendarDayButton11",
+ "CalendarDayButton11DarkFrame",
+ "CalendarDayButton11DarkFrameBottom",
+ "CalendarDayButton11DarkFrameTop",
+ "CalendarDayButton11DateFrame",
+ "CalendarDayButton11DateFrameBackground",
+ "CalendarDayButton11DateFrameDate",
+ "CalendarDayButton11EventBackgroundTexture",
+ "CalendarDayButton11EventButton1",
+ "CalendarDayButton11EventButton1Black",
+ "CalendarDayButton11EventButton1Text1",
+ "CalendarDayButton11EventButton1Text2",
+ "CalendarDayButton11EventButton2",
+ "CalendarDayButton11EventButton2Black",
+ "CalendarDayButton11EventButton2Text1",
+ "CalendarDayButton11EventButton2Text2",
+ "CalendarDayButton11EventButton3",
+ "CalendarDayButton11EventButton3Black",
+ "CalendarDayButton11EventButton3Text1",
+ "CalendarDayButton11EventButton3Text2",
+ "CalendarDayButton11EventButton4",
+ "CalendarDayButton11EventButton4Black",
+ "CalendarDayButton11EventButton4Text1",
+ "CalendarDayButton11EventButton4Text2",
+ "CalendarDayButton11EventTexture",
+ "CalendarDayButton11MoreEventsButton",
+ "CalendarDayButton11OverlayFrame",
+ "CalendarDayButton11OverlayFrameTexture",
+ "CalendarDayButton11PendingInviteTexture",
+ "CalendarDayButton12",
+ "CalendarDayButton12DarkFrame",
+ "CalendarDayButton12DarkFrameBottom",
+ "CalendarDayButton12DarkFrameTop",
+ "CalendarDayButton12DateFrame",
+ "CalendarDayButton12DateFrameBackground",
+ "CalendarDayButton12DateFrameDate",
+ "CalendarDayButton12EventBackgroundTexture",
+ "CalendarDayButton12EventButton1",
+ "CalendarDayButton12EventButton1Black",
+ "CalendarDayButton12EventButton1Text1",
+ "CalendarDayButton12EventButton1Text2",
+ "CalendarDayButton12EventButton2",
+ "CalendarDayButton12EventButton2Black",
+ "CalendarDayButton12EventButton2Text1",
+ "CalendarDayButton12EventButton2Text2",
+ "CalendarDayButton12EventButton3",
+ "CalendarDayButton12EventButton3Black",
+ "CalendarDayButton12EventButton3Text1",
+ "CalendarDayButton12EventButton3Text2",
+ "CalendarDayButton12EventButton4",
+ "CalendarDayButton12EventButton4Black",
+ "CalendarDayButton12EventButton4Text1",
+ "CalendarDayButton12EventButton4Text2",
+ "CalendarDayButton12EventTexture",
+ "CalendarDayButton12MoreEventsButton",
+ "CalendarDayButton12OverlayFrame",
+ "CalendarDayButton12OverlayFrameTexture",
+ "CalendarDayButton12PendingInviteTexture",
+ "CalendarDayButton13",
+ "CalendarDayButton13DarkFrame",
+ "CalendarDayButton13DarkFrameBottom",
+ "CalendarDayButton13DarkFrameTop",
+ "CalendarDayButton13DateFrame",
+ "CalendarDayButton13DateFrameBackground",
+ "CalendarDayButton13DateFrameDate",
+ "CalendarDayButton13EventBackgroundTexture",
+ "CalendarDayButton13EventButton1",
+ "CalendarDayButton13EventButton1Black",
+ "CalendarDayButton13EventButton1Text1",
+ "CalendarDayButton13EventButton1Text2",
+ "CalendarDayButton13EventButton2",
+ "CalendarDayButton13EventButton2Black",
+ "CalendarDayButton13EventButton2Text1",
+ "CalendarDayButton13EventButton2Text2",
+ "CalendarDayButton13EventButton3",
+ "CalendarDayButton13EventButton3Black",
+ "CalendarDayButton13EventButton3Text1",
+ "CalendarDayButton13EventButton3Text2",
+ "CalendarDayButton13EventButton4",
+ "CalendarDayButton13EventButton4Black",
+ "CalendarDayButton13EventButton4Text1",
+ "CalendarDayButton13EventButton4Text2",
+ "CalendarDayButton13EventTexture",
+ "CalendarDayButton13MoreEventsButton",
+ "CalendarDayButton13OverlayFrame",
+ "CalendarDayButton13OverlayFrameTexture",
+ "CalendarDayButton13PendingInviteTexture",
+ "CalendarDayButton14",
+ "CalendarDayButton14DarkFrame",
+ "CalendarDayButton14DarkFrameBottom",
+ "CalendarDayButton14DarkFrameTop",
+ "CalendarDayButton14DateFrame",
+ "CalendarDayButton14DateFrameBackground",
+ "CalendarDayButton14DateFrameDate",
+ "CalendarDayButton14EventBackgroundTexture",
+ "CalendarDayButton14EventButton1",
+ "CalendarDayButton14EventButton1Black",
+ "CalendarDayButton14EventButton1Text1",
+ "CalendarDayButton14EventButton1Text2",
+ "CalendarDayButton14EventButton2",
+ "CalendarDayButton14EventButton2Black",
+ "CalendarDayButton14EventButton2Text1",
+ "CalendarDayButton14EventButton2Text2",
+ "CalendarDayButton14EventButton3",
+ "CalendarDayButton14EventButton3Black",
+ "CalendarDayButton14EventButton3Text1",
+ "CalendarDayButton14EventButton3Text2",
+ "CalendarDayButton14EventButton4",
+ "CalendarDayButton14EventButton4Black",
+ "CalendarDayButton14EventButton4Text1",
+ "CalendarDayButton14EventButton4Text2",
+ "CalendarDayButton14EventTexture",
+ "CalendarDayButton14MoreEventsButton",
+ "CalendarDayButton14OverlayFrame",
+ "CalendarDayButton14OverlayFrameTexture",
+ "CalendarDayButton14PendingInviteTexture",
+ "CalendarDayButton15",
+ "CalendarDayButton15DarkFrame",
+ "CalendarDayButton15DarkFrameBottom",
+ "CalendarDayButton15DarkFrameTop",
+ "CalendarDayButton15DateFrame",
+ "CalendarDayButton15DateFrameBackground",
+ "CalendarDayButton15DateFrameDate",
+ "CalendarDayButton15EventBackgroundTexture",
+ "CalendarDayButton15EventButton1",
+ "CalendarDayButton15EventButton1Black",
+ "CalendarDayButton15EventButton1Text1",
+ "CalendarDayButton15EventButton1Text2",
+ "CalendarDayButton15EventButton2",
+ "CalendarDayButton15EventButton2Black",
+ "CalendarDayButton15EventButton2Text1",
+ "CalendarDayButton15EventButton2Text2",
+ "CalendarDayButton15EventButton3",
+ "CalendarDayButton15EventButton3Black",
+ "CalendarDayButton15EventButton3Text1",
+ "CalendarDayButton15EventButton3Text2",
+ "CalendarDayButton15EventButton4",
+ "CalendarDayButton15EventButton4Black",
+ "CalendarDayButton15EventButton4Text1",
+ "CalendarDayButton15EventButton4Text2",
+ "CalendarDayButton15EventTexture",
+ "CalendarDayButton15MoreEventsButton",
+ "CalendarDayButton15OverlayFrame",
+ "CalendarDayButton15OverlayFrameTexture",
+ "CalendarDayButton15PendingInviteTexture",
+ "CalendarDayButton16",
+ "CalendarDayButton16DarkFrame",
+ "CalendarDayButton16DarkFrameBottom",
+ "CalendarDayButton16DarkFrameTop",
+ "CalendarDayButton16DateFrame",
+ "CalendarDayButton16DateFrameBackground",
+ "CalendarDayButton16DateFrameDate",
+ "CalendarDayButton16EventBackgroundTexture",
+ "CalendarDayButton16EventButton1",
+ "CalendarDayButton16EventButton1Black",
+ "CalendarDayButton16EventButton1Text1",
+ "CalendarDayButton16EventButton1Text2",
+ "CalendarDayButton16EventButton2",
+ "CalendarDayButton16EventButton2Black",
+ "CalendarDayButton16EventButton2Text1",
+ "CalendarDayButton16EventButton2Text2",
+ "CalendarDayButton16EventButton3",
+ "CalendarDayButton16EventButton3Black",
+ "CalendarDayButton16EventButton3Text1",
+ "CalendarDayButton16EventButton3Text2",
+ "CalendarDayButton16EventButton4",
+ "CalendarDayButton16EventButton4Black",
+ "CalendarDayButton16EventButton4Text1",
+ "CalendarDayButton16EventButton4Text2",
+ "CalendarDayButton16EventTexture",
+ "CalendarDayButton16MoreEventsButton",
+ "CalendarDayButton16OverlayFrame",
+ "CalendarDayButton16OverlayFrameTexture",
+ "CalendarDayButton16PendingInviteTexture",
+ "CalendarDayButton17",
+ "CalendarDayButton17DarkFrame",
+ "CalendarDayButton17DarkFrameBottom",
+ "CalendarDayButton17DarkFrameTop",
+ "CalendarDayButton17DateFrame",
+ "CalendarDayButton17DateFrameBackground",
+ "CalendarDayButton17DateFrameDate",
+ "CalendarDayButton17EventBackgroundTexture",
+ "CalendarDayButton17EventButton1",
+ "CalendarDayButton17EventButton1Black",
+ "CalendarDayButton17EventButton1Text1",
+ "CalendarDayButton17EventButton1Text2",
+ "CalendarDayButton17EventButton2",
+ "CalendarDayButton17EventButton2Black",
+ "CalendarDayButton17EventButton2Text1",
+ "CalendarDayButton17EventButton2Text2",
+ "CalendarDayButton17EventButton3",
+ "CalendarDayButton17EventButton3Black",
+ "CalendarDayButton17EventButton3Text1",
+ "CalendarDayButton17EventButton3Text2",
+ "CalendarDayButton17EventButton4",
+ "CalendarDayButton17EventButton4Black",
+ "CalendarDayButton17EventButton4Text1",
+ "CalendarDayButton17EventButton4Text2",
+ "CalendarDayButton17EventTexture",
+ "CalendarDayButton17MoreEventsButton",
+ "CalendarDayButton17OverlayFrame",
+ "CalendarDayButton17OverlayFrameTexture",
+ "CalendarDayButton17PendingInviteTexture",
+ "CalendarDayButton18",
+ "CalendarDayButton18DarkFrame",
+ "CalendarDayButton18DarkFrameBottom",
+ "CalendarDayButton18DarkFrameTop",
+ "CalendarDayButton18DateFrame",
+ "CalendarDayButton18DateFrameBackground",
+ "CalendarDayButton18DateFrameDate",
+ "CalendarDayButton18EventBackgroundTexture",
+ "CalendarDayButton18EventButton1",
+ "CalendarDayButton18EventButton1Black",
+ "CalendarDayButton18EventButton1Text1",
+ "CalendarDayButton18EventButton1Text2",
+ "CalendarDayButton18EventButton2",
+ "CalendarDayButton18EventButton2Black",
+ "CalendarDayButton18EventButton2Text1",
+ "CalendarDayButton18EventButton2Text2",
+ "CalendarDayButton18EventButton3",
+ "CalendarDayButton18EventButton3Black",
+ "CalendarDayButton18EventButton3Text1",
+ "CalendarDayButton18EventButton3Text2",
+ "CalendarDayButton18EventButton4",
+ "CalendarDayButton18EventButton4Black",
+ "CalendarDayButton18EventButton4Text1",
+ "CalendarDayButton18EventButton4Text2",
+ "CalendarDayButton18EventTexture",
+ "CalendarDayButton18MoreEventsButton",
+ "CalendarDayButton18OverlayFrame",
+ "CalendarDayButton18OverlayFrameTexture",
+ "CalendarDayButton18PendingInviteTexture",
+ "CalendarDayButton19",
+ "CalendarDayButton19DarkFrame",
+ "CalendarDayButton19DarkFrameBottom",
+ "CalendarDayButton19DarkFrameTop",
+ "CalendarDayButton19DateFrame",
+ "CalendarDayButton19DateFrameBackground",
+ "CalendarDayButton19DateFrameDate",
+ "CalendarDayButton19EventBackgroundTexture",
+ "CalendarDayButton19EventButton1",
+ "CalendarDayButton19EventButton1Black",
+ "CalendarDayButton19EventButton1Text1",
+ "CalendarDayButton19EventButton1Text2",
+ "CalendarDayButton19EventButton2",
+ "CalendarDayButton19EventButton2Black",
+ "CalendarDayButton19EventButton2Text1",
+ "CalendarDayButton19EventButton2Text2",
+ "CalendarDayButton19EventButton3",
+ "CalendarDayButton19EventButton3Black",
+ "CalendarDayButton19EventButton3Text1",
+ "CalendarDayButton19EventButton3Text2",
+ "CalendarDayButton19EventButton4",
+ "CalendarDayButton19EventButton4Black",
+ "CalendarDayButton19EventButton4Text1",
+ "CalendarDayButton19EventButton4Text2",
+ "CalendarDayButton19EventTexture",
+ "CalendarDayButton19MoreEventsButton",
+ "CalendarDayButton19OverlayFrame",
+ "CalendarDayButton19OverlayFrameTexture",
+ "CalendarDayButton19PendingInviteTexture",
+ "CalendarDayButton1DarkFrame",
+ "CalendarDayButton1DarkFrameBottom",
+ "CalendarDayButton1DarkFrameTop",
+ "CalendarDayButton1DateFrame",
+ "CalendarDayButton1DateFrameBackground",
+ "CalendarDayButton1DateFrameDate",
+ "CalendarDayButton1EventBackgroundTexture",
+ "CalendarDayButton1EventButton1",
+ "CalendarDayButton1EventButton1Black",
+ "CalendarDayButton1EventButton1Text1",
+ "CalendarDayButton1EventButton1Text2",
+ "CalendarDayButton1EventButton2",
+ "CalendarDayButton1EventButton2Black",
+ "CalendarDayButton1EventButton2Text1",
+ "CalendarDayButton1EventButton2Text2",
+ "CalendarDayButton1EventButton3",
+ "CalendarDayButton1EventButton3Black",
+ "CalendarDayButton1EventButton3Text1",
+ "CalendarDayButton1EventButton3Text2",
+ "CalendarDayButton1EventButton4",
+ "CalendarDayButton1EventButton4Black",
+ "CalendarDayButton1EventButton4Text1",
+ "CalendarDayButton1EventButton4Text2",
+ "CalendarDayButton1EventTexture",
+ "CalendarDayButton1MoreEventsButton",
+ "CalendarDayButton1OverlayFrame",
+ "CalendarDayButton1OverlayFrameTexture",
+ "CalendarDayButton1PendingInviteTexture",
+ "CalendarDayButton2",
+ "CalendarDayButton20",
+ "CalendarDayButton20DarkFrame",
+ "CalendarDayButton20DarkFrameBottom",
+ "CalendarDayButton20DarkFrameTop",
+ "CalendarDayButton20DateFrame",
+ "CalendarDayButton20DateFrameBackground",
+ "CalendarDayButton20DateFrameDate",
+ "CalendarDayButton20EventBackgroundTexture",
+ "CalendarDayButton20EventButton1",
+ "CalendarDayButton20EventButton1Black",
+ "CalendarDayButton20EventButton1Text1",
+ "CalendarDayButton20EventButton1Text2",
+ "CalendarDayButton20EventButton2",
+ "CalendarDayButton20EventButton2Black",
+ "CalendarDayButton20EventButton2Text1",
+ "CalendarDayButton20EventButton2Text2",
+ "CalendarDayButton20EventButton3",
+ "CalendarDayButton20EventButton3Black",
+ "CalendarDayButton20EventButton3Text1",
+ "CalendarDayButton20EventButton3Text2",
+ "CalendarDayButton20EventButton4",
+ "CalendarDayButton20EventButton4Black",
+ "CalendarDayButton20EventButton4Text1",
+ "CalendarDayButton20EventButton4Text2",
+ "CalendarDayButton20EventTexture",
+ "CalendarDayButton20MoreEventsButton",
+ "CalendarDayButton20OverlayFrame",
+ "CalendarDayButton20OverlayFrameTexture",
+ "CalendarDayButton20PendingInviteTexture",
+ "CalendarDayButton21",
+ "CalendarDayButton21DarkFrame",
+ "CalendarDayButton21DarkFrameBottom",
+ "CalendarDayButton21DarkFrameTop",
+ "CalendarDayButton21DateFrame",
+ "CalendarDayButton21DateFrameBackground",
+ "CalendarDayButton21DateFrameDate",
+ "CalendarDayButton21EventBackgroundTexture",
+ "CalendarDayButton21EventButton1",
+ "CalendarDayButton21EventButton1Black",
+ "CalendarDayButton21EventButton1Text1",
+ "CalendarDayButton21EventButton1Text2",
+ "CalendarDayButton21EventButton2",
+ "CalendarDayButton21EventButton2Black",
+ "CalendarDayButton21EventButton2Text1",
+ "CalendarDayButton21EventButton2Text2",
+ "CalendarDayButton21EventButton3",
+ "CalendarDayButton21EventButton3Black",
+ "CalendarDayButton21EventButton3Text1",
+ "CalendarDayButton21EventButton3Text2",
+ "CalendarDayButton21EventButton4",
+ "CalendarDayButton21EventButton4Black",
+ "CalendarDayButton21EventButton4Text1",
+ "CalendarDayButton21EventButton4Text2",
+ "CalendarDayButton21EventTexture",
+ "CalendarDayButton21MoreEventsButton",
+ "CalendarDayButton21OverlayFrame",
+ "CalendarDayButton21OverlayFrameTexture",
+ "CalendarDayButton21PendingInviteTexture",
+ "CalendarDayButton22",
+ "CalendarDayButton22DarkFrame",
+ "CalendarDayButton22DarkFrameBottom",
+ "CalendarDayButton22DarkFrameTop",
+ "CalendarDayButton22DateFrame",
+ "CalendarDayButton22DateFrameBackground",
+ "CalendarDayButton22DateFrameDate",
+ "CalendarDayButton22EventBackgroundTexture",
+ "CalendarDayButton22EventButton1",
+ "CalendarDayButton22EventButton1Black",
+ "CalendarDayButton22EventButton1Text1",
+ "CalendarDayButton22EventButton1Text2",
+ "CalendarDayButton22EventButton2",
+ "CalendarDayButton22EventButton2Black",
+ "CalendarDayButton22EventButton2Text1",
+ "CalendarDayButton22EventButton2Text2",
+ "CalendarDayButton22EventButton3",
+ "CalendarDayButton22EventButton3Black",
+ "CalendarDayButton22EventButton3Text1",
+ "CalendarDayButton22EventButton3Text2",
+ "CalendarDayButton22EventButton4",
+ "CalendarDayButton22EventButton4Black",
+ "CalendarDayButton22EventButton4Text1",
+ "CalendarDayButton22EventButton4Text2",
+ "CalendarDayButton22EventTexture",
+ "CalendarDayButton22MoreEventsButton",
+ "CalendarDayButton22OverlayFrame",
+ "CalendarDayButton22OverlayFrameTexture",
+ "CalendarDayButton22PendingInviteTexture",
+ "CalendarDayButton23",
+ "CalendarDayButton23DarkFrame",
+ "CalendarDayButton23DarkFrameBottom",
+ "CalendarDayButton23DarkFrameTop",
+ "CalendarDayButton23DateFrame",
+ "CalendarDayButton23DateFrameBackground",
+ "CalendarDayButton23DateFrameDate",
+ "CalendarDayButton23EventBackgroundTexture",
+ "CalendarDayButton23EventButton1",
+ "CalendarDayButton23EventButton1Black",
+ "CalendarDayButton23EventButton1Text1",
+ "CalendarDayButton23EventButton1Text2",
+ "CalendarDayButton23EventButton2",
+ "CalendarDayButton23EventButton2Black",
+ "CalendarDayButton23EventButton2Text1",
+ "CalendarDayButton23EventButton2Text2",
+ "CalendarDayButton23EventButton3",
+ "CalendarDayButton23EventButton3Black",
+ "CalendarDayButton23EventButton3Text1",
+ "CalendarDayButton23EventButton3Text2",
+ "CalendarDayButton23EventButton4",
+ "CalendarDayButton23EventButton4Black",
+ "CalendarDayButton23EventButton4Text1",
+ "CalendarDayButton23EventButton4Text2",
+ "CalendarDayButton23EventTexture",
+ "CalendarDayButton23MoreEventsButton",
+ "CalendarDayButton23OverlayFrame",
+ "CalendarDayButton23OverlayFrameTexture",
+ "CalendarDayButton23PendingInviteTexture",
+ "CalendarDayButton24",
+ "CalendarDayButton24DarkFrame",
+ "CalendarDayButton24DarkFrameBottom",
+ "CalendarDayButton24DarkFrameTop",
+ "CalendarDayButton24DateFrame",
+ "CalendarDayButton24DateFrameBackground",
+ "CalendarDayButton24DateFrameDate",
+ "CalendarDayButton24EventBackgroundTexture",
+ "CalendarDayButton24EventButton1",
+ "CalendarDayButton24EventButton1Black",
+ "CalendarDayButton24EventButton1Text1",
+ "CalendarDayButton24EventButton1Text2",
+ "CalendarDayButton24EventButton2",
+ "CalendarDayButton24EventButton2Black",
+ "CalendarDayButton24EventButton2Text1",
+ "CalendarDayButton24EventButton2Text2",
+ "CalendarDayButton24EventButton3",
+ "CalendarDayButton24EventButton3Black",
+ "CalendarDayButton24EventButton3Text1",
+ "CalendarDayButton24EventButton3Text2",
+ "CalendarDayButton24EventButton4",
+ "CalendarDayButton24EventButton4Black",
+ "CalendarDayButton24EventButton4Text1",
+ "CalendarDayButton24EventButton4Text2",
+ "CalendarDayButton24EventTexture",
+ "CalendarDayButton24MoreEventsButton",
+ "CalendarDayButton24OverlayFrame",
+ "CalendarDayButton24OverlayFrameTexture",
+ "CalendarDayButton24PendingInviteTexture",
+ "CalendarDayButton25",
+ "CalendarDayButton25DarkFrame",
+ "CalendarDayButton25DarkFrameBottom",
+ "CalendarDayButton25DarkFrameTop",
+ "CalendarDayButton25DateFrame",
+ "CalendarDayButton25DateFrameBackground",
+ "CalendarDayButton25DateFrameDate",
+ "CalendarDayButton25EventBackgroundTexture",
+ "CalendarDayButton25EventButton1",
+ "CalendarDayButton25EventButton1Black",
+ "CalendarDayButton25EventButton1Text1",
+ "CalendarDayButton25EventButton1Text2",
+ "CalendarDayButton25EventButton2",
+ "CalendarDayButton25EventButton2Black",
+ "CalendarDayButton25EventButton2Text1",
+ "CalendarDayButton25EventButton2Text2",
+ "CalendarDayButton25EventButton3",
+ "CalendarDayButton25EventButton3Black",
+ "CalendarDayButton25EventButton3Text1",
+ "CalendarDayButton25EventButton3Text2",
+ "CalendarDayButton25EventButton4",
+ "CalendarDayButton25EventButton4Black",
+ "CalendarDayButton25EventButton4Text1",
+ "CalendarDayButton25EventButton4Text2",
+ "CalendarDayButton25EventTexture",
+ "CalendarDayButton25MoreEventsButton",
+ "CalendarDayButton25OverlayFrame",
+ "CalendarDayButton25OverlayFrameTexture",
+ "CalendarDayButton25PendingInviteTexture",
+ "CalendarDayButton26",
+ "CalendarDayButton26DarkFrame",
+ "CalendarDayButton26DarkFrameBottom",
+ "CalendarDayButton26DarkFrameTop",
+ "CalendarDayButton26DateFrame",
+ "CalendarDayButton26DateFrameBackground",
+ "CalendarDayButton26DateFrameDate",
+ "CalendarDayButton26EventBackgroundTexture",
+ "CalendarDayButton26EventButton1",
+ "CalendarDayButton26EventButton1Black",
+ "CalendarDayButton26EventButton1Text1",
+ "CalendarDayButton26EventButton1Text2",
+ "CalendarDayButton26EventButton2",
+ "CalendarDayButton26EventButton2Black",
+ "CalendarDayButton26EventButton2Text1",
+ "CalendarDayButton26EventButton2Text2",
+ "CalendarDayButton26EventButton3",
+ "CalendarDayButton26EventButton3Black",
+ "CalendarDayButton26EventButton3Text1",
+ "CalendarDayButton26EventButton3Text2",
+ "CalendarDayButton26EventButton4",
+ "CalendarDayButton26EventButton4Black",
+ "CalendarDayButton26EventButton4Text1",
+ "CalendarDayButton26EventButton4Text2",
+ "CalendarDayButton26EventTexture",
+ "CalendarDayButton26MoreEventsButton",
+ "CalendarDayButton26OverlayFrame",
+ "CalendarDayButton26OverlayFrameTexture",
+ "CalendarDayButton26PendingInviteTexture",
+ "CalendarDayButton27",
+ "CalendarDayButton27DarkFrame",
+ "CalendarDayButton27DarkFrameBottom",
+ "CalendarDayButton27DarkFrameTop",
+ "CalendarDayButton27DateFrame",
+ "CalendarDayButton27DateFrameBackground",
+ "CalendarDayButton27DateFrameDate",
+ "CalendarDayButton27EventBackgroundTexture",
+ "CalendarDayButton27EventButton1",
+ "CalendarDayButton27EventButton1Black",
+ "CalendarDayButton27EventButton1Text1",
+ "CalendarDayButton27EventButton1Text2",
+ "CalendarDayButton27EventButton2",
+ "CalendarDayButton27EventButton2Black",
+ "CalendarDayButton27EventButton2Text1",
+ "CalendarDayButton27EventButton2Text2",
+ "CalendarDayButton27EventButton3",
+ "CalendarDayButton27EventButton3Black",
+ "CalendarDayButton27EventButton3Text1",
+ "CalendarDayButton27EventButton3Text2",
+ "CalendarDayButton27EventButton4",
+ "CalendarDayButton27EventButton4Black",
+ "CalendarDayButton27EventButton4Text1",
+ "CalendarDayButton27EventButton4Text2",
+ "CalendarDayButton27EventTexture",
+ "CalendarDayButton27MoreEventsButton",
+ "CalendarDayButton27OverlayFrame",
+ "CalendarDayButton27OverlayFrameTexture",
+ "CalendarDayButton27PendingInviteTexture",
+ "CalendarDayButton28",
+ "CalendarDayButton28DarkFrame",
+ "CalendarDayButton28DarkFrameBottom",
+ "CalendarDayButton28DarkFrameTop",
+ "CalendarDayButton28DateFrame",
+ "CalendarDayButton28DateFrameBackground",
+ "CalendarDayButton28DateFrameDate",
+ "CalendarDayButton28EventBackgroundTexture",
+ "CalendarDayButton28EventButton1",
+ "CalendarDayButton28EventButton1Black",
+ "CalendarDayButton28EventButton1Text1",
+ "CalendarDayButton28EventButton1Text2",
+ "CalendarDayButton28EventButton2",
+ "CalendarDayButton28EventButton2Black",
+ "CalendarDayButton28EventButton2Text1",
+ "CalendarDayButton28EventButton2Text2",
+ "CalendarDayButton28EventButton3",
+ "CalendarDayButton28EventButton3Black",
+ "CalendarDayButton28EventButton3Text1",
+ "CalendarDayButton28EventButton3Text2",
+ "CalendarDayButton28EventButton4",
+ "CalendarDayButton28EventButton4Black",
+ "CalendarDayButton28EventButton4Text1",
+ "CalendarDayButton28EventButton4Text2",
+ "CalendarDayButton28EventTexture",
+ "CalendarDayButton28MoreEventsButton",
+ "CalendarDayButton28OverlayFrame",
+ "CalendarDayButton28OverlayFrameTexture",
+ "CalendarDayButton28PendingInviteTexture",
+ "CalendarDayButton29",
+ "CalendarDayButton29DarkFrame",
+ "CalendarDayButton29DarkFrameBottom",
+ "CalendarDayButton29DarkFrameTop",
+ "CalendarDayButton29DateFrame",
+ "CalendarDayButton29DateFrameBackground",
+ "CalendarDayButton29DateFrameDate",
+ "CalendarDayButton29EventBackgroundTexture",
+ "CalendarDayButton29EventButton1",
+ "CalendarDayButton29EventButton1Black",
+ "CalendarDayButton29EventButton1Text1",
+ "CalendarDayButton29EventButton1Text2",
+ "CalendarDayButton29EventButton2",
+ "CalendarDayButton29EventButton2Black",
+ "CalendarDayButton29EventButton2Text1",
+ "CalendarDayButton29EventButton2Text2",
+ "CalendarDayButton29EventButton3",
+ "CalendarDayButton29EventButton3Black",
+ "CalendarDayButton29EventButton3Text1",
+ "CalendarDayButton29EventButton3Text2",
+ "CalendarDayButton29EventButton4",
+ "CalendarDayButton29EventButton4Black",
+ "CalendarDayButton29EventButton4Text1",
+ "CalendarDayButton29EventButton4Text2",
+ "CalendarDayButton29EventTexture",
+ "CalendarDayButton29MoreEventsButton",
+ "CalendarDayButton29OverlayFrame",
+ "CalendarDayButton29OverlayFrameTexture",
+ "CalendarDayButton29PendingInviteTexture",
+ "CalendarDayButton2DarkFrame",
+ "CalendarDayButton2DarkFrameBottom",
+ "CalendarDayButton2DarkFrameTop",
+ "CalendarDayButton2DateFrame",
+ "CalendarDayButton2DateFrameBackground",
+ "CalendarDayButton2DateFrameDate",
+ "CalendarDayButton2EventBackgroundTexture",
+ "CalendarDayButton2EventButton1",
+ "CalendarDayButton2EventButton1Black",
+ "CalendarDayButton2EventButton1Text1",
+ "CalendarDayButton2EventButton1Text2",
+ "CalendarDayButton2EventButton2",
+ "CalendarDayButton2EventButton2Black",
+ "CalendarDayButton2EventButton2Text1",
+ "CalendarDayButton2EventButton2Text2",
+ "CalendarDayButton2EventButton3",
+ "CalendarDayButton2EventButton3Black",
+ "CalendarDayButton2EventButton3Text1",
+ "CalendarDayButton2EventButton3Text2",
+ "CalendarDayButton2EventButton4",
+ "CalendarDayButton2EventButton4Black",
+ "CalendarDayButton2EventButton4Text1",
+ "CalendarDayButton2EventButton4Text2",
+ "CalendarDayButton2EventTexture",
+ "CalendarDayButton2MoreEventsButton",
+ "CalendarDayButton2OverlayFrame",
+ "CalendarDayButton2OverlayFrameTexture",
+ "CalendarDayButton2PendingInviteTexture",
+ "CalendarDayButton3",
+ "CalendarDayButton30",
+ "CalendarDayButton30DarkFrame",
+ "CalendarDayButton30DarkFrameBottom",
+ "CalendarDayButton30DarkFrameTop",
+ "CalendarDayButton30DateFrame",
+ "CalendarDayButton30DateFrameBackground",
+ "CalendarDayButton30DateFrameDate",
+ "CalendarDayButton30EventBackgroundTexture",
+ "CalendarDayButton30EventButton1",
+ "CalendarDayButton30EventButton1Black",
+ "CalendarDayButton30EventButton1Text1",
+ "CalendarDayButton30EventButton1Text2",
+ "CalendarDayButton30EventButton2",
+ "CalendarDayButton30EventButton2Black",
+ "CalendarDayButton30EventButton2Text1",
+ "CalendarDayButton30EventButton2Text2",
+ "CalendarDayButton30EventButton3",
+ "CalendarDayButton30EventButton3Black",
+ "CalendarDayButton30EventButton3Text1",
+ "CalendarDayButton30EventButton3Text2",
+ "CalendarDayButton30EventButton4",
+ "CalendarDayButton30EventButton4Black",
+ "CalendarDayButton30EventButton4Text1",
+ "CalendarDayButton30EventButton4Text2",
+ "CalendarDayButton30EventTexture",
+ "CalendarDayButton30MoreEventsButton",
+ "CalendarDayButton30OverlayFrame",
+ "CalendarDayButton30OverlayFrameTexture",
+ "CalendarDayButton30PendingInviteTexture",
+ "CalendarDayButton31",
+ "CalendarDayButton31DarkFrame",
+ "CalendarDayButton31DarkFrameBottom",
+ "CalendarDayButton31DarkFrameTop",
+ "CalendarDayButton31DateFrame",
+ "CalendarDayButton31DateFrameBackground",
+ "CalendarDayButton31DateFrameDate",
+ "CalendarDayButton31EventBackgroundTexture",
+ "CalendarDayButton31EventButton1",
+ "CalendarDayButton31EventButton1Black",
+ "CalendarDayButton31EventButton1Text1",
+ "CalendarDayButton31EventButton1Text2",
+ "CalendarDayButton31EventButton2",
+ "CalendarDayButton31EventButton2Black",
+ "CalendarDayButton31EventButton2Text1",
+ "CalendarDayButton31EventButton2Text2",
+ "CalendarDayButton31EventButton3",
+ "CalendarDayButton31EventButton3Black",
+ "CalendarDayButton31EventButton3Text1",
+ "CalendarDayButton31EventButton3Text2",
+ "CalendarDayButton31EventButton4",
+ "CalendarDayButton31EventButton4Black",
+ "CalendarDayButton31EventButton4Text1",
+ "CalendarDayButton31EventButton4Text2",
+ "CalendarDayButton31EventTexture",
+ "CalendarDayButton31MoreEventsButton",
+ "CalendarDayButton31OverlayFrame",
+ "CalendarDayButton31OverlayFrameTexture",
+ "CalendarDayButton31PendingInviteTexture",
+ "CalendarDayButton32",
+ "CalendarDayButton32DarkFrame",
+ "CalendarDayButton32DarkFrameBottom",
+ "CalendarDayButton32DarkFrameTop",
+ "CalendarDayButton32DateFrame",
+ "CalendarDayButton32DateFrameBackground",
+ "CalendarDayButton32DateFrameDate",
+ "CalendarDayButton32EventBackgroundTexture",
+ "CalendarDayButton32EventButton1",
+ "CalendarDayButton32EventButton1Black",
+ "CalendarDayButton32EventButton1Text1",
+ "CalendarDayButton32EventButton1Text2",
+ "CalendarDayButton32EventButton2",
+ "CalendarDayButton32EventButton2Black",
+ "CalendarDayButton32EventButton2Text1",
+ "CalendarDayButton32EventButton2Text2",
+ "CalendarDayButton32EventButton3",
+ "CalendarDayButton32EventButton3Black",
+ "CalendarDayButton32EventButton3Text1",
+ "CalendarDayButton32EventButton3Text2",
+ "CalendarDayButton32EventButton4",
+ "CalendarDayButton32EventButton4Black",
+ "CalendarDayButton32EventButton4Text1",
+ "CalendarDayButton32EventButton4Text2",
+ "CalendarDayButton32EventTexture",
+ "CalendarDayButton32MoreEventsButton",
+ "CalendarDayButton32OverlayFrame",
+ "CalendarDayButton32OverlayFrameTexture",
+ "CalendarDayButton32PendingInviteTexture",
+ "CalendarDayButton33",
+ "CalendarDayButton33DarkFrame",
+ "CalendarDayButton33DarkFrameBottom",
+ "CalendarDayButton33DarkFrameTop",
+ "CalendarDayButton33DateFrame",
+ "CalendarDayButton33DateFrameBackground",
+ "CalendarDayButton33DateFrameDate",
+ "CalendarDayButton33EventBackgroundTexture",
+ "CalendarDayButton33EventButton1",
+ "CalendarDayButton33EventButton1Black",
+ "CalendarDayButton33EventButton1Text1",
+ "CalendarDayButton33EventButton1Text2",
+ "CalendarDayButton33EventButton2",
+ "CalendarDayButton33EventButton2Black",
+ "CalendarDayButton33EventButton2Text1",
+ "CalendarDayButton33EventButton2Text2",
+ "CalendarDayButton33EventButton3",
+ "CalendarDayButton33EventButton3Black",
+ "CalendarDayButton33EventButton3Text1",
+ "CalendarDayButton33EventButton3Text2",
+ "CalendarDayButton33EventButton4",
+ "CalendarDayButton33EventButton4Black",
+ "CalendarDayButton33EventButton4Text1",
+ "CalendarDayButton33EventButton4Text2",
+ "CalendarDayButton33EventTexture",
+ "CalendarDayButton33MoreEventsButton",
+ "CalendarDayButton33OverlayFrame",
+ "CalendarDayButton33OverlayFrameTexture",
+ "CalendarDayButton33PendingInviteTexture",
+ "CalendarDayButton34",
+ "CalendarDayButton34DarkFrame",
+ "CalendarDayButton34DarkFrameBottom",
+ "CalendarDayButton34DarkFrameTop",
+ "CalendarDayButton34DateFrame",
+ "CalendarDayButton34DateFrameBackground",
+ "CalendarDayButton34DateFrameDate",
+ "CalendarDayButton34EventBackgroundTexture",
+ "CalendarDayButton34EventButton1",
+ "CalendarDayButton34EventButton1Black",
+ "CalendarDayButton34EventButton1Text1",
+ "CalendarDayButton34EventButton1Text2",
+ "CalendarDayButton34EventButton2",
+ "CalendarDayButton34EventButton2Black",
+ "CalendarDayButton34EventButton2Text1",
+ "CalendarDayButton34EventButton2Text2",
+ "CalendarDayButton34EventButton3",
+ "CalendarDayButton34EventButton3Black",
+ "CalendarDayButton34EventButton3Text1",
+ "CalendarDayButton34EventButton3Text2",
+ "CalendarDayButton34EventButton4",
+ "CalendarDayButton34EventButton4Black",
+ "CalendarDayButton34EventButton4Text1",
+ "CalendarDayButton34EventButton4Text2",
+ "CalendarDayButton34EventTexture",
+ "CalendarDayButton34MoreEventsButton",
+ "CalendarDayButton34OverlayFrame",
+ "CalendarDayButton34OverlayFrameTexture",
+ "CalendarDayButton34PendingInviteTexture",
+ "CalendarDayButton35",
+ "CalendarDayButton35DarkFrame",
+ "CalendarDayButton35DarkFrameBottom",
+ "CalendarDayButton35DarkFrameTop",
+ "CalendarDayButton35DateFrame",
+ "CalendarDayButton35DateFrameBackground",
+ "CalendarDayButton35DateFrameDate",
+ "CalendarDayButton35EventBackgroundTexture",
+ "CalendarDayButton35EventButton1",
+ "CalendarDayButton35EventButton1Black",
+ "CalendarDayButton35EventButton1Text1",
+ "CalendarDayButton35EventButton1Text2",
+ "CalendarDayButton35EventButton2",
+ "CalendarDayButton35EventButton2Black",
+ "CalendarDayButton35EventButton2Text1",
+ "CalendarDayButton35EventButton2Text2",
+ "CalendarDayButton35EventButton3",
+ "CalendarDayButton35EventButton3Black",
+ "CalendarDayButton35EventButton3Text1",
+ "CalendarDayButton35EventButton3Text2",
+ "CalendarDayButton35EventButton4",
+ "CalendarDayButton35EventButton4Black",
+ "CalendarDayButton35EventButton4Text1",
+ "CalendarDayButton35EventButton4Text2",
+ "CalendarDayButton35EventTexture",
+ "CalendarDayButton35MoreEventsButton",
+ "CalendarDayButton35OverlayFrame",
+ "CalendarDayButton35OverlayFrameTexture",
+ "CalendarDayButton35PendingInviteTexture",
+ "CalendarDayButton36",
+ "CalendarDayButton36DarkFrame",
+ "CalendarDayButton36DarkFrameBottom",
+ "CalendarDayButton36DarkFrameTop",
+ "CalendarDayButton36DateFrame",
+ "CalendarDayButton36DateFrameBackground",
+ "CalendarDayButton36DateFrameDate",
+ "CalendarDayButton36EventBackgroundTexture",
+ "CalendarDayButton36EventButton1",
+ "CalendarDayButton36EventButton1Black",
+ "CalendarDayButton36EventButton1Text1",
+ "CalendarDayButton36EventButton1Text2",
+ "CalendarDayButton36EventButton2",
+ "CalendarDayButton36EventButton2Black",
+ "CalendarDayButton36EventButton2Text1",
+ "CalendarDayButton36EventButton2Text2",
+ "CalendarDayButton36EventButton3",
+ "CalendarDayButton36EventButton3Black",
+ "CalendarDayButton36EventButton3Text1",
+ "CalendarDayButton36EventButton3Text2",
+ "CalendarDayButton36EventButton4",
+ "CalendarDayButton36EventButton4Black",
+ "CalendarDayButton36EventButton4Text1",
+ "CalendarDayButton36EventButton4Text2",
+ "CalendarDayButton36EventTexture",
+ "CalendarDayButton36MoreEventsButton",
+ "CalendarDayButton36OverlayFrame",
+ "CalendarDayButton36OverlayFrameTexture",
+ "CalendarDayButton36PendingInviteTexture",
+ "CalendarDayButton37",
+ "CalendarDayButton37DarkFrame",
+ "CalendarDayButton37DarkFrameBottom",
+ "CalendarDayButton37DarkFrameTop",
+ "CalendarDayButton37DateFrame",
+ "CalendarDayButton37DateFrameBackground",
+ "CalendarDayButton37DateFrameDate",
+ "CalendarDayButton37EventBackgroundTexture",
+ "CalendarDayButton37EventButton1",
+ "CalendarDayButton37EventButton1Black",
+ "CalendarDayButton37EventButton1Text1",
+ "CalendarDayButton37EventButton1Text2",
+ "CalendarDayButton37EventButton2",
+ "CalendarDayButton37EventButton2Black",
+ "CalendarDayButton37EventButton2Text1",
+ "CalendarDayButton37EventButton2Text2",
+ "CalendarDayButton37EventButton3",
+ "CalendarDayButton37EventButton3Black",
+ "CalendarDayButton37EventButton3Text1",
+ "CalendarDayButton37EventButton3Text2",
+ "CalendarDayButton37EventButton4",
+ "CalendarDayButton37EventButton4Black",
+ "CalendarDayButton37EventButton4Text1",
+ "CalendarDayButton37EventButton4Text2",
+ "CalendarDayButton37EventTexture",
+ "CalendarDayButton37MoreEventsButton",
+ "CalendarDayButton37OverlayFrame",
+ "CalendarDayButton37OverlayFrameTexture",
+ "CalendarDayButton37PendingInviteTexture",
+ "CalendarDayButton38",
+ "CalendarDayButton38DarkFrame",
+ "CalendarDayButton38DarkFrameBottom",
+ "CalendarDayButton38DarkFrameTop",
+ "CalendarDayButton38DateFrame",
+ "CalendarDayButton38DateFrameBackground",
+ "CalendarDayButton38DateFrameDate",
+ "CalendarDayButton38EventBackgroundTexture",
+ "CalendarDayButton38EventButton1",
+ "CalendarDayButton38EventButton1Black",
+ "CalendarDayButton38EventButton1Text1",
+ "CalendarDayButton38EventButton1Text2",
+ "CalendarDayButton38EventButton2",
+ "CalendarDayButton38EventButton2Black",
+ "CalendarDayButton38EventButton2Text1",
+ "CalendarDayButton38EventButton2Text2",
+ "CalendarDayButton38EventButton3",
+ "CalendarDayButton38EventButton3Black",
+ "CalendarDayButton38EventButton3Text1",
+ "CalendarDayButton38EventButton3Text2",
+ "CalendarDayButton38EventButton4",
+ "CalendarDayButton38EventButton4Black",
+ "CalendarDayButton38EventButton4Text1",
+ "CalendarDayButton38EventButton4Text2",
+ "CalendarDayButton38EventTexture",
+ "CalendarDayButton38MoreEventsButton",
+ "CalendarDayButton38OverlayFrame",
+ "CalendarDayButton38OverlayFrameTexture",
+ "CalendarDayButton38PendingInviteTexture",
+ "CalendarDayButton39",
+ "CalendarDayButton39DarkFrame",
+ "CalendarDayButton39DarkFrameBottom",
+ "CalendarDayButton39DarkFrameTop",
+ "CalendarDayButton39DateFrame",
+ "CalendarDayButton39DateFrameBackground",
+ "CalendarDayButton39DateFrameDate",
+ "CalendarDayButton39EventBackgroundTexture",
+ "CalendarDayButton39EventButton1",
+ "CalendarDayButton39EventButton1Black",
+ "CalendarDayButton39EventButton1Text1",
+ "CalendarDayButton39EventButton1Text2",
+ "CalendarDayButton39EventButton2",
+ "CalendarDayButton39EventButton2Black",
+ "CalendarDayButton39EventButton2Text1",
+ "CalendarDayButton39EventButton2Text2",
+ "CalendarDayButton39EventButton3",
+ "CalendarDayButton39EventButton3Black",
+ "CalendarDayButton39EventButton3Text1",
+ "CalendarDayButton39EventButton3Text2",
+ "CalendarDayButton39EventButton4",
+ "CalendarDayButton39EventButton4Black",
+ "CalendarDayButton39EventButton4Text1",
+ "CalendarDayButton39EventButton4Text2",
+ "CalendarDayButton39EventTexture",
+ "CalendarDayButton39MoreEventsButton",
+ "CalendarDayButton39OverlayFrame",
+ "CalendarDayButton39OverlayFrameTexture",
+ "CalendarDayButton39PendingInviteTexture",
+ "CalendarDayButton3DarkFrame",
+ "CalendarDayButton3DarkFrameBottom",
+ "CalendarDayButton3DarkFrameTop",
+ "CalendarDayButton3DateFrame",
+ "CalendarDayButton3DateFrameBackground",
+ "CalendarDayButton3DateFrameDate",
+ "CalendarDayButton3EventBackgroundTexture",
+ "CalendarDayButton3EventButton1",
+ "CalendarDayButton3EventButton1Black",
+ "CalendarDayButton3EventButton1Text1",
+ "CalendarDayButton3EventButton1Text2",
+ "CalendarDayButton3EventButton2",
+ "CalendarDayButton3EventButton2Black",
+ "CalendarDayButton3EventButton2Text1",
+ "CalendarDayButton3EventButton2Text2",
+ "CalendarDayButton3EventButton3",
+ "CalendarDayButton3EventButton3Black",
+ "CalendarDayButton3EventButton3Text1",
+ "CalendarDayButton3EventButton3Text2",
+ "CalendarDayButton3EventButton4",
+ "CalendarDayButton3EventButton4Black",
+ "CalendarDayButton3EventButton4Text1",
+ "CalendarDayButton3EventButton4Text2",
+ "CalendarDayButton3EventTexture",
+ "CalendarDayButton3MoreEventsButton",
+ "CalendarDayButton3OverlayFrame",
+ "CalendarDayButton3OverlayFrameTexture",
+ "CalendarDayButton3PendingInviteTexture",
+ "CalendarDayButton4",
+ "CalendarDayButton40",
+ "CalendarDayButton40DarkFrame",
+ "CalendarDayButton40DarkFrameBottom",
+ "CalendarDayButton40DarkFrameTop",
+ "CalendarDayButton40DateFrame",
+ "CalendarDayButton40DateFrameBackground",
+ "CalendarDayButton40DateFrameDate",
+ "CalendarDayButton40EventBackgroundTexture",
+ "CalendarDayButton40EventButton1",
+ "CalendarDayButton40EventButton1Black",
+ "CalendarDayButton40EventButton1Text1",
+ "CalendarDayButton40EventButton1Text2",
+ "CalendarDayButton40EventButton2",
+ "CalendarDayButton40EventButton2Black",
+ "CalendarDayButton40EventButton2Text1",
+ "CalendarDayButton40EventButton2Text2",
+ "CalendarDayButton40EventButton3",
+ "CalendarDayButton40EventButton3Black",
+ "CalendarDayButton40EventButton3Text1",
+ "CalendarDayButton40EventButton3Text2",
+ "CalendarDayButton40EventButton4",
+ "CalendarDayButton40EventButton4Black",
+ "CalendarDayButton40EventButton4Text1",
+ "CalendarDayButton40EventButton4Text2",
+ "CalendarDayButton40EventTexture",
+ "CalendarDayButton40MoreEventsButton",
+ "CalendarDayButton40OverlayFrame",
+ "CalendarDayButton40OverlayFrameTexture",
+ "CalendarDayButton40PendingInviteTexture",
+ "CalendarDayButton41",
+ "CalendarDayButton41DarkFrame",
+ "CalendarDayButton41DarkFrameBottom",
+ "CalendarDayButton41DarkFrameTop",
+ "CalendarDayButton41DateFrame",
+ "CalendarDayButton41DateFrameBackground",
+ "CalendarDayButton41DateFrameDate",
+ "CalendarDayButton41EventBackgroundTexture",
+ "CalendarDayButton41EventButton1",
+ "CalendarDayButton41EventButton1Black",
+ "CalendarDayButton41EventButton1Text1",
+ "CalendarDayButton41EventButton1Text2",
+ "CalendarDayButton41EventButton2",
+ "CalendarDayButton41EventButton2Black",
+ "CalendarDayButton41EventButton2Text1",
+ "CalendarDayButton41EventButton2Text2",
+ "CalendarDayButton41EventButton3",
+ "CalendarDayButton41EventButton3Black",
+ "CalendarDayButton41EventButton3Text1",
+ "CalendarDayButton41EventButton3Text2",
+ "CalendarDayButton41EventButton4",
+ "CalendarDayButton41EventButton4Black",
+ "CalendarDayButton41EventButton4Text1",
+ "CalendarDayButton41EventButton4Text2",
+ "CalendarDayButton41EventTexture",
+ "CalendarDayButton41MoreEventsButton",
+ "CalendarDayButton41OverlayFrame",
+ "CalendarDayButton41OverlayFrameTexture",
+ "CalendarDayButton41PendingInviteTexture",
+ "CalendarDayButton42",
+ "CalendarDayButton42DarkFrame",
+ "CalendarDayButton42DarkFrameBottom",
+ "CalendarDayButton42DarkFrameTop",
+ "CalendarDayButton42DateFrame",
+ "CalendarDayButton42DateFrameBackground",
+ "CalendarDayButton42DateFrameDate",
+ "CalendarDayButton42EventBackgroundTexture",
+ "CalendarDayButton42EventButton1",
+ "CalendarDayButton42EventButton1Black",
+ "CalendarDayButton42EventButton1Text1",
+ "CalendarDayButton42EventButton1Text2",
+ "CalendarDayButton42EventButton2",
+ "CalendarDayButton42EventButton2Black",
+ "CalendarDayButton42EventButton2Text1",
+ "CalendarDayButton42EventButton2Text2",
+ "CalendarDayButton42EventButton3",
+ "CalendarDayButton42EventButton3Black",
+ "CalendarDayButton42EventButton3Text1",
+ "CalendarDayButton42EventButton3Text2",
+ "CalendarDayButton42EventButton4",
+ "CalendarDayButton42EventButton4Black",
+ "CalendarDayButton42EventButton4Text1",
+ "CalendarDayButton42EventButton4Text2",
+ "CalendarDayButton42EventTexture",
+ "CalendarDayButton42MoreEventsButton",
+ "CalendarDayButton42OverlayFrame",
+ "CalendarDayButton42OverlayFrameTexture",
+ "CalendarDayButton42PendingInviteTexture",
+ "CalendarDayButton4DarkFrame",
+ "CalendarDayButton4DarkFrameBottom",
+ "CalendarDayButton4DarkFrameTop",
+ "CalendarDayButton4DateFrame",
+ "CalendarDayButton4DateFrameBackground",
+ "CalendarDayButton4DateFrameDate",
+ "CalendarDayButton4EventBackgroundTexture",
+ "CalendarDayButton4EventButton1",
+ "CalendarDayButton4EventButton1Black",
+ "CalendarDayButton4EventButton1Text1",
+ "CalendarDayButton4EventButton1Text2",
+ "CalendarDayButton4EventButton2",
+ "CalendarDayButton4EventButton2Black",
+ "CalendarDayButton4EventButton2Text1",
+ "CalendarDayButton4EventButton2Text2",
+ "CalendarDayButton4EventButton3",
+ "CalendarDayButton4EventButton3Black",
+ "CalendarDayButton4EventButton3Text1",
+ "CalendarDayButton4EventButton3Text2",
+ "CalendarDayButton4EventButton4",
+ "CalendarDayButton4EventButton4Black",
+ "CalendarDayButton4EventButton4Text1",
+ "CalendarDayButton4EventButton4Text2",
+ "CalendarDayButton4EventTexture",
+ "CalendarDayButton4MoreEventsButton",
+ "CalendarDayButton4OverlayFrame",
+ "CalendarDayButton4OverlayFrameTexture",
+ "CalendarDayButton4PendingInviteTexture",
+ "CalendarDayButton5",
+ "CalendarDayButton5DarkFrame",
+ "CalendarDayButton5DarkFrameBottom",
+ "CalendarDayButton5DarkFrameTop",
+ "CalendarDayButton5DateFrame",
+ "CalendarDayButton5DateFrameBackground",
+ "CalendarDayButton5DateFrameDate",
+ "CalendarDayButton5EventBackgroundTexture",
+ "CalendarDayButton5EventButton1",
+ "CalendarDayButton5EventButton1Black",
+ "CalendarDayButton5EventButton1Text1",
+ "CalendarDayButton5EventButton1Text2",
+ "CalendarDayButton5EventButton2",
+ "CalendarDayButton5EventButton2Black",
+ "CalendarDayButton5EventButton2Text1",
+ "CalendarDayButton5EventButton2Text2",
+ "CalendarDayButton5EventButton3",
+ "CalendarDayButton5EventButton3Black",
+ "CalendarDayButton5EventButton3Text1",
+ "CalendarDayButton5EventButton3Text2",
+ "CalendarDayButton5EventButton4",
+ "CalendarDayButton5EventButton4Black",
+ "CalendarDayButton5EventButton4Text1",
+ "CalendarDayButton5EventButton4Text2",
+ "CalendarDayButton5EventTexture",
+ "CalendarDayButton5MoreEventsButton",
+ "CalendarDayButton5OverlayFrame",
+ "CalendarDayButton5OverlayFrameTexture",
+ "CalendarDayButton5PendingInviteTexture",
+ "CalendarDayButton6",
+ "CalendarDayButton6DarkFrame",
+ "CalendarDayButton6DarkFrameBottom",
+ "CalendarDayButton6DarkFrameTop",
+ "CalendarDayButton6DateFrame",
+ "CalendarDayButton6DateFrameBackground",
+ "CalendarDayButton6DateFrameDate",
+ "CalendarDayButton6EventBackgroundTexture",
+ "CalendarDayButton6EventButton1",
+ "CalendarDayButton6EventButton1Black",
+ "CalendarDayButton6EventButton1Text1",
+ "CalendarDayButton6EventButton1Text2",
+ "CalendarDayButton6EventButton2",
+ "CalendarDayButton6EventButton2Black",
+ "CalendarDayButton6EventButton2Text1",
+ "CalendarDayButton6EventButton2Text2",
+ "CalendarDayButton6EventButton3",
+ "CalendarDayButton6EventButton3Black",
+ "CalendarDayButton6EventButton3Text1",
+ "CalendarDayButton6EventButton3Text2",
+ "CalendarDayButton6EventButton4",
+ "CalendarDayButton6EventButton4Black",
+ "CalendarDayButton6EventButton4Text1",
+ "CalendarDayButton6EventButton4Text2",
+ "CalendarDayButton6EventTexture",
+ "CalendarDayButton6MoreEventsButton",
+ "CalendarDayButton6OverlayFrame",
+ "CalendarDayButton6OverlayFrameTexture",
+ "CalendarDayButton6PendingInviteTexture",
+ "CalendarDayButton7",
+ "CalendarDayButton7DarkFrame",
+ "CalendarDayButton7DarkFrameBottom",
+ "CalendarDayButton7DarkFrameTop",
+ "CalendarDayButton7DateFrame",
+ "CalendarDayButton7DateFrameBackground",
+ "CalendarDayButton7DateFrameDate",
+ "CalendarDayButton7EventBackgroundTexture",
+ "CalendarDayButton7EventButton1",
+ "CalendarDayButton7EventButton1Black",
+ "CalendarDayButton7EventButton1Text1",
+ "CalendarDayButton7EventButton1Text2",
+ "CalendarDayButton7EventButton2",
+ "CalendarDayButton7EventButton2Black",
+ "CalendarDayButton7EventButton2Text1",
+ "CalendarDayButton7EventButton2Text2",
+ "CalendarDayButton7EventButton3",
+ "CalendarDayButton7EventButton3Black",
+ "CalendarDayButton7EventButton3Text1",
+ "CalendarDayButton7EventButton3Text2",
+ "CalendarDayButton7EventButton4",
+ "CalendarDayButton7EventButton4Black",
+ "CalendarDayButton7EventButton4Text1",
+ "CalendarDayButton7EventButton4Text2",
+ "CalendarDayButton7EventTexture",
+ "CalendarDayButton7MoreEventsButton",
+ "CalendarDayButton7OverlayFrame",
+ "CalendarDayButton7OverlayFrameTexture",
+ "CalendarDayButton7PendingInviteTexture",
+ "CalendarDayButton8",
+ "CalendarDayButton8DarkFrame",
+ "CalendarDayButton8DarkFrameBottom",
+ "CalendarDayButton8DarkFrameTop",
+ "CalendarDayButton8DateFrame",
+ "CalendarDayButton8DateFrameBackground",
+ "CalendarDayButton8DateFrameDate",
+ "CalendarDayButton8EventBackgroundTexture",
+ "CalendarDayButton8EventButton1",
+ "CalendarDayButton8EventButton1Black",
+ "CalendarDayButton8EventButton1Text1",
+ "CalendarDayButton8EventButton1Text2",
+ "CalendarDayButton8EventButton2",
+ "CalendarDayButton8EventButton2Black",
+ "CalendarDayButton8EventButton2Text1",
+ "CalendarDayButton8EventButton2Text2",
+ "CalendarDayButton8EventButton3",
+ "CalendarDayButton8EventButton3Black",
+ "CalendarDayButton8EventButton3Text1",
+ "CalendarDayButton8EventButton3Text2",
+ "CalendarDayButton8EventButton4",
+ "CalendarDayButton8EventButton4Black",
+ "CalendarDayButton8EventButton4Text1",
+ "CalendarDayButton8EventButton4Text2",
+ "CalendarDayButton8EventTexture",
+ "CalendarDayButton8MoreEventsButton",
+ "CalendarDayButton8OverlayFrame",
+ "CalendarDayButton8OverlayFrameTexture",
+ "CalendarDayButton8PendingInviteTexture",
+ "CalendarDayButton9",
+ "CalendarDayButton9DarkFrame",
+ "CalendarDayButton9DarkFrameBottom",
+ "CalendarDayButton9DarkFrameTop",
+ "CalendarDayButton9DateFrame",
+ "CalendarDayButton9DateFrameBackground",
+ "CalendarDayButton9DateFrameDate",
+ "CalendarDayButton9EventBackgroundTexture",
+ "CalendarDayButton9EventButton1",
+ "CalendarDayButton9EventButton1Black",
+ "CalendarDayButton9EventButton1Text1",
+ "CalendarDayButton9EventButton1Text2",
+ "CalendarDayButton9EventButton2",
+ "CalendarDayButton9EventButton2Black",
+ "CalendarDayButton9EventButton2Text1",
+ "CalendarDayButton9EventButton2Text2",
+ "CalendarDayButton9EventButton3",
+ "CalendarDayButton9EventButton3Black",
+ "CalendarDayButton9EventButton3Text1",
+ "CalendarDayButton9EventButton3Text2",
+ "CalendarDayButton9EventButton4",
+ "CalendarDayButton9EventButton4Black",
+ "CalendarDayButton9EventButton4Text1",
+ "CalendarDayButton9EventButton4Text2",
+ "CalendarDayButton9EventTexture",
+ "CalendarDayButton9MoreEventsButton",
+ "CalendarDayButton9OverlayFrame",
+ "CalendarDayButton9OverlayFrameTexture",
+ "CalendarDayButton9PendingInviteTexture",
+ "CalendarDayButtonMoreEventsButton_OnClick",
+ "CalendarDayButtonMoreEventsButton_OnEnter",
+ "CalendarDayButtonMoreEventsButton_OnLeave",
+ "CalendarDayButtonMoreEventsButton_OnLoad",
+ "CalendarDayButton_Click",
+ "CalendarDayButton_OnClick",
+ "CalendarDayButton_OnEnter",
+ "CalendarDayButton_OnLeave",
+ "CalendarDayButton_OnLoad",
+ "CalendarDayContextMenu_AcceptInvite",
+ "CalendarDayContextMenu_CopyEvent",
+ "CalendarDayContextMenu_CreateEvent",
+ "CalendarDayContextMenu_CreateGuildAnnouncement",
+ "CalendarDayContextMenu_CreateGuildEvent",
+ "CalendarDayContextMenu_DeclineInvite",
+ "CalendarDayContextMenu_DeleteEvent",
+ "CalendarDayContextMenu_Initialize",
+ "CalendarDayContextMenu_PasteEvent",
+ "CalendarDayContextMenu_RefreshEvent",
+ "CalendarDayContextMenu_RemoveInvite",
+ "CalendarDayContextMenu_ReportSpam",
+ "CalendarDayContextMenu_SignUp",
+ "CalendarDayContextMenu_TentativeInvite",
+ "CalendarDayContextMenu_UnlockHighlights",
+ "CalendarDayEventButton_Click",
+ "CalendarDayEventButton_OnClick",
+ "CalendarDayEventButton_OnEnter",
+ "CalendarDayEventButton_OnLeave",
+ "CalendarDayEventButton_OnLoad",
+ "CalendarDefaultGuildFilter",
+ "CalendarEventAvailable",
+ "CalendarEventCanEdit",
+ "CalendarEventCanModerate",
+ "CalendarEventClearAutoApprove",
+ "CalendarEventClearLocked",
+ "CalendarEventClearModerator",
+ "CalendarEventCloseButton_OnClick",
+ "CalendarEventDecline",
+ "CalendarEventDescriptionScrollFrame_OnEvent",
+ "CalendarEventDescriptionScrollFrame_OnLoad",
+ "CalendarEventFrameBlocker",
+ "CalendarEventFrameBlocker_OnHide",
+ "CalendarEventFrameBlocker_OnShow",
+ "CalendarEventFrameBlocker_Update",
+ "CalendarEventGetCalendarType",
+ "CalendarEventGetInvite",
+ "CalendarEventGetInviteResponseTime",
+ "CalendarEventGetInviteSortCriterion",
+ "CalendarEventGetNumInvites",
+ "CalendarEventGetRepeatOptions",
+ "CalendarEventGetSelectedInvite",
+ "CalendarEventGetStatusOptions",
+ "CalendarEventGetTextures",
+ "CalendarEventGetTypes",
+ "CalendarEventHasPendingInvite",
+ "CalendarEventHaveSettingsChanged",
+ "CalendarEventInvite",
+ "CalendarEventInviteListButton_OnEnter",
+ "CalendarEventInviteList_AnchorSortButtons",
+ "CalendarEventInviteList_OnEvent",
+ "CalendarEventInviteList_OnLoad",
+ "CalendarEventInviteList_UpdateSortButtons",
+ "CalendarEventInviteSortButton_OnClick",
+ "CalendarEventInviteSortButton_OnLoad",
+ "CalendarEventIsModerator",
+ "CalendarEventPickerButton_Click",
+ "CalendarEventPickerButton_OnClick",
+ "CalendarEventPickerButton_OnDoubleClick",
+ "CalendarEventPickerButton_OnLoad",
+ "CalendarEventPickerCloseButton",
+ "CalendarEventPickerCloseButtonBorder",
+ "CalendarEventPickerCloseButtonLeft",
+ "CalendarEventPickerCloseButtonMiddle",
+ "CalendarEventPickerCloseButtonRight",
+ "CalendarEventPickerCloseButtonText",
+ "CalendarEventPickerCloseButton_OnClick",
+ "CalendarEventPickerFrame",
+ "CalendarEventPickerFrameButtonBackground",
+ "CalendarEventPickerFrame_Hide",
+ "CalendarEventPickerFrame_OnEvent",
+ "CalendarEventPickerFrame_OnLoad",
+ "CalendarEventPickerFrame_SetSelectedEvent",
+ "CalendarEventPickerFrame_Show",
+ "CalendarEventPickerFrame_Toggle",
+ "CalendarEventPickerScrollBar",
+ "CalendarEventPickerScrollBarBG",
+ "CalendarEventPickerScrollBarBottom",
+ "CalendarEventPickerScrollBarMiddle",
+ "CalendarEventPickerScrollBarScrollDownButton",
+ "CalendarEventPickerScrollBarScrollUpButton",
+ "CalendarEventPickerScrollBarThumbTexture",
+ "CalendarEventPickerScrollBarTop",
+ "CalendarEventPickerScrollFrame",
+ "CalendarEventPickerScrollFrameButton1",
+ "CalendarEventPickerScrollFrameButton10",
+ "CalendarEventPickerScrollFrameButton10Icon",
+ "CalendarEventPickerScrollFrameButton10Time",
+ "CalendarEventPickerScrollFrameButton10Title",
+ "CalendarEventPickerScrollFrameButton11",
+ "CalendarEventPickerScrollFrameButton11Icon",
+ "CalendarEventPickerScrollFrameButton11Time",
+ "CalendarEventPickerScrollFrameButton11Title",
+ "CalendarEventPickerScrollFrameButton12",
+ "CalendarEventPickerScrollFrameButton12Icon",
+ "CalendarEventPickerScrollFrameButton12Time",
+ "CalendarEventPickerScrollFrameButton12Title",
+ "CalendarEventPickerScrollFrameButton1Icon",
+ "CalendarEventPickerScrollFrameButton1Time",
+ "CalendarEventPickerScrollFrameButton1Title",
+ "CalendarEventPickerScrollFrameButton2",
+ "CalendarEventPickerScrollFrameButton2Icon",
+ "CalendarEventPickerScrollFrameButton2Time",
+ "CalendarEventPickerScrollFrameButton2Title",
+ "CalendarEventPickerScrollFrameButton3",
+ "CalendarEventPickerScrollFrameButton3Icon",
+ "CalendarEventPickerScrollFrameButton3Time",
+ "CalendarEventPickerScrollFrameButton3Title",
+ "CalendarEventPickerScrollFrameButton4",
+ "CalendarEventPickerScrollFrameButton4Icon",
+ "CalendarEventPickerScrollFrameButton4Time",
+ "CalendarEventPickerScrollFrameButton4Title",
+ "CalendarEventPickerScrollFrameButton5",
+ "CalendarEventPickerScrollFrameButton5Icon",
+ "CalendarEventPickerScrollFrameButton5Time",
+ "CalendarEventPickerScrollFrameButton5Title",
+ "CalendarEventPickerScrollFrameButton6",
+ "CalendarEventPickerScrollFrameButton6Icon",
+ "CalendarEventPickerScrollFrameButton6Time",
+ "CalendarEventPickerScrollFrameButton6Title",
+ "CalendarEventPickerScrollFrameButton7",
+ "CalendarEventPickerScrollFrameButton7Icon",
+ "CalendarEventPickerScrollFrameButton7Time",
+ "CalendarEventPickerScrollFrameButton7Title",
+ "CalendarEventPickerScrollFrameButton8",
+ "CalendarEventPickerScrollFrameButton8Icon",
+ "CalendarEventPickerScrollFrameButton8Time",
+ "CalendarEventPickerScrollFrameButton8Title",
+ "CalendarEventPickerScrollFrameButton9",
+ "CalendarEventPickerScrollFrameButton9Icon",
+ "CalendarEventPickerScrollFrameButton9Time",
+ "CalendarEventPickerScrollFrameButton9Title",
+ "CalendarEventPickerScrollFrameScrollChild",
+ "CalendarEventPickerScrollFrame_OnEvent",
+ "CalendarEventPickerScrollFrame_OnLoad",
+ "CalendarEventPickerScrollFrame_Update",
+ "CalendarEventPickerTitleFrame",
+ "CalendarEventPickerTitleFrameBackgroundLeft",
+ "CalendarEventPickerTitleFrameBackgroundMiddle",
+ "CalendarEventPickerTitleFrameBackgroundRight",
+ "CalendarEventPickerTitleFrameText",
+ "CalendarEventRemoveInvite",
+ "CalendarEventSelectInvite",
+ "CalendarEventSetAutoApprove",
+ "CalendarEventSetDate",
+ "CalendarEventSetDescription",
+ "CalendarEventSetLocked",
+ "CalendarEventSetLockoutDate",
+ "CalendarEventSetLockoutTime",
+ "CalendarEventSetModerator",
+ "CalendarEventSetRepeatOption",
+ "CalendarEventSetSize",
+ "CalendarEventSetStatus",
+ "CalendarEventSetTextureID",
+ "CalendarEventSetTime",
+ "CalendarEventSetTitle",
+ "CalendarEventSetType",
+ "CalendarEventSignUp",
+ "CalendarEventSortInvites",
+ "CalendarEventTentative",
+ "CalendarFilterButton",
+ "CalendarFilterButtonDisabledTexture",
+ "CalendarFilterButtonHighlightTexture",
+ "CalendarFilterButtonNormalTexture",
+ "CalendarFilterButtonPushedTexture",
+ "CalendarFilterButton_OnClick",
+ "CalendarFilterDropDown",
+ "CalendarFilterDropDownButton",
+ "CalendarFilterDropDownButtonDisabledTexture",
+ "CalendarFilterDropDownButtonHighlightTexture",
+ "CalendarFilterDropDownButtonNormalTexture",
+ "CalendarFilterDropDownButtonPushedTexture",
+ "CalendarFilterDropDownLeft",
+ "CalendarFilterDropDownMiddle",
+ "CalendarFilterDropDownRight",
+ "CalendarFilterDropDownText",
+ "CalendarFilterDropDown_Initialize",
+ "CalendarFilterDropDown_OnClick",
+ "CalendarFilterDropDown_OnLoad",
+ "CalendarFilterFrame",
+ "CalendarFilterFrameLeft",
+ "CalendarFilterFrameMiddle",
+ "CalendarFilterFrameRight",
+ "CalendarFilterFrameText",
+ "CalendarFrame",
+ "CalendarFrameBlocker",
+ "CalendarFrameBottomLeftTexture",
+ "CalendarFrameBottomMiddleTexture",
+ "CalendarFrameBottomRightTexture",
+ "CalendarFrameLeftBottomTexture",
+ "CalendarFrameLeftMiddleTexture",
+ "CalendarFrameLeftTopTexture",
+ "CalendarFrameModalOverlay",
+ "CalendarFrameRightBottomTexture",
+ "CalendarFrameRightMiddleTexture",
+ "CalendarFrameRightTopTexture",
+ "CalendarFrameTopLeftTexture",
+ "CalendarFrameTopMiddleTexture",
+ "CalendarFrameTopRightTexture",
+ "CalendarFrame_CloseEvent",
+ "CalendarFrame_GetEventFrame",
+ "CalendarFrame_GetModal",
+ "CalendarFrame_HideEventFrame",
+ "CalendarFrame_InitDay",
+ "CalendarFrame_InitWeekday",
+ "CalendarFrame_OffsetMonth",
+ "CalendarFrame_OnEvent",
+ "CalendarFrame_OnHide",
+ "CalendarFrame_OnLoad",
+ "CalendarFrame_OnShow",
+ "CalendarFrame_OpenEvent",
+ "CalendarFrame_PopModal",
+ "CalendarFrame_PushModal",
+ "CalendarFrame_SetLastDay",
+ "CalendarFrame_SetSelectedDay",
+ "CalendarFrame_SetSelectedEvent",
+ "CalendarFrame_SetToday",
+ "CalendarFrame_ShowEventFrame",
+ "CalendarFrame_Update",
+ "CalendarFrame_UpdateDay",
+ "CalendarFrame_UpdateDayEvents",
+ "CalendarFrame_UpdateDayTextures",
+ "CalendarFrame_UpdateFilter",
+ "CalendarFrame_UpdateMonthOffsetButtons",
+ "CalendarFrame_UpdateTimeFormat",
+ "CalendarFrame_UpdateTitle",
+ "CalendarGetAbsMonth",
+ "CalendarGetDate",
+ "CalendarGetDayEvent",
+ "CalendarGetDayEventSequenceInfo",
+ "CalendarGetEventIndex",
+ "CalendarGetEventInfo",
+ "CalendarGetFirstPendingInvite",
+ "CalendarGetHolidayInfo",
+ "CalendarGetMaxCreateDate",
+ "CalendarGetMaxDate",
+ "CalendarGetMinDate",
+ "CalendarGetMinHistoryDate",
+ "CalendarGetMonth",
+ "CalendarGetMonthNames",
+ "CalendarGetNumDayEvents",
+ "CalendarGetNumPendingInvites",
+ "CalendarGetRaidInfo",
+ "CalendarGetWeekdayNames",
+ "CalendarInviteContextMenu_ClearModerator",
+ "CalendarInviteContextMenu_InviteToGroup",
+ "CalendarInviteContextMenu_RemoveInvite",
+ "CalendarInviteContextMenu_SetModerator",
+ "CalendarInviteContextMenu_UnlockHighlights",
+ "CalendarInviteStatusContextMenu",
+ "CalendarInviteStatusContextMenuButton1",
+ "CalendarInviteStatusContextMenuButton10",
+ "CalendarInviteStatusContextMenuButton10ShortcutText",
+ "CalendarInviteStatusContextMenuButton11",
+ "CalendarInviteStatusContextMenuButton11ShortcutText",
+ "CalendarInviteStatusContextMenuButton12",
+ "CalendarInviteStatusContextMenuButton12ShortcutText",
+ "CalendarInviteStatusContextMenuButton13",
+ "CalendarInviteStatusContextMenuButton13ShortcutText",
+ "CalendarInviteStatusContextMenuButton14",
+ "CalendarInviteStatusContextMenuButton14ShortcutText",
+ "CalendarInviteStatusContextMenuButton15",
+ "CalendarInviteStatusContextMenuButton15ShortcutText",
+ "CalendarInviteStatusContextMenuButton16",
+ "CalendarInviteStatusContextMenuButton16ShortcutText",
+ "CalendarInviteStatusContextMenuButton17",
+ "CalendarInviteStatusContextMenuButton17ShortcutText",
+ "CalendarInviteStatusContextMenuButton18",
+ "CalendarInviteStatusContextMenuButton18ShortcutText",
+ "CalendarInviteStatusContextMenuButton19",
+ "CalendarInviteStatusContextMenuButton19ShortcutText",
+ "CalendarInviteStatusContextMenuButton1ShortcutText",
+ "CalendarInviteStatusContextMenuButton2",
+ "CalendarInviteStatusContextMenuButton20",
+ "CalendarInviteStatusContextMenuButton20ShortcutText",
+ "CalendarInviteStatusContextMenuButton21",
+ "CalendarInviteStatusContextMenuButton21ShortcutText",
+ "CalendarInviteStatusContextMenuButton22",
+ "CalendarInviteStatusContextMenuButton22ShortcutText",
+ "CalendarInviteStatusContextMenuButton23",
+ "CalendarInviteStatusContextMenuButton23ShortcutText",
+ "CalendarInviteStatusContextMenuButton24",
+ "CalendarInviteStatusContextMenuButton24ShortcutText",
+ "CalendarInviteStatusContextMenuButton25",
+ "CalendarInviteStatusContextMenuButton25ShortcutText",
+ "CalendarInviteStatusContextMenuButton26",
+ "CalendarInviteStatusContextMenuButton26ShortcutText",
+ "CalendarInviteStatusContextMenuButton27",
+ "CalendarInviteStatusContextMenuButton27ShortcutText",
+ "CalendarInviteStatusContextMenuButton28",
+ "CalendarInviteStatusContextMenuButton28ShortcutText",
+ "CalendarInviteStatusContextMenuButton29",
+ "CalendarInviteStatusContextMenuButton29ShortcutText",
+ "CalendarInviteStatusContextMenuButton2ShortcutText",
+ "CalendarInviteStatusContextMenuButton3",
+ "CalendarInviteStatusContextMenuButton30",
+ "CalendarInviteStatusContextMenuButton30ShortcutText",
+ "CalendarInviteStatusContextMenuButton31",
+ "CalendarInviteStatusContextMenuButton31ShortcutText",
+ "CalendarInviteStatusContextMenuButton32",
+ "CalendarInviteStatusContextMenuButton32ShortcutText",
+ "CalendarInviteStatusContextMenuButton3ShortcutText",
+ "CalendarInviteStatusContextMenuButton4",
+ "CalendarInviteStatusContextMenuButton4ShortcutText",
+ "CalendarInviteStatusContextMenuButton5",
+ "CalendarInviteStatusContextMenuButton5ShortcutText",
+ "CalendarInviteStatusContextMenuButton6",
+ "CalendarInviteStatusContextMenuButton6ShortcutText",
+ "CalendarInviteStatusContextMenuButton7",
+ "CalendarInviteStatusContextMenuButton7ShortcutText",
+ "CalendarInviteStatusContextMenuButton8",
+ "CalendarInviteStatusContextMenuButton8ShortcutText",
+ "CalendarInviteStatusContextMenuButton9",
+ "CalendarInviteStatusContextMenuButton9ShortcutText",
+ "CalendarInviteStatusContextMenu_Initialize",
+ "CalendarInviteStatusContextMenu_OnEvent",
+ "CalendarInviteStatusContextMenu_OnLoad",
+ "CalendarInviteStatusContextMenu_OnShow",
+ "CalendarInviteStatusContextMenu_SetStatusOption",
+ "CalendarIsActionPending",
+ "CalendarLastDayDarkTexture",
+ "CalendarMassInviteArenaButton2",
+ "CalendarMassInviteArenaButton2Left",
+ "CalendarMassInviteArenaButton2Middle",
+ "CalendarMassInviteArenaButton2Right",
+ "CalendarMassInviteArenaButton2Text",
+ "CalendarMassInviteArenaButton3",
+ "CalendarMassInviteArenaButton3Left",
+ "CalendarMassInviteArenaButton3Middle",
+ "CalendarMassInviteArenaButton3Right",
+ "CalendarMassInviteArenaButton3Text",
+ "CalendarMassInviteArenaButton5",
+ "CalendarMassInviteArenaButton5Left",
+ "CalendarMassInviteArenaButton5Middle",
+ "CalendarMassInviteArenaButton5Right",
+ "CalendarMassInviteArenaButton5Text",
+ "CalendarMassInviteArenaButton_OnClick",
+ "CalendarMassInviteArenaButton_OnEnter",
+ "CalendarMassInviteArenaButton_OnLoad",
+ "CalendarMassInviteArenaTeam",
+ "CalendarMassInviteArena_Update",
+ "CalendarMassInviteCloseButton",
+ "CalendarMassInviteFrame",
+ "CalendarMassInviteFrameDivider",
+ "CalendarMassInviteFrameLevelDivider",
+ "CalendarMassInviteFrameModalOverlay",
+ "CalendarMassInviteFrame_OnEvent",
+ "CalendarMassInviteFrame_OnLoad",
+ "CalendarMassInviteFrame_OnShow",
+ "CalendarMassInviteFrame_OnUpdate",
+ "CalendarMassInviteGuild",
+ "CalendarMassInviteGuildAcceptButton",
+ "CalendarMassInviteGuildAcceptButtonLeft",
+ "CalendarMassInviteGuildAcceptButtonMiddle",
+ "CalendarMassInviteGuildAcceptButtonRight",
+ "CalendarMassInviteGuildAcceptButtonText",
+ "CalendarMassInviteGuildAcceptButton_OnClick",
+ "CalendarMassInviteGuildLevelText",
+ "CalendarMassInviteGuildMaxLevelEdit",
+ "CalendarMassInviteGuildMaxLevelEditLeft",
+ "CalendarMassInviteGuildMaxLevelEditMiddle",
+ "CalendarMassInviteGuildMaxLevelEditRight",
+ "CalendarMassInviteGuildMinLevelEdit",
+ "CalendarMassInviteGuildMinLevelEditLeft",
+ "CalendarMassInviteGuildMinLevelEditMiddle",
+ "CalendarMassInviteGuildMinLevelEditRight",
+ "CalendarMassInviteGuildRankMenu",
+ "CalendarMassInviteGuildRankMenuButton",
+ "CalendarMassInviteGuildRankMenuButtonDisabledTexture",
+ "CalendarMassInviteGuildRankMenuButtonHighlightTexture",
+ "CalendarMassInviteGuildRankMenuButtonNormalTexture",
+ "CalendarMassInviteGuildRankMenuButtonPushedTexture",
+ "CalendarMassInviteGuildRankMenuLeft",
+ "CalendarMassInviteGuildRankMenuMiddle",
+ "CalendarMassInviteGuildRankMenuRight",
+ "CalendarMassInviteGuildRankMenuText",
+ "CalendarMassInviteGuildRankMenu_Initialize",
+ "CalendarMassInviteGuildRankMenu_OnClick",
+ "CalendarMassInviteGuildRankText",
+ "CalendarMassInviteGuild_Update",
+ "CalendarMassInviteTitleFrame",
+ "CalendarMassInviteTitleFrameBackgroundLeft",
+ "CalendarMassInviteTitleFrameBackgroundMiddle",
+ "CalendarMassInviteTitleFrameBackgroundRight",
+ "CalendarMassInviteTitleFrameText",
+ "CalendarModalDummy",
+ "CalendarModalDummy_Hide",
+ "CalendarModalDummy_Show",
+ "CalendarMonthBackground",
+ "CalendarMonthName",
+ "CalendarNewEvent",
+ "CalendarNewGuildAnnouncement",
+ "CalendarNewGuildEvent",
+ "CalendarNextMonthButton",
+ "CalendarNextMonthButton_OnClick",
+ "CalendarOpenEvent",
+ "CalendarPrevMonthButton",
+ "CalendarPrevMonthButton_OnClick",
+ "CalendarRemoveEvent",
+ "CalendarSetAbsMonth",
+ "CalendarSetMonth",
+ "CalendarTexturePickerAcceptButton",
+ "CalendarTexturePickerAcceptButtonBorder",
+ "CalendarTexturePickerAcceptButtonLeft",
+ "CalendarTexturePickerAcceptButtonMiddle",
+ "CalendarTexturePickerAcceptButtonRight",
+ "CalendarTexturePickerAcceptButtonText",
+ "CalendarTexturePickerAcceptButton_OnClick",
+ "CalendarTexturePickerButton_OnClick",
+ "CalendarTexturePickerButton_OnDoubleClick",
+ "CalendarTexturePickerButton_OnLoad",
+ "CalendarTexturePickerCancelButton",
+ "CalendarTexturePickerCancelButtonBorder",
+ "CalendarTexturePickerCancelButtonLeft",
+ "CalendarTexturePickerCancelButtonMiddle",
+ "CalendarTexturePickerCancelButtonRight",
+ "CalendarTexturePickerCancelButtonText",
+ "CalendarTexturePickerFrame",
+ "CalendarTexturePickerFrameButtonBackground",
+ "CalendarTexturePickerFrame_Hide",
+ "CalendarTexturePickerFrame_OnLoad",
+ "CalendarTexturePickerFrame_Show",
+ "CalendarTexturePickerFrame_Toggle",
+ "CalendarTexturePickerFrame_Update",
+ "CalendarTexturePickerScrollBar",
+ "CalendarTexturePickerScrollBarBG",
+ "CalendarTexturePickerScrollBarBottom",
+ "CalendarTexturePickerScrollBarMiddle",
+ "CalendarTexturePickerScrollBarScrollDownButton",
+ "CalendarTexturePickerScrollBarScrollUpButton",
+ "CalendarTexturePickerScrollBarThumbTexture",
+ "CalendarTexturePickerScrollBarTop",
+ "CalendarTexturePickerScrollFrame",
+ "CalendarTexturePickerScrollFrameButton1",
+ "CalendarTexturePickerScrollFrameButton10",
+ "CalendarTexturePickerScrollFrameButton10Icon",
+ "CalendarTexturePickerScrollFrameButton10Title",
+ "CalendarTexturePickerScrollFrameButton11",
+ "CalendarTexturePickerScrollFrameButton11Icon",
+ "CalendarTexturePickerScrollFrameButton11Title",
+ "CalendarTexturePickerScrollFrameButton12",
+ "CalendarTexturePickerScrollFrameButton12Icon",
+ "CalendarTexturePickerScrollFrameButton12Title",
+ "CalendarTexturePickerScrollFrameButton13",
+ "CalendarTexturePickerScrollFrameButton13Icon",
+ "CalendarTexturePickerScrollFrameButton13Title",
+ "CalendarTexturePickerScrollFrameButton14",
+ "CalendarTexturePickerScrollFrameButton14Icon",
+ "CalendarTexturePickerScrollFrameButton14Title",
+ "CalendarTexturePickerScrollFrameButton15",
+ "CalendarTexturePickerScrollFrameButton15Icon",
+ "CalendarTexturePickerScrollFrameButton15Title",
+ "CalendarTexturePickerScrollFrameButton16",
+ "CalendarTexturePickerScrollFrameButton16Icon",
+ "CalendarTexturePickerScrollFrameButton16Title",
+ "CalendarTexturePickerScrollFrameButton1Icon",
+ "CalendarTexturePickerScrollFrameButton1Title",
+ "CalendarTexturePickerScrollFrameButton2",
+ "CalendarTexturePickerScrollFrameButton2Icon",
+ "CalendarTexturePickerScrollFrameButton2Title",
+ "CalendarTexturePickerScrollFrameButton3",
+ "CalendarTexturePickerScrollFrameButton3Icon",
+ "CalendarTexturePickerScrollFrameButton3Title",
+ "CalendarTexturePickerScrollFrameButton4",
+ "CalendarTexturePickerScrollFrameButton4Icon",
+ "CalendarTexturePickerScrollFrameButton4Title",
+ "CalendarTexturePickerScrollFrameButton5",
+ "CalendarTexturePickerScrollFrameButton5Icon",
+ "CalendarTexturePickerScrollFrameButton5Title",
+ "CalendarTexturePickerScrollFrameButton6",
+ "CalendarTexturePickerScrollFrameButton6Icon",
+ "CalendarTexturePickerScrollFrameButton6Title",
+ "CalendarTexturePickerScrollFrameButton7",
+ "CalendarTexturePickerScrollFrameButton7Icon",
+ "CalendarTexturePickerScrollFrameButton7Title",
+ "CalendarTexturePickerScrollFrameButton8",
+ "CalendarTexturePickerScrollFrameButton8Icon",
+ "CalendarTexturePickerScrollFrameButton8Title",
+ "CalendarTexturePickerScrollFrameButton9",
+ "CalendarTexturePickerScrollFrameButton9Icon",
+ "CalendarTexturePickerScrollFrameButton9Title",
+ "CalendarTexturePickerScrollFrameScrollChild",
+ "CalendarTexturePickerScrollFrame_OnEvent",
+ "CalendarTexturePickerScrollFrame_OnLoad",
+ "CalendarTexturePickerScrollFrame_Update",
+ "CalendarTexturePickerTitleFrame",
+ "CalendarTexturePickerTitleFrameBackgroundLeft",
+ "CalendarTexturePickerTitleFrameBackgroundMiddle",
+ "CalendarTexturePickerTitleFrameBackgroundRight",
+ "CalendarTexturePickerTitleFrameText",
+ "CalendarTexturePickerTitleFrame_Update",
+ "CalendarTitleFrame_SetText",
+ "CalendarTodayFrame",
+ "CalendarTodayFrame_OnUpdate",
+ "CalendarTodayTexture",
+ "CalendarTodayTextureGlow",
+ "CalendarUpdateEvent",
+ "CalendarViewEventAcceptButton",
+ "CalendarViewEventAcceptButtonFlashTexture",
+ "CalendarViewEventAcceptButtonLeft",
+ "CalendarViewEventAcceptButtonMiddle",
+ "CalendarViewEventAcceptButtonRight",
+ "CalendarViewEventAcceptButtonText",
+ "CalendarViewEventAcceptButton_OnClick",
+ "CalendarViewEventAcceptButton_OnEnter",
+ "CalendarViewEventBackground",
+ "CalendarViewEventCloseButton",
+ "CalendarViewEventCreatorName",
+ "CalendarViewEventDateLabel",
+ "CalendarViewEventDeclineButton",
+ "CalendarViewEventDeclineButtonFlashTexture",
+ "CalendarViewEventDeclineButtonLeft",
+ "CalendarViewEventDeclineButtonMiddle",
+ "CalendarViewEventDeclineButtonRight",
+ "CalendarViewEventDeclineButtonText",
+ "CalendarViewEventDeclineButton_OnClick",
+ "CalendarViewEventDeclineButton_OnEnter",
+ "CalendarViewEventDescription",
+ "CalendarViewEventDescriptionContainer",
+ "CalendarViewEventDescriptionScrollChild",
+ "CalendarViewEventDescriptionScrollFrame",
+ "CalendarViewEventDescriptionScrollFrameScrollBar",
+ "CalendarViewEventDescriptionScrollFrameScrollBarScrollDownButton",
+ "CalendarViewEventDescriptionScrollFrameScrollBarScrollUpButton",
+ "CalendarViewEventDescriptionScrollFrameScrollBarThumbTexture",
+ "CalendarViewEventDescriptionScrollFrame_OnLoad",
+ "CalendarViewEventDivider",
+ "CalendarViewEventFlashTimer",
+ "CalendarViewEventFrame",
+ "CalendarViewEventFrameModalOverlay",
+ "CalendarViewEventFrame_OnEvent",
+ "CalendarViewEventFrame_OnHide",
+ "CalendarViewEventFrame_OnLoad",
+ "CalendarViewEventFrame_OnShow",
+ "CalendarViewEventFrame_SetSelectedInvite",
+ "CalendarViewEventFrame_Update",
+ "CalendarViewEventIcon",
+ "CalendarViewEventInviteContextMenu_Initialize",
+ "CalendarViewEventInviteList",
+ "CalendarViewEventInviteListButton_Click",
+ "CalendarViewEventInviteListButton_OnClick",
+ "CalendarViewEventInviteListClassSortButton",
+ "CalendarViewEventInviteListClassSortButtonDirection",
+ "CalendarViewEventInviteListNameSortButton",
+ "CalendarViewEventInviteListNameSortButtonDirection",
+ "CalendarViewEventInviteListScrollFrame",
+ "CalendarViewEventInviteListScrollFrameButton1",
+ "CalendarViewEventInviteListScrollFrameButton10",
+ "CalendarViewEventInviteListScrollFrameButton10Class",
+ "CalendarViewEventInviteListScrollFrameButton10ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton10Name",
+ "CalendarViewEventInviteListScrollFrameButton10PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton10Status",
+ "CalendarViewEventInviteListScrollFrameButton11",
+ "CalendarViewEventInviteListScrollFrameButton11Class",
+ "CalendarViewEventInviteListScrollFrameButton11ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton11Name",
+ "CalendarViewEventInviteListScrollFrameButton11PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton11Status",
+ "CalendarViewEventInviteListScrollFrameButton12",
+ "CalendarViewEventInviteListScrollFrameButton12Class",
+ "CalendarViewEventInviteListScrollFrameButton12ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton12Name",
+ "CalendarViewEventInviteListScrollFrameButton12PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton12Status",
+ "CalendarViewEventInviteListScrollFrameButton13",
+ "CalendarViewEventInviteListScrollFrameButton13Class",
+ "CalendarViewEventInviteListScrollFrameButton13ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton13Name",
+ "CalendarViewEventInviteListScrollFrameButton13PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton13Status",
+ "CalendarViewEventInviteListScrollFrameButton14",
+ "CalendarViewEventInviteListScrollFrameButton14Class",
+ "CalendarViewEventInviteListScrollFrameButton14ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton14Name",
+ "CalendarViewEventInviteListScrollFrameButton14PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton14Status",
+ "CalendarViewEventInviteListScrollFrameButton15",
+ "CalendarViewEventInviteListScrollFrameButton15Class",
+ "CalendarViewEventInviteListScrollFrameButton15ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton15Name",
+ "CalendarViewEventInviteListScrollFrameButton15PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton15Status",
+ "CalendarViewEventInviteListScrollFrameButton16",
+ "CalendarViewEventInviteListScrollFrameButton16Class",
+ "CalendarViewEventInviteListScrollFrameButton16ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton16Name",
+ "CalendarViewEventInviteListScrollFrameButton16PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton16Status",
+ "CalendarViewEventInviteListScrollFrameButton17",
+ "CalendarViewEventInviteListScrollFrameButton17Class",
+ "CalendarViewEventInviteListScrollFrameButton17ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton17Name",
+ "CalendarViewEventInviteListScrollFrameButton17PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton17Status",
+ "CalendarViewEventInviteListScrollFrameButton18",
+ "CalendarViewEventInviteListScrollFrameButton18Class",
+ "CalendarViewEventInviteListScrollFrameButton18ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton18Name",
+ "CalendarViewEventInviteListScrollFrameButton18PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton18Status",
+ "CalendarViewEventInviteListScrollFrameButton19",
+ "CalendarViewEventInviteListScrollFrameButton19Class",
+ "CalendarViewEventInviteListScrollFrameButton19ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton19Name",
+ "CalendarViewEventInviteListScrollFrameButton19PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton19Status",
+ "CalendarViewEventInviteListScrollFrameButton1Class",
+ "CalendarViewEventInviteListScrollFrameButton1ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton1Name",
+ "CalendarViewEventInviteListScrollFrameButton1PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton1Status",
+ "CalendarViewEventInviteListScrollFrameButton2",
+ "CalendarViewEventInviteListScrollFrameButton2Class",
+ "CalendarViewEventInviteListScrollFrameButton2ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton2Name",
+ "CalendarViewEventInviteListScrollFrameButton2PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton2Status",
+ "CalendarViewEventInviteListScrollFrameButton3",
+ "CalendarViewEventInviteListScrollFrameButton3Class",
+ "CalendarViewEventInviteListScrollFrameButton3ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton3Name",
+ "CalendarViewEventInviteListScrollFrameButton3PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton3Status",
+ "CalendarViewEventInviteListScrollFrameButton4",
+ "CalendarViewEventInviteListScrollFrameButton4Class",
+ "CalendarViewEventInviteListScrollFrameButton4ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton4Name",
+ "CalendarViewEventInviteListScrollFrameButton4PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton4Status",
+ "CalendarViewEventInviteListScrollFrameButton5",
+ "CalendarViewEventInviteListScrollFrameButton5Class",
+ "CalendarViewEventInviteListScrollFrameButton5ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton5Name",
+ "CalendarViewEventInviteListScrollFrameButton5PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton5Status",
+ "CalendarViewEventInviteListScrollFrameButton6",
+ "CalendarViewEventInviteListScrollFrameButton6Class",
+ "CalendarViewEventInviteListScrollFrameButton6ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton6Name",
+ "CalendarViewEventInviteListScrollFrameButton6PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton6Status",
+ "CalendarViewEventInviteListScrollFrameButton7",
+ "CalendarViewEventInviteListScrollFrameButton7Class",
+ "CalendarViewEventInviteListScrollFrameButton7ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton7Name",
+ "CalendarViewEventInviteListScrollFrameButton7PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton7Status",
+ "CalendarViewEventInviteListScrollFrameButton8",
+ "CalendarViewEventInviteListScrollFrameButton8Class",
+ "CalendarViewEventInviteListScrollFrameButton8ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton8Name",
+ "CalendarViewEventInviteListScrollFrameButton8PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton8Status",
+ "CalendarViewEventInviteListScrollFrameButton9",
+ "CalendarViewEventInviteListScrollFrameButton9Class",
+ "CalendarViewEventInviteListScrollFrameButton9ModIcon",
+ "CalendarViewEventInviteListScrollFrameButton9Name",
+ "CalendarViewEventInviteListScrollFrameButton9PartyIcon",
+ "CalendarViewEventInviteListScrollFrameButton9Status",
+ "CalendarViewEventInviteListScrollFrameScrollBar",
+ "CalendarViewEventInviteListScrollFrameScrollBarBG",
+ "CalendarViewEventInviteListScrollFrameScrollBarBottom",
+ "CalendarViewEventInviteListScrollFrameScrollBarMiddle",
+ "CalendarViewEventInviteListScrollFrameScrollBarScrollDownButton",
+ "CalendarViewEventInviteListScrollFrameScrollBarScrollUpButton",
+ "CalendarViewEventInviteListScrollFrameScrollBarThumbTexture",
+ "CalendarViewEventInviteListScrollFrameScrollBarTop",
+ "CalendarViewEventInviteListScrollFrameScrollChild",
+ "CalendarViewEventInviteListScrollFrame_Update",
+ "CalendarViewEventInviteListSection",
+ "CalendarViewEventInviteListStatusSortButton",
+ "CalendarViewEventInviteListStatusSortButtonDirection",
+ "CalendarViewEventInviteList_Update",
+ "CalendarViewEventRSVPButton_OnUpdate",
+ "CalendarViewEventRSVP_Update",
+ "CalendarViewEventRemoveButton",
+ "CalendarViewEventRemoveButtonLeft",
+ "CalendarViewEventRemoveButtonMiddle",
+ "CalendarViewEventRemoveButtonRight",
+ "CalendarViewEventRemoveButtonText",
+ "CalendarViewEventRemoveButton_OnClick",
+ "CalendarViewEventRemoveButton_OnEnter",
+ "CalendarViewEventTentativeButton",
+ "CalendarViewEventTentativeButtonFlashTexture",
+ "CalendarViewEventTentativeButtonLeft",
+ "CalendarViewEventTentativeButtonMiddle",
+ "CalendarViewEventTentativeButtonRight",
+ "CalendarViewEventTentativeButtonText",
+ "CalendarViewEventTentativeButton_OnClick",
+ "CalendarViewEventTentativeButton_OnEnter",
+ "CalendarViewEventTimeLabel",
+ "CalendarViewEventTitle",
+ "CalendarViewEventTitleFrame",
+ "CalendarViewEventTitleFrameBackgroundLeft",
+ "CalendarViewEventTitleFrameBackgroundMiddle",
+ "CalendarViewEventTitleFrameBackgroundRight",
+ "CalendarViewEventTitleFrameText",
+ "CalendarViewEventTypeName",
+ "CalendarViewHolidayBackground",
+ "CalendarViewHolidayCloseButton",
+ "CalendarViewHolidayDescription",
+ "CalendarViewHolidayFrame",
+ "CalendarViewHolidayFrameModalOverlay",
+ "CalendarViewHolidayFrame_OnHide",
+ "CalendarViewHolidayFrame_OnLoad",
+ "CalendarViewHolidayFrame_OnShow",
+ "CalendarViewHolidayFrame_Update",
+ "CalendarViewHolidayInfoTexture",
+ "CalendarViewHolidayScrollChild",
+ "CalendarViewHolidayScrollFrame",
+ "CalendarViewHolidayScrollFrameScrollBar",
+ "CalendarViewHolidayScrollFrameScrollBarScrollDownButton",
+ "CalendarViewHolidayScrollFrameScrollBarScrollUpButton",
+ "CalendarViewHolidayScrollFrameScrollBarThumbTexture",
+ "CalendarViewHolidayTitleFrame",
+ "CalendarViewHolidayTitleFrameBackgroundLeft",
+ "CalendarViewHolidayTitleFrameBackgroundMiddle",
+ "CalendarViewHolidayTitleFrameBackgroundRight",
+ "CalendarViewHolidayTitleFrameText",
+ "CalendarViewRaidBackground",
+ "CalendarViewRaidCloseButton",
+ "CalendarViewRaidDescription",
+ "CalendarViewRaidFrame",
+ "CalendarViewRaidFrameModalOverlay",
+ "CalendarViewRaidFrame_OnHide",
+ "CalendarViewRaidFrame_OnLoad",
+ "CalendarViewRaidFrame_OnShow",
+ "CalendarViewRaidFrame_Update",
+ "CalendarViewRaidScrollChild",
+ "CalendarViewRaidScrollFrame",
+ "CalendarViewRaidScrollFrameScrollBar",
+ "CalendarViewRaidScrollFrameScrollBarScrollDownButton",
+ "CalendarViewRaidScrollFrameScrollBarScrollUpButton",
+ "CalendarViewRaidScrollFrameScrollBarThumbTexture",
+ "CalendarViewRaidTitleFrame",
+ "CalendarViewRaidTitleFrameBackgroundLeft",
+ "CalendarViewRaidTitleFrameBackgroundMiddle",
+ "CalendarViewRaidTitleFrameBackgroundRight",
+ "CalendarViewRaidTitleFrameText",
+ "CalendarWeekday1Background",
+ "CalendarWeekday1Name",
+ "CalendarWeekday2Background",
+ "CalendarWeekday2Name",
+ "CalendarWeekday3Background",
+ "CalendarWeekday3Name",
+ "CalendarWeekday4Background",
+ "CalendarWeekday4Name",
+ "CalendarWeekday5Background",
+ "CalendarWeekday5Name",
+ "CalendarWeekday6Background",
+ "CalendarWeekday6Name",
+ "CalendarWeekday7Background",
+ "CalendarWeekday7Name",
+ "CalendarWeekdaySelectedTexture",
+ "CalendarYearBackground",
+ "CalendarYearName",
+ "Calendar_Hide",
+ "Calendar_LoadUI",
+ "Calendar_Show",
+ "Calendar_Toggle",
+ "CallCompanion",
+ "CallRestrictedClosure",
+ "CameraOrSelectOrMoveStart",
+ "CameraOrSelectOrMoveStop",
+ "CameraPanelOptions",
+ "CameraZoomIn",
+ "CameraZoomOut",
+ "CanAlterSkin",
+ "CanCancelAuction",
+ "CanChangePlayerDifficulty",
+ "CanComplainChat",
+ "CanComplainInboxItem",
+ "CanCooperateWithToon",
+ "CanCreateFilters",
+ "CanEditGuildEvent",
+ "CanEditGuildInfo",
+ "CanEditGuildTabInfo",
+ "CanEditMOTD",
+ "CanEditOfficerNote",
+ "CanEditPublicNote",
+ "CanEjectPassengerFromSeat",
+ "CanExitVehicle",
+ "CanGrantLevel",
+ "CanGroupInvite",
+ "CanGuildBankRepair",
+ "CanGuildDemote",
+ "CanGuildInvite",
+ "CanGuildPromote",
+ "CanGuildRemove",
+ "CanHearthAndResurrectFromArea",
+ "CanInspect",
+ "CanJoinBattlefieldAsGroup",
+ "CanMapChangeDifficulty",
+ "CanMerchantRepair",
+ "CanOpenPanels",
+ "CanPartyLFGBackfill",
+ "CanQueueForWintergrasp",
+ "CanResetTutorials",
+ "CanSendAuctionQuery",
+ "CanShowAchievementUI",
+ "CanShowCenterUIPanel",
+ "CanShowResetInstances",
+ "CanShowRightUIPanel",
+ "CanShowUIPanels",
+ "CanSignPetition",
+ "CanSummonFriend",
+ "CanSwitchVehicleSeat",
+ "CanSwitchVehicleSeats",
+ "CanUseEquipmentSets",
+ "CanViewOfficerNote",
+ "CanWithdrawGuildBankMoney",
+ "CancelAreaSpiritHeal",
+ "CancelAuction",
+ "CancelBarberShop",
+ "CancelDuel",
+ "CancelItemTempEnchantment",
+ "CancelLogout",
+ "CancelPendingEquip",
+ "CancelSell",
+ "CancelShapeshiftForm",
+ "CancelSkillUps",
+ "CancelSummon",
+ "CancelTrade",
+ "CancelTradeAccept",
+ "CancelUnitBuff",
+ "CannotBeResurrected",
+ "CaptureBar_Create",
+ "CaptureBar_Update",
+ "CastPetAction",
+ "CastShapeshiftForm",
+ "CastSpell",
+ "CastSpellByID",
+ "CastSpellByName",
+ "CastingBarFrame",
+ "CastingBarFrameBorder",
+ "CastingBarFrameBorderShield",
+ "CastingBarFrameFlash",
+ "CastingBarFrameIcon",
+ "CastingBarFrameSpark",
+ "CastingBarFrameText",
+ "CastingBarFrame_FinishSpell",
+ "CastingBarFrame_OnEvent",
+ "CastingBarFrame_OnLoad",
+ "CastingBarFrame_OnShow",
+ "CastingBarFrame_OnUpdate",
+ "CastingBarFrame_UpdateIsShown",
+ "ChangeActionBarPage",
+ "ChangeChatColor",
+ "ChangeMultiCastActionPage",
+ "ChangePlayerDifficulty",
+ "ChannelBan",
+ "ChannelButton1",
+ "ChannelButton10",
+ "ChannelButton10Collapsed",
+ "ChannelButton10NormalTexture",
+ "ChannelButton10SpeakerFrame",
+ "ChannelButton10SpeakerFrameFlash",
+ "ChannelButton10SpeakerFrameMuted",
+ "ChannelButton10SpeakerFrameOn",
+ "ChannelButton10Text",
+ "ChannelButton11",
+ "ChannelButton11Collapsed",
+ "ChannelButton11NormalTexture",
+ "ChannelButton11SpeakerFrame",
+ "ChannelButton11SpeakerFrameFlash",
+ "ChannelButton11SpeakerFrameMuted",
+ "ChannelButton11SpeakerFrameOn",
+ "ChannelButton11Text",
+ "ChannelButton12",
+ "ChannelButton12Collapsed",
+ "ChannelButton12NormalTexture",
+ "ChannelButton12SpeakerFrame",
+ "ChannelButton12SpeakerFrameFlash",
+ "ChannelButton12SpeakerFrameMuted",
+ "ChannelButton12SpeakerFrameOn",
+ "ChannelButton12Text",
+ "ChannelButton13",
+ "ChannelButton13Collapsed",
+ "ChannelButton13NormalTexture",
+ "ChannelButton13SpeakerFrame",
+ "ChannelButton13SpeakerFrameFlash",
+ "ChannelButton13SpeakerFrameMuted",
+ "ChannelButton13SpeakerFrameOn",
+ "ChannelButton13Text",
+ "ChannelButton14",
+ "ChannelButton14Collapsed",
+ "ChannelButton14NormalTexture",
+ "ChannelButton14SpeakerFrame",
+ "ChannelButton14SpeakerFrameFlash",
+ "ChannelButton14SpeakerFrameMuted",
+ "ChannelButton14SpeakerFrameOn",
+ "ChannelButton14Text",
+ "ChannelButton15",
+ "ChannelButton15Collapsed",
+ "ChannelButton15NormalTexture",
+ "ChannelButton15SpeakerFrame",
+ "ChannelButton15SpeakerFrameFlash",
+ "ChannelButton15SpeakerFrameMuted",
+ "ChannelButton15SpeakerFrameOn",
+ "ChannelButton15Text",
+ "ChannelButton16",
+ "ChannelButton16Collapsed",
+ "ChannelButton16NormalTexture",
+ "ChannelButton16SpeakerFrame",
+ "ChannelButton16SpeakerFrameFlash",
+ "ChannelButton16SpeakerFrameMuted",
+ "ChannelButton16SpeakerFrameOn",
+ "ChannelButton16Text",
+ "ChannelButton17",
+ "ChannelButton17Collapsed",
+ "ChannelButton17NormalTexture",
+ "ChannelButton17SpeakerFrame",
+ "ChannelButton17SpeakerFrameFlash",
+ "ChannelButton17SpeakerFrameMuted",
+ "ChannelButton17SpeakerFrameOn",
+ "ChannelButton17Text",
+ "ChannelButton18",
+ "ChannelButton18Collapsed",
+ "ChannelButton18NormalTexture",
+ "ChannelButton18SpeakerFrame",
+ "ChannelButton18SpeakerFrameFlash",
+ "ChannelButton18SpeakerFrameMuted",
+ "ChannelButton18SpeakerFrameOn",
+ "ChannelButton18Text",
+ "ChannelButton19",
+ "ChannelButton19Collapsed",
+ "ChannelButton19NormalTexture",
+ "ChannelButton19SpeakerFrame",
+ "ChannelButton19SpeakerFrameFlash",
+ "ChannelButton19SpeakerFrameMuted",
+ "ChannelButton19SpeakerFrameOn",
+ "ChannelButton19Text",
+ "ChannelButton1Collapsed",
+ "ChannelButton1NormalTexture",
+ "ChannelButton1SpeakerFrame",
+ "ChannelButton1SpeakerFrameFlash",
+ "ChannelButton1SpeakerFrameMuted",
+ "ChannelButton1SpeakerFrameOn",
+ "ChannelButton1Text",
+ "ChannelButton2",
+ "ChannelButton20",
+ "ChannelButton20Collapsed",
+ "ChannelButton20NormalTexture",
+ "ChannelButton20SpeakerFrame",
+ "ChannelButton20SpeakerFrameFlash",
+ "ChannelButton20SpeakerFrameMuted",
+ "ChannelButton20SpeakerFrameOn",
+ "ChannelButton20Text",
+ "ChannelButton2Collapsed",
+ "ChannelButton2NormalTexture",
+ "ChannelButton2SpeakerFrame",
+ "ChannelButton2SpeakerFrameFlash",
+ "ChannelButton2SpeakerFrameMuted",
+ "ChannelButton2SpeakerFrameOn",
+ "ChannelButton2Text",
+ "ChannelButton3",
+ "ChannelButton3Collapsed",
+ "ChannelButton3NormalTexture",
+ "ChannelButton3SpeakerFrame",
+ "ChannelButton3SpeakerFrameFlash",
+ "ChannelButton3SpeakerFrameMuted",
+ "ChannelButton3SpeakerFrameOn",
+ "ChannelButton3Text",
+ "ChannelButton4",
+ "ChannelButton4Collapsed",
+ "ChannelButton4NormalTexture",
+ "ChannelButton4SpeakerFrame",
+ "ChannelButton4SpeakerFrameFlash",
+ "ChannelButton4SpeakerFrameMuted",
+ "ChannelButton4SpeakerFrameOn",
+ "ChannelButton4Text",
+ "ChannelButton5",
+ "ChannelButton5Collapsed",
+ "ChannelButton5NormalTexture",
+ "ChannelButton5SpeakerFrame",
+ "ChannelButton5SpeakerFrameFlash",
+ "ChannelButton5SpeakerFrameMuted",
+ "ChannelButton5SpeakerFrameOn",
+ "ChannelButton5Text",
+ "ChannelButton6",
+ "ChannelButton6Collapsed",
+ "ChannelButton6NormalTexture",
+ "ChannelButton6SpeakerFrame",
+ "ChannelButton6SpeakerFrameFlash",
+ "ChannelButton6SpeakerFrameMuted",
+ "ChannelButton6SpeakerFrameOn",
+ "ChannelButton6Text",
+ "ChannelButton7",
+ "ChannelButton7Collapsed",
+ "ChannelButton7NormalTexture",
+ "ChannelButton7SpeakerFrame",
+ "ChannelButton7SpeakerFrameFlash",
+ "ChannelButton7SpeakerFrameMuted",
+ "ChannelButton7SpeakerFrameOn",
+ "ChannelButton7Text",
+ "ChannelButton8",
+ "ChannelButton8Collapsed",
+ "ChannelButton8NormalTexture",
+ "ChannelButton8SpeakerFrame",
+ "ChannelButton8SpeakerFrameFlash",
+ "ChannelButton8SpeakerFrameMuted",
+ "ChannelButton8SpeakerFrameOn",
+ "ChannelButton8Text",
+ "ChannelButton9",
+ "ChannelButton9Collapsed",
+ "ChannelButton9NormalTexture",
+ "ChannelButton9SpeakerFrame",
+ "ChannelButton9SpeakerFrameFlash",
+ "ChannelButton9SpeakerFrameMuted",
+ "ChannelButton9SpeakerFrameOn",
+ "ChannelButton9Text",
+ "ChannelFrame",
+ "ChannelFrameAutoJoin",
+ "ChannelFrameAutoJoinBattleground",
+ "ChannelFrameAutoJoinBattlegroundText",
+ "ChannelFrameAutoJoinParty",
+ "ChannelFrameAutoJoinPartyText",
+ "ChannelFrameDaughterFrame",
+ "ChannelFrameDaughterFrameCancelButton",
+ "ChannelFrameDaughterFrameCancelButtonText",
+ "ChannelFrameDaughterFrameChannelName",
+ "ChannelFrameDaughterFrameChannelNameLabel",
+ "ChannelFrameDaughterFrameChannelNameLeft",
+ "ChannelFrameDaughterFrameChannelNameMiddle",
+ "ChannelFrameDaughterFrameChannelNameRight",
+ "ChannelFrameDaughterFrameChannelPassword",
+ "ChannelFrameDaughterFrameChannelPasswordLabel",
+ "ChannelFrameDaughterFrameChannelPasswordLeft",
+ "ChannelFrameDaughterFrameChannelPasswordMiddle",
+ "ChannelFrameDaughterFrameChannelPasswordOptional",
+ "ChannelFrameDaughterFrameChannelPasswordRight",
+ "ChannelFrameDaughterFrameCorner",
+ "ChannelFrameDaughterFrameDetailCloseButton",
+ "ChannelFrameDaughterFrameName",
+ "ChannelFrameDaughterFrameOkayButton",
+ "ChannelFrameDaughterFrameOkayButtonText",
+ "ChannelFrameDaughterFrameTitlebar",
+ "ChannelFrameDaughterFrame_Cancel",
+ "ChannelFrameDaughterFrame_Okay",
+ "ChannelFrameDaughterFrame_OnHide",
+ "ChannelFrameNewButton",
+ "ChannelFrameNewButtonText",
+ "ChannelFrameVerticalBar",
+ "ChannelFrameVerticalBarMiddle",
+ "ChannelFrameVerticalBarTop",
+ "ChannelFrame_Desaturate",
+ "ChannelFrame_Join_OnClick",
+ "ChannelFrame_New_OnClick",
+ "ChannelFrame_OnEvent",
+ "ChannelFrame_OnLoad",
+ "ChannelFrame_OnUpdate",
+ "ChannelFrame_Update",
+ "ChannelFrame_UpdateJoin",
+ "ChannelInvite",
+ "ChannelKick",
+ "ChannelListButton_OnDragStart",
+ "ChannelListButton_OnDragStop",
+ "ChannelListDropDown",
+ "ChannelListDropDownButton",
+ "ChannelListDropDownButtonDisabledTexture",
+ "ChannelListDropDownButtonHighlightTexture",
+ "ChannelListDropDownButtonNormalTexture",
+ "ChannelListDropDownButtonPushedTexture",
+ "ChannelListDropDownLeft",
+ "ChannelListDropDownMiddle",
+ "ChannelListDropDownRight",
+ "ChannelListDropDownText",
+ "ChannelListDropDown_HideDropDown",
+ "ChannelListDropDown_Initialize",
+ "ChannelListDropDown_Invite",
+ "ChannelListDropDown_SetPassword",
+ "ChannelListScrollChildFrame",
+ "ChannelListScrollFrame",
+ "ChannelListScrollFrameBottom",
+ "ChannelListScrollFrameScrollBar",
+ "ChannelListScrollFrameScrollBarScrollDownButton",
+ "ChannelListScrollFrameScrollBarScrollUpButton",
+ "ChannelListScrollFrameScrollBarThumbTexture",
+ "ChannelListScrollFrameTop",
+ "ChannelList_CountUpdate",
+ "ChannelList_OnClick",
+ "ChannelList_SetScroll",
+ "ChannelList_ShowDropdown",
+ "ChannelList_Update",
+ "ChannelList_UpdateHighlight",
+ "ChannelList_UpdateVoice",
+ "ChannelMemberButton1",
+ "ChannelMemberButton10",
+ "ChannelMemberButton10Name",
+ "ChannelMemberButton10Rank",
+ "ChannelMemberButton10RankTexture",
+ "ChannelMemberButton10SpeakerFrame",
+ "ChannelMemberButton10SpeakerFrameFlash",
+ "ChannelMemberButton10SpeakerFrameMuted",
+ "ChannelMemberButton10SpeakerFrameOn",
+ "ChannelMemberButton11",
+ "ChannelMemberButton11Name",
+ "ChannelMemberButton11Rank",
+ "ChannelMemberButton11RankTexture",
+ "ChannelMemberButton11SpeakerFrame",
+ "ChannelMemberButton11SpeakerFrameFlash",
+ "ChannelMemberButton11SpeakerFrameMuted",
+ "ChannelMemberButton11SpeakerFrameOn",
+ "ChannelMemberButton12",
+ "ChannelMemberButton12Name",
+ "ChannelMemberButton12Rank",
+ "ChannelMemberButton12RankTexture",
+ "ChannelMemberButton12SpeakerFrame",
+ "ChannelMemberButton12SpeakerFrameFlash",
+ "ChannelMemberButton12SpeakerFrameMuted",
+ "ChannelMemberButton12SpeakerFrameOn",
+ "ChannelMemberButton13",
+ "ChannelMemberButton13Name",
+ "ChannelMemberButton13Rank",
+ "ChannelMemberButton13RankTexture",
+ "ChannelMemberButton13SpeakerFrame",
+ "ChannelMemberButton13SpeakerFrameFlash",
+ "ChannelMemberButton13SpeakerFrameMuted",
+ "ChannelMemberButton13SpeakerFrameOn",
+ "ChannelMemberButton14",
+ "ChannelMemberButton14Name",
+ "ChannelMemberButton14Rank",
+ "ChannelMemberButton14RankTexture",
+ "ChannelMemberButton14SpeakerFrame",
+ "ChannelMemberButton14SpeakerFrameFlash",
+ "ChannelMemberButton14SpeakerFrameMuted",
+ "ChannelMemberButton14SpeakerFrameOn",
+ "ChannelMemberButton15",
+ "ChannelMemberButton15Name",
+ "ChannelMemberButton15Rank",
+ "ChannelMemberButton15RankTexture",
+ "ChannelMemberButton15SpeakerFrame",
+ "ChannelMemberButton15SpeakerFrameFlash",
+ "ChannelMemberButton15SpeakerFrameMuted",
+ "ChannelMemberButton15SpeakerFrameOn",
+ "ChannelMemberButton16",
+ "ChannelMemberButton16Name",
+ "ChannelMemberButton16Rank",
+ "ChannelMemberButton16RankTexture",
+ "ChannelMemberButton16SpeakerFrame",
+ "ChannelMemberButton16SpeakerFrameFlash",
+ "ChannelMemberButton16SpeakerFrameMuted",
+ "ChannelMemberButton16SpeakerFrameOn",
+ "ChannelMemberButton17",
+ "ChannelMemberButton17Name",
+ "ChannelMemberButton17Rank",
+ "ChannelMemberButton17RankTexture",
+ "ChannelMemberButton17SpeakerFrame",
+ "ChannelMemberButton17SpeakerFrameFlash",
+ "ChannelMemberButton17SpeakerFrameMuted",
+ "ChannelMemberButton17SpeakerFrameOn",
+ "ChannelMemberButton18",
+ "ChannelMemberButton18Name",
+ "ChannelMemberButton18Rank",
+ "ChannelMemberButton18RankTexture",
+ "ChannelMemberButton18SpeakerFrame",
+ "ChannelMemberButton18SpeakerFrameFlash",
+ "ChannelMemberButton18SpeakerFrameMuted",
+ "ChannelMemberButton18SpeakerFrameOn",
+ "ChannelMemberButton19",
+ "ChannelMemberButton19Name",
+ "ChannelMemberButton19Rank",
+ "ChannelMemberButton19RankTexture",
+ "ChannelMemberButton19SpeakerFrame",
+ "ChannelMemberButton19SpeakerFrameFlash",
+ "ChannelMemberButton19SpeakerFrameMuted",
+ "ChannelMemberButton19SpeakerFrameOn",
+ "ChannelMemberButton1Name",
+ "ChannelMemberButton1Rank",
+ "ChannelMemberButton1RankTexture",
+ "ChannelMemberButton1SpeakerFrame",
+ "ChannelMemberButton1SpeakerFrameFlash",
+ "ChannelMemberButton1SpeakerFrameMuted",
+ "ChannelMemberButton1SpeakerFrameOn",
+ "ChannelMemberButton2",
+ "ChannelMemberButton20",
+ "ChannelMemberButton20Name",
+ "ChannelMemberButton20Rank",
+ "ChannelMemberButton20RankTexture",
+ "ChannelMemberButton20SpeakerFrame",
+ "ChannelMemberButton20SpeakerFrameFlash",
+ "ChannelMemberButton20SpeakerFrameMuted",
+ "ChannelMemberButton20SpeakerFrameOn",
+ "ChannelMemberButton21",
+ "ChannelMemberButton21Name",
+ "ChannelMemberButton21Rank",
+ "ChannelMemberButton21RankTexture",
+ "ChannelMemberButton21SpeakerFrame",
+ "ChannelMemberButton21SpeakerFrameFlash",
+ "ChannelMemberButton21SpeakerFrameMuted",
+ "ChannelMemberButton21SpeakerFrameOn",
+ "ChannelMemberButton22",
+ "ChannelMemberButton22Name",
+ "ChannelMemberButton22Rank",
+ "ChannelMemberButton22RankTexture",
+ "ChannelMemberButton22SpeakerFrame",
+ "ChannelMemberButton22SpeakerFrameFlash",
+ "ChannelMemberButton22SpeakerFrameMuted",
+ "ChannelMemberButton22SpeakerFrameOn",
+ "ChannelMemberButton2Name",
+ "ChannelMemberButton2Rank",
+ "ChannelMemberButton2RankTexture",
+ "ChannelMemberButton2SpeakerFrame",
+ "ChannelMemberButton2SpeakerFrameFlash",
+ "ChannelMemberButton2SpeakerFrameMuted",
+ "ChannelMemberButton2SpeakerFrameOn",
+ "ChannelMemberButton3",
+ "ChannelMemberButton3Name",
+ "ChannelMemberButton3Rank",
+ "ChannelMemberButton3RankTexture",
+ "ChannelMemberButton3SpeakerFrame",
+ "ChannelMemberButton3SpeakerFrameFlash",
+ "ChannelMemberButton3SpeakerFrameMuted",
+ "ChannelMemberButton3SpeakerFrameOn",
+ "ChannelMemberButton4",
+ "ChannelMemberButton4Name",
+ "ChannelMemberButton4Rank",
+ "ChannelMemberButton4RankTexture",
+ "ChannelMemberButton4SpeakerFrame",
+ "ChannelMemberButton4SpeakerFrameFlash",
+ "ChannelMemberButton4SpeakerFrameMuted",
+ "ChannelMemberButton4SpeakerFrameOn",
+ "ChannelMemberButton5",
+ "ChannelMemberButton5Name",
+ "ChannelMemberButton5Rank",
+ "ChannelMemberButton5RankTexture",
+ "ChannelMemberButton5SpeakerFrame",
+ "ChannelMemberButton5SpeakerFrameFlash",
+ "ChannelMemberButton5SpeakerFrameMuted",
+ "ChannelMemberButton5SpeakerFrameOn",
+ "ChannelMemberButton6",
+ "ChannelMemberButton6Name",
+ "ChannelMemberButton6Rank",
+ "ChannelMemberButton6RankTexture",
+ "ChannelMemberButton6SpeakerFrame",
+ "ChannelMemberButton6SpeakerFrameFlash",
+ "ChannelMemberButton6SpeakerFrameMuted",
+ "ChannelMemberButton6SpeakerFrameOn",
+ "ChannelMemberButton7",
+ "ChannelMemberButton7Name",
+ "ChannelMemberButton7Rank",
+ "ChannelMemberButton7RankTexture",
+ "ChannelMemberButton7SpeakerFrame",
+ "ChannelMemberButton7SpeakerFrameFlash",
+ "ChannelMemberButton7SpeakerFrameMuted",
+ "ChannelMemberButton7SpeakerFrameOn",
+ "ChannelMemberButton8",
+ "ChannelMemberButton8Name",
+ "ChannelMemberButton8Rank",
+ "ChannelMemberButton8RankTexture",
+ "ChannelMemberButton8SpeakerFrame",
+ "ChannelMemberButton8SpeakerFrameFlash",
+ "ChannelMemberButton8SpeakerFrameMuted",
+ "ChannelMemberButton8SpeakerFrameOn",
+ "ChannelMemberButton9",
+ "ChannelMemberButton9Name",
+ "ChannelMemberButton9Rank",
+ "ChannelMemberButton9RankTexture",
+ "ChannelMemberButton9SpeakerFrame",
+ "ChannelMemberButton9SpeakerFrameFlash",
+ "ChannelMemberButton9SpeakerFrameMuted",
+ "ChannelMemberButton9SpeakerFrameOn",
+ "ChannelMenuChatTypeGroups",
+ "ChannelModerator",
+ "ChannelMute",
+ "ChannelPullout",
+ "ChannelPulloutBackground",
+ "ChannelPulloutCloseButton",
+ "ChannelPulloutRoster",
+ "ChannelPulloutRosterButton1",
+ "ChannelPulloutRosterButton1Name",
+ "ChannelPulloutRosterButton1Speaker",
+ "ChannelPulloutRosterButton1SpeakerFlash",
+ "ChannelPulloutRosterButton1SpeakerMuted",
+ "ChannelPulloutRosterButton1SpeakerOn",
+ "ChannelPulloutRosterButton2",
+ "ChannelPulloutRosterButton2Name",
+ "ChannelPulloutRosterButton2Speaker",
+ "ChannelPulloutRosterButton2SpeakerFlash",
+ "ChannelPulloutRosterButton2SpeakerMuted",
+ "ChannelPulloutRosterButton2SpeakerOn",
+ "ChannelPulloutRosterButton3",
+ "ChannelPulloutRosterButton3Name",
+ "ChannelPulloutRosterButton3Speaker",
+ "ChannelPulloutRosterButton3SpeakerFlash",
+ "ChannelPulloutRosterButton3SpeakerMuted",
+ "ChannelPulloutRosterButton3SpeakerOn",
+ "ChannelPulloutRosterButton4",
+ "ChannelPulloutRosterButton4Name",
+ "ChannelPulloutRosterButton4Speaker",
+ "ChannelPulloutRosterButton4SpeakerFlash",
+ "ChannelPulloutRosterButton4SpeakerMuted",
+ "ChannelPulloutRosterButton4SpeakerOn",
+ "ChannelPulloutRosterButton5",
+ "ChannelPulloutRosterButton5Name",
+ "ChannelPulloutRosterButton5Speaker",
+ "ChannelPulloutRosterButton5SpeakerFlash",
+ "ChannelPulloutRosterButton5SpeakerMuted",
+ "ChannelPulloutRosterButton5SpeakerOn",
+ "ChannelPulloutRosterButton_OnEvent",
+ "ChannelPulloutRosterScroll",
+ "ChannelPulloutRosterScrollDownBtn",
+ "ChannelPulloutRosterScrollUpBtn",
+ "ChannelPulloutRoster_DrawButton",
+ "ChannelPulloutRoster_GetActiveSession",
+ "ChannelPulloutRoster_GetSessionIDByName",
+ "ChannelPulloutRoster_GetSessionInfo",
+ "ChannelPulloutRoster_OnEvent",
+ "ChannelPulloutRoster_OnLoad",
+ "ChannelPulloutRoster_Populate",
+ "ChannelPulloutRoster_Scroll",
+ "ChannelPulloutRoster_ScrollToBottom",
+ "ChannelPulloutRoster_ScrollToTop",
+ "ChannelPulloutRoster_Sort",
+ "ChannelPulloutRoster_Update",
+ "ChannelPulloutRoster_UpdateScrollControls",
+ "ChannelPulloutTab",
+ "ChannelPulloutTabDropDown",
+ "ChannelPulloutTabDropDownButton",
+ "ChannelPulloutTabDropDownButtonDisabledTexture",
+ "ChannelPulloutTabDropDownButtonHighlightTexture",
+ "ChannelPulloutTabDropDownButtonNormalTexture",
+ "ChannelPulloutTabDropDownButtonPushedTexture",
+ "ChannelPulloutTabDropDownLeft",
+ "ChannelPulloutTabDropDownMiddle",
+ "ChannelPulloutTabDropDownRight",
+ "ChannelPulloutTabDropDownText",
+ "ChannelPulloutTabDropDown_Initialize",
+ "ChannelPulloutTabFlash",
+ "ChannelPulloutTabLeft",
+ "ChannelPulloutTabMiddle",
+ "ChannelPulloutTabRight",
+ "ChannelPulloutTabText",
+ "ChannelPulloutTab_OnClick",
+ "ChannelPulloutTab_ReanchorLeft",
+ "ChannelPulloutTab_UpdateText",
+ "ChannelPullout_OnEvent",
+ "ChannelPullout_OnLoad",
+ "ChannelPullout_OnUpdate",
+ "ChannelPullout_SaveOpacity",
+ "ChannelPullout_SetOpacity",
+ "ChannelPullout_ShowOpacity",
+ "ChannelPullout_ToggleDisplay",
+ "ChannelRoster",
+ "ChannelRosterChannelCount",
+ "ChannelRosterChannelName",
+ "ChannelRosterDropDown",
+ "ChannelRosterDropDownButton",
+ "ChannelRosterDropDownButtonDisabledTexture",
+ "ChannelRosterDropDownButtonHighlightTexture",
+ "ChannelRosterDropDownButtonNormalTexture",
+ "ChannelRosterDropDownButtonPushedTexture",
+ "ChannelRosterDropDownLeft",
+ "ChannelRosterDropDownMiddle",
+ "ChannelRosterDropDownRight",
+ "ChannelRosterDropDownText",
+ "ChannelRosterDropDown_Initialize",
+ "ChannelRosterFrame_ShowDropdown",
+ "ChannelRosterHiddenText",
+ "ChannelRosterScrollFrame",
+ "ChannelRosterScrollFrameBottom",
+ "ChannelRosterScrollFrameScrollBar",
+ "ChannelRosterScrollFrameScrollBarScrollDownButton",
+ "ChannelRosterScrollFrameScrollBarScrollUpButton",
+ "ChannelRosterScrollFrameScrollBarThumbTexture",
+ "ChannelRosterScrollFrameScrollChildFrame",
+ "ChannelRosterScrollFrameTop",
+ "ChannelRoster_OnClick",
+ "ChannelRoster_SetScroll",
+ "ChannelRoster_Update",
+ "ChannelRoster_UpdateVoice",
+ "ChannelSilenceAll",
+ "ChannelSilenceVoice",
+ "ChannelToggleAnnouncements",
+ "ChannelUnSilenceAll",
+ "ChannelUnSilenceVoice",
+ "ChannelUnban",
+ "ChannelUnmoderator",
+ "ChannelUnmute",
+ "ChannelVoiceOff",
+ "ChannelVoiceOn",
+ "CharacterAmmoSlot",
+ "CharacterAmmoSlotCooldown",
+ "CharacterAmmoSlotCount",
+ "CharacterAmmoSlotIconTexture",
+ "CharacterAmmoSlotNormalTexture",
+ "CharacterAmmoSlotStock",
+ "CharacterAttackFrame_OnEnter",
+ "CharacterAttributesFrame",
+ "CharacterBackSlot",
+ "CharacterBackSlotCooldown",
+ "CharacterBackSlotCount",
+ "CharacterBackSlotIconTexture",
+ "CharacterBackSlotNormalTexture",
+ "CharacterBackSlotPopoutButton",
+ "CharacterBackSlotStock",
+ "CharacterBag0Slot",
+ "CharacterBag0SlotCount",
+ "CharacterBag0SlotIconTexture",
+ "CharacterBag0SlotItemAnim",
+ "CharacterBag0SlotNormalTexture",
+ "CharacterBag0SlotStock",
+ "CharacterBag1Slot",
+ "CharacterBag1SlotCount",
+ "CharacterBag1SlotIconTexture",
+ "CharacterBag1SlotItemAnim",
+ "CharacterBag1SlotNormalTexture",
+ "CharacterBag1SlotStock",
+ "CharacterBag2Slot",
+ "CharacterBag2SlotCount",
+ "CharacterBag2SlotIconTexture",
+ "CharacterBag2SlotItemAnim",
+ "CharacterBag2SlotNormalTexture",
+ "CharacterBag2SlotStock",
+ "CharacterBag3Slot",
+ "CharacterBag3SlotCount",
+ "CharacterBag3SlotIconTexture",
+ "CharacterBag3SlotItemAnim",
+ "CharacterBag3SlotNormalTexture",
+ "CharacterBag3SlotStock",
+ "CharacterChestSlot",
+ "CharacterChestSlotCooldown",
+ "CharacterChestSlotCount",
+ "CharacterChestSlotIconTexture",
+ "CharacterChestSlotNormalTexture",
+ "CharacterChestSlotPopoutButton",
+ "CharacterChestSlotStock",
+ "CharacterDamageFrame_OnEnter",
+ "CharacterFeetSlot",
+ "CharacterFeetSlotCooldown",
+ "CharacterFeetSlotCount",
+ "CharacterFeetSlotIconTexture",
+ "CharacterFeetSlotNormalTexture",
+ "CharacterFeetSlotPopoutButton",
+ "CharacterFeetSlotStock",
+ "CharacterFinger0Slot",
+ "CharacterFinger0SlotCooldown",
+ "CharacterFinger0SlotCount",
+ "CharacterFinger0SlotIconTexture",
+ "CharacterFinger0SlotNormalTexture",
+ "CharacterFinger0SlotPopoutButton",
+ "CharacterFinger0SlotStock",
+ "CharacterFinger1Slot",
+ "CharacterFinger1SlotCooldown",
+ "CharacterFinger1SlotCount",
+ "CharacterFinger1SlotIconTexture",
+ "CharacterFinger1SlotNormalTexture",
+ "CharacterFinger1SlotPopoutButton",
+ "CharacterFinger1SlotStock",
+ "CharacterFrame",
+ "CharacterFrameCloseButton",
+ "CharacterFramePortrait",
+ "CharacterFrameTab1",
+ "CharacterFrameTab1HighlightTexture",
+ "CharacterFrameTab1Left",
+ "CharacterFrameTab1LeftDisabled",
+ "CharacterFrameTab1Middle",
+ "CharacterFrameTab1MiddleDisabled",
+ "CharacterFrameTab1Right",
+ "CharacterFrameTab1RightDisabled",
+ "CharacterFrameTab1Text",
+ "CharacterFrameTab2",
+ "CharacterFrameTab2HighlightTexture",
+ "CharacterFrameTab2Left",
+ "CharacterFrameTab2LeftDisabled",
+ "CharacterFrameTab2Middle",
+ "CharacterFrameTab2MiddleDisabled",
+ "CharacterFrameTab2Right",
+ "CharacterFrameTab2RightDisabled",
+ "CharacterFrameTab2Text",
+ "CharacterFrameTab3",
+ "CharacterFrameTab3HighlightTexture",
+ "CharacterFrameTab3Left",
+ "CharacterFrameTab3LeftDisabled",
+ "CharacterFrameTab3Middle",
+ "CharacterFrameTab3MiddleDisabled",
+ "CharacterFrameTab3Right",
+ "CharacterFrameTab3RightDisabled",
+ "CharacterFrameTab3Text",
+ "CharacterFrameTab4",
+ "CharacterFrameTab4HighlightTexture",
+ "CharacterFrameTab4Left",
+ "CharacterFrameTab4LeftDisabled",
+ "CharacterFrameTab4Middle",
+ "CharacterFrameTab4MiddleDisabled",
+ "CharacterFrameTab4Right",
+ "CharacterFrameTab4RightDisabled",
+ "CharacterFrameTab4Text",
+ "CharacterFrameTab5",
+ "CharacterFrameTab5HighlightTexture",
+ "CharacterFrameTab5Left",
+ "CharacterFrameTab5LeftDisabled",
+ "CharacterFrameTab5Middle",
+ "CharacterFrameTab5MiddleDisabled",
+ "CharacterFrameTab5Right",
+ "CharacterFrameTab5RightDisabled",
+ "CharacterFrameTab5Text",
+ "CharacterFrameTab_OnClick",
+ "CharacterFrame_OnEvent",
+ "CharacterFrame_OnHide",
+ "CharacterFrame_OnLoad",
+ "CharacterFrame_OnShow",
+ "CharacterFrame_ShowSubFrame",
+ "CharacterFrame_TabBoundsCheck",
+ "CharacterGuildText",
+ "CharacterHandsSlot",
+ "CharacterHandsSlotCooldown",
+ "CharacterHandsSlotCount",
+ "CharacterHandsSlotIconTexture",
+ "CharacterHandsSlotNormalTexture",
+ "CharacterHandsSlotPopoutButton",
+ "CharacterHandsSlotStock",
+ "CharacterHeadSlot",
+ "CharacterHeadSlotCooldown",
+ "CharacterHeadSlotCount",
+ "CharacterHeadSlotIconTexture",
+ "CharacterHeadSlotNormalTexture",
+ "CharacterHeadSlotPopoutButton",
+ "CharacterHeadSlotStock",
+ "CharacterLegsSlot",
+ "CharacterLegsSlotCooldown",
+ "CharacterLegsSlotCount",
+ "CharacterLegsSlotIconTexture",
+ "CharacterLegsSlotNormalTexture",
+ "CharacterLegsSlotPopoutButton",
+ "CharacterLegsSlotStock",
+ "CharacterLevelText",
+ "CharacterMainHandSlot",
+ "CharacterMainHandSlotCooldown",
+ "CharacterMainHandSlotCount",
+ "CharacterMainHandSlotIconTexture",
+ "CharacterMainHandSlotNormalTexture",
+ "CharacterMainHandSlotPopoutButton",
+ "CharacterMainHandSlotStock",
+ "CharacterMicroButton",
+ "CharacterMicroButton_OnEvent",
+ "CharacterMicroButton_OnLoad",
+ "CharacterMicroButton_SetNormal",
+ "CharacterMicroButton_SetPushed",
+ "CharacterModelFrame",
+ "CharacterModelFrameRotateLeftButton",
+ "CharacterModelFrameRotateRightButton",
+ "CharacterModelFrame_OnMouseUp",
+ "CharacterNameFrame",
+ "CharacterNameText",
+ "CharacterNeckSlot",
+ "CharacterNeckSlotCooldown",
+ "CharacterNeckSlotCount",
+ "CharacterNeckSlotIconTexture",
+ "CharacterNeckSlotNormalTexture",
+ "CharacterNeckSlotPopoutButton",
+ "CharacterNeckSlotStock",
+ "CharacterRangedDamageFrame_OnEnter",
+ "CharacterRangedSlot",
+ "CharacterRangedSlotCooldown",
+ "CharacterRangedSlotCount",
+ "CharacterRangedSlotIconTexture",
+ "CharacterRangedSlotNormalTexture",
+ "CharacterRangedSlotPopoutButton",
+ "CharacterRangedSlotStock",
+ "CharacterResistanceFrame",
+ "CharacterSecondaryHandSlot",
+ "CharacterSecondaryHandSlotCooldown",
+ "CharacterSecondaryHandSlotCount",
+ "CharacterSecondaryHandSlotIconTexture",
+ "CharacterSecondaryHandSlotNormalTexture",
+ "CharacterSecondaryHandSlotPopoutButton",
+ "CharacterSecondaryHandSlotStock",
+ "CharacterShirtSlot",
+ "CharacterShirtSlotCooldown",
+ "CharacterShirtSlotCount",
+ "CharacterShirtSlotIconTexture",
+ "CharacterShirtSlotNormalTexture",
+ "CharacterShirtSlotPopoutButton",
+ "CharacterShirtSlotStock",
+ "CharacterShoulderSlot",
+ "CharacterShoulderSlotCooldown",
+ "CharacterShoulderSlotCount",
+ "CharacterShoulderSlotIconTexture",
+ "CharacterShoulderSlotNormalTexture",
+ "CharacterShoulderSlotPopoutButton",
+ "CharacterShoulderSlotStock",
+ "CharacterSpellBonusDamage_OnEnter",
+ "CharacterSpellCritChance_OnEnter",
+ "CharacterTabardSlot",
+ "CharacterTabardSlotCooldown",
+ "CharacterTabardSlotCount",
+ "CharacterTabardSlotIconTexture",
+ "CharacterTabardSlotNormalTexture",
+ "CharacterTabardSlotPopoutButton",
+ "CharacterTabardSlotStock",
+ "CharacterTitleText",
+ "CharacterTrinket0Slot",
+ "CharacterTrinket0SlotCooldown",
+ "CharacterTrinket0SlotCount",
+ "CharacterTrinket0SlotIconTexture",
+ "CharacterTrinket0SlotNormalTexture",
+ "CharacterTrinket0SlotPopoutButton",
+ "CharacterTrinket0SlotStock",
+ "CharacterTrinket1Slot",
+ "CharacterTrinket1SlotCooldown",
+ "CharacterTrinket1SlotCount",
+ "CharacterTrinket1SlotIconTexture",
+ "CharacterTrinket1SlotNormalTexture",
+ "CharacterTrinket1SlotPopoutButton",
+ "CharacterTrinket1SlotStock",
+ "CharacterWaistSlot",
+ "CharacterWaistSlotCooldown",
+ "CharacterWaistSlotCount",
+ "CharacterWaistSlotIconTexture",
+ "CharacterWaistSlotNormalTexture",
+ "CharacterWaistSlotPopoutButton",
+ "CharacterWaistSlotStock",
+ "CharacterWristSlot",
+ "CharacterWristSlotCooldown",
+ "CharacterWristSlotCount",
+ "CharacterWristSlotIconTexture",
+ "CharacterWristSlotNormalTexture",
+ "CharacterWristSlotPopoutButton",
+ "CharacterWristSlotStock",
+ "ChatBNPlayerDropDown",
+ "ChatBNPlayerDropDownButton",
+ "ChatBNPlayerDropDownButtonDisabledTexture",
+ "ChatBNPlayerDropDownButtonHighlightTexture",
+ "ChatBNPlayerDropDownButtonNormalTexture",
+ "ChatBNPlayerDropDownButtonPushedTexture",
+ "ChatBNPlayerDropDownLeft",
+ "ChatBNPlayerDropDownMiddle",
+ "ChatBNPlayerDropDownRight",
+ "ChatBNPlayerDropDownText",
+ "ChatChannelDropDown",
+ "ChatChannelDropDownButton",
+ "ChatChannelDropDownButtonDisabledTexture",
+ "ChatChannelDropDownButtonHighlightTexture",
+ "ChatChannelDropDownButtonNormalTexture",
+ "ChatChannelDropDownButtonPushedTexture",
+ "ChatChannelDropDownLeft",
+ "ChatChannelDropDownMiddle",
+ "ChatChannelDropDownRight",
+ "ChatChannelDropDownText",
+ "ChatChannelDropDown_Initialize",
+ "ChatChannelDropDown_InviteToConversation",
+ "ChatChannelDropDown_LeaveConversation",
+ "ChatChannelDropDown_PopInChat",
+ "ChatChannelDropDown_PopOutChat",
+ "ChatChannelDropDown_Show",
+ "ChatChannelPasswordHandler",
+ "ChatConfigBackgroundFrame",
+ "ChatConfigCancel_OnClick",
+ "ChatConfigCategoryFrame",
+ "ChatConfigCategoryFrameButton1",
+ "ChatConfigCategoryFrameButton1Highlight",
+ "ChatConfigCategoryFrameButton1NormalText",
+ "ChatConfigCategoryFrameButton2",
+ "ChatConfigCategoryFrameButton2Highlight",
+ "ChatConfigCategoryFrameButton2NormalText",
+ "ChatConfigCategoryFrameButton3",
+ "ChatConfigCategoryFrameButton3Highlight",
+ "ChatConfigCategoryFrameButton3NormalText",
+ "ChatConfigCategoryFrameButton4",
+ "ChatConfigCategoryFrameButton4Highlight",
+ "ChatConfigCategoryFrameButton4NormalText",
+ "ChatConfigCategoryFrameTitle",
+ "ChatConfigCategory_OnClick",
+ "ChatConfigChannelSettings",
+ "ChatConfigChannelSettingsClassColorLegend",
+ "ChatConfigChannelSettingsClassColorLegendTitle",
+ "ChatConfigChannelSettingsLeft",
+ "ChatConfigChannelSettingsLeftClassColorHeader",
+ "ChatConfigChannelSettingsLeftColorHeader",
+ "ChatConfigChannelSettingsLeftTitle",
+ "ChatConfigChatSettings",
+ "ChatConfigChatSettingsClassColorLegend",
+ "ChatConfigChatSettingsClassColorLegendTitle",
+ "ChatConfigChatSettingsLeft",
+ "ChatConfigChatSettingsLeftCheckBox1",
+ "ChatConfigChatSettingsLeftCheckBox10",
+ "ChatConfigChatSettingsLeftCheckBox10Check",
+ "ChatConfigChatSettingsLeftCheckBox10CheckText",
+ "ChatConfigChatSettingsLeftCheckBox10ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox10ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox10ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox10ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox11",
+ "ChatConfigChatSettingsLeftCheckBox11Check",
+ "ChatConfigChatSettingsLeftCheckBox11CheckText",
+ "ChatConfigChatSettingsLeftCheckBox11ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox11ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox11ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox11ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox12",
+ "ChatConfigChatSettingsLeftCheckBox12Check",
+ "ChatConfigChatSettingsLeftCheckBox12CheckText",
+ "ChatConfigChatSettingsLeftCheckBox12ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox12ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox12ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox12ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox13",
+ "ChatConfigChatSettingsLeftCheckBox13Check",
+ "ChatConfigChatSettingsLeftCheckBox13CheckText",
+ "ChatConfigChatSettingsLeftCheckBox13ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox13ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox13ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox13ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox14",
+ "ChatConfigChatSettingsLeftCheckBox14Check",
+ "ChatConfigChatSettingsLeftCheckBox14CheckText",
+ "ChatConfigChatSettingsLeftCheckBox14ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox14ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox14ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox14ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox15",
+ "ChatConfigChatSettingsLeftCheckBox15Check",
+ "ChatConfigChatSettingsLeftCheckBox15CheckText",
+ "ChatConfigChatSettingsLeftCheckBox15ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox15ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox15ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox15ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox16",
+ "ChatConfigChatSettingsLeftCheckBox16Check",
+ "ChatConfigChatSettingsLeftCheckBox16CheckText",
+ "ChatConfigChatSettingsLeftCheckBox16ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox16ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox16ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox16ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox17",
+ "ChatConfigChatSettingsLeftCheckBox17Check",
+ "ChatConfigChatSettingsLeftCheckBox17CheckText",
+ "ChatConfigChatSettingsLeftCheckBox17ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox17ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox17ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox17ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox1Check",
+ "ChatConfigChatSettingsLeftCheckBox1CheckText",
+ "ChatConfigChatSettingsLeftCheckBox1ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox1ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox1ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox1ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox2",
+ "ChatConfigChatSettingsLeftCheckBox2Check",
+ "ChatConfigChatSettingsLeftCheckBox2CheckText",
+ "ChatConfigChatSettingsLeftCheckBox2ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox2ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox2ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox2ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox3",
+ "ChatConfigChatSettingsLeftCheckBox3Check",
+ "ChatConfigChatSettingsLeftCheckBox3CheckText",
+ "ChatConfigChatSettingsLeftCheckBox3ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox3ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox3ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox3ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox4",
+ "ChatConfigChatSettingsLeftCheckBox4Check",
+ "ChatConfigChatSettingsLeftCheckBox4CheckText",
+ "ChatConfigChatSettingsLeftCheckBox4ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox4ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox4ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox4ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox5",
+ "ChatConfigChatSettingsLeftCheckBox5Check",
+ "ChatConfigChatSettingsLeftCheckBox5CheckText",
+ "ChatConfigChatSettingsLeftCheckBox5ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox5ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox5ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox5ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox6",
+ "ChatConfigChatSettingsLeftCheckBox6Check",
+ "ChatConfigChatSettingsLeftCheckBox6CheckText",
+ "ChatConfigChatSettingsLeftCheckBox6ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox6ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox6ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox6ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox7",
+ "ChatConfigChatSettingsLeftCheckBox7Check",
+ "ChatConfigChatSettingsLeftCheckBox7CheckText",
+ "ChatConfigChatSettingsLeftCheckBox7ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox7ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox7ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox7ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox8",
+ "ChatConfigChatSettingsLeftCheckBox8Check",
+ "ChatConfigChatSettingsLeftCheckBox8CheckText",
+ "ChatConfigChatSettingsLeftCheckBox8ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox8ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox8ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox8ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftCheckBox9",
+ "ChatConfigChatSettingsLeftCheckBox9Check",
+ "ChatConfigChatSettingsLeftCheckBox9CheckText",
+ "ChatConfigChatSettingsLeftCheckBox9ColorClasses",
+ "ChatConfigChatSettingsLeftCheckBox9ColorSwatch",
+ "ChatConfigChatSettingsLeftCheckBox9ColorSwatchNormalTexture",
+ "ChatConfigChatSettingsLeftCheckBox9ColorSwatchSwatchBg",
+ "ChatConfigChatSettingsLeftClassColorHeader",
+ "ChatConfigChatSettingsLeftColorHeader",
+ "ChatConfigChatSettingsLeftTitle",
+ "ChatConfigCombatSettings",
+ "ChatConfigCombatSettingsFilters",
+ "ChatConfigCombatSettingsFiltersAddFilterButton",
+ "ChatConfigCombatSettingsFiltersAddFilterButtonText",
+ "ChatConfigCombatSettingsFiltersButton1",
+ "ChatConfigCombatSettingsFiltersButton1Highlight",
+ "ChatConfigCombatSettingsFiltersButton1NormalText",
+ "ChatConfigCombatSettingsFiltersButton2",
+ "ChatConfigCombatSettingsFiltersButton2Highlight",
+ "ChatConfigCombatSettingsFiltersButton2NormalText",
+ "ChatConfigCombatSettingsFiltersButton3",
+ "ChatConfigCombatSettingsFiltersButton3Highlight",
+ "ChatConfigCombatSettingsFiltersButton3NormalText",
+ "ChatConfigCombatSettingsFiltersButton4",
+ "ChatConfigCombatSettingsFiltersButton4Highlight",
+ "ChatConfigCombatSettingsFiltersButton4NormalText",
+ "ChatConfigCombatSettingsFiltersCopyFilterButton",
+ "ChatConfigCombatSettingsFiltersCopyFilterButtonText",
+ "ChatConfigCombatSettingsFiltersDeleteButton",
+ "ChatConfigCombatSettingsFiltersDeleteButtonText",
+ "ChatConfigCombatSettingsFiltersScrollFrame",
+ "ChatConfigCombatSettingsFiltersScrollFrameScrollBar",
+ "ChatConfigCombatSettingsFiltersScrollFrameScrollBarBorder",
+ "ChatConfigCombatSettingsFiltersScrollFrameScrollBarScrollDownButton",
+ "ChatConfigCombatSettingsFiltersScrollFrameScrollBarScrollUpButton",
+ "ChatConfigCombatSettingsFiltersScrollFrameScrollBarThumbTexture",
+ "ChatConfigCombatSettingsFiltersScrollFrameScrollChildFrame",
+ "ChatConfigCombat_OnLoad",
+ "ChatConfigFilter_OnClick",
+ "ChatConfigFrame",
+ "ChatConfigFrameCancelButton",
+ "ChatConfigFrameCancelButtonText",
+ "ChatConfigFrameDefaultButton",
+ "ChatConfigFrameHeader",
+ "ChatConfigFrameHeaderText",
+ "ChatConfigFrameOkayButton",
+ "ChatConfigFrameOkayButtonText",
+ "ChatConfigFrame_OnEvent",
+ "ChatConfigFrame_OnLoad",
+ "ChatConfigFrame_PlayCheckboxSound",
+ "ChatConfigMoveFilterDownButton",
+ "ChatConfigMoveFilterUpButton",
+ "ChatConfigOtherSettings",
+ "ChatConfigOtherSettingsCombat",
+ "ChatConfigOtherSettingsCombatCheckBox1",
+ "ChatConfigOtherSettingsCombatCheckBox10",
+ "ChatConfigOtherSettingsCombatCheckBox10Check",
+ "ChatConfigOtherSettingsCombatCheckBox10CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox10ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox10ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox10ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox1Check",
+ "ChatConfigOtherSettingsCombatCheckBox1CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox1ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox1ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox1ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox2",
+ "ChatConfigOtherSettingsCombatCheckBox2Check",
+ "ChatConfigOtherSettingsCombatCheckBox2CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox2ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox2ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox2ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox3",
+ "ChatConfigOtherSettingsCombatCheckBox3Check",
+ "ChatConfigOtherSettingsCombatCheckBox3CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox3ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox3ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox3ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox4",
+ "ChatConfigOtherSettingsCombatCheckBox4Check",
+ "ChatConfigOtherSettingsCombatCheckBox4CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox4ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox4ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox4ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox5",
+ "ChatConfigOtherSettingsCombatCheckBox5Check",
+ "ChatConfigOtherSettingsCombatCheckBox5CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox5ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox5ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox5ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox6",
+ "ChatConfigOtherSettingsCombatCheckBox6Check",
+ "ChatConfigOtherSettingsCombatCheckBox6CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox6ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox6ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox6ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox7",
+ "ChatConfigOtherSettingsCombatCheckBox7Check",
+ "ChatConfigOtherSettingsCombatCheckBox7CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox7ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox7ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox7ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox8",
+ "ChatConfigOtherSettingsCombatCheckBox8Check",
+ "ChatConfigOtherSettingsCombatCheckBox8CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox8ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox8ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox8ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatCheckBox9",
+ "ChatConfigOtherSettingsCombatCheckBox9Check",
+ "ChatConfigOtherSettingsCombatCheckBox9CheckText",
+ "ChatConfigOtherSettingsCombatCheckBox9ColorSwatch",
+ "ChatConfigOtherSettingsCombatCheckBox9ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCombatCheckBox9ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCombatTitle",
+ "ChatConfigOtherSettingsCreature",
+ "ChatConfigOtherSettingsCreatureCheckBox1",
+ "ChatConfigOtherSettingsCreatureCheckBox1Check",
+ "ChatConfigOtherSettingsCreatureCheckBox1CheckText",
+ "ChatConfigOtherSettingsCreatureCheckBox1ColorSwatch",
+ "ChatConfigOtherSettingsCreatureCheckBox1ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCreatureCheckBox1ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCreatureCheckBox2",
+ "ChatConfigOtherSettingsCreatureCheckBox2Check",
+ "ChatConfigOtherSettingsCreatureCheckBox2CheckText",
+ "ChatConfigOtherSettingsCreatureCheckBox2ColorSwatch",
+ "ChatConfigOtherSettingsCreatureCheckBox2ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCreatureCheckBox2ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCreatureCheckBox3",
+ "ChatConfigOtherSettingsCreatureCheckBox3Check",
+ "ChatConfigOtherSettingsCreatureCheckBox3CheckText",
+ "ChatConfigOtherSettingsCreatureCheckBox3ColorSwatch",
+ "ChatConfigOtherSettingsCreatureCheckBox3ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCreatureCheckBox3ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCreatureCheckBox4",
+ "ChatConfigOtherSettingsCreatureCheckBox4Check",
+ "ChatConfigOtherSettingsCreatureCheckBox4CheckText",
+ "ChatConfigOtherSettingsCreatureCheckBox4ColorSwatch",
+ "ChatConfigOtherSettingsCreatureCheckBox4ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCreatureCheckBox4ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCreatureCheckBox5",
+ "ChatConfigOtherSettingsCreatureCheckBox5Check",
+ "ChatConfigOtherSettingsCreatureCheckBox5CheckText",
+ "ChatConfigOtherSettingsCreatureCheckBox5ColorSwatch",
+ "ChatConfigOtherSettingsCreatureCheckBox5ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCreatureCheckBox5ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCreatureCheckBox6",
+ "ChatConfigOtherSettingsCreatureCheckBox6Check",
+ "ChatConfigOtherSettingsCreatureCheckBox6CheckText",
+ "ChatConfigOtherSettingsCreatureCheckBox6ColorSwatch",
+ "ChatConfigOtherSettingsCreatureCheckBox6ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsCreatureCheckBox6ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsCreatureTitle",
+ "ChatConfigOtherSettingsPVP",
+ "ChatConfigOtherSettingsPVPCheckBox1",
+ "ChatConfigOtherSettingsPVPCheckBox1Check",
+ "ChatConfigOtherSettingsPVPCheckBox1CheckText",
+ "ChatConfigOtherSettingsPVPCheckBox1ColorSwatch",
+ "ChatConfigOtherSettingsPVPCheckBox1ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsPVPCheckBox1ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsPVPCheckBox2",
+ "ChatConfigOtherSettingsPVPCheckBox2Check",
+ "ChatConfigOtherSettingsPVPCheckBox2CheckText",
+ "ChatConfigOtherSettingsPVPCheckBox2ColorSwatch",
+ "ChatConfigOtherSettingsPVPCheckBox2ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsPVPCheckBox2ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsPVPCheckBox3",
+ "ChatConfigOtherSettingsPVPCheckBox3Check",
+ "ChatConfigOtherSettingsPVPCheckBox3CheckText",
+ "ChatConfigOtherSettingsPVPCheckBox3ColorSwatch",
+ "ChatConfigOtherSettingsPVPCheckBox3ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsPVPCheckBox3ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsPVPTitle",
+ "ChatConfigOtherSettingsSystem",
+ "ChatConfigOtherSettingsSystemCheckBox1",
+ "ChatConfigOtherSettingsSystemCheckBox1Check",
+ "ChatConfigOtherSettingsSystemCheckBox1CheckText",
+ "ChatConfigOtherSettingsSystemCheckBox1ColorSwatch",
+ "ChatConfigOtherSettingsSystemCheckBox1ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsSystemCheckBox1ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsSystemCheckBox2",
+ "ChatConfigOtherSettingsSystemCheckBox2Check",
+ "ChatConfigOtherSettingsSystemCheckBox2CheckText",
+ "ChatConfigOtherSettingsSystemCheckBox2ColorSwatch",
+ "ChatConfigOtherSettingsSystemCheckBox2ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsSystemCheckBox2ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsSystemCheckBox3",
+ "ChatConfigOtherSettingsSystemCheckBox3Check",
+ "ChatConfigOtherSettingsSystemCheckBox3CheckText",
+ "ChatConfigOtherSettingsSystemCheckBox3ColorSwatch",
+ "ChatConfigOtherSettingsSystemCheckBox3ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsSystemCheckBox3ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsSystemCheckBox4",
+ "ChatConfigOtherSettingsSystemCheckBox4Check",
+ "ChatConfigOtherSettingsSystemCheckBox4CheckText",
+ "ChatConfigOtherSettingsSystemCheckBox4ColorSwatch",
+ "ChatConfigOtherSettingsSystemCheckBox4ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsSystemCheckBox4ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsSystemCheckBox5",
+ "ChatConfigOtherSettingsSystemCheckBox5Check",
+ "ChatConfigOtherSettingsSystemCheckBox5CheckText",
+ "ChatConfigOtherSettingsSystemCheckBox5ColorSwatch",
+ "ChatConfigOtherSettingsSystemCheckBox5ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsSystemCheckBox5ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsSystemCheckBox6",
+ "ChatConfigOtherSettingsSystemCheckBox6Check",
+ "ChatConfigOtherSettingsSystemCheckBox6CheckText",
+ "ChatConfigOtherSettingsSystemCheckBox6ColorSwatch",
+ "ChatConfigOtherSettingsSystemCheckBox6ColorSwatchNormalTexture",
+ "ChatConfigOtherSettingsSystemCheckBox6ColorSwatchSwatchBg",
+ "ChatConfigOtherSettingsSystemTitle",
+ "ChatConfig_CreateCheckboxes",
+ "ChatConfig_CreateColorSwatches",
+ "ChatConfig_CreateTieredCheckboxes",
+ "ChatConfig_HideCombatTabs",
+ "ChatConfig_MoveFilterDown",
+ "ChatConfig_MoveFilterUp",
+ "ChatConfig_ShowCombatTabs",
+ "ChatConfig_UpdateChatSettings",
+ "ChatConfig_UpdateCheckboxes",
+ "ChatConfig_UpdateCombatSettings",
+ "ChatConfig_UpdateCombatTabs",
+ "ChatConfig_UpdateFilterList",
+ "ChatConfig_UpdateSwatches",
+ "ChatConfig_UpdateTieredCheckboxFrame",
+ "ChatConfig_UpdateTieredCheckboxes",
+ "ChatEdit_ActivateChat",
+ "ChatEdit_AddHistory",
+ "ChatEdit_ChooseBoxForSend",
+ "ChatEdit_CustomTabPressed",
+ "ChatEdit_DeactivateChat",
+ "ChatEdit_ExtractBNConversation",
+ "ChatEdit_ExtractChannel",
+ "ChatEdit_ExtractTellTarget",
+ "ChatEdit_FocusActiveWindow",
+ "ChatEdit_GetActiveWindow",
+ "ChatEdit_GetLastActiveWindow",
+ "ChatEdit_GetLastTellTarget",
+ "ChatEdit_GetLastToldTarget",
+ "ChatEdit_GetNextTellTarget",
+ "ChatEdit_HandleChatType",
+ "ChatEdit_InsertLink",
+ "ChatEdit_LanguageShow",
+ "ChatEdit_OnEditFocusGained",
+ "ChatEdit_OnEditFocusLost",
+ "ChatEdit_OnEnterPressed",
+ "ChatEdit_OnEscapePressed",
+ "ChatEdit_OnEvent",
+ "ChatEdit_OnHide",
+ "ChatEdit_OnInputLanguageChanged",
+ "ChatEdit_OnLoad",
+ "ChatEdit_OnShow",
+ "ChatEdit_OnSpacePressed",
+ "ChatEdit_OnTabPressed",
+ "ChatEdit_OnTextChanged",
+ "ChatEdit_OnTextSet",
+ "ChatEdit_OnUpdate",
+ "ChatEdit_ParseText",
+ "ChatEdit_ResetChatType",
+ "ChatEdit_ResetChatTypeToSticky",
+ "ChatEdit_SecureTabPressed",
+ "ChatEdit_SendText",
+ "ChatEdit_SetLastActiveWindow",
+ "ChatEdit_SetLastTellTarget",
+ "ChatEdit_SetLastToldTarget",
+ "ChatEdit_UpdateHeader",
+ "ChatFontNormal",
+ "ChatFontSmall",
+ "ChatFrame1",
+ "ChatFrame10",
+ "ChatFrame10Background",
+ "ChatFrame10BottomLeftTexture",
+ "ChatFrame10BottomRightTexture",
+ "ChatFrame10BottomTexture",
+ "ChatFrame10ButtonFrame",
+ "ChatFrame10ButtonFrameBackground",
+ "ChatFrame10ButtonFrameBottomButton",
+ "ChatFrame10ButtonFrameBottomButtonFlash",
+ "ChatFrame10ButtonFrameBottomLeftTexture",
+ "ChatFrame10ButtonFrameBottomRightTexture",
+ "ChatFrame10ButtonFrameBottomTexture",
+ "ChatFrame10ButtonFrameDownButton",
+ "ChatFrame10ButtonFrameLeftTexture",
+ "ChatFrame10ButtonFrameMinimizeButton",
+ "ChatFrame10ButtonFrameRightTexture",
+ "ChatFrame10ButtonFrameTopLeftTexture",
+ "ChatFrame10ButtonFrameTopRightTexture",
+ "ChatFrame10ButtonFrameTopTexture",
+ "ChatFrame10ButtonFrameUpButton",
+ "ChatFrame10ClickAnywhereButton",
+ "ChatFrame10EditBox",
+ "ChatFrame10EditBoxFocusLeft",
+ "ChatFrame10EditBoxFocusMid",
+ "ChatFrame10EditBoxFocusRight",
+ "ChatFrame10EditBoxHeader",
+ "ChatFrame10EditBoxLanguage",
+ "ChatFrame10EditBoxLeft",
+ "ChatFrame10EditBoxMid",
+ "ChatFrame10EditBoxRight",
+ "ChatFrame10LeftTexture",
+ "ChatFrame10ResizeButton",
+ "ChatFrame10RightTexture",
+ "ChatFrame10Tab",
+ "ChatFrame10TabDropDown",
+ "ChatFrame10TabDropDownButton",
+ "ChatFrame10TabDropDownButtonDisabledTexture",
+ "ChatFrame10TabDropDownButtonHighlightTexture",
+ "ChatFrame10TabDropDownButtonNormalTexture",
+ "ChatFrame10TabDropDownButtonPushedTexture",
+ "ChatFrame10TabDropDownLeft",
+ "ChatFrame10TabDropDownMiddle",
+ "ChatFrame10TabDropDownRight",
+ "ChatFrame10TabDropDownText",
+ "ChatFrame10TabFlash",
+ "ChatFrame10TabGlow",
+ "ChatFrame10TabHighlightLeft",
+ "ChatFrame10TabHighlightMiddle",
+ "ChatFrame10TabHighlightRight",
+ "ChatFrame10TabLeft",
+ "ChatFrame10TabMiddle",
+ "ChatFrame10TabRight",
+ "ChatFrame10TabSelectedLeft",
+ "ChatFrame10TabSelectedMiddle",
+ "ChatFrame10TabSelectedRight",
+ "ChatFrame10TabText",
+ "ChatFrame10TopLeftTexture",
+ "ChatFrame10TopRightTexture",
+ "ChatFrame10TopTexture",
+ "ChatFrame1Background",
+ "ChatFrame1BottomLeftTexture",
+ "ChatFrame1BottomRightTexture",
+ "ChatFrame1BottomTexture",
+ "ChatFrame1ButtonFrame",
+ "ChatFrame1ButtonFrameBackground",
+ "ChatFrame1ButtonFrameBottomButton",
+ "ChatFrame1ButtonFrameBottomButtonFlash",
+ "ChatFrame1ButtonFrameBottomLeftTexture",
+ "ChatFrame1ButtonFrameBottomRightTexture",
+ "ChatFrame1ButtonFrameBottomTexture",
+ "ChatFrame1ButtonFrameDownButton",
+ "ChatFrame1ButtonFrameLeftTexture",
+ "ChatFrame1ButtonFrameMinimizeButton",
+ "ChatFrame1ButtonFrameRightTexture",
+ "ChatFrame1ButtonFrameTopLeftTexture",
+ "ChatFrame1ButtonFrameTopRightTexture",
+ "ChatFrame1ButtonFrameTopTexture",
+ "ChatFrame1ButtonFrameUpButton",
+ "ChatFrame1ClickAnywhereButton",
+ "ChatFrame1EditBox",
+ "ChatFrame1EditBoxFocusLeft",
+ "ChatFrame1EditBoxFocusMid",
+ "ChatFrame1EditBoxFocusRight",
+ "ChatFrame1EditBoxHeader",
+ "ChatFrame1EditBoxLanguage",
+ "ChatFrame1EditBoxLeft",
+ "ChatFrame1EditBoxMid",
+ "ChatFrame1EditBoxRight",
+ "ChatFrame1LeftTexture",
+ "ChatFrame1ResizeButton",
+ "ChatFrame1RightTexture",
+ "ChatFrame1Tab",
+ "ChatFrame1TabDropDown",
+ "ChatFrame1TabDropDownButton",
+ "ChatFrame1TabDropDownButtonDisabledTexture",
+ "ChatFrame1TabDropDownButtonHighlightTexture",
+ "ChatFrame1TabDropDownButtonNormalTexture",
+ "ChatFrame1TabDropDownButtonPushedTexture",
+ "ChatFrame1TabDropDownLeft",
+ "ChatFrame1TabDropDownMiddle",
+ "ChatFrame1TabDropDownRight",
+ "ChatFrame1TabDropDownText",
+ "ChatFrame1TabFlash",
+ "ChatFrame1TabGlow",
+ "ChatFrame1TabHighlightLeft",
+ "ChatFrame1TabHighlightMiddle",
+ "ChatFrame1TabHighlightRight",
+ "ChatFrame1TabLeft",
+ "ChatFrame1TabMiddle",
+ "ChatFrame1TabRight",
+ "ChatFrame1TabSelectedLeft",
+ "ChatFrame1TabSelectedMiddle",
+ "ChatFrame1TabSelectedRight",
+ "ChatFrame1TabText",
+ "ChatFrame1TopLeftTexture",
+ "ChatFrame1TopRightTexture",
+ "ChatFrame1TopTexture",
+ "ChatFrame2",
+ "ChatFrame2Background",
+ "ChatFrame2BottomLeftTexture",
+ "ChatFrame2BottomRightTexture",
+ "ChatFrame2BottomTexture",
+ "ChatFrame2ButtonFrame",
+ "ChatFrame2ButtonFrameBackground",
+ "ChatFrame2ButtonFrameBottomButton",
+ "ChatFrame2ButtonFrameBottomButtonFlash",
+ "ChatFrame2ButtonFrameBottomLeftTexture",
+ "ChatFrame2ButtonFrameBottomRightTexture",
+ "ChatFrame2ButtonFrameBottomTexture",
+ "ChatFrame2ButtonFrameDownButton",
+ "ChatFrame2ButtonFrameLeftTexture",
+ "ChatFrame2ButtonFrameMinimizeButton",
+ "ChatFrame2ButtonFrameRightTexture",
+ "ChatFrame2ButtonFrameTopLeftTexture",
+ "ChatFrame2ButtonFrameTopRightTexture",
+ "ChatFrame2ButtonFrameTopTexture",
+ "ChatFrame2ButtonFrameUpButton",
+ "ChatFrame2ClickAnywhereButton",
+ "ChatFrame2EditBox",
+ "ChatFrame2EditBoxFocusLeft",
+ "ChatFrame2EditBoxFocusMid",
+ "ChatFrame2EditBoxFocusRight",
+ "ChatFrame2EditBoxHeader",
+ "ChatFrame2EditBoxLanguage",
+ "ChatFrame2EditBoxLeft",
+ "ChatFrame2EditBoxMid",
+ "ChatFrame2EditBoxRight",
+ "ChatFrame2LeftTexture",
+ "ChatFrame2ResizeButton",
+ "ChatFrame2RightTexture",
+ "ChatFrame2Tab",
+ "ChatFrame2TabDropDown",
+ "ChatFrame2TabDropDownButton",
+ "ChatFrame2TabDropDownButtonDisabledTexture",
+ "ChatFrame2TabDropDownButtonHighlightTexture",
+ "ChatFrame2TabDropDownButtonNormalTexture",
+ "ChatFrame2TabDropDownButtonPushedTexture",
+ "ChatFrame2TabDropDownLeft",
+ "ChatFrame2TabDropDownMiddle",
+ "ChatFrame2TabDropDownRight",
+ "ChatFrame2TabDropDownText",
+ "ChatFrame2TabFlash",
+ "ChatFrame2TabGlow",
+ "ChatFrame2TabHighlightLeft",
+ "ChatFrame2TabHighlightMiddle",
+ "ChatFrame2TabHighlightRight",
+ "ChatFrame2TabLeft",
+ "ChatFrame2TabMiddle",
+ "ChatFrame2TabRight",
+ "ChatFrame2TabSelectedLeft",
+ "ChatFrame2TabSelectedMiddle",
+ "ChatFrame2TabSelectedRight",
+ "ChatFrame2TabText",
+ "ChatFrame2TopLeftTexture",
+ "ChatFrame2TopRightTexture",
+ "ChatFrame2TopTexture",
+ "ChatFrame3",
+ "ChatFrame3Background",
+ "ChatFrame3BottomLeftTexture",
+ "ChatFrame3BottomRightTexture",
+ "ChatFrame3BottomTexture",
+ "ChatFrame3ButtonFrame",
+ "ChatFrame3ButtonFrameBackground",
+ "ChatFrame3ButtonFrameBottomButton",
+ "ChatFrame3ButtonFrameBottomButtonFlash",
+ "ChatFrame3ButtonFrameBottomLeftTexture",
+ "ChatFrame3ButtonFrameBottomRightTexture",
+ "ChatFrame3ButtonFrameBottomTexture",
+ "ChatFrame3ButtonFrameDownButton",
+ "ChatFrame3ButtonFrameLeftTexture",
+ "ChatFrame3ButtonFrameMinimizeButton",
+ "ChatFrame3ButtonFrameRightTexture",
+ "ChatFrame3ButtonFrameTopLeftTexture",
+ "ChatFrame3ButtonFrameTopRightTexture",
+ "ChatFrame3ButtonFrameTopTexture",
+ "ChatFrame3ButtonFrameUpButton",
+ "ChatFrame3ClickAnywhereButton",
+ "ChatFrame3EditBox",
+ "ChatFrame3EditBoxFocusLeft",
+ "ChatFrame3EditBoxFocusMid",
+ "ChatFrame3EditBoxFocusRight",
+ "ChatFrame3EditBoxHeader",
+ "ChatFrame3EditBoxLanguage",
+ "ChatFrame3EditBoxLeft",
+ "ChatFrame3EditBoxMid",
+ "ChatFrame3EditBoxRight",
+ "ChatFrame3LeftTexture",
+ "ChatFrame3ResizeButton",
+ "ChatFrame3RightTexture",
+ "ChatFrame3Tab",
+ "ChatFrame3TabDropDown",
+ "ChatFrame3TabDropDownButton",
+ "ChatFrame3TabDropDownButtonDisabledTexture",
+ "ChatFrame3TabDropDownButtonHighlightTexture",
+ "ChatFrame3TabDropDownButtonNormalTexture",
+ "ChatFrame3TabDropDownButtonPushedTexture",
+ "ChatFrame3TabDropDownLeft",
+ "ChatFrame3TabDropDownMiddle",
+ "ChatFrame3TabDropDownRight",
+ "ChatFrame3TabDropDownText",
+ "ChatFrame3TabFlash",
+ "ChatFrame3TabGlow",
+ "ChatFrame3TabHighlightLeft",
+ "ChatFrame3TabHighlightMiddle",
+ "ChatFrame3TabHighlightRight",
+ "ChatFrame3TabLeft",
+ "ChatFrame3TabMiddle",
+ "ChatFrame3TabRight",
+ "ChatFrame3TabSelectedLeft",
+ "ChatFrame3TabSelectedMiddle",
+ "ChatFrame3TabSelectedRight",
+ "ChatFrame3TabText",
+ "ChatFrame3TopLeftTexture",
+ "ChatFrame3TopRightTexture",
+ "ChatFrame3TopTexture",
+ "ChatFrame4",
+ "ChatFrame4Background",
+ "ChatFrame4BottomLeftTexture",
+ "ChatFrame4BottomRightTexture",
+ "ChatFrame4BottomTexture",
+ "ChatFrame4ButtonFrame",
+ "ChatFrame4ButtonFrameBackground",
+ "ChatFrame4ButtonFrameBottomButton",
+ "ChatFrame4ButtonFrameBottomButtonFlash",
+ "ChatFrame4ButtonFrameBottomLeftTexture",
+ "ChatFrame4ButtonFrameBottomRightTexture",
+ "ChatFrame4ButtonFrameBottomTexture",
+ "ChatFrame4ButtonFrameDownButton",
+ "ChatFrame4ButtonFrameLeftTexture",
+ "ChatFrame4ButtonFrameMinimizeButton",
+ "ChatFrame4ButtonFrameRightTexture",
+ "ChatFrame4ButtonFrameTopLeftTexture",
+ "ChatFrame4ButtonFrameTopRightTexture",
+ "ChatFrame4ButtonFrameTopTexture",
+ "ChatFrame4ButtonFrameUpButton",
+ "ChatFrame4ClickAnywhereButton",
+ "ChatFrame4EditBox",
+ "ChatFrame4EditBoxFocusLeft",
+ "ChatFrame4EditBoxFocusMid",
+ "ChatFrame4EditBoxFocusRight",
+ "ChatFrame4EditBoxHeader",
+ "ChatFrame4EditBoxLanguage",
+ "ChatFrame4EditBoxLeft",
+ "ChatFrame4EditBoxMid",
+ "ChatFrame4EditBoxRight",
+ "ChatFrame4LeftTexture",
+ "ChatFrame4ResizeButton",
+ "ChatFrame4RightTexture",
+ "ChatFrame4Tab",
+ "ChatFrame4TabDropDown",
+ "ChatFrame4TabDropDownButton",
+ "ChatFrame4TabDropDownButtonDisabledTexture",
+ "ChatFrame4TabDropDownButtonHighlightTexture",
+ "ChatFrame4TabDropDownButtonNormalTexture",
+ "ChatFrame4TabDropDownButtonPushedTexture",
+ "ChatFrame4TabDropDownLeft",
+ "ChatFrame4TabDropDownMiddle",
+ "ChatFrame4TabDropDownRight",
+ "ChatFrame4TabDropDownText",
+ "ChatFrame4TabFlash",
+ "ChatFrame4TabGlow",
+ "ChatFrame4TabHighlightLeft",
+ "ChatFrame4TabHighlightMiddle",
+ "ChatFrame4TabHighlightRight",
+ "ChatFrame4TabLeft",
+ "ChatFrame4TabMiddle",
+ "ChatFrame4TabRight",
+ "ChatFrame4TabSelectedLeft",
+ "ChatFrame4TabSelectedMiddle",
+ "ChatFrame4TabSelectedRight",
+ "ChatFrame4TabText",
+ "ChatFrame4TopLeftTexture",
+ "ChatFrame4TopRightTexture",
+ "ChatFrame4TopTexture",
+ "ChatFrame5",
+ "ChatFrame5Background",
+ "ChatFrame5BottomLeftTexture",
+ "ChatFrame5BottomRightTexture",
+ "ChatFrame5BottomTexture",
+ "ChatFrame5ButtonFrame",
+ "ChatFrame5ButtonFrameBackground",
+ "ChatFrame5ButtonFrameBottomButton",
+ "ChatFrame5ButtonFrameBottomButtonFlash",
+ "ChatFrame5ButtonFrameBottomLeftTexture",
+ "ChatFrame5ButtonFrameBottomRightTexture",
+ "ChatFrame5ButtonFrameBottomTexture",
+ "ChatFrame5ButtonFrameDownButton",
+ "ChatFrame5ButtonFrameLeftTexture",
+ "ChatFrame5ButtonFrameMinimizeButton",
+ "ChatFrame5ButtonFrameRightTexture",
+ "ChatFrame5ButtonFrameTopLeftTexture",
+ "ChatFrame5ButtonFrameTopRightTexture",
+ "ChatFrame5ButtonFrameTopTexture",
+ "ChatFrame5ButtonFrameUpButton",
+ "ChatFrame5ClickAnywhereButton",
+ "ChatFrame5EditBox",
+ "ChatFrame5EditBoxFocusLeft",
+ "ChatFrame5EditBoxFocusMid",
+ "ChatFrame5EditBoxFocusRight",
+ "ChatFrame5EditBoxHeader",
+ "ChatFrame5EditBoxLanguage",
+ "ChatFrame5EditBoxLeft",
+ "ChatFrame5EditBoxMid",
+ "ChatFrame5EditBoxRight",
+ "ChatFrame5LeftTexture",
+ "ChatFrame5ResizeButton",
+ "ChatFrame5RightTexture",
+ "ChatFrame5Tab",
+ "ChatFrame5TabDropDown",
+ "ChatFrame5TabDropDownButton",
+ "ChatFrame5TabDropDownButtonDisabledTexture",
+ "ChatFrame5TabDropDownButtonHighlightTexture",
+ "ChatFrame5TabDropDownButtonNormalTexture",
+ "ChatFrame5TabDropDownButtonPushedTexture",
+ "ChatFrame5TabDropDownLeft",
+ "ChatFrame5TabDropDownMiddle",
+ "ChatFrame5TabDropDownRight",
+ "ChatFrame5TabDropDownText",
+ "ChatFrame5TabFlash",
+ "ChatFrame5TabGlow",
+ "ChatFrame5TabHighlightLeft",
+ "ChatFrame5TabHighlightMiddle",
+ "ChatFrame5TabHighlightRight",
+ "ChatFrame5TabLeft",
+ "ChatFrame5TabMiddle",
+ "ChatFrame5TabRight",
+ "ChatFrame5TabSelectedLeft",
+ "ChatFrame5TabSelectedMiddle",
+ "ChatFrame5TabSelectedRight",
+ "ChatFrame5TabText",
+ "ChatFrame5TopLeftTexture",
+ "ChatFrame5TopRightTexture",
+ "ChatFrame5TopTexture",
+ "ChatFrame6",
+ "ChatFrame6Background",
+ "ChatFrame6BottomLeftTexture",
+ "ChatFrame6BottomRightTexture",
+ "ChatFrame6BottomTexture",
+ "ChatFrame6ButtonFrame",
+ "ChatFrame6ButtonFrameBackground",
+ "ChatFrame6ButtonFrameBottomButton",
+ "ChatFrame6ButtonFrameBottomButtonFlash",
+ "ChatFrame6ButtonFrameBottomLeftTexture",
+ "ChatFrame6ButtonFrameBottomRightTexture",
+ "ChatFrame6ButtonFrameBottomTexture",
+ "ChatFrame6ButtonFrameDownButton",
+ "ChatFrame6ButtonFrameLeftTexture",
+ "ChatFrame6ButtonFrameMinimizeButton",
+ "ChatFrame6ButtonFrameRightTexture",
+ "ChatFrame6ButtonFrameTopLeftTexture",
+ "ChatFrame6ButtonFrameTopRightTexture",
+ "ChatFrame6ButtonFrameTopTexture",
+ "ChatFrame6ButtonFrameUpButton",
+ "ChatFrame6ClickAnywhereButton",
+ "ChatFrame6EditBox",
+ "ChatFrame6EditBoxFocusLeft",
+ "ChatFrame6EditBoxFocusMid",
+ "ChatFrame6EditBoxFocusRight",
+ "ChatFrame6EditBoxHeader",
+ "ChatFrame6EditBoxLanguage",
+ "ChatFrame6EditBoxLeft",
+ "ChatFrame6EditBoxMid",
+ "ChatFrame6EditBoxRight",
+ "ChatFrame6LeftTexture",
+ "ChatFrame6ResizeButton",
+ "ChatFrame6RightTexture",
+ "ChatFrame6Tab",
+ "ChatFrame6TabDropDown",
+ "ChatFrame6TabDropDownButton",
+ "ChatFrame6TabDropDownButtonDisabledTexture",
+ "ChatFrame6TabDropDownButtonHighlightTexture",
+ "ChatFrame6TabDropDownButtonNormalTexture",
+ "ChatFrame6TabDropDownButtonPushedTexture",
+ "ChatFrame6TabDropDownLeft",
+ "ChatFrame6TabDropDownMiddle",
+ "ChatFrame6TabDropDownRight",
+ "ChatFrame6TabDropDownText",
+ "ChatFrame6TabFlash",
+ "ChatFrame6TabGlow",
+ "ChatFrame6TabHighlightLeft",
+ "ChatFrame6TabHighlightMiddle",
+ "ChatFrame6TabHighlightRight",
+ "ChatFrame6TabLeft",
+ "ChatFrame6TabMiddle",
+ "ChatFrame6TabRight",
+ "ChatFrame6TabSelectedLeft",
+ "ChatFrame6TabSelectedMiddle",
+ "ChatFrame6TabSelectedRight",
+ "ChatFrame6TabText",
+ "ChatFrame6TopLeftTexture",
+ "ChatFrame6TopRightTexture",
+ "ChatFrame6TopTexture",
+ "ChatFrame7",
+ "ChatFrame7Background",
+ "ChatFrame7BottomLeftTexture",
+ "ChatFrame7BottomRightTexture",
+ "ChatFrame7BottomTexture",
+ "ChatFrame7ButtonFrame",
+ "ChatFrame7ButtonFrameBackground",
+ "ChatFrame7ButtonFrameBottomButton",
+ "ChatFrame7ButtonFrameBottomButtonFlash",
+ "ChatFrame7ButtonFrameBottomLeftTexture",
+ "ChatFrame7ButtonFrameBottomRightTexture",
+ "ChatFrame7ButtonFrameBottomTexture",
+ "ChatFrame7ButtonFrameDownButton",
+ "ChatFrame7ButtonFrameLeftTexture",
+ "ChatFrame7ButtonFrameMinimizeButton",
+ "ChatFrame7ButtonFrameRightTexture",
+ "ChatFrame7ButtonFrameTopLeftTexture",
+ "ChatFrame7ButtonFrameTopRightTexture",
+ "ChatFrame7ButtonFrameTopTexture",
+ "ChatFrame7ButtonFrameUpButton",
+ "ChatFrame7ClickAnywhereButton",
+ "ChatFrame7EditBox",
+ "ChatFrame7EditBoxFocusLeft",
+ "ChatFrame7EditBoxFocusMid",
+ "ChatFrame7EditBoxFocusRight",
+ "ChatFrame7EditBoxHeader",
+ "ChatFrame7EditBoxLanguage",
+ "ChatFrame7EditBoxLeft",
+ "ChatFrame7EditBoxMid",
+ "ChatFrame7EditBoxRight",
+ "ChatFrame7LeftTexture",
+ "ChatFrame7ResizeButton",
+ "ChatFrame7RightTexture",
+ "ChatFrame7Tab",
+ "ChatFrame7TabDropDown",
+ "ChatFrame7TabDropDownButton",
+ "ChatFrame7TabDropDownButtonDisabledTexture",
+ "ChatFrame7TabDropDownButtonHighlightTexture",
+ "ChatFrame7TabDropDownButtonNormalTexture",
+ "ChatFrame7TabDropDownButtonPushedTexture",
+ "ChatFrame7TabDropDownLeft",
+ "ChatFrame7TabDropDownMiddle",
+ "ChatFrame7TabDropDownRight",
+ "ChatFrame7TabDropDownText",
+ "ChatFrame7TabFlash",
+ "ChatFrame7TabGlow",
+ "ChatFrame7TabHighlightLeft",
+ "ChatFrame7TabHighlightMiddle",
+ "ChatFrame7TabHighlightRight",
+ "ChatFrame7TabLeft",
+ "ChatFrame7TabMiddle",
+ "ChatFrame7TabRight",
+ "ChatFrame7TabSelectedLeft",
+ "ChatFrame7TabSelectedMiddle",
+ "ChatFrame7TabSelectedRight",
+ "ChatFrame7TabText",
+ "ChatFrame7TopLeftTexture",
+ "ChatFrame7TopRightTexture",
+ "ChatFrame7TopTexture",
+ "ChatFrame8",
+ "ChatFrame8Background",
+ "ChatFrame8BottomLeftTexture",
+ "ChatFrame8BottomRightTexture",
+ "ChatFrame8BottomTexture",
+ "ChatFrame8ButtonFrame",
+ "ChatFrame8ButtonFrameBackground",
+ "ChatFrame8ButtonFrameBottomButton",
+ "ChatFrame8ButtonFrameBottomButtonFlash",
+ "ChatFrame8ButtonFrameBottomLeftTexture",
+ "ChatFrame8ButtonFrameBottomRightTexture",
+ "ChatFrame8ButtonFrameBottomTexture",
+ "ChatFrame8ButtonFrameDownButton",
+ "ChatFrame8ButtonFrameLeftTexture",
+ "ChatFrame8ButtonFrameMinimizeButton",
+ "ChatFrame8ButtonFrameRightTexture",
+ "ChatFrame8ButtonFrameTopLeftTexture",
+ "ChatFrame8ButtonFrameTopRightTexture",
+ "ChatFrame8ButtonFrameTopTexture",
+ "ChatFrame8ButtonFrameUpButton",
+ "ChatFrame8ClickAnywhereButton",
+ "ChatFrame8EditBox",
+ "ChatFrame8EditBoxFocusLeft",
+ "ChatFrame8EditBoxFocusMid",
+ "ChatFrame8EditBoxFocusRight",
+ "ChatFrame8EditBoxHeader",
+ "ChatFrame8EditBoxLanguage",
+ "ChatFrame8EditBoxLeft",
+ "ChatFrame8EditBoxMid",
+ "ChatFrame8EditBoxRight",
+ "ChatFrame8LeftTexture",
+ "ChatFrame8ResizeButton",
+ "ChatFrame8RightTexture",
+ "ChatFrame8Tab",
+ "ChatFrame8TabDropDown",
+ "ChatFrame8TabDropDownButton",
+ "ChatFrame8TabDropDownButtonDisabledTexture",
+ "ChatFrame8TabDropDownButtonHighlightTexture",
+ "ChatFrame8TabDropDownButtonNormalTexture",
+ "ChatFrame8TabDropDownButtonPushedTexture",
+ "ChatFrame8TabDropDownLeft",
+ "ChatFrame8TabDropDownMiddle",
+ "ChatFrame8TabDropDownRight",
+ "ChatFrame8TabDropDownText",
+ "ChatFrame8TabFlash",
+ "ChatFrame8TabGlow",
+ "ChatFrame8TabHighlightLeft",
+ "ChatFrame8TabHighlightMiddle",
+ "ChatFrame8TabHighlightRight",
+ "ChatFrame8TabLeft",
+ "ChatFrame8TabMiddle",
+ "ChatFrame8TabRight",
+ "ChatFrame8TabSelectedLeft",
+ "ChatFrame8TabSelectedMiddle",
+ "ChatFrame8TabSelectedRight",
+ "ChatFrame8TabText",
+ "ChatFrame8TopLeftTexture",
+ "ChatFrame8TopRightTexture",
+ "ChatFrame8TopTexture",
+ "ChatFrame9",
+ "ChatFrame9Background",
+ "ChatFrame9BottomLeftTexture",
+ "ChatFrame9BottomRightTexture",
+ "ChatFrame9BottomTexture",
+ "ChatFrame9ButtonFrame",
+ "ChatFrame9ButtonFrameBackground",
+ "ChatFrame9ButtonFrameBottomButton",
+ "ChatFrame9ButtonFrameBottomButtonFlash",
+ "ChatFrame9ButtonFrameBottomLeftTexture",
+ "ChatFrame9ButtonFrameBottomRightTexture",
+ "ChatFrame9ButtonFrameBottomTexture",
+ "ChatFrame9ButtonFrameDownButton",
+ "ChatFrame9ButtonFrameLeftTexture",
+ "ChatFrame9ButtonFrameMinimizeButton",
+ "ChatFrame9ButtonFrameRightTexture",
+ "ChatFrame9ButtonFrameTopLeftTexture",
+ "ChatFrame9ButtonFrameTopRightTexture",
+ "ChatFrame9ButtonFrameTopTexture",
+ "ChatFrame9ButtonFrameUpButton",
+ "ChatFrame9ClickAnywhereButton",
+ "ChatFrame9EditBox",
+ "ChatFrame9EditBoxFocusLeft",
+ "ChatFrame9EditBoxFocusMid",
+ "ChatFrame9EditBoxFocusRight",
+ "ChatFrame9EditBoxHeader",
+ "ChatFrame9EditBoxLanguage",
+ "ChatFrame9EditBoxLeft",
+ "ChatFrame9EditBoxMid",
+ "ChatFrame9EditBoxRight",
+ "ChatFrame9LeftTexture",
+ "ChatFrame9ResizeButton",
+ "ChatFrame9RightTexture",
+ "ChatFrame9Tab",
+ "ChatFrame9TabDropDown",
+ "ChatFrame9TabDropDownButton",
+ "ChatFrame9TabDropDownButtonDisabledTexture",
+ "ChatFrame9TabDropDownButtonHighlightTexture",
+ "ChatFrame9TabDropDownButtonNormalTexture",
+ "ChatFrame9TabDropDownButtonPushedTexture",
+ "ChatFrame9TabDropDownLeft",
+ "ChatFrame9TabDropDownMiddle",
+ "ChatFrame9TabDropDownRight",
+ "ChatFrame9TabDropDownText",
+ "ChatFrame9TabFlash",
+ "ChatFrame9TabGlow",
+ "ChatFrame9TabHighlightLeft",
+ "ChatFrame9TabHighlightMiddle",
+ "ChatFrame9TabHighlightRight",
+ "ChatFrame9TabLeft",
+ "ChatFrame9TabMiddle",
+ "ChatFrame9TabRight",
+ "ChatFrame9TabSelectedLeft",
+ "ChatFrame9TabSelectedMiddle",
+ "ChatFrame9TabSelectedRight",
+ "ChatFrame9TabText",
+ "ChatFrame9TopLeftTexture",
+ "ChatFrame9TopRightTexture",
+ "ChatFrame9TopTexture",
+ "ChatFrameMenuButton",
+ "ChatFrameMenu_UpdateAnchorPoint",
+ "ChatFrame_ActivateCombatMessages",
+ "ChatFrame_AddBNConversationTarget",
+ "ChatFrame_AddChannel",
+ "ChatFrame_AddMessageEventFilter",
+ "ChatFrame_AddMessageGroup",
+ "ChatFrame_AddPrivateMessageTarget",
+ "ChatFrame_ChatPageDown",
+ "ChatFrame_ChatPageUp",
+ "ChatFrame_ConfigEventHandler",
+ "ChatFrame_DisplayChatHelp",
+ "ChatFrame_DisplayGameTime",
+ "ChatFrame_DisplayGuildHelp",
+ "ChatFrame_DisplayHelpText",
+ "ChatFrame_DisplayMacroHelpText",
+ "ChatFrame_DisplayStartupText",
+ "ChatFrame_DisplayTimePlayed",
+ "ChatFrame_DisplayUsageError",
+ "ChatFrame_ExcludeBNConversationTarget",
+ "ChatFrame_ExcludePrivateMessageTarget",
+ "ChatFrame_GetMessageEventFilters",
+ "ChatFrame_MessageEventHandler",
+ "ChatFrame_OnEvent",
+ "ChatFrame_OnHyperlinkShow",
+ "ChatFrame_OnLoad",
+ "ChatFrame_OnMouseWheel",
+ "ChatFrame_OnUpdate",
+ "ChatFrame_OpenChat",
+ "ChatFrame_OpenMenu",
+ "ChatFrame_ReceiveAllBNConversations",
+ "ChatFrame_ReceiveAllPrivateMessages",
+ "ChatFrame_RegisterForChannels",
+ "ChatFrame_RegisterForMessages",
+ "ChatFrame_RemoveAllChannels",
+ "ChatFrame_RemoveAllMessageGroups",
+ "ChatFrame_RemoveBNConversationTarget",
+ "ChatFrame_RemoveChannel",
+ "ChatFrame_RemoveExcludeBNConversationTarget",
+ "ChatFrame_RemoveExcludePrivateMessageTarget",
+ "ChatFrame_RemoveMessageEventFilter",
+ "ChatFrame_RemoveMessageGroup",
+ "ChatFrame_RemovePrivateMessageTarget",
+ "ChatFrame_ReplyTell",
+ "ChatFrame_ReplyTell2",
+ "ChatFrame_ScrollDown",
+ "ChatFrame_ScrollToBottom",
+ "ChatFrame_ScrollUp",
+ "ChatFrame_SendTell",
+ "ChatFrame_SystemEventHandler",
+ "ChatFrame_TimeBreakDown",
+ "ChatHistory_GetAccessID",
+ "ChatHistory_GetChatType",
+ "ChatHistory_GetToken",
+ "ChatMenu",
+ "ChatMenuButton1",
+ "ChatMenuButton10",
+ "ChatMenuButton10ShortcutText",
+ "ChatMenuButton11",
+ "ChatMenuButton11ShortcutText",
+ "ChatMenuButton12",
+ "ChatMenuButton12ShortcutText",
+ "ChatMenuButton13",
+ "ChatMenuButton13ShortcutText",
+ "ChatMenuButton14",
+ "ChatMenuButton14ShortcutText",
+ "ChatMenuButton15",
+ "ChatMenuButton15ShortcutText",
+ "ChatMenuButton16",
+ "ChatMenuButton16ShortcutText",
+ "ChatMenuButton17",
+ "ChatMenuButton17ShortcutText",
+ "ChatMenuButton18",
+ "ChatMenuButton18ShortcutText",
+ "ChatMenuButton19",
+ "ChatMenuButton19ShortcutText",
+ "ChatMenuButton1ShortcutText",
+ "ChatMenuButton2",
+ "ChatMenuButton20",
+ "ChatMenuButton20ShortcutText",
+ "ChatMenuButton21",
+ "ChatMenuButton21ShortcutText",
+ "ChatMenuButton22",
+ "ChatMenuButton22ShortcutText",
+ "ChatMenuButton23",
+ "ChatMenuButton23ShortcutText",
+ "ChatMenuButton24",
+ "ChatMenuButton24ShortcutText",
+ "ChatMenuButton25",
+ "ChatMenuButton25ShortcutText",
+ "ChatMenuButton26",
+ "ChatMenuButton26ShortcutText",
+ "ChatMenuButton27",
+ "ChatMenuButton27ShortcutText",
+ "ChatMenuButton28",
+ "ChatMenuButton28ShortcutText",
+ "ChatMenuButton29",
+ "ChatMenuButton29ShortcutText",
+ "ChatMenuButton2ShortcutText",
+ "ChatMenuButton3",
+ "ChatMenuButton30",
+ "ChatMenuButton30ShortcutText",
+ "ChatMenuButton31",
+ "ChatMenuButton31ShortcutText",
+ "ChatMenuButton32",
+ "ChatMenuButton32ShortcutText",
+ "ChatMenuButton3ShortcutText",
+ "ChatMenuButton4",
+ "ChatMenuButton4ShortcutText",
+ "ChatMenuButton5",
+ "ChatMenuButton5ShortcutText",
+ "ChatMenuButton6",
+ "ChatMenuButton6ShortcutText",
+ "ChatMenuButton7",
+ "ChatMenuButton7ShortcutText",
+ "ChatMenuButton8",
+ "ChatMenuButton8ShortcutText",
+ "ChatMenuButton9",
+ "ChatMenuButton9ShortcutText",
+ "ChatMenu_Battleground",
+ "ChatMenu_Emote",
+ "ChatMenu_Guild",
+ "ChatMenu_OnLoad",
+ "ChatMenu_OnShow",
+ "ChatMenu_Party",
+ "ChatMenu_Raid",
+ "ChatMenu_Reply",
+ "ChatMenu_Say",
+ "ChatMenu_SetChatType",
+ "ChatMenu_VoiceMacro",
+ "ChatMenu_Whisper",
+ "ChatMenu_Yell",
+ "ChatTypeGroup",
+ "ChatTypeGroupInverted",
+ "ChatTypeInfo",
+ "ChatUnitColor_OpenColorPicker",
+ "Chat_GetChannelShortcutName",
+ "Chat_GetChatCategory",
+ "Chat_GetColoredChatName",
+ "CheckBinderDist",
+ "CheckInbox",
+ "CheckInteractDistance",
+ "CheckSpiritHealerDist",
+ "CheckTalentMasterDist",
+ "CinematicFrame",
+ "CinematicFrame_OnEvent",
+ "CinematicFrame_OnLoad",
+ "ClassTrainerCancelButton",
+ "ClassTrainerCancelButtonText",
+ "ClassTrainerCollapseAllButton",
+ "ClassTrainerCollapseAllButtonHighlight",
+ "ClassTrainerCollapseAllButtonSubText",
+ "ClassTrainerCollapseAllButtonText",
+ "ClassTrainerCollapseAllButton_OnClick",
+ "ClassTrainerCostLabel",
+ "ClassTrainerDetailMoneyFrame",
+ "ClassTrainerDetailMoneyFrameCopperButton",
+ "ClassTrainerDetailMoneyFrameCopperButtonText",
+ "ClassTrainerDetailMoneyFrameGoldButton",
+ "ClassTrainerDetailMoneyFrameGoldButtonText",
+ "ClassTrainerDetailMoneyFrameSilverButton",
+ "ClassTrainerDetailMoneyFrameSilverButtonText",
+ "ClassTrainerDetailScrollChildFrame",
+ "ClassTrainerDetailScrollFrame",
+ "ClassTrainerDetailScrollFrameBottom",
+ "ClassTrainerDetailScrollFrameScrollBar",
+ "ClassTrainerDetailScrollFrameScrollBarScrollDownButton",
+ "ClassTrainerDetailScrollFrameScrollBarScrollUpButton",
+ "ClassTrainerDetailScrollFrameScrollBarThumbTexture",
+ "ClassTrainerDetailScrollFrameTop",
+ "ClassTrainerExpandButtonFrame",
+ "ClassTrainerExpandTabLeft",
+ "ClassTrainerExpandTabMiddle",
+ "ClassTrainerFrame",
+ "ClassTrainerFrameBottomLeft",
+ "ClassTrainerFrameBottomRight",
+ "ClassTrainerFrameCloseButton",
+ "ClassTrainerFrameFilterDropDown",
+ "ClassTrainerFrameFilterDropDownButton",
+ "ClassTrainerFrameFilterDropDownButtonDisabledTexture",
+ "ClassTrainerFrameFilterDropDownButtonHighlightTexture",
+ "ClassTrainerFrameFilterDropDownButtonNormalTexture",
+ "ClassTrainerFrameFilterDropDownButtonPushedTexture",
+ "ClassTrainerFrameFilterDropDownLeft",
+ "ClassTrainerFrameFilterDropDownMiddle",
+ "ClassTrainerFrameFilterDropDownRight",
+ "ClassTrainerFrameFilterDropDownText",
+ "ClassTrainerFrameFilterDropDown_Initialize",
+ "ClassTrainerFrameFilterDropDown_OnClick",
+ "ClassTrainerFrameFilterDropDown_OnLoad",
+ "ClassTrainerFramePortrait",
+ "ClassTrainerFrame_Hide",
+ "ClassTrainerFrame_LoadUI",
+ "ClassTrainerFrame_OnEvent",
+ "ClassTrainerFrame_OnLoad",
+ "ClassTrainerFrame_Show",
+ "ClassTrainerFrame_Update",
+ "ClassTrainerGreetingText",
+ "ClassTrainerHorizontalBarLeft",
+ "ClassTrainerListScrollFrame",
+ "ClassTrainerListScrollFrameScrollBar",
+ "ClassTrainerListScrollFrameScrollBarScrollDownButton",
+ "ClassTrainerListScrollFrameScrollBarScrollUpButton",
+ "ClassTrainerListScrollFrameScrollBarThumbTexture",
+ "ClassTrainerListScrollFrameScrollChildFrame",
+ "ClassTrainerMoneyFrame",
+ "ClassTrainerMoneyFrameCopperButton",
+ "ClassTrainerMoneyFrameCopperButtonText",
+ "ClassTrainerMoneyFrameGoldButton",
+ "ClassTrainerMoneyFrameGoldButtonText",
+ "ClassTrainerMoneyFrameSilverButton",
+ "ClassTrainerMoneyFrameSilverButtonText",
+ "ClassTrainerNameText",
+ "ClassTrainerSkill1",
+ "ClassTrainerSkill10",
+ "ClassTrainerSkill10Highlight",
+ "ClassTrainerSkill10SubText",
+ "ClassTrainerSkill10Text",
+ "ClassTrainerSkill11",
+ "ClassTrainerSkill11Highlight",
+ "ClassTrainerSkill11SubText",
+ "ClassTrainerSkill11Text",
+ "ClassTrainerSkill1Highlight",
+ "ClassTrainerSkill1SubText",
+ "ClassTrainerSkill1Text",
+ "ClassTrainerSkill2",
+ "ClassTrainerSkill2Highlight",
+ "ClassTrainerSkill2SubText",
+ "ClassTrainerSkill2Text",
+ "ClassTrainerSkill3",
+ "ClassTrainerSkill3Highlight",
+ "ClassTrainerSkill3SubText",
+ "ClassTrainerSkill3Text",
+ "ClassTrainerSkill4",
+ "ClassTrainerSkill4Highlight",
+ "ClassTrainerSkill4SubText",
+ "ClassTrainerSkill4Text",
+ "ClassTrainerSkill5",
+ "ClassTrainerSkill5Highlight",
+ "ClassTrainerSkill5SubText",
+ "ClassTrainerSkill5Text",
+ "ClassTrainerSkill6",
+ "ClassTrainerSkill6Highlight",
+ "ClassTrainerSkill6SubText",
+ "ClassTrainerSkill6Text",
+ "ClassTrainerSkill7",
+ "ClassTrainerSkill7Highlight",
+ "ClassTrainerSkill7SubText",
+ "ClassTrainerSkill7Text",
+ "ClassTrainerSkill8",
+ "ClassTrainerSkill8Highlight",
+ "ClassTrainerSkill8SubText",
+ "ClassTrainerSkill8Text",
+ "ClassTrainerSkill9",
+ "ClassTrainerSkill9Highlight",
+ "ClassTrainerSkill9SubText",
+ "ClassTrainerSkill9Text",
+ "ClassTrainerSkillButton_OnClick",
+ "ClassTrainerSkillDescription",
+ "ClassTrainerSkillHighlight",
+ "ClassTrainerSkillHighlightFrame",
+ "ClassTrainerSkillIcon",
+ "ClassTrainerSkillName",
+ "ClassTrainerSkillRequirements",
+ "ClassTrainerSubSkillName",
+ "ClassTrainerTrainButton",
+ "ClassTrainerTrainButtonText",
+ "ClassTrainerTrainButton_OnClick",
+ "ClassTrainer_HideSkillDetails",
+ "ClassTrainer_SelectFirstLearnableSkill",
+ "ClassTrainer_SetSelection",
+ "ClassTrainer_SetSubTextColor",
+ "ClassTrainer_SetToClassTrainer",
+ "ClassTrainer_SetToTradeSkillTrainer",
+ "ClassTrainer_ShowSkillDetails",
+ "ClearAchievementComparisonUnit",
+ "ClearAllLFGDungeons",
+ "ClearChannelWatch",
+ "ClearCursor",
+ "ClearFocus",
+ "ClearInspectPlayer",
+ "ClearLFGDungeon",
+ "ClearOverrideBindings",
+ "ClearPartyAssignment",
+ "ClearPendingGuildBankPermissions",
+ "ClearSendMail",
+ "ClearTarget",
+ "ClearTutorials",
+ "ClickAuctionSellItemButton",
+ "ClickLandmark",
+ "ClickPetitionButton",
+ "ClickSendMailItemButton",
+ "ClickSocketButton",
+ "ClickStablePet",
+ "ClickTargetTradeButton",
+ "ClickTradeButton",
+ "CloseAllBags",
+ "CloseAllWindows",
+ "CloseAllWindows_WithExceptions",
+ "CloseArenaTeamRoster",
+ "CloseAuctionHouse",
+ "CloseAuctionStaticPopups",
+ "CloseBackpack",
+ "CloseBag",
+ "CloseBankBagFrames",
+ "CloseBankFrame",
+ "CloseBattlefield",
+ "CloseCalendarMenus",
+ "CloseChildWindows",
+ "CloseDropDownMenus",
+ "CloseGossip",
+ "CloseGuildBankFrame",
+ "CloseGuildRegistrar",
+ "CloseGuildRoster",
+ "CloseItemText",
+ "CloseLoot",
+ "CloseMail",
+ "CloseMenus",
+ "CloseMerchant",
+ "ClosePetStables",
+ "ClosePetition",
+ "ClosePetitionVendor",
+ "CloseQuest",
+ "CloseSocketInfo",
+ "CloseSpecialWindows",
+ "CloseTabardCreation",
+ "CloseTaxiMap",
+ "CloseTrade",
+ "CloseTradeSkill",
+ "CloseTrainer",
+ "CloseWindows",
+ "CoinPickupCancelButton",
+ "CoinPickupCancelButtonText",
+ "CoinPickupCopperIcon",
+ "CoinPickupFrame",
+ "CoinPickupFrameCancel_Click",
+ "CoinPickupFrameLeft_Click",
+ "CoinPickupFrameOkay_Click",
+ "CoinPickupFrameRight_Click",
+ "CoinPickupFrame_OnChar",
+ "CoinPickupFrame_OnHide",
+ "CoinPickupFrame_OnKeyDown",
+ "CoinPickupFrame_OnKeyUp",
+ "CoinPickupGoldIcon",
+ "CoinPickupLabel",
+ "CoinPickupLeftButton",
+ "CoinPickupOkayButton",
+ "CoinPickupOkayButtonText",
+ "CoinPickupRightButton",
+ "CoinPickupSilverIcon",
+ "CoinPickupText",
+ "CollapseAllFactionHeaders",
+ "CollapseChannelHeader",
+ "CollapseFactionHeader",
+ "CollapseQuestHeader",
+ "CollapseSkillHeader",
+ "CollapseTradeSkillSubClass",
+ "CollapseTrainerSkillLine",
+ "ColorClassesCheckBox_OnClick",
+ "ColorPaperDollStat",
+ "ColorPickerCancelButton",
+ "ColorPickerCancelButtonText",
+ "ColorPickerFrame",
+ "ColorPickerFrameHeader",
+ "ColorPickerOkayButton",
+ "ColorPickerOkayButtonText",
+ "ColorPickerWheel",
+ "ColorPicker_GetPreviousValues",
+ "ColorSwatch",
+ "CombatConfigColors",
+ "CombatConfigColorsColorize",
+ "CombatConfigColorsColorizeDamageNumber",
+ "CombatConfigColorsColorizeDamageNumberCheck",
+ "CombatConfigColorsColorizeDamageNumberCheckText",
+ "CombatConfigColorsColorizeDamageNumberColorSwatch",
+ "CombatConfigColorsColorizeDamageNumberColorSwatchNormalTexture",
+ "CombatConfigColorsColorizeDamageNumberColorSwatchSwatchBg",
+ "CombatConfigColorsColorizeDamageNumberSchoolColoring",
+ "CombatConfigColorsColorizeDamageNumberSchoolColoringText",
+ "CombatConfigColorsColorizeDamageSchool",
+ "CombatConfigColorsColorizeDamageSchoolCheck",
+ "CombatConfigColorsColorizeDamageSchoolCheckText",
+ "CombatConfigColorsColorizeEntireLine",
+ "CombatConfigColorsColorizeEntireLineBySource",
+ "CombatConfigColorsColorizeEntireLineBySourceText",
+ "CombatConfigColorsColorizeEntireLineByTarget",
+ "CombatConfigColorsColorizeEntireLineByTargetText",
+ "CombatConfigColorsColorizeEntireLineCheck",
+ "CombatConfigColorsColorizeEntireLineCheckText",
+ "CombatConfigColorsColorizeSpellNames",
+ "CombatConfigColorsColorizeSpellNamesCheck",
+ "CombatConfigColorsColorizeSpellNamesCheckText",
+ "CombatConfigColorsColorizeSpellNamesColorSwatch",
+ "CombatConfigColorsColorizeSpellNamesColorSwatchNormalTexture",
+ "CombatConfigColorsColorizeSpellNamesColorSwatchSwatchBg",
+ "CombatConfigColorsColorizeSpellNamesSchoolColoring",
+ "CombatConfigColorsColorizeSpellNamesSchoolColoringText",
+ "CombatConfigColorsColorizeUnitName",
+ "CombatConfigColorsColorizeUnitNameCheck",
+ "CombatConfigColorsColorizeUnitNameCheckText",
+ "CombatConfigColorsExampleString1",
+ "CombatConfigColorsExampleString2",
+ "CombatConfigColorsExampleTitle",
+ "CombatConfigColorsHighlighting",
+ "CombatConfigColorsHighlightingAbility",
+ "CombatConfigColorsHighlightingAbilityText",
+ "CombatConfigColorsHighlightingDamage",
+ "CombatConfigColorsHighlightingDamageText",
+ "CombatConfigColorsHighlightingLine",
+ "CombatConfigColorsHighlightingLineText",
+ "CombatConfigColorsHighlightingSchool",
+ "CombatConfigColorsHighlightingSchoolText",
+ "CombatConfigColorsHighlightingTitle",
+ "CombatConfigColorsUnitColors",
+ "CombatConfigColorsUnitColorsSwatch1",
+ "CombatConfigColorsUnitColorsSwatch1ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch1ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch1ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch1Text",
+ "CombatConfigColorsUnitColorsSwatch2",
+ "CombatConfigColorsUnitColorsSwatch2ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch2ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch2ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch2Text",
+ "CombatConfigColorsUnitColorsSwatch3",
+ "CombatConfigColorsUnitColorsSwatch3ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch3ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch3ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch3Text",
+ "CombatConfigColorsUnitColorsSwatch4",
+ "CombatConfigColorsUnitColorsSwatch4ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch4ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch4ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch4Text",
+ "CombatConfigColorsUnitColorsSwatch5",
+ "CombatConfigColorsUnitColorsSwatch5ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch5ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch5ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch5Text",
+ "CombatConfigColorsUnitColorsSwatch6",
+ "CombatConfigColorsUnitColorsSwatch6ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch6ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch6ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch6Text",
+ "CombatConfigColorsUnitColorsSwatch7",
+ "CombatConfigColorsUnitColorsSwatch7ColorSwatch",
+ "CombatConfigColorsUnitColorsSwatch7ColorSwatchNormalTexture",
+ "CombatConfigColorsUnitColorsSwatch7ColorSwatchSwatchBg",
+ "CombatConfigColorsUnitColorsSwatch7Text",
+ "CombatConfigColorsUnitColorsTitle",
+ "CombatConfigFormatting",
+ "CombatConfigFormattingExampleString1",
+ "CombatConfigFormattingExampleString2",
+ "CombatConfigFormattingExampleTitle",
+ "CombatConfigFormattingFullText",
+ "CombatConfigFormattingFullTextText",
+ "CombatConfigFormattingItemNames",
+ "CombatConfigFormattingItemNamesText",
+ "CombatConfigFormattingShowBraces",
+ "CombatConfigFormattingShowBracesText",
+ "CombatConfigFormattingShowTimeStamp",
+ "CombatConfigFormattingShowTimeStampText",
+ "CombatConfigFormattingSpellNames",
+ "CombatConfigFormattingSpellNamesText",
+ "CombatConfigFormattingUnitNames",
+ "CombatConfigFormattingUnitNamesText",
+ "CombatConfigMessageSources",
+ "CombatConfigMessageSourcesDoneBy",
+ "CombatConfigMessageSourcesDoneByCheckBox1",
+ "CombatConfigMessageSourcesDoneByCheckBox1Check",
+ "CombatConfigMessageSourcesDoneByCheckBox1CheckText",
+ "CombatConfigMessageSourcesDoneByCheckBox2",
+ "CombatConfigMessageSourcesDoneByCheckBox2Check",
+ "CombatConfigMessageSourcesDoneByCheckBox2CheckText",
+ "CombatConfigMessageSourcesDoneByCheckBox3",
+ "CombatConfigMessageSourcesDoneByCheckBox3Check",
+ "CombatConfigMessageSourcesDoneByCheckBox3CheckText",
+ "CombatConfigMessageSourcesDoneByCheckBox4",
+ "CombatConfigMessageSourcesDoneByCheckBox4Check",
+ "CombatConfigMessageSourcesDoneByCheckBox4CheckText",
+ "CombatConfigMessageSourcesDoneByCheckBox5",
+ "CombatConfigMessageSourcesDoneByCheckBox5Check",
+ "CombatConfigMessageSourcesDoneByCheckBox5CheckText",
+ "CombatConfigMessageSourcesDoneByCheckBox6",
+ "CombatConfigMessageSourcesDoneByCheckBox6Check",
+ "CombatConfigMessageSourcesDoneByCheckBox6CheckText",
+ "CombatConfigMessageSourcesDoneByCheckBox7",
+ "CombatConfigMessageSourcesDoneByCheckBox7Check",
+ "CombatConfigMessageSourcesDoneByCheckBox7CheckText",
+ "CombatConfigMessageSourcesDoneByTitle",
+ "CombatConfigMessageSourcesDoneTo",
+ "CombatConfigMessageSourcesDoneToCheckBox1",
+ "CombatConfigMessageSourcesDoneToCheckBox1Check",
+ "CombatConfigMessageSourcesDoneToCheckBox1CheckText",
+ "CombatConfigMessageSourcesDoneToCheckBox2",
+ "CombatConfigMessageSourcesDoneToCheckBox2Check",
+ "CombatConfigMessageSourcesDoneToCheckBox2CheckText",
+ "CombatConfigMessageSourcesDoneToCheckBox3",
+ "CombatConfigMessageSourcesDoneToCheckBox3Check",
+ "CombatConfigMessageSourcesDoneToCheckBox3CheckText",
+ "CombatConfigMessageSourcesDoneToCheckBox4",
+ "CombatConfigMessageSourcesDoneToCheckBox4Check",
+ "CombatConfigMessageSourcesDoneToCheckBox4CheckText",
+ "CombatConfigMessageSourcesDoneToCheckBox5",
+ "CombatConfigMessageSourcesDoneToCheckBox5Check",
+ "CombatConfigMessageSourcesDoneToCheckBox5CheckText",
+ "CombatConfigMessageSourcesDoneToCheckBox6",
+ "CombatConfigMessageSourcesDoneToCheckBox6Check",
+ "CombatConfigMessageSourcesDoneToCheckBox6CheckText",
+ "CombatConfigMessageSourcesDoneToCheckBox7",
+ "CombatConfigMessageSourcesDoneToCheckBox7Check",
+ "CombatConfigMessageSourcesDoneToCheckBox7CheckText",
+ "CombatConfigMessageSourcesDoneToTitle",
+ "CombatConfigMessageTypes",
+ "CombatConfigMessageTypesLeft",
+ "CombatConfigMessageTypesLeftCheckBox1",
+ "CombatConfigMessageTypesLeftCheckBox1Text",
+ "CombatConfigMessageTypesLeftCheckBox1_1",
+ "CombatConfigMessageTypesLeftCheckBox1_1Text",
+ "CombatConfigMessageTypesLeftCheckBox1_2",
+ "CombatConfigMessageTypesLeftCheckBox1_2Text",
+ "CombatConfigMessageTypesLeftCheckBox2",
+ "CombatConfigMessageTypesLeftCheckBox2Text",
+ "CombatConfigMessageTypesLeftCheckBox2_1",
+ "CombatConfigMessageTypesLeftCheckBox2_1Text",
+ "CombatConfigMessageTypesLeftCheckBox2_2",
+ "CombatConfigMessageTypesLeftCheckBox2_2Text",
+ "CombatConfigMessageTypesLeftCheckBox3",
+ "CombatConfigMessageTypesLeftCheckBox3Text",
+ "CombatConfigMessageTypesLeftCheckBox3_1",
+ "CombatConfigMessageTypesLeftCheckBox3_1Text",
+ "CombatConfigMessageTypesLeftCheckBox3_2",
+ "CombatConfigMessageTypesLeftCheckBox3_2Text",
+ "CombatConfigMessageTypesLeftCheckBox3_3",
+ "CombatConfigMessageTypesLeftCheckBox3_3Text",
+ "CombatConfigMessageTypesLeftCheckBox3_4",
+ "CombatConfigMessageTypesLeftCheckBox3_4Text",
+ "CombatConfigMessageTypesLeftCheckBox4",
+ "CombatConfigMessageTypesLeftCheckBox4Text",
+ "CombatConfigMessageTypesLeftCheckBox4_1",
+ "CombatConfigMessageTypesLeftCheckBox4_1Text",
+ "CombatConfigMessageTypesLeftCheckBox4_2",
+ "CombatConfigMessageTypesLeftCheckBox4_2Text",
+ "CombatConfigMessageTypesLeftCheckBox4_3",
+ "CombatConfigMessageTypesLeftCheckBox4_3Text",
+ "CombatConfigMessageTypesLeftCheckBox4_4",
+ "CombatConfigMessageTypesLeftCheckBox4_4Text",
+ "CombatConfigMessageTypesMisc",
+ "CombatConfigMessageTypesMiscCheckBox1",
+ "CombatConfigMessageTypesMiscCheckBox1Text",
+ "CombatConfigMessageTypesMiscCheckBox2",
+ "CombatConfigMessageTypesMiscCheckBox2Text",
+ "CombatConfigMessageTypesMiscCheckBox3",
+ "CombatConfigMessageTypesMiscCheckBox3Text",
+ "CombatConfigMessageTypesMiscCheckBox4",
+ "CombatConfigMessageTypesMiscCheckBox4Text",
+ "CombatConfigMessageTypesRight",
+ "CombatConfigMessageTypesRightCheckBox1",
+ "CombatConfigMessageTypesRightCheckBox1Text",
+ "CombatConfigMessageTypesRightCheckBox1_1",
+ "CombatConfigMessageTypesRightCheckBox1_10",
+ "CombatConfigMessageTypesRightCheckBox1_10Text",
+ "CombatConfigMessageTypesRightCheckBox1_1Text",
+ "CombatConfigMessageTypesRightCheckBox1_2",
+ "CombatConfigMessageTypesRightCheckBox1_2Text",
+ "CombatConfigMessageTypesRightCheckBox1_3",
+ "CombatConfigMessageTypesRightCheckBox1_3Text",
+ "CombatConfigMessageTypesRightCheckBox1_4",
+ "CombatConfigMessageTypesRightCheckBox1_4Text",
+ "CombatConfigMessageTypesRightCheckBox1_5",
+ "CombatConfigMessageTypesRightCheckBox1_5Text",
+ "CombatConfigMessageTypesRightCheckBox1_6",
+ "CombatConfigMessageTypesRightCheckBox1_6Text",
+ "CombatConfigMessageTypesRightCheckBox1_7",
+ "CombatConfigMessageTypesRightCheckBox1_7Text",
+ "CombatConfigMessageTypesRightCheckBox1_8",
+ "CombatConfigMessageTypesRightCheckBox1_8Text",
+ "CombatConfigMessageTypesRightCheckBox1_9",
+ "CombatConfigMessageTypesRightCheckBox1_9Text",
+ "CombatConfigMessageTypesRightCheckBox2",
+ "CombatConfigMessageTypesRightCheckBox2Text",
+ "CombatConfigMessageTypesRightCheckBox2_1",
+ "CombatConfigMessageTypesRightCheckBox2_1Text",
+ "CombatConfigMessageTypesRightCheckBox2_2",
+ "CombatConfigMessageTypesRightCheckBox2_2Text",
+ "CombatConfigMessageTypesRightCheckBox2_3",
+ "CombatConfigMessageTypesRightCheckBox2_3Text",
+ "CombatConfigSettings",
+ "CombatConfigSettingsNameEditBox",
+ "CombatConfigSettingsNameEditBoxLeft",
+ "CombatConfigSettingsNameEditBoxMiddle",
+ "CombatConfigSettingsNameEditBoxRight",
+ "CombatConfigSettingsParty",
+ "CombatConfigSettingsPartyText",
+ "CombatConfigSettingsRaid",
+ "CombatConfigSettingsRaidText",
+ "CombatConfigSettingsSaveButton",
+ "CombatConfigSettingsSaveButtonText",
+ "CombatConfigSettingsShowQuickButton",
+ "CombatConfigSettingsShowQuickButtonText",
+ "CombatConfigSettingsSolo",
+ "CombatConfigSettingsSoloText",
+ "CombatConfigTab1",
+ "CombatConfigTab1Left",
+ "CombatConfigTab1Middle",
+ "CombatConfigTab1Right",
+ "CombatConfigTab1Text",
+ "CombatConfigTab2",
+ "CombatConfigTab2Left",
+ "CombatConfigTab2Middle",
+ "CombatConfigTab2Right",
+ "CombatConfigTab2Text",
+ "CombatConfigTab3",
+ "CombatConfigTab3Left",
+ "CombatConfigTab3Middle",
+ "CombatConfigTab3Right",
+ "CombatConfigTab3Text",
+ "CombatConfigTab4",
+ "CombatConfigTab4Left",
+ "CombatConfigTab4Middle",
+ "CombatConfigTab4Right",
+ "CombatConfigTab4Text",
+ "CombatConfigTab5",
+ "CombatConfigTab5Left",
+ "CombatConfigTab5Middle",
+ "CombatConfigTab5Right",
+ "CombatConfigTab5Text",
+ "CombatConfig_Colorize_Update",
+ "CombatConfig_CreateCombatFilter",
+ "CombatConfig_DeleteCurrentCombatFilter",
+ "CombatConfig_Formatting_Update",
+ "CombatConfig_SetCombatFiltersToDefault",
+ "CombatConfig_SetFilterName",
+ "CombatConfig_Settings_Update",
+ "CombatFeedbackText",
+ "CombatFeedback_Initialize",
+ "CombatFeedback_OnCombatEvent",
+ "CombatFeedback_OnUpdate",
+ "CombatFeedback_StartFullscreenStatus",
+ "CombatFeedback_StopFullscreenStatus",
+ "CombatLogAddFilter",
+ "CombatLogAdvanceEntry",
+ "CombatLogClearEntries",
+ "CombatLogDefaultButton",
+ "CombatLogDropDown",
+ "CombatLogDropDownButton",
+ "CombatLogDropDownButtonDisabledTexture",
+ "CombatLogDropDownButtonHighlightTexture",
+ "CombatLogDropDownButtonNormalTexture",
+ "CombatLogDropDownButtonPushedTexture",
+ "CombatLogDropDownLeft",
+ "CombatLogDropDownMiddle",
+ "CombatLogDropDownRight",
+ "CombatLogDropDownText",
+ "CombatLogFont",
+ "CombatLogGetCurrentEntry",
+ "CombatLogGetCurrentEventInfo",
+ "CombatLogGetNumEntries",
+ "CombatLogGetRetentionTime",
+ "CombatLogMenuChatTypeGroups",
+ "CombatLogQuickButtonFrame",
+ "CombatLogQuickButtonFrameButton1",
+ "CombatLogQuickButtonFrameButton2",
+ "CombatLogQuickButtonFrameButton3",
+ "CombatLogQuickButtonFrame_Custom",
+ "CombatLogQuickButtonFrame_CustomAdditionalFilterButton",
+ "CombatLogQuickButtonFrame_CustomProgressBar",
+ "CombatLogQuickButtonFrame_CustomTexture",
+ "CombatLogResetFilter",
+ "CombatLogSetCurrentEntry",
+ "CombatLogSetRetentionTime",
+ "CombatLogUpdateFrame",
+ "CombatLog_AddEvent",
+ "CombatLog_Color_ColorArrayByEventType",
+ "CombatLog_Color_ColorArrayBySchool",
+ "CombatLog_Color_ColorArrayByUnitType",
+ "CombatLog_Color_ColorStringByEventType",
+ "CombatLog_Color_ColorStringBySchool",
+ "CombatLog_Color_ColorStringByUnitType",
+ "CombatLog_Color_FloatToText",
+ "CombatLog_Color_HighlightColorArray",
+ "CombatLog_LoadUI",
+ "CombatLog_Object_IsA",
+ "CombatLog_OnEvent",
+ "CombatLog_String_DamageResultString",
+ "CombatLog_String_GetIcon",
+ "CombatLog_String_GetToken",
+ "CombatLog_String_PowerType",
+ "CombatLog_String_SchoolString",
+ "CombatPanelOptions",
+ "CombatText",
+ "CombatText1",
+ "CombatText10",
+ "CombatText11",
+ "CombatText12",
+ "CombatText13",
+ "CombatText14",
+ "CombatText15",
+ "CombatText16",
+ "CombatText17",
+ "CombatText18",
+ "CombatText19",
+ "CombatText2",
+ "CombatText20",
+ "CombatText3",
+ "CombatText4",
+ "CombatText5",
+ "CombatText6",
+ "CombatText7",
+ "CombatText8",
+ "CombatText9",
+ "CombatTextFont",
+ "CombatTextSetActiveUnit",
+ "CombatText_AddMessage",
+ "CombatText_ClearAnimationList",
+ "CombatText_FountainScroll",
+ "CombatText_GetAvailableString",
+ "CombatText_GetOldestString",
+ "CombatText_OnEvent",
+ "CombatText_OnLoad",
+ "CombatText_OnUpdate",
+ "CombatText_RemoveMessage",
+ "CombatText_StandardScroll",
+ "CombatText_UpdateDisplayedMessages",
+ "ComboFrame",
+ "ComboFrame_OnEvent",
+ "ComboFrame_Update",
+ "ComboPoint1",
+ "ComboPoint1Highlight",
+ "ComboPoint1Shine",
+ "ComboPoint2",
+ "ComboPoint2Highlight",
+ "ComboPoint2Shine",
+ "ComboPoint3",
+ "ComboPoint3Highlight",
+ "ComboPoint3Shine",
+ "ComboPoint4",
+ "ComboPoint4Highlight",
+ "ComboPoint4Shine",
+ "ComboPoint5",
+ "ComboPoint5Highlight",
+ "ComboPoint5Shine",
+ "ComboPointShineFadeIn",
+ "ComboPointShineFadeOut",
+ "CommentatorAddPlayer",
+ "CommentatorEnterInstance",
+ "CommentatorExitInstance",
+ "CommentatorFollowPlayer",
+ "CommentatorGetCamera",
+ "CommentatorGetCurrentMapID",
+ "CommentatorGetInstanceInfo",
+ "CommentatorGetMapInfo",
+ "CommentatorGetMode",
+ "CommentatorGetNumMaps",
+ "CommentatorGetNumPlayers",
+ "CommentatorGetPlayerInfo",
+ "CommentatorGetSkirmishMode",
+ "CommentatorGetSkirmishQueueCount",
+ "CommentatorGetSkirmishQueuePlayerInfo",
+ "CommentatorLookatPlayer",
+ "CommentatorRemovePlayer",
+ "CommentatorRequestSkirmishMode",
+ "CommentatorRequestSkirmishQueueData",
+ "CommentatorSetBattlemaster",
+ "CommentatorSetCamera",
+ "CommentatorSetCameraCollision",
+ "CommentatorSetMapAndInstanceIndex",
+ "CommentatorSetMode",
+ "CommentatorSetMoveSpeed",
+ "CommentatorSetPlayerIndex",
+ "CommentatorSetSkirmishMatchmakingMode",
+ "CommentatorSetTargetHeightOffset",
+ "CommentatorStartInstance",
+ "CommentatorStartSkirmishMatch",
+ "CommentatorToggleMode",
+ "CommentatorUpdateMapInfo",
+ "CommentatorUpdatePlayerInfo",
+ "CommentatorZoomIn",
+ "CommentatorZoomOut",
+ "CompanionButton1",
+ "CompanionButton10",
+ "CompanionButton10ActiveTexture",
+ "CompanionButton10Cooldown",
+ "CompanionButton10Highlight",
+ "CompanionButton11",
+ "CompanionButton11ActiveTexture",
+ "CompanionButton11Cooldown",
+ "CompanionButton11Highlight",
+ "CompanionButton12",
+ "CompanionButton12ActiveTexture",
+ "CompanionButton12Cooldown",
+ "CompanionButton12Highlight",
+ "CompanionButton1ActiveTexture",
+ "CompanionButton1Cooldown",
+ "CompanionButton1Highlight",
+ "CompanionButton2",
+ "CompanionButton2ActiveTexture",
+ "CompanionButton2Cooldown",
+ "CompanionButton2Highlight",
+ "CompanionButton3",
+ "CompanionButton3ActiveTexture",
+ "CompanionButton3Cooldown",
+ "CompanionButton3Highlight",
+ "CompanionButton4",
+ "CompanionButton4ActiveTexture",
+ "CompanionButton4Cooldown",
+ "CompanionButton4Highlight",
+ "CompanionButton5",
+ "CompanionButton5ActiveTexture",
+ "CompanionButton5Cooldown",
+ "CompanionButton5Highlight",
+ "CompanionButton6",
+ "CompanionButton6ActiveTexture",
+ "CompanionButton6Cooldown",
+ "CompanionButton6Highlight",
+ "CompanionButton7",
+ "CompanionButton7ActiveTexture",
+ "CompanionButton7Cooldown",
+ "CompanionButton7Highlight",
+ "CompanionButton8",
+ "CompanionButton8ActiveTexture",
+ "CompanionButton8Cooldown",
+ "CompanionButton8Highlight",
+ "CompanionButton9",
+ "CompanionButton9ActiveTexture",
+ "CompanionButton9Cooldown",
+ "CompanionButton9Highlight",
+ "CompanionButton_OnClick",
+ "CompanionButton_OnDrag",
+ "CompanionButton_OnEnter",
+ "CompanionButton_OnLoad",
+ "CompanionButton_OnModifiedClick",
+ "CompanionModelFrame",
+ "CompanionModelFrameRotateLeftButton",
+ "CompanionModelFrameRotateRightButton",
+ "CompanionNextPageButton",
+ "CompanionPageNumber",
+ "CompanionPrevPageButton",
+ "CompanionSelectedName",
+ "CompanionSummonButton",
+ "CompanionSummonButtonText",
+ "CompanionSummonButton_OnClick",
+ "ComplainChat",
+ "ComplainInboxItem",
+ "CompleteLFGRoleCheck",
+ "CompleteQuest",
+ "ComputePetBonus",
+ "ConfirmAcceptQuest",
+ "ConfirmBindOnUse",
+ "ConfirmBinder",
+ "ConfirmLootRoll",
+ "ConfirmLootSlot",
+ "ConfirmReadyCheck",
+ "ConfirmSummon",
+ "ConfirmTalentWipe",
+ "ConsoleAddMessage",
+ "ConsoleExec",
+ "ConsolePrint",
+ "ConsolidatedBuffs",
+ "ConsolidatedBuffsContainer",
+ "ConsolidatedBuffsCount",
+ "ConsolidatedBuffsDuration",
+ "ConsolidatedBuffsIcon",
+ "ConsolidatedBuffsTooltip",
+ "ConsolidatedBuffs_OnEnter",
+ "ConsolidatedBuffs_OnHide",
+ "ConsolidatedBuffs_OnShow",
+ "ConsolidatedBuffs_OnUpdate",
+ "ConsolidatedBuffs_UpdateAllAnchors",
+ "ContainerFrame1",
+ "ContainerFrame10",
+ "ContainerFrame10Background1Slot",
+ "ContainerFrame10BackgroundBottom",
+ "ContainerFrame10BackgroundMiddle1",
+ "ContainerFrame10BackgroundMiddle2",
+ "ContainerFrame10BackgroundTop",
+ "ContainerFrame10CloseButton",
+ "ContainerFrame10Item1",
+ "ContainerFrame10Item10",
+ "ContainerFrame10Item10Cooldown",
+ "ContainerFrame10Item10Count",
+ "ContainerFrame10Item10IconQuestTexture",
+ "ContainerFrame10Item10IconTexture",
+ "ContainerFrame10Item10NormalTexture",
+ "ContainerFrame10Item10Stock",
+ "ContainerFrame10Item11",
+ "ContainerFrame10Item11Cooldown",
+ "ContainerFrame10Item11Count",
+ "ContainerFrame10Item11IconQuestTexture",
+ "ContainerFrame10Item11IconTexture",
+ "ContainerFrame10Item11NormalTexture",
+ "ContainerFrame10Item11Stock",
+ "ContainerFrame10Item12",
+ "ContainerFrame10Item12Cooldown",
+ "ContainerFrame10Item12Count",
+ "ContainerFrame10Item12IconQuestTexture",
+ "ContainerFrame10Item12IconTexture",
+ "ContainerFrame10Item12NormalTexture",
+ "ContainerFrame10Item12Stock",
+ "ContainerFrame10Item13",
+ "ContainerFrame10Item13Cooldown",
+ "ContainerFrame10Item13Count",
+ "ContainerFrame10Item13IconQuestTexture",
+ "ContainerFrame10Item13IconTexture",
+ "ContainerFrame10Item13NormalTexture",
+ "ContainerFrame10Item13Stock",
+ "ContainerFrame10Item14",
+ "ContainerFrame10Item14Cooldown",
+ "ContainerFrame10Item14Count",
+ "ContainerFrame10Item14IconQuestTexture",
+ "ContainerFrame10Item14IconTexture",
+ "ContainerFrame10Item14NormalTexture",
+ "ContainerFrame10Item14Stock",
+ "ContainerFrame10Item15",
+ "ContainerFrame10Item15Cooldown",
+ "ContainerFrame10Item15Count",
+ "ContainerFrame10Item15IconQuestTexture",
+ "ContainerFrame10Item15IconTexture",
+ "ContainerFrame10Item15NormalTexture",
+ "ContainerFrame10Item15Stock",
+ "ContainerFrame10Item16",
+ "ContainerFrame10Item16Cooldown",
+ "ContainerFrame10Item16Count",
+ "ContainerFrame10Item16IconQuestTexture",
+ "ContainerFrame10Item16IconTexture",
+ "ContainerFrame10Item16NormalTexture",
+ "ContainerFrame10Item16Stock",
+ "ContainerFrame10Item17",
+ "ContainerFrame10Item17Cooldown",
+ "ContainerFrame10Item17Count",
+ "ContainerFrame10Item17IconQuestTexture",
+ "ContainerFrame10Item17IconTexture",
+ "ContainerFrame10Item17NormalTexture",
+ "ContainerFrame10Item17Stock",
+ "ContainerFrame10Item18",
+ "ContainerFrame10Item18Cooldown",
+ "ContainerFrame10Item18Count",
+ "ContainerFrame10Item18IconQuestTexture",
+ "ContainerFrame10Item18IconTexture",
+ "ContainerFrame10Item18NormalTexture",
+ "ContainerFrame10Item18Stock",
+ "ContainerFrame10Item19",
+ "ContainerFrame10Item19Cooldown",
+ "ContainerFrame10Item19Count",
+ "ContainerFrame10Item19IconQuestTexture",
+ "ContainerFrame10Item19IconTexture",
+ "ContainerFrame10Item19NormalTexture",
+ "ContainerFrame10Item19Stock",
+ "ContainerFrame10Item1Cooldown",
+ "ContainerFrame10Item1Count",
+ "ContainerFrame10Item1IconQuestTexture",
+ "ContainerFrame10Item1IconTexture",
+ "ContainerFrame10Item1NormalTexture",
+ "ContainerFrame10Item1Stock",
+ "ContainerFrame10Item2",
+ "ContainerFrame10Item20",
+ "ContainerFrame10Item20Cooldown",
+ "ContainerFrame10Item20Count",
+ "ContainerFrame10Item20IconQuestTexture",
+ "ContainerFrame10Item20IconTexture",
+ "ContainerFrame10Item20NormalTexture",
+ "ContainerFrame10Item20Stock",
+ "ContainerFrame10Item21",
+ "ContainerFrame10Item21Cooldown",
+ "ContainerFrame10Item21Count",
+ "ContainerFrame10Item21IconQuestTexture",
+ "ContainerFrame10Item21IconTexture",
+ "ContainerFrame10Item21NormalTexture",
+ "ContainerFrame10Item21Stock",
+ "ContainerFrame10Item22",
+ "ContainerFrame10Item22Cooldown",
+ "ContainerFrame10Item22Count",
+ "ContainerFrame10Item22IconQuestTexture",
+ "ContainerFrame10Item22IconTexture",
+ "ContainerFrame10Item22NormalTexture",
+ "ContainerFrame10Item22Stock",
+ "ContainerFrame10Item23",
+ "ContainerFrame10Item23Cooldown",
+ "ContainerFrame10Item23Count",
+ "ContainerFrame10Item23IconQuestTexture",
+ "ContainerFrame10Item23IconTexture",
+ "ContainerFrame10Item23NormalTexture",
+ "ContainerFrame10Item23Stock",
+ "ContainerFrame10Item24",
+ "ContainerFrame10Item24Cooldown",
+ "ContainerFrame10Item24Count",
+ "ContainerFrame10Item24IconQuestTexture",
+ "ContainerFrame10Item24IconTexture",
+ "ContainerFrame10Item24NormalTexture",
+ "ContainerFrame10Item24Stock",
+ "ContainerFrame10Item25",
+ "ContainerFrame10Item25Cooldown",
+ "ContainerFrame10Item25Count",
+ "ContainerFrame10Item25IconQuestTexture",
+ "ContainerFrame10Item25IconTexture",
+ "ContainerFrame10Item25NormalTexture",
+ "ContainerFrame10Item25Stock",
+ "ContainerFrame10Item26",
+ "ContainerFrame10Item26Cooldown",
+ "ContainerFrame10Item26Count",
+ "ContainerFrame10Item26IconQuestTexture",
+ "ContainerFrame10Item26IconTexture",
+ "ContainerFrame10Item26NormalTexture",
+ "ContainerFrame10Item26Stock",
+ "ContainerFrame10Item27",
+ "ContainerFrame10Item27Cooldown",
+ "ContainerFrame10Item27Count",
+ "ContainerFrame10Item27IconQuestTexture",
+ "ContainerFrame10Item27IconTexture",
+ "ContainerFrame10Item27NormalTexture",
+ "ContainerFrame10Item27Stock",
+ "ContainerFrame10Item28",
+ "ContainerFrame10Item28Cooldown",
+ "ContainerFrame10Item28Count",
+ "ContainerFrame10Item28IconQuestTexture",
+ "ContainerFrame10Item28IconTexture",
+ "ContainerFrame10Item28NormalTexture",
+ "ContainerFrame10Item28Stock",
+ "ContainerFrame10Item29",
+ "ContainerFrame10Item29Cooldown",
+ "ContainerFrame10Item29Count",
+ "ContainerFrame10Item29IconQuestTexture",
+ "ContainerFrame10Item29IconTexture",
+ "ContainerFrame10Item29NormalTexture",
+ "ContainerFrame10Item29Stock",
+ "ContainerFrame10Item2Cooldown",
+ "ContainerFrame10Item2Count",
+ "ContainerFrame10Item2IconQuestTexture",
+ "ContainerFrame10Item2IconTexture",
+ "ContainerFrame10Item2NormalTexture",
+ "ContainerFrame10Item2Stock",
+ "ContainerFrame10Item3",
+ "ContainerFrame10Item30",
+ "ContainerFrame10Item30Cooldown",
+ "ContainerFrame10Item30Count",
+ "ContainerFrame10Item30IconQuestTexture",
+ "ContainerFrame10Item30IconTexture",
+ "ContainerFrame10Item30NormalTexture",
+ "ContainerFrame10Item30Stock",
+ "ContainerFrame10Item31",
+ "ContainerFrame10Item31Cooldown",
+ "ContainerFrame10Item31Count",
+ "ContainerFrame10Item31IconQuestTexture",
+ "ContainerFrame10Item31IconTexture",
+ "ContainerFrame10Item31NormalTexture",
+ "ContainerFrame10Item31Stock",
+ "ContainerFrame10Item32",
+ "ContainerFrame10Item32Cooldown",
+ "ContainerFrame10Item32Count",
+ "ContainerFrame10Item32IconQuestTexture",
+ "ContainerFrame10Item32IconTexture",
+ "ContainerFrame10Item32NormalTexture",
+ "ContainerFrame10Item32Stock",
+ "ContainerFrame10Item33",
+ "ContainerFrame10Item33Cooldown",
+ "ContainerFrame10Item33Count",
+ "ContainerFrame10Item33IconQuestTexture",
+ "ContainerFrame10Item33IconTexture",
+ "ContainerFrame10Item33NormalTexture",
+ "ContainerFrame10Item33Stock",
+ "ContainerFrame10Item34",
+ "ContainerFrame10Item34Cooldown",
+ "ContainerFrame10Item34Count",
+ "ContainerFrame10Item34IconQuestTexture",
+ "ContainerFrame10Item34IconTexture",
+ "ContainerFrame10Item34NormalTexture",
+ "ContainerFrame10Item34Stock",
+ "ContainerFrame10Item35",
+ "ContainerFrame10Item35Cooldown",
+ "ContainerFrame10Item35Count",
+ "ContainerFrame10Item35IconQuestTexture",
+ "ContainerFrame10Item35IconTexture",
+ "ContainerFrame10Item35NormalTexture",
+ "ContainerFrame10Item35Stock",
+ "ContainerFrame10Item36",
+ "ContainerFrame10Item36Cooldown",
+ "ContainerFrame10Item36Count",
+ "ContainerFrame10Item36IconQuestTexture",
+ "ContainerFrame10Item36IconTexture",
+ "ContainerFrame10Item36NormalTexture",
+ "ContainerFrame10Item36Stock",
+ "ContainerFrame10Item3Cooldown",
+ "ContainerFrame10Item3Count",
+ "ContainerFrame10Item3IconQuestTexture",
+ "ContainerFrame10Item3IconTexture",
+ "ContainerFrame10Item3NormalTexture",
+ "ContainerFrame10Item3Stock",
+ "ContainerFrame10Item4",
+ "ContainerFrame10Item4Cooldown",
+ "ContainerFrame10Item4Count",
+ "ContainerFrame10Item4IconQuestTexture",
+ "ContainerFrame10Item4IconTexture",
+ "ContainerFrame10Item4NormalTexture",
+ "ContainerFrame10Item4Stock",
+ "ContainerFrame10Item5",
+ "ContainerFrame10Item5Cooldown",
+ "ContainerFrame10Item5Count",
+ "ContainerFrame10Item5IconQuestTexture",
+ "ContainerFrame10Item5IconTexture",
+ "ContainerFrame10Item5NormalTexture",
+ "ContainerFrame10Item5Stock",
+ "ContainerFrame10Item6",
+ "ContainerFrame10Item6Cooldown",
+ "ContainerFrame10Item6Count",
+ "ContainerFrame10Item6IconQuestTexture",
+ "ContainerFrame10Item6IconTexture",
+ "ContainerFrame10Item6NormalTexture",
+ "ContainerFrame10Item6Stock",
+ "ContainerFrame10Item7",
+ "ContainerFrame10Item7Cooldown",
+ "ContainerFrame10Item7Count",
+ "ContainerFrame10Item7IconQuestTexture",
+ "ContainerFrame10Item7IconTexture",
+ "ContainerFrame10Item7NormalTexture",
+ "ContainerFrame10Item7Stock",
+ "ContainerFrame10Item8",
+ "ContainerFrame10Item8Cooldown",
+ "ContainerFrame10Item8Count",
+ "ContainerFrame10Item8IconQuestTexture",
+ "ContainerFrame10Item8IconTexture",
+ "ContainerFrame10Item8NormalTexture",
+ "ContainerFrame10Item8Stock",
+ "ContainerFrame10Item9",
+ "ContainerFrame10Item9Cooldown",
+ "ContainerFrame10Item9Count",
+ "ContainerFrame10Item9IconQuestTexture",
+ "ContainerFrame10Item9IconTexture",
+ "ContainerFrame10Item9NormalTexture",
+ "ContainerFrame10Item9Stock",
+ "ContainerFrame10MoneyFrame",
+ "ContainerFrame10MoneyFrameCopperButton",
+ "ContainerFrame10MoneyFrameCopperButtonText",
+ "ContainerFrame10MoneyFrameGoldButton",
+ "ContainerFrame10MoneyFrameGoldButtonText",
+ "ContainerFrame10MoneyFrameSilverButton",
+ "ContainerFrame10MoneyFrameSilverButtonText",
+ "ContainerFrame10Name",
+ "ContainerFrame10Portrait",
+ "ContainerFrame10PortraitButton",
+ "ContainerFrame11",
+ "ContainerFrame11Background1Slot",
+ "ContainerFrame11BackgroundBottom",
+ "ContainerFrame11BackgroundMiddle1",
+ "ContainerFrame11BackgroundMiddle2",
+ "ContainerFrame11BackgroundTop",
+ "ContainerFrame11CloseButton",
+ "ContainerFrame11Item1",
+ "ContainerFrame11Item10",
+ "ContainerFrame11Item10Cooldown",
+ "ContainerFrame11Item10Count",
+ "ContainerFrame11Item10IconQuestTexture",
+ "ContainerFrame11Item10IconTexture",
+ "ContainerFrame11Item10NormalTexture",
+ "ContainerFrame11Item10Stock",
+ "ContainerFrame11Item11",
+ "ContainerFrame11Item11Cooldown",
+ "ContainerFrame11Item11Count",
+ "ContainerFrame11Item11IconQuestTexture",
+ "ContainerFrame11Item11IconTexture",
+ "ContainerFrame11Item11NormalTexture",
+ "ContainerFrame11Item11Stock",
+ "ContainerFrame11Item12",
+ "ContainerFrame11Item12Cooldown",
+ "ContainerFrame11Item12Count",
+ "ContainerFrame11Item12IconQuestTexture",
+ "ContainerFrame11Item12IconTexture",
+ "ContainerFrame11Item12NormalTexture",
+ "ContainerFrame11Item12Stock",
+ "ContainerFrame11Item13",
+ "ContainerFrame11Item13Cooldown",
+ "ContainerFrame11Item13Count",
+ "ContainerFrame11Item13IconQuestTexture",
+ "ContainerFrame11Item13IconTexture",
+ "ContainerFrame11Item13NormalTexture",
+ "ContainerFrame11Item13Stock",
+ "ContainerFrame11Item14",
+ "ContainerFrame11Item14Cooldown",
+ "ContainerFrame11Item14Count",
+ "ContainerFrame11Item14IconQuestTexture",
+ "ContainerFrame11Item14IconTexture",
+ "ContainerFrame11Item14NormalTexture",
+ "ContainerFrame11Item14Stock",
+ "ContainerFrame11Item15",
+ "ContainerFrame11Item15Cooldown",
+ "ContainerFrame11Item15Count",
+ "ContainerFrame11Item15IconQuestTexture",
+ "ContainerFrame11Item15IconTexture",
+ "ContainerFrame11Item15NormalTexture",
+ "ContainerFrame11Item15Stock",
+ "ContainerFrame11Item16",
+ "ContainerFrame11Item16Cooldown",
+ "ContainerFrame11Item16Count",
+ "ContainerFrame11Item16IconQuestTexture",
+ "ContainerFrame11Item16IconTexture",
+ "ContainerFrame11Item16NormalTexture",
+ "ContainerFrame11Item16Stock",
+ "ContainerFrame11Item17",
+ "ContainerFrame11Item17Cooldown",
+ "ContainerFrame11Item17Count",
+ "ContainerFrame11Item17IconQuestTexture",
+ "ContainerFrame11Item17IconTexture",
+ "ContainerFrame11Item17NormalTexture",
+ "ContainerFrame11Item17Stock",
+ "ContainerFrame11Item18",
+ "ContainerFrame11Item18Cooldown",
+ "ContainerFrame11Item18Count",
+ "ContainerFrame11Item18IconQuestTexture",
+ "ContainerFrame11Item18IconTexture",
+ "ContainerFrame11Item18NormalTexture",
+ "ContainerFrame11Item18Stock",
+ "ContainerFrame11Item19",
+ "ContainerFrame11Item19Cooldown",
+ "ContainerFrame11Item19Count",
+ "ContainerFrame11Item19IconQuestTexture",
+ "ContainerFrame11Item19IconTexture",
+ "ContainerFrame11Item19NormalTexture",
+ "ContainerFrame11Item19Stock",
+ "ContainerFrame11Item1Cooldown",
+ "ContainerFrame11Item1Count",
+ "ContainerFrame11Item1IconQuestTexture",
+ "ContainerFrame11Item1IconTexture",
+ "ContainerFrame11Item1NormalTexture",
+ "ContainerFrame11Item1Stock",
+ "ContainerFrame11Item2",
+ "ContainerFrame11Item20",
+ "ContainerFrame11Item20Cooldown",
+ "ContainerFrame11Item20Count",
+ "ContainerFrame11Item20IconQuestTexture",
+ "ContainerFrame11Item20IconTexture",
+ "ContainerFrame11Item20NormalTexture",
+ "ContainerFrame11Item20Stock",
+ "ContainerFrame11Item21",
+ "ContainerFrame11Item21Cooldown",
+ "ContainerFrame11Item21Count",
+ "ContainerFrame11Item21IconQuestTexture",
+ "ContainerFrame11Item21IconTexture",
+ "ContainerFrame11Item21NormalTexture",
+ "ContainerFrame11Item21Stock",
+ "ContainerFrame11Item22",
+ "ContainerFrame11Item22Cooldown",
+ "ContainerFrame11Item22Count",
+ "ContainerFrame11Item22IconQuestTexture",
+ "ContainerFrame11Item22IconTexture",
+ "ContainerFrame11Item22NormalTexture",
+ "ContainerFrame11Item22Stock",
+ "ContainerFrame11Item23",
+ "ContainerFrame11Item23Cooldown",
+ "ContainerFrame11Item23Count",
+ "ContainerFrame11Item23IconQuestTexture",
+ "ContainerFrame11Item23IconTexture",
+ "ContainerFrame11Item23NormalTexture",
+ "ContainerFrame11Item23Stock",
+ "ContainerFrame11Item24",
+ "ContainerFrame11Item24Cooldown",
+ "ContainerFrame11Item24Count",
+ "ContainerFrame11Item24IconQuestTexture",
+ "ContainerFrame11Item24IconTexture",
+ "ContainerFrame11Item24NormalTexture",
+ "ContainerFrame11Item24Stock",
+ "ContainerFrame11Item25",
+ "ContainerFrame11Item25Cooldown",
+ "ContainerFrame11Item25Count",
+ "ContainerFrame11Item25IconQuestTexture",
+ "ContainerFrame11Item25IconTexture",
+ "ContainerFrame11Item25NormalTexture",
+ "ContainerFrame11Item25Stock",
+ "ContainerFrame11Item26",
+ "ContainerFrame11Item26Cooldown",
+ "ContainerFrame11Item26Count",
+ "ContainerFrame11Item26IconQuestTexture",
+ "ContainerFrame11Item26IconTexture",
+ "ContainerFrame11Item26NormalTexture",
+ "ContainerFrame11Item26Stock",
+ "ContainerFrame11Item27",
+ "ContainerFrame11Item27Cooldown",
+ "ContainerFrame11Item27Count",
+ "ContainerFrame11Item27IconQuestTexture",
+ "ContainerFrame11Item27IconTexture",
+ "ContainerFrame11Item27NormalTexture",
+ "ContainerFrame11Item27Stock",
+ "ContainerFrame11Item28",
+ "ContainerFrame11Item28Cooldown",
+ "ContainerFrame11Item28Count",
+ "ContainerFrame11Item28IconQuestTexture",
+ "ContainerFrame11Item28IconTexture",
+ "ContainerFrame11Item28NormalTexture",
+ "ContainerFrame11Item28Stock",
+ "ContainerFrame11Item29",
+ "ContainerFrame11Item29Cooldown",
+ "ContainerFrame11Item29Count",
+ "ContainerFrame11Item29IconQuestTexture",
+ "ContainerFrame11Item29IconTexture",
+ "ContainerFrame11Item29NormalTexture",
+ "ContainerFrame11Item29Stock",
+ "ContainerFrame11Item2Cooldown",
+ "ContainerFrame11Item2Count",
+ "ContainerFrame11Item2IconQuestTexture",
+ "ContainerFrame11Item2IconTexture",
+ "ContainerFrame11Item2NormalTexture",
+ "ContainerFrame11Item2Stock",
+ "ContainerFrame11Item3",
+ "ContainerFrame11Item30",
+ "ContainerFrame11Item30Cooldown",
+ "ContainerFrame11Item30Count",
+ "ContainerFrame11Item30IconQuestTexture",
+ "ContainerFrame11Item30IconTexture",
+ "ContainerFrame11Item30NormalTexture",
+ "ContainerFrame11Item30Stock",
+ "ContainerFrame11Item31",
+ "ContainerFrame11Item31Cooldown",
+ "ContainerFrame11Item31Count",
+ "ContainerFrame11Item31IconQuestTexture",
+ "ContainerFrame11Item31IconTexture",
+ "ContainerFrame11Item31NormalTexture",
+ "ContainerFrame11Item31Stock",
+ "ContainerFrame11Item32",
+ "ContainerFrame11Item32Cooldown",
+ "ContainerFrame11Item32Count",
+ "ContainerFrame11Item32IconQuestTexture",
+ "ContainerFrame11Item32IconTexture",
+ "ContainerFrame11Item32NormalTexture",
+ "ContainerFrame11Item32Stock",
+ "ContainerFrame11Item33",
+ "ContainerFrame11Item33Cooldown",
+ "ContainerFrame11Item33Count",
+ "ContainerFrame11Item33IconQuestTexture",
+ "ContainerFrame11Item33IconTexture",
+ "ContainerFrame11Item33NormalTexture",
+ "ContainerFrame11Item33Stock",
+ "ContainerFrame11Item34",
+ "ContainerFrame11Item34Cooldown",
+ "ContainerFrame11Item34Count",
+ "ContainerFrame11Item34IconQuestTexture",
+ "ContainerFrame11Item34IconTexture",
+ "ContainerFrame11Item34NormalTexture",
+ "ContainerFrame11Item34Stock",
+ "ContainerFrame11Item35",
+ "ContainerFrame11Item35Cooldown",
+ "ContainerFrame11Item35Count",
+ "ContainerFrame11Item35IconQuestTexture",
+ "ContainerFrame11Item35IconTexture",
+ "ContainerFrame11Item35NormalTexture",
+ "ContainerFrame11Item35Stock",
+ "ContainerFrame11Item36",
+ "ContainerFrame11Item36Cooldown",
+ "ContainerFrame11Item36Count",
+ "ContainerFrame11Item36IconQuestTexture",
+ "ContainerFrame11Item36IconTexture",
+ "ContainerFrame11Item36NormalTexture",
+ "ContainerFrame11Item36Stock",
+ "ContainerFrame11Item3Cooldown",
+ "ContainerFrame11Item3Count",
+ "ContainerFrame11Item3IconQuestTexture",
+ "ContainerFrame11Item3IconTexture",
+ "ContainerFrame11Item3NormalTexture",
+ "ContainerFrame11Item3Stock",
+ "ContainerFrame11Item4",
+ "ContainerFrame11Item4Cooldown",
+ "ContainerFrame11Item4Count",
+ "ContainerFrame11Item4IconQuestTexture",
+ "ContainerFrame11Item4IconTexture",
+ "ContainerFrame11Item4NormalTexture",
+ "ContainerFrame11Item4Stock",
+ "ContainerFrame11Item5",
+ "ContainerFrame11Item5Cooldown",
+ "ContainerFrame11Item5Count",
+ "ContainerFrame11Item5IconQuestTexture",
+ "ContainerFrame11Item5IconTexture",
+ "ContainerFrame11Item5NormalTexture",
+ "ContainerFrame11Item5Stock",
+ "ContainerFrame11Item6",
+ "ContainerFrame11Item6Cooldown",
+ "ContainerFrame11Item6Count",
+ "ContainerFrame11Item6IconQuestTexture",
+ "ContainerFrame11Item6IconTexture",
+ "ContainerFrame11Item6NormalTexture",
+ "ContainerFrame11Item6Stock",
+ "ContainerFrame11Item7",
+ "ContainerFrame11Item7Cooldown",
+ "ContainerFrame11Item7Count",
+ "ContainerFrame11Item7IconQuestTexture",
+ "ContainerFrame11Item7IconTexture",
+ "ContainerFrame11Item7NormalTexture",
+ "ContainerFrame11Item7Stock",
+ "ContainerFrame11Item8",
+ "ContainerFrame11Item8Cooldown",
+ "ContainerFrame11Item8Count",
+ "ContainerFrame11Item8IconQuestTexture",
+ "ContainerFrame11Item8IconTexture",
+ "ContainerFrame11Item8NormalTexture",
+ "ContainerFrame11Item8Stock",
+ "ContainerFrame11Item9",
+ "ContainerFrame11Item9Cooldown",
+ "ContainerFrame11Item9Count",
+ "ContainerFrame11Item9IconQuestTexture",
+ "ContainerFrame11Item9IconTexture",
+ "ContainerFrame11Item9NormalTexture",
+ "ContainerFrame11Item9Stock",
+ "ContainerFrame11MoneyFrame",
+ "ContainerFrame11MoneyFrameCopperButton",
+ "ContainerFrame11MoneyFrameCopperButtonText",
+ "ContainerFrame11MoneyFrameGoldButton",
+ "ContainerFrame11MoneyFrameGoldButtonText",
+ "ContainerFrame11MoneyFrameSilverButton",
+ "ContainerFrame11MoneyFrameSilverButtonText",
+ "ContainerFrame11Name",
+ "ContainerFrame11Portrait",
+ "ContainerFrame11PortraitButton",
+ "ContainerFrame12",
+ "ContainerFrame12Background1Slot",
+ "ContainerFrame12BackgroundBottom",
+ "ContainerFrame12BackgroundMiddle1",
+ "ContainerFrame12BackgroundMiddle2",
+ "ContainerFrame12BackgroundTop",
+ "ContainerFrame12CloseButton",
+ "ContainerFrame12Item1",
+ "ContainerFrame12Item10",
+ "ContainerFrame12Item10Cooldown",
+ "ContainerFrame12Item10Count",
+ "ContainerFrame12Item10IconQuestTexture",
+ "ContainerFrame12Item10IconTexture",
+ "ContainerFrame12Item10NormalTexture",
+ "ContainerFrame12Item10Stock",
+ "ContainerFrame12Item11",
+ "ContainerFrame12Item11Cooldown",
+ "ContainerFrame12Item11Count",
+ "ContainerFrame12Item11IconQuestTexture",
+ "ContainerFrame12Item11IconTexture",
+ "ContainerFrame12Item11NormalTexture",
+ "ContainerFrame12Item11Stock",
+ "ContainerFrame12Item12",
+ "ContainerFrame12Item12Cooldown",
+ "ContainerFrame12Item12Count",
+ "ContainerFrame12Item12IconQuestTexture",
+ "ContainerFrame12Item12IconTexture",
+ "ContainerFrame12Item12NormalTexture",
+ "ContainerFrame12Item12Stock",
+ "ContainerFrame12Item13",
+ "ContainerFrame12Item13Cooldown",
+ "ContainerFrame12Item13Count",
+ "ContainerFrame12Item13IconQuestTexture",
+ "ContainerFrame12Item13IconTexture",
+ "ContainerFrame12Item13NormalTexture",
+ "ContainerFrame12Item13Stock",
+ "ContainerFrame12Item14",
+ "ContainerFrame12Item14Cooldown",
+ "ContainerFrame12Item14Count",
+ "ContainerFrame12Item14IconQuestTexture",
+ "ContainerFrame12Item14IconTexture",
+ "ContainerFrame12Item14NormalTexture",
+ "ContainerFrame12Item14Stock",
+ "ContainerFrame12Item15",
+ "ContainerFrame12Item15Cooldown",
+ "ContainerFrame12Item15Count",
+ "ContainerFrame12Item15IconQuestTexture",
+ "ContainerFrame12Item15IconTexture",
+ "ContainerFrame12Item15NormalTexture",
+ "ContainerFrame12Item15Stock",
+ "ContainerFrame12Item16",
+ "ContainerFrame12Item16Cooldown",
+ "ContainerFrame12Item16Count",
+ "ContainerFrame12Item16IconQuestTexture",
+ "ContainerFrame12Item16IconTexture",
+ "ContainerFrame12Item16NormalTexture",
+ "ContainerFrame12Item16Stock",
+ "ContainerFrame12Item17",
+ "ContainerFrame12Item17Cooldown",
+ "ContainerFrame12Item17Count",
+ "ContainerFrame12Item17IconQuestTexture",
+ "ContainerFrame12Item17IconTexture",
+ "ContainerFrame12Item17NormalTexture",
+ "ContainerFrame12Item17Stock",
+ "ContainerFrame12Item18",
+ "ContainerFrame12Item18Cooldown",
+ "ContainerFrame12Item18Count",
+ "ContainerFrame12Item18IconQuestTexture",
+ "ContainerFrame12Item18IconTexture",
+ "ContainerFrame12Item18NormalTexture",
+ "ContainerFrame12Item18Stock",
+ "ContainerFrame12Item19",
+ "ContainerFrame12Item19Cooldown",
+ "ContainerFrame12Item19Count",
+ "ContainerFrame12Item19IconQuestTexture",
+ "ContainerFrame12Item19IconTexture",
+ "ContainerFrame12Item19NormalTexture",
+ "ContainerFrame12Item19Stock",
+ "ContainerFrame12Item1Cooldown",
+ "ContainerFrame12Item1Count",
+ "ContainerFrame12Item1IconQuestTexture",
+ "ContainerFrame12Item1IconTexture",
+ "ContainerFrame12Item1NormalTexture",
+ "ContainerFrame12Item1Stock",
+ "ContainerFrame12Item2",
+ "ContainerFrame12Item20",
+ "ContainerFrame12Item20Cooldown",
+ "ContainerFrame12Item20Count",
+ "ContainerFrame12Item20IconQuestTexture",
+ "ContainerFrame12Item20IconTexture",
+ "ContainerFrame12Item20NormalTexture",
+ "ContainerFrame12Item20Stock",
+ "ContainerFrame12Item21",
+ "ContainerFrame12Item21Cooldown",
+ "ContainerFrame12Item21Count",
+ "ContainerFrame12Item21IconQuestTexture",
+ "ContainerFrame12Item21IconTexture",
+ "ContainerFrame12Item21NormalTexture",
+ "ContainerFrame12Item21Stock",
+ "ContainerFrame12Item22",
+ "ContainerFrame12Item22Cooldown",
+ "ContainerFrame12Item22Count",
+ "ContainerFrame12Item22IconQuestTexture",
+ "ContainerFrame12Item22IconTexture",
+ "ContainerFrame12Item22NormalTexture",
+ "ContainerFrame12Item22Stock",
+ "ContainerFrame12Item23",
+ "ContainerFrame12Item23Cooldown",
+ "ContainerFrame12Item23Count",
+ "ContainerFrame12Item23IconQuestTexture",
+ "ContainerFrame12Item23IconTexture",
+ "ContainerFrame12Item23NormalTexture",
+ "ContainerFrame12Item23Stock",
+ "ContainerFrame12Item24",
+ "ContainerFrame12Item24Cooldown",
+ "ContainerFrame12Item24Count",
+ "ContainerFrame12Item24IconQuestTexture",
+ "ContainerFrame12Item24IconTexture",
+ "ContainerFrame12Item24NormalTexture",
+ "ContainerFrame12Item24Stock",
+ "ContainerFrame12Item25",
+ "ContainerFrame12Item25Cooldown",
+ "ContainerFrame12Item25Count",
+ "ContainerFrame12Item25IconQuestTexture",
+ "ContainerFrame12Item25IconTexture",
+ "ContainerFrame12Item25NormalTexture",
+ "ContainerFrame12Item25Stock",
+ "ContainerFrame12Item26",
+ "ContainerFrame12Item26Cooldown",
+ "ContainerFrame12Item26Count",
+ "ContainerFrame12Item26IconQuestTexture",
+ "ContainerFrame12Item26IconTexture",
+ "ContainerFrame12Item26NormalTexture",
+ "ContainerFrame12Item26Stock",
+ "ContainerFrame12Item27",
+ "ContainerFrame12Item27Cooldown",
+ "ContainerFrame12Item27Count",
+ "ContainerFrame12Item27IconQuestTexture",
+ "ContainerFrame12Item27IconTexture",
+ "ContainerFrame12Item27NormalTexture",
+ "ContainerFrame12Item27Stock",
+ "ContainerFrame12Item28",
+ "ContainerFrame12Item28Cooldown",
+ "ContainerFrame12Item28Count",
+ "ContainerFrame12Item28IconQuestTexture",
+ "ContainerFrame12Item28IconTexture",
+ "ContainerFrame12Item28NormalTexture",
+ "ContainerFrame12Item28Stock",
+ "ContainerFrame12Item29",
+ "ContainerFrame12Item29Cooldown",
+ "ContainerFrame12Item29Count",
+ "ContainerFrame12Item29IconQuestTexture",
+ "ContainerFrame12Item29IconTexture",
+ "ContainerFrame12Item29NormalTexture",
+ "ContainerFrame12Item29Stock",
+ "ContainerFrame12Item2Cooldown",
+ "ContainerFrame12Item2Count",
+ "ContainerFrame12Item2IconQuestTexture",
+ "ContainerFrame12Item2IconTexture",
+ "ContainerFrame12Item2NormalTexture",
+ "ContainerFrame12Item2Stock",
+ "ContainerFrame12Item3",
+ "ContainerFrame12Item30",
+ "ContainerFrame12Item30Cooldown",
+ "ContainerFrame12Item30Count",
+ "ContainerFrame12Item30IconQuestTexture",
+ "ContainerFrame12Item30IconTexture",
+ "ContainerFrame12Item30NormalTexture",
+ "ContainerFrame12Item30Stock",
+ "ContainerFrame12Item31",
+ "ContainerFrame12Item31Cooldown",
+ "ContainerFrame12Item31Count",
+ "ContainerFrame12Item31IconQuestTexture",
+ "ContainerFrame12Item31IconTexture",
+ "ContainerFrame12Item31NormalTexture",
+ "ContainerFrame12Item31Stock",
+ "ContainerFrame12Item32",
+ "ContainerFrame12Item32Cooldown",
+ "ContainerFrame12Item32Count",
+ "ContainerFrame12Item32IconQuestTexture",
+ "ContainerFrame12Item32IconTexture",
+ "ContainerFrame12Item32NormalTexture",
+ "ContainerFrame12Item32Stock",
+ "ContainerFrame12Item33",
+ "ContainerFrame12Item33Cooldown",
+ "ContainerFrame12Item33Count",
+ "ContainerFrame12Item33IconQuestTexture",
+ "ContainerFrame12Item33IconTexture",
+ "ContainerFrame12Item33NormalTexture",
+ "ContainerFrame12Item33Stock",
+ "ContainerFrame12Item34",
+ "ContainerFrame12Item34Cooldown",
+ "ContainerFrame12Item34Count",
+ "ContainerFrame12Item34IconQuestTexture",
+ "ContainerFrame12Item34IconTexture",
+ "ContainerFrame12Item34NormalTexture",
+ "ContainerFrame12Item34Stock",
+ "ContainerFrame12Item35",
+ "ContainerFrame12Item35Cooldown",
+ "ContainerFrame12Item35Count",
+ "ContainerFrame12Item35IconQuestTexture",
+ "ContainerFrame12Item35IconTexture",
+ "ContainerFrame12Item35NormalTexture",
+ "ContainerFrame12Item35Stock",
+ "ContainerFrame12Item36",
+ "ContainerFrame12Item36Cooldown",
+ "ContainerFrame12Item36Count",
+ "ContainerFrame12Item36IconQuestTexture",
+ "ContainerFrame12Item36IconTexture",
+ "ContainerFrame12Item36NormalTexture",
+ "ContainerFrame12Item36Stock",
+ "ContainerFrame12Item3Cooldown",
+ "ContainerFrame12Item3Count",
+ "ContainerFrame12Item3IconQuestTexture",
+ "ContainerFrame12Item3IconTexture",
+ "ContainerFrame12Item3NormalTexture",
+ "ContainerFrame12Item3Stock",
+ "ContainerFrame12Item4",
+ "ContainerFrame12Item4Cooldown",
+ "ContainerFrame12Item4Count",
+ "ContainerFrame12Item4IconQuestTexture",
+ "ContainerFrame12Item4IconTexture",
+ "ContainerFrame12Item4NormalTexture",
+ "ContainerFrame12Item4Stock",
+ "ContainerFrame12Item5",
+ "ContainerFrame12Item5Cooldown",
+ "ContainerFrame12Item5Count",
+ "ContainerFrame12Item5IconQuestTexture",
+ "ContainerFrame12Item5IconTexture",
+ "ContainerFrame12Item5NormalTexture",
+ "ContainerFrame12Item5Stock",
+ "ContainerFrame12Item6",
+ "ContainerFrame12Item6Cooldown",
+ "ContainerFrame12Item6Count",
+ "ContainerFrame12Item6IconQuestTexture",
+ "ContainerFrame12Item6IconTexture",
+ "ContainerFrame12Item6NormalTexture",
+ "ContainerFrame12Item6Stock",
+ "ContainerFrame12Item7",
+ "ContainerFrame12Item7Cooldown",
+ "ContainerFrame12Item7Count",
+ "ContainerFrame12Item7IconQuestTexture",
+ "ContainerFrame12Item7IconTexture",
+ "ContainerFrame12Item7NormalTexture",
+ "ContainerFrame12Item7Stock",
+ "ContainerFrame12Item8",
+ "ContainerFrame12Item8Cooldown",
+ "ContainerFrame12Item8Count",
+ "ContainerFrame12Item8IconQuestTexture",
+ "ContainerFrame12Item8IconTexture",
+ "ContainerFrame12Item8NormalTexture",
+ "ContainerFrame12Item8Stock",
+ "ContainerFrame12Item9",
+ "ContainerFrame12Item9Cooldown",
+ "ContainerFrame12Item9Count",
+ "ContainerFrame12Item9IconQuestTexture",
+ "ContainerFrame12Item9IconTexture",
+ "ContainerFrame12Item9NormalTexture",
+ "ContainerFrame12Item9Stock",
+ "ContainerFrame12MoneyFrame",
+ "ContainerFrame12MoneyFrameCopperButton",
+ "ContainerFrame12MoneyFrameCopperButtonText",
+ "ContainerFrame12MoneyFrameGoldButton",
+ "ContainerFrame12MoneyFrameGoldButtonText",
+ "ContainerFrame12MoneyFrameSilverButton",
+ "ContainerFrame12MoneyFrameSilverButtonText",
+ "ContainerFrame12Name",
+ "ContainerFrame12Portrait",
+ "ContainerFrame12PortraitButton",
+ "ContainerFrame13",
+ "ContainerFrame13Background1Slot",
+ "ContainerFrame13BackgroundBottom",
+ "ContainerFrame13BackgroundMiddle1",
+ "ContainerFrame13BackgroundMiddle2",
+ "ContainerFrame13BackgroundTop",
+ "ContainerFrame13CloseButton",
+ "ContainerFrame13Item1",
+ "ContainerFrame13Item10",
+ "ContainerFrame13Item10Cooldown",
+ "ContainerFrame13Item10Count",
+ "ContainerFrame13Item10IconQuestTexture",
+ "ContainerFrame13Item10IconTexture",
+ "ContainerFrame13Item10NormalTexture",
+ "ContainerFrame13Item10Stock",
+ "ContainerFrame13Item11",
+ "ContainerFrame13Item11Cooldown",
+ "ContainerFrame13Item11Count",
+ "ContainerFrame13Item11IconQuestTexture",
+ "ContainerFrame13Item11IconTexture",
+ "ContainerFrame13Item11NormalTexture",
+ "ContainerFrame13Item11Stock",
+ "ContainerFrame13Item12",
+ "ContainerFrame13Item12Cooldown",
+ "ContainerFrame13Item12Count",
+ "ContainerFrame13Item12IconQuestTexture",
+ "ContainerFrame13Item12IconTexture",
+ "ContainerFrame13Item12NormalTexture",
+ "ContainerFrame13Item12Stock",
+ "ContainerFrame13Item13",
+ "ContainerFrame13Item13Cooldown",
+ "ContainerFrame13Item13Count",
+ "ContainerFrame13Item13IconQuestTexture",
+ "ContainerFrame13Item13IconTexture",
+ "ContainerFrame13Item13NormalTexture",
+ "ContainerFrame13Item13Stock",
+ "ContainerFrame13Item14",
+ "ContainerFrame13Item14Cooldown",
+ "ContainerFrame13Item14Count",
+ "ContainerFrame13Item14IconQuestTexture",
+ "ContainerFrame13Item14IconTexture",
+ "ContainerFrame13Item14NormalTexture",
+ "ContainerFrame13Item14Stock",
+ "ContainerFrame13Item15",
+ "ContainerFrame13Item15Cooldown",
+ "ContainerFrame13Item15Count",
+ "ContainerFrame13Item15IconQuestTexture",
+ "ContainerFrame13Item15IconTexture",
+ "ContainerFrame13Item15NormalTexture",
+ "ContainerFrame13Item15Stock",
+ "ContainerFrame13Item16",
+ "ContainerFrame13Item16Cooldown",
+ "ContainerFrame13Item16Count",
+ "ContainerFrame13Item16IconQuestTexture",
+ "ContainerFrame13Item16IconTexture",
+ "ContainerFrame13Item16NormalTexture",
+ "ContainerFrame13Item16Stock",
+ "ContainerFrame13Item17",
+ "ContainerFrame13Item17Cooldown",
+ "ContainerFrame13Item17Count",
+ "ContainerFrame13Item17IconQuestTexture",
+ "ContainerFrame13Item17IconTexture",
+ "ContainerFrame13Item17NormalTexture",
+ "ContainerFrame13Item17Stock",
+ "ContainerFrame13Item18",
+ "ContainerFrame13Item18Cooldown",
+ "ContainerFrame13Item18Count",
+ "ContainerFrame13Item18IconQuestTexture",
+ "ContainerFrame13Item18IconTexture",
+ "ContainerFrame13Item18NormalTexture",
+ "ContainerFrame13Item18Stock",
+ "ContainerFrame13Item19",
+ "ContainerFrame13Item19Cooldown",
+ "ContainerFrame13Item19Count",
+ "ContainerFrame13Item19IconQuestTexture",
+ "ContainerFrame13Item19IconTexture",
+ "ContainerFrame13Item19NormalTexture",
+ "ContainerFrame13Item19Stock",
+ "ContainerFrame13Item1Cooldown",
+ "ContainerFrame13Item1Count",
+ "ContainerFrame13Item1IconQuestTexture",
+ "ContainerFrame13Item1IconTexture",
+ "ContainerFrame13Item1NormalTexture",
+ "ContainerFrame13Item1Stock",
+ "ContainerFrame13Item2",
+ "ContainerFrame13Item20",
+ "ContainerFrame13Item20Cooldown",
+ "ContainerFrame13Item20Count",
+ "ContainerFrame13Item20IconQuestTexture",
+ "ContainerFrame13Item20IconTexture",
+ "ContainerFrame13Item20NormalTexture",
+ "ContainerFrame13Item20Stock",
+ "ContainerFrame13Item21",
+ "ContainerFrame13Item21Cooldown",
+ "ContainerFrame13Item21Count",
+ "ContainerFrame13Item21IconQuestTexture",
+ "ContainerFrame13Item21IconTexture",
+ "ContainerFrame13Item21NormalTexture",
+ "ContainerFrame13Item21Stock",
+ "ContainerFrame13Item22",
+ "ContainerFrame13Item22Cooldown",
+ "ContainerFrame13Item22Count",
+ "ContainerFrame13Item22IconQuestTexture",
+ "ContainerFrame13Item22IconTexture",
+ "ContainerFrame13Item22NormalTexture",
+ "ContainerFrame13Item22Stock",
+ "ContainerFrame13Item23",
+ "ContainerFrame13Item23Cooldown",
+ "ContainerFrame13Item23Count",
+ "ContainerFrame13Item23IconQuestTexture",
+ "ContainerFrame13Item23IconTexture",
+ "ContainerFrame13Item23NormalTexture",
+ "ContainerFrame13Item23Stock",
+ "ContainerFrame13Item24",
+ "ContainerFrame13Item24Cooldown",
+ "ContainerFrame13Item24Count",
+ "ContainerFrame13Item24IconQuestTexture",
+ "ContainerFrame13Item24IconTexture",
+ "ContainerFrame13Item24NormalTexture",
+ "ContainerFrame13Item24Stock",
+ "ContainerFrame13Item25",
+ "ContainerFrame13Item25Cooldown",
+ "ContainerFrame13Item25Count",
+ "ContainerFrame13Item25IconQuestTexture",
+ "ContainerFrame13Item25IconTexture",
+ "ContainerFrame13Item25NormalTexture",
+ "ContainerFrame13Item25Stock",
+ "ContainerFrame13Item26",
+ "ContainerFrame13Item26Cooldown",
+ "ContainerFrame13Item26Count",
+ "ContainerFrame13Item26IconQuestTexture",
+ "ContainerFrame13Item26IconTexture",
+ "ContainerFrame13Item26NormalTexture",
+ "ContainerFrame13Item26Stock",
+ "ContainerFrame13Item27",
+ "ContainerFrame13Item27Cooldown",
+ "ContainerFrame13Item27Count",
+ "ContainerFrame13Item27IconQuestTexture",
+ "ContainerFrame13Item27IconTexture",
+ "ContainerFrame13Item27NormalTexture",
+ "ContainerFrame13Item27Stock",
+ "ContainerFrame13Item28",
+ "ContainerFrame13Item28Cooldown",
+ "ContainerFrame13Item28Count",
+ "ContainerFrame13Item28IconQuestTexture",
+ "ContainerFrame13Item28IconTexture",
+ "ContainerFrame13Item28NormalTexture",
+ "ContainerFrame13Item28Stock",
+ "ContainerFrame13Item29",
+ "ContainerFrame13Item29Cooldown",
+ "ContainerFrame13Item29Count",
+ "ContainerFrame13Item29IconQuestTexture",
+ "ContainerFrame13Item29IconTexture",
+ "ContainerFrame13Item29NormalTexture",
+ "ContainerFrame13Item29Stock",
+ "ContainerFrame13Item2Cooldown",
+ "ContainerFrame13Item2Count",
+ "ContainerFrame13Item2IconQuestTexture",
+ "ContainerFrame13Item2IconTexture",
+ "ContainerFrame13Item2NormalTexture",
+ "ContainerFrame13Item2Stock",
+ "ContainerFrame13Item3",
+ "ContainerFrame13Item30",
+ "ContainerFrame13Item30Cooldown",
+ "ContainerFrame13Item30Count",
+ "ContainerFrame13Item30IconQuestTexture",
+ "ContainerFrame13Item30IconTexture",
+ "ContainerFrame13Item30NormalTexture",
+ "ContainerFrame13Item30Stock",
+ "ContainerFrame13Item31",
+ "ContainerFrame13Item31Cooldown",
+ "ContainerFrame13Item31Count",
+ "ContainerFrame13Item31IconQuestTexture",
+ "ContainerFrame13Item31IconTexture",
+ "ContainerFrame13Item31NormalTexture",
+ "ContainerFrame13Item31Stock",
+ "ContainerFrame13Item32",
+ "ContainerFrame13Item32Cooldown",
+ "ContainerFrame13Item32Count",
+ "ContainerFrame13Item32IconQuestTexture",
+ "ContainerFrame13Item32IconTexture",
+ "ContainerFrame13Item32NormalTexture",
+ "ContainerFrame13Item32Stock",
+ "ContainerFrame13Item33",
+ "ContainerFrame13Item33Cooldown",
+ "ContainerFrame13Item33Count",
+ "ContainerFrame13Item33IconQuestTexture",
+ "ContainerFrame13Item33IconTexture",
+ "ContainerFrame13Item33NormalTexture",
+ "ContainerFrame13Item33Stock",
+ "ContainerFrame13Item34",
+ "ContainerFrame13Item34Cooldown",
+ "ContainerFrame13Item34Count",
+ "ContainerFrame13Item34IconQuestTexture",
+ "ContainerFrame13Item34IconTexture",
+ "ContainerFrame13Item34NormalTexture",
+ "ContainerFrame13Item34Stock",
+ "ContainerFrame13Item35",
+ "ContainerFrame13Item35Cooldown",
+ "ContainerFrame13Item35Count",
+ "ContainerFrame13Item35IconQuestTexture",
+ "ContainerFrame13Item35IconTexture",
+ "ContainerFrame13Item35NormalTexture",
+ "ContainerFrame13Item35Stock",
+ "ContainerFrame13Item36",
+ "ContainerFrame13Item36Cooldown",
+ "ContainerFrame13Item36Count",
+ "ContainerFrame13Item36IconQuestTexture",
+ "ContainerFrame13Item36IconTexture",
+ "ContainerFrame13Item36NormalTexture",
+ "ContainerFrame13Item36Stock",
+ "ContainerFrame13Item3Cooldown",
+ "ContainerFrame13Item3Count",
+ "ContainerFrame13Item3IconQuestTexture",
+ "ContainerFrame13Item3IconTexture",
+ "ContainerFrame13Item3NormalTexture",
+ "ContainerFrame13Item3Stock",
+ "ContainerFrame13Item4",
+ "ContainerFrame13Item4Cooldown",
+ "ContainerFrame13Item4Count",
+ "ContainerFrame13Item4IconQuestTexture",
+ "ContainerFrame13Item4IconTexture",
+ "ContainerFrame13Item4NormalTexture",
+ "ContainerFrame13Item4Stock",
+ "ContainerFrame13Item5",
+ "ContainerFrame13Item5Cooldown",
+ "ContainerFrame13Item5Count",
+ "ContainerFrame13Item5IconQuestTexture",
+ "ContainerFrame13Item5IconTexture",
+ "ContainerFrame13Item5NormalTexture",
+ "ContainerFrame13Item5Stock",
+ "ContainerFrame13Item6",
+ "ContainerFrame13Item6Cooldown",
+ "ContainerFrame13Item6Count",
+ "ContainerFrame13Item6IconQuestTexture",
+ "ContainerFrame13Item6IconTexture",
+ "ContainerFrame13Item6NormalTexture",
+ "ContainerFrame13Item6Stock",
+ "ContainerFrame13Item7",
+ "ContainerFrame13Item7Cooldown",
+ "ContainerFrame13Item7Count",
+ "ContainerFrame13Item7IconQuestTexture",
+ "ContainerFrame13Item7IconTexture",
+ "ContainerFrame13Item7NormalTexture",
+ "ContainerFrame13Item7Stock",
+ "ContainerFrame13Item8",
+ "ContainerFrame13Item8Cooldown",
+ "ContainerFrame13Item8Count",
+ "ContainerFrame13Item8IconQuestTexture",
+ "ContainerFrame13Item8IconTexture",
+ "ContainerFrame13Item8NormalTexture",
+ "ContainerFrame13Item8Stock",
+ "ContainerFrame13Item9",
+ "ContainerFrame13Item9Cooldown",
+ "ContainerFrame13Item9Count",
+ "ContainerFrame13Item9IconQuestTexture",
+ "ContainerFrame13Item9IconTexture",
+ "ContainerFrame13Item9NormalTexture",
+ "ContainerFrame13Item9Stock",
+ "ContainerFrame13MoneyFrame",
+ "ContainerFrame13MoneyFrameCopperButton",
+ "ContainerFrame13MoneyFrameCopperButtonText",
+ "ContainerFrame13MoneyFrameGoldButton",
+ "ContainerFrame13MoneyFrameGoldButtonText",
+ "ContainerFrame13MoneyFrameSilverButton",
+ "ContainerFrame13MoneyFrameSilverButtonText",
+ "ContainerFrame13Name",
+ "ContainerFrame13Portrait",
+ "ContainerFrame13PortraitButton",
+ "ContainerFrame1Background1Slot",
+ "ContainerFrame1BackgroundBottom",
+ "ContainerFrame1BackgroundMiddle1",
+ "ContainerFrame1BackgroundMiddle2",
+ "ContainerFrame1BackgroundTop",
+ "ContainerFrame1CloseButton",
+ "ContainerFrame1Item1",
+ "ContainerFrame1Item10",
+ "ContainerFrame1Item10Cooldown",
+ "ContainerFrame1Item10Count",
+ "ContainerFrame1Item10IconQuestTexture",
+ "ContainerFrame1Item10IconTexture",
+ "ContainerFrame1Item10NormalTexture",
+ "ContainerFrame1Item10Stock",
+ "ContainerFrame1Item11",
+ "ContainerFrame1Item11Cooldown",
+ "ContainerFrame1Item11Count",
+ "ContainerFrame1Item11IconQuestTexture",
+ "ContainerFrame1Item11IconTexture",
+ "ContainerFrame1Item11NormalTexture",
+ "ContainerFrame1Item11Stock",
+ "ContainerFrame1Item12",
+ "ContainerFrame1Item12Cooldown",
+ "ContainerFrame1Item12Count",
+ "ContainerFrame1Item12IconQuestTexture",
+ "ContainerFrame1Item12IconTexture",
+ "ContainerFrame1Item12NormalTexture",
+ "ContainerFrame1Item12Stock",
+ "ContainerFrame1Item13",
+ "ContainerFrame1Item13Cooldown",
+ "ContainerFrame1Item13Count",
+ "ContainerFrame1Item13IconQuestTexture",
+ "ContainerFrame1Item13IconTexture",
+ "ContainerFrame1Item13NormalTexture",
+ "ContainerFrame1Item13Stock",
+ "ContainerFrame1Item14",
+ "ContainerFrame1Item14Cooldown",
+ "ContainerFrame1Item14Count",
+ "ContainerFrame1Item14IconQuestTexture",
+ "ContainerFrame1Item14IconTexture",
+ "ContainerFrame1Item14NormalTexture",
+ "ContainerFrame1Item14Stock",
+ "ContainerFrame1Item15",
+ "ContainerFrame1Item15Cooldown",
+ "ContainerFrame1Item15Count",
+ "ContainerFrame1Item15IconQuestTexture",
+ "ContainerFrame1Item15IconTexture",
+ "ContainerFrame1Item15NormalTexture",
+ "ContainerFrame1Item15Stock",
+ "ContainerFrame1Item16",
+ "ContainerFrame1Item16Cooldown",
+ "ContainerFrame1Item16Count",
+ "ContainerFrame1Item16IconQuestTexture",
+ "ContainerFrame1Item16IconTexture",
+ "ContainerFrame1Item16NormalTexture",
+ "ContainerFrame1Item16Stock",
+ "ContainerFrame1Item17",
+ "ContainerFrame1Item17Cooldown",
+ "ContainerFrame1Item17Count",
+ "ContainerFrame1Item17IconQuestTexture",
+ "ContainerFrame1Item17IconTexture",
+ "ContainerFrame1Item17NormalTexture",
+ "ContainerFrame1Item17Stock",
+ "ContainerFrame1Item18",
+ "ContainerFrame1Item18Cooldown",
+ "ContainerFrame1Item18Count",
+ "ContainerFrame1Item18IconQuestTexture",
+ "ContainerFrame1Item18IconTexture",
+ "ContainerFrame1Item18NormalTexture",
+ "ContainerFrame1Item18Stock",
+ "ContainerFrame1Item19",
+ "ContainerFrame1Item19Cooldown",
+ "ContainerFrame1Item19Count",
+ "ContainerFrame1Item19IconQuestTexture",
+ "ContainerFrame1Item19IconTexture",
+ "ContainerFrame1Item19NormalTexture",
+ "ContainerFrame1Item19Stock",
+ "ContainerFrame1Item1Cooldown",
+ "ContainerFrame1Item1Count",
+ "ContainerFrame1Item1IconQuestTexture",
+ "ContainerFrame1Item1IconTexture",
+ "ContainerFrame1Item1NormalTexture",
+ "ContainerFrame1Item1Stock",
+ "ContainerFrame1Item2",
+ "ContainerFrame1Item20",
+ "ContainerFrame1Item20Cooldown",
+ "ContainerFrame1Item20Count",
+ "ContainerFrame1Item20IconQuestTexture",
+ "ContainerFrame1Item20IconTexture",
+ "ContainerFrame1Item20NormalTexture",
+ "ContainerFrame1Item20Stock",
+ "ContainerFrame1Item21",
+ "ContainerFrame1Item21Cooldown",
+ "ContainerFrame1Item21Count",
+ "ContainerFrame1Item21IconQuestTexture",
+ "ContainerFrame1Item21IconTexture",
+ "ContainerFrame1Item21NormalTexture",
+ "ContainerFrame1Item21Stock",
+ "ContainerFrame1Item22",
+ "ContainerFrame1Item22Cooldown",
+ "ContainerFrame1Item22Count",
+ "ContainerFrame1Item22IconQuestTexture",
+ "ContainerFrame1Item22IconTexture",
+ "ContainerFrame1Item22NormalTexture",
+ "ContainerFrame1Item22Stock",
+ "ContainerFrame1Item23",
+ "ContainerFrame1Item23Cooldown",
+ "ContainerFrame1Item23Count",
+ "ContainerFrame1Item23IconQuestTexture",
+ "ContainerFrame1Item23IconTexture",
+ "ContainerFrame1Item23NormalTexture",
+ "ContainerFrame1Item23Stock",
+ "ContainerFrame1Item24",
+ "ContainerFrame1Item24Cooldown",
+ "ContainerFrame1Item24Count",
+ "ContainerFrame1Item24IconQuestTexture",
+ "ContainerFrame1Item24IconTexture",
+ "ContainerFrame1Item24NormalTexture",
+ "ContainerFrame1Item24Stock",
+ "ContainerFrame1Item25",
+ "ContainerFrame1Item25Cooldown",
+ "ContainerFrame1Item25Count",
+ "ContainerFrame1Item25IconQuestTexture",
+ "ContainerFrame1Item25IconTexture",
+ "ContainerFrame1Item25NormalTexture",
+ "ContainerFrame1Item25Stock",
+ "ContainerFrame1Item26",
+ "ContainerFrame1Item26Cooldown",
+ "ContainerFrame1Item26Count",
+ "ContainerFrame1Item26IconQuestTexture",
+ "ContainerFrame1Item26IconTexture",
+ "ContainerFrame1Item26NormalTexture",
+ "ContainerFrame1Item26Stock",
+ "ContainerFrame1Item27",
+ "ContainerFrame1Item27Cooldown",
+ "ContainerFrame1Item27Count",
+ "ContainerFrame1Item27IconQuestTexture",
+ "ContainerFrame1Item27IconTexture",
+ "ContainerFrame1Item27NormalTexture",
+ "ContainerFrame1Item27Stock",
+ "ContainerFrame1Item28",
+ "ContainerFrame1Item28Cooldown",
+ "ContainerFrame1Item28Count",
+ "ContainerFrame1Item28IconQuestTexture",
+ "ContainerFrame1Item28IconTexture",
+ "ContainerFrame1Item28NormalTexture",
+ "ContainerFrame1Item28Stock",
+ "ContainerFrame1Item29",
+ "ContainerFrame1Item29Cooldown",
+ "ContainerFrame1Item29Count",
+ "ContainerFrame1Item29IconQuestTexture",
+ "ContainerFrame1Item29IconTexture",
+ "ContainerFrame1Item29NormalTexture",
+ "ContainerFrame1Item29Stock",
+ "ContainerFrame1Item2Cooldown",
+ "ContainerFrame1Item2Count",
+ "ContainerFrame1Item2IconQuestTexture",
+ "ContainerFrame1Item2IconTexture",
+ "ContainerFrame1Item2NormalTexture",
+ "ContainerFrame1Item2Stock",
+ "ContainerFrame1Item3",
+ "ContainerFrame1Item30",
+ "ContainerFrame1Item30Cooldown",
+ "ContainerFrame1Item30Count",
+ "ContainerFrame1Item30IconQuestTexture",
+ "ContainerFrame1Item30IconTexture",
+ "ContainerFrame1Item30NormalTexture",
+ "ContainerFrame1Item30Stock",
+ "ContainerFrame1Item31",
+ "ContainerFrame1Item31Cooldown",
+ "ContainerFrame1Item31Count",
+ "ContainerFrame1Item31IconQuestTexture",
+ "ContainerFrame1Item31IconTexture",
+ "ContainerFrame1Item31NormalTexture",
+ "ContainerFrame1Item31Stock",
+ "ContainerFrame1Item32",
+ "ContainerFrame1Item32Cooldown",
+ "ContainerFrame1Item32Count",
+ "ContainerFrame1Item32IconQuestTexture",
+ "ContainerFrame1Item32IconTexture",
+ "ContainerFrame1Item32NormalTexture",
+ "ContainerFrame1Item32Stock",
+ "ContainerFrame1Item33",
+ "ContainerFrame1Item33Cooldown",
+ "ContainerFrame1Item33Count",
+ "ContainerFrame1Item33IconQuestTexture",
+ "ContainerFrame1Item33IconTexture",
+ "ContainerFrame1Item33NormalTexture",
+ "ContainerFrame1Item33Stock",
+ "ContainerFrame1Item34",
+ "ContainerFrame1Item34Cooldown",
+ "ContainerFrame1Item34Count",
+ "ContainerFrame1Item34IconQuestTexture",
+ "ContainerFrame1Item34IconTexture",
+ "ContainerFrame1Item34NormalTexture",
+ "ContainerFrame1Item34Stock",
+ "ContainerFrame1Item35",
+ "ContainerFrame1Item35Cooldown",
+ "ContainerFrame1Item35Count",
+ "ContainerFrame1Item35IconQuestTexture",
+ "ContainerFrame1Item35IconTexture",
+ "ContainerFrame1Item35NormalTexture",
+ "ContainerFrame1Item35Stock",
+ "ContainerFrame1Item36",
+ "ContainerFrame1Item36Cooldown",
+ "ContainerFrame1Item36Count",
+ "ContainerFrame1Item36IconQuestTexture",
+ "ContainerFrame1Item36IconTexture",
+ "ContainerFrame1Item36NormalTexture",
+ "ContainerFrame1Item36Stock",
+ "ContainerFrame1Item3Cooldown",
+ "ContainerFrame1Item3Count",
+ "ContainerFrame1Item3IconQuestTexture",
+ "ContainerFrame1Item3IconTexture",
+ "ContainerFrame1Item3NormalTexture",
+ "ContainerFrame1Item3Stock",
+ "ContainerFrame1Item4",
+ "ContainerFrame1Item4Cooldown",
+ "ContainerFrame1Item4Count",
+ "ContainerFrame1Item4IconQuestTexture",
+ "ContainerFrame1Item4IconTexture",
+ "ContainerFrame1Item4NormalTexture",
+ "ContainerFrame1Item4Stock",
+ "ContainerFrame1Item5",
+ "ContainerFrame1Item5Cooldown",
+ "ContainerFrame1Item5Count",
+ "ContainerFrame1Item5IconQuestTexture",
+ "ContainerFrame1Item5IconTexture",
+ "ContainerFrame1Item5NormalTexture",
+ "ContainerFrame1Item5Stock",
+ "ContainerFrame1Item6",
+ "ContainerFrame1Item6Cooldown",
+ "ContainerFrame1Item6Count",
+ "ContainerFrame1Item6IconQuestTexture",
+ "ContainerFrame1Item6IconTexture",
+ "ContainerFrame1Item6NormalTexture",
+ "ContainerFrame1Item6Stock",
+ "ContainerFrame1Item7",
+ "ContainerFrame1Item7Cooldown",
+ "ContainerFrame1Item7Count",
+ "ContainerFrame1Item7IconQuestTexture",
+ "ContainerFrame1Item7IconTexture",
+ "ContainerFrame1Item7NormalTexture",
+ "ContainerFrame1Item7Stock",
+ "ContainerFrame1Item8",
+ "ContainerFrame1Item8Cooldown",
+ "ContainerFrame1Item8Count",
+ "ContainerFrame1Item8IconQuestTexture",
+ "ContainerFrame1Item8IconTexture",
+ "ContainerFrame1Item8NormalTexture",
+ "ContainerFrame1Item8Stock",
+ "ContainerFrame1Item9",
+ "ContainerFrame1Item9Cooldown",
+ "ContainerFrame1Item9Count",
+ "ContainerFrame1Item9IconQuestTexture",
+ "ContainerFrame1Item9IconTexture",
+ "ContainerFrame1Item9NormalTexture",
+ "ContainerFrame1Item9Stock",
+ "ContainerFrame1MoneyFrame",
+ "ContainerFrame1MoneyFrameCopperButton",
+ "ContainerFrame1MoneyFrameCopperButtonText",
+ "ContainerFrame1MoneyFrameGoldButton",
+ "ContainerFrame1MoneyFrameGoldButtonText",
+ "ContainerFrame1MoneyFrameSilverButton",
+ "ContainerFrame1MoneyFrameSilverButtonText",
+ "ContainerFrame1Name",
+ "ContainerFrame1Portrait",
+ "ContainerFrame1PortraitButton",
+ "ContainerFrame2",
+ "ContainerFrame2Background1Slot",
+ "ContainerFrame2BackgroundBottom",
+ "ContainerFrame2BackgroundMiddle1",
+ "ContainerFrame2BackgroundMiddle2",
+ "ContainerFrame2BackgroundTop",
+ "ContainerFrame2CloseButton",
+ "ContainerFrame2Item1",
+ "ContainerFrame2Item10",
+ "ContainerFrame2Item10Cooldown",
+ "ContainerFrame2Item10Count",
+ "ContainerFrame2Item10IconQuestTexture",
+ "ContainerFrame2Item10IconTexture",
+ "ContainerFrame2Item10NormalTexture",
+ "ContainerFrame2Item10Stock",
+ "ContainerFrame2Item11",
+ "ContainerFrame2Item11Cooldown",
+ "ContainerFrame2Item11Count",
+ "ContainerFrame2Item11IconQuestTexture",
+ "ContainerFrame2Item11IconTexture",
+ "ContainerFrame2Item11NormalTexture",
+ "ContainerFrame2Item11Stock",
+ "ContainerFrame2Item12",
+ "ContainerFrame2Item12Cooldown",
+ "ContainerFrame2Item12Count",
+ "ContainerFrame2Item12IconQuestTexture",
+ "ContainerFrame2Item12IconTexture",
+ "ContainerFrame2Item12NormalTexture",
+ "ContainerFrame2Item12Stock",
+ "ContainerFrame2Item13",
+ "ContainerFrame2Item13Cooldown",
+ "ContainerFrame2Item13Count",
+ "ContainerFrame2Item13IconQuestTexture",
+ "ContainerFrame2Item13IconTexture",
+ "ContainerFrame2Item13NormalTexture",
+ "ContainerFrame2Item13Stock",
+ "ContainerFrame2Item14",
+ "ContainerFrame2Item14Cooldown",
+ "ContainerFrame2Item14Count",
+ "ContainerFrame2Item14IconQuestTexture",
+ "ContainerFrame2Item14IconTexture",
+ "ContainerFrame2Item14NormalTexture",
+ "ContainerFrame2Item14Stock",
+ "ContainerFrame2Item15",
+ "ContainerFrame2Item15Cooldown",
+ "ContainerFrame2Item15Count",
+ "ContainerFrame2Item15IconQuestTexture",
+ "ContainerFrame2Item15IconTexture",
+ "ContainerFrame2Item15NormalTexture",
+ "ContainerFrame2Item15Stock",
+ "ContainerFrame2Item16",
+ "ContainerFrame2Item16Cooldown",
+ "ContainerFrame2Item16Count",
+ "ContainerFrame2Item16IconQuestTexture",
+ "ContainerFrame2Item16IconTexture",
+ "ContainerFrame2Item16NormalTexture",
+ "ContainerFrame2Item16Stock",
+ "ContainerFrame2Item17",
+ "ContainerFrame2Item17Cooldown",
+ "ContainerFrame2Item17Count",
+ "ContainerFrame2Item17IconQuestTexture",
+ "ContainerFrame2Item17IconTexture",
+ "ContainerFrame2Item17NormalTexture",
+ "ContainerFrame2Item17Stock",
+ "ContainerFrame2Item18",
+ "ContainerFrame2Item18Cooldown",
+ "ContainerFrame2Item18Count",
+ "ContainerFrame2Item18IconQuestTexture",
+ "ContainerFrame2Item18IconTexture",
+ "ContainerFrame2Item18NormalTexture",
+ "ContainerFrame2Item18Stock",
+ "ContainerFrame2Item19",
+ "ContainerFrame2Item19Cooldown",
+ "ContainerFrame2Item19Count",
+ "ContainerFrame2Item19IconQuestTexture",
+ "ContainerFrame2Item19IconTexture",
+ "ContainerFrame2Item19NormalTexture",
+ "ContainerFrame2Item19Stock",
+ "ContainerFrame2Item1Cooldown",
+ "ContainerFrame2Item1Count",
+ "ContainerFrame2Item1IconQuestTexture",
+ "ContainerFrame2Item1IconTexture",
+ "ContainerFrame2Item1NormalTexture",
+ "ContainerFrame2Item1Stock",
+ "ContainerFrame2Item2",
+ "ContainerFrame2Item20",
+ "ContainerFrame2Item20Cooldown",
+ "ContainerFrame2Item20Count",
+ "ContainerFrame2Item20IconQuestTexture",
+ "ContainerFrame2Item20IconTexture",
+ "ContainerFrame2Item20NormalTexture",
+ "ContainerFrame2Item20Stock",
+ "ContainerFrame2Item21",
+ "ContainerFrame2Item21Cooldown",
+ "ContainerFrame2Item21Count",
+ "ContainerFrame2Item21IconQuestTexture",
+ "ContainerFrame2Item21IconTexture",
+ "ContainerFrame2Item21NormalTexture",
+ "ContainerFrame2Item21Stock",
+ "ContainerFrame2Item22",
+ "ContainerFrame2Item22Cooldown",
+ "ContainerFrame2Item22Count",
+ "ContainerFrame2Item22IconQuestTexture",
+ "ContainerFrame2Item22IconTexture",
+ "ContainerFrame2Item22NormalTexture",
+ "ContainerFrame2Item22Stock",
+ "ContainerFrame2Item23",
+ "ContainerFrame2Item23Cooldown",
+ "ContainerFrame2Item23Count",
+ "ContainerFrame2Item23IconQuestTexture",
+ "ContainerFrame2Item23IconTexture",
+ "ContainerFrame2Item23NormalTexture",
+ "ContainerFrame2Item23Stock",
+ "ContainerFrame2Item24",
+ "ContainerFrame2Item24Cooldown",
+ "ContainerFrame2Item24Count",
+ "ContainerFrame2Item24IconQuestTexture",
+ "ContainerFrame2Item24IconTexture",
+ "ContainerFrame2Item24NormalTexture",
+ "ContainerFrame2Item24Stock",
+ "ContainerFrame2Item25",
+ "ContainerFrame2Item25Cooldown",
+ "ContainerFrame2Item25Count",
+ "ContainerFrame2Item25IconQuestTexture",
+ "ContainerFrame2Item25IconTexture",
+ "ContainerFrame2Item25NormalTexture",
+ "ContainerFrame2Item25Stock",
+ "ContainerFrame2Item26",
+ "ContainerFrame2Item26Cooldown",
+ "ContainerFrame2Item26Count",
+ "ContainerFrame2Item26IconQuestTexture",
+ "ContainerFrame2Item26IconTexture",
+ "ContainerFrame2Item26NormalTexture",
+ "ContainerFrame2Item26Stock",
+ "ContainerFrame2Item27",
+ "ContainerFrame2Item27Cooldown",
+ "ContainerFrame2Item27Count",
+ "ContainerFrame2Item27IconQuestTexture",
+ "ContainerFrame2Item27IconTexture",
+ "ContainerFrame2Item27NormalTexture",
+ "ContainerFrame2Item27Stock",
+ "ContainerFrame2Item28",
+ "ContainerFrame2Item28Cooldown",
+ "ContainerFrame2Item28Count",
+ "ContainerFrame2Item28IconQuestTexture",
+ "ContainerFrame2Item28IconTexture",
+ "ContainerFrame2Item28NormalTexture",
+ "ContainerFrame2Item28Stock",
+ "ContainerFrame2Item29",
+ "ContainerFrame2Item29Cooldown",
+ "ContainerFrame2Item29Count",
+ "ContainerFrame2Item29IconQuestTexture",
+ "ContainerFrame2Item29IconTexture",
+ "ContainerFrame2Item29NormalTexture",
+ "ContainerFrame2Item29Stock",
+ "ContainerFrame2Item2Cooldown",
+ "ContainerFrame2Item2Count",
+ "ContainerFrame2Item2IconQuestTexture",
+ "ContainerFrame2Item2IconTexture",
+ "ContainerFrame2Item2NormalTexture",
+ "ContainerFrame2Item2Stock",
+ "ContainerFrame2Item3",
+ "ContainerFrame2Item30",
+ "ContainerFrame2Item30Cooldown",
+ "ContainerFrame2Item30Count",
+ "ContainerFrame2Item30IconQuestTexture",
+ "ContainerFrame2Item30IconTexture",
+ "ContainerFrame2Item30NormalTexture",
+ "ContainerFrame2Item30Stock",
+ "ContainerFrame2Item31",
+ "ContainerFrame2Item31Cooldown",
+ "ContainerFrame2Item31Count",
+ "ContainerFrame2Item31IconQuestTexture",
+ "ContainerFrame2Item31IconTexture",
+ "ContainerFrame2Item31NormalTexture",
+ "ContainerFrame2Item31Stock",
+ "ContainerFrame2Item32",
+ "ContainerFrame2Item32Cooldown",
+ "ContainerFrame2Item32Count",
+ "ContainerFrame2Item32IconQuestTexture",
+ "ContainerFrame2Item32IconTexture",
+ "ContainerFrame2Item32NormalTexture",
+ "ContainerFrame2Item32Stock",
+ "ContainerFrame2Item33",
+ "ContainerFrame2Item33Cooldown",
+ "ContainerFrame2Item33Count",
+ "ContainerFrame2Item33IconQuestTexture",
+ "ContainerFrame2Item33IconTexture",
+ "ContainerFrame2Item33NormalTexture",
+ "ContainerFrame2Item33Stock",
+ "ContainerFrame2Item34",
+ "ContainerFrame2Item34Cooldown",
+ "ContainerFrame2Item34Count",
+ "ContainerFrame2Item34IconQuestTexture",
+ "ContainerFrame2Item34IconTexture",
+ "ContainerFrame2Item34NormalTexture",
+ "ContainerFrame2Item34Stock",
+ "ContainerFrame2Item35",
+ "ContainerFrame2Item35Cooldown",
+ "ContainerFrame2Item35Count",
+ "ContainerFrame2Item35IconQuestTexture",
+ "ContainerFrame2Item35IconTexture",
+ "ContainerFrame2Item35NormalTexture",
+ "ContainerFrame2Item35Stock",
+ "ContainerFrame2Item36",
+ "ContainerFrame2Item36Cooldown",
+ "ContainerFrame2Item36Count",
+ "ContainerFrame2Item36IconQuestTexture",
+ "ContainerFrame2Item36IconTexture",
+ "ContainerFrame2Item36NormalTexture",
+ "ContainerFrame2Item36Stock",
+ "ContainerFrame2Item3Cooldown",
+ "ContainerFrame2Item3Count",
+ "ContainerFrame2Item3IconQuestTexture",
+ "ContainerFrame2Item3IconTexture",
+ "ContainerFrame2Item3NormalTexture",
+ "ContainerFrame2Item3Stock",
+ "ContainerFrame2Item4",
+ "ContainerFrame2Item4Cooldown",
+ "ContainerFrame2Item4Count",
+ "ContainerFrame2Item4IconQuestTexture",
+ "ContainerFrame2Item4IconTexture",
+ "ContainerFrame2Item4NormalTexture",
+ "ContainerFrame2Item4Stock",
+ "ContainerFrame2Item5",
+ "ContainerFrame2Item5Cooldown",
+ "ContainerFrame2Item5Count",
+ "ContainerFrame2Item5IconQuestTexture",
+ "ContainerFrame2Item5IconTexture",
+ "ContainerFrame2Item5NormalTexture",
+ "ContainerFrame2Item5Stock",
+ "ContainerFrame2Item6",
+ "ContainerFrame2Item6Cooldown",
+ "ContainerFrame2Item6Count",
+ "ContainerFrame2Item6IconQuestTexture",
+ "ContainerFrame2Item6IconTexture",
+ "ContainerFrame2Item6NormalTexture",
+ "ContainerFrame2Item6Stock",
+ "ContainerFrame2Item7",
+ "ContainerFrame2Item7Cooldown",
+ "ContainerFrame2Item7Count",
+ "ContainerFrame2Item7IconQuestTexture",
+ "ContainerFrame2Item7IconTexture",
+ "ContainerFrame2Item7NormalTexture",
+ "ContainerFrame2Item7Stock",
+ "ContainerFrame2Item8",
+ "ContainerFrame2Item8Cooldown",
+ "ContainerFrame2Item8Count",
+ "ContainerFrame2Item8IconQuestTexture",
+ "ContainerFrame2Item8IconTexture",
+ "ContainerFrame2Item8NormalTexture",
+ "ContainerFrame2Item8Stock",
+ "ContainerFrame2Item9",
+ "ContainerFrame2Item9Cooldown",
+ "ContainerFrame2Item9Count",
+ "ContainerFrame2Item9IconQuestTexture",
+ "ContainerFrame2Item9IconTexture",
+ "ContainerFrame2Item9NormalTexture",
+ "ContainerFrame2Item9Stock",
+ "ContainerFrame2MoneyFrame",
+ "ContainerFrame2MoneyFrameCopperButton",
+ "ContainerFrame2MoneyFrameCopperButtonText",
+ "ContainerFrame2MoneyFrameGoldButton",
+ "ContainerFrame2MoneyFrameGoldButtonText",
+ "ContainerFrame2MoneyFrameSilverButton",
+ "ContainerFrame2MoneyFrameSilverButtonText",
+ "ContainerFrame2Name",
+ "ContainerFrame2Portrait",
+ "ContainerFrame2PortraitButton",
+ "ContainerFrame3",
+ "ContainerFrame3Background1Slot",
+ "ContainerFrame3BackgroundBottom",
+ "ContainerFrame3BackgroundMiddle1",
+ "ContainerFrame3BackgroundMiddle2",
+ "ContainerFrame3BackgroundTop",
+ "ContainerFrame3CloseButton",
+ "ContainerFrame3Item1",
+ "ContainerFrame3Item10",
+ "ContainerFrame3Item10Cooldown",
+ "ContainerFrame3Item10Count",
+ "ContainerFrame3Item10IconQuestTexture",
+ "ContainerFrame3Item10IconTexture",
+ "ContainerFrame3Item10NormalTexture",
+ "ContainerFrame3Item10Stock",
+ "ContainerFrame3Item11",
+ "ContainerFrame3Item11Cooldown",
+ "ContainerFrame3Item11Count",
+ "ContainerFrame3Item11IconQuestTexture",
+ "ContainerFrame3Item11IconTexture",
+ "ContainerFrame3Item11NormalTexture",
+ "ContainerFrame3Item11Stock",
+ "ContainerFrame3Item12",
+ "ContainerFrame3Item12Cooldown",
+ "ContainerFrame3Item12Count",
+ "ContainerFrame3Item12IconQuestTexture",
+ "ContainerFrame3Item12IconTexture",
+ "ContainerFrame3Item12NormalTexture",
+ "ContainerFrame3Item12Stock",
+ "ContainerFrame3Item13",
+ "ContainerFrame3Item13Cooldown",
+ "ContainerFrame3Item13Count",
+ "ContainerFrame3Item13IconQuestTexture",
+ "ContainerFrame3Item13IconTexture",
+ "ContainerFrame3Item13NormalTexture",
+ "ContainerFrame3Item13Stock",
+ "ContainerFrame3Item14",
+ "ContainerFrame3Item14Cooldown",
+ "ContainerFrame3Item14Count",
+ "ContainerFrame3Item14IconQuestTexture",
+ "ContainerFrame3Item14IconTexture",
+ "ContainerFrame3Item14NormalTexture",
+ "ContainerFrame3Item14Stock",
+ "ContainerFrame3Item15",
+ "ContainerFrame3Item15Cooldown",
+ "ContainerFrame3Item15Count",
+ "ContainerFrame3Item15IconQuestTexture",
+ "ContainerFrame3Item15IconTexture",
+ "ContainerFrame3Item15NormalTexture",
+ "ContainerFrame3Item15Stock",
+ "ContainerFrame3Item16",
+ "ContainerFrame3Item16Cooldown",
+ "ContainerFrame3Item16Count",
+ "ContainerFrame3Item16IconQuestTexture",
+ "ContainerFrame3Item16IconTexture",
+ "ContainerFrame3Item16NormalTexture",
+ "ContainerFrame3Item16Stock",
+ "ContainerFrame3Item17",
+ "ContainerFrame3Item17Cooldown",
+ "ContainerFrame3Item17Count",
+ "ContainerFrame3Item17IconQuestTexture",
+ "ContainerFrame3Item17IconTexture",
+ "ContainerFrame3Item17NormalTexture",
+ "ContainerFrame3Item17Stock",
+ "ContainerFrame3Item18",
+ "ContainerFrame3Item18Cooldown",
+ "ContainerFrame3Item18Count",
+ "ContainerFrame3Item18IconQuestTexture",
+ "ContainerFrame3Item18IconTexture",
+ "ContainerFrame3Item18NormalTexture",
+ "ContainerFrame3Item18Stock",
+ "ContainerFrame3Item19",
+ "ContainerFrame3Item19Cooldown",
+ "ContainerFrame3Item19Count",
+ "ContainerFrame3Item19IconQuestTexture",
+ "ContainerFrame3Item19IconTexture",
+ "ContainerFrame3Item19NormalTexture",
+ "ContainerFrame3Item19Stock",
+ "ContainerFrame3Item1Cooldown",
+ "ContainerFrame3Item1Count",
+ "ContainerFrame3Item1IconQuestTexture",
+ "ContainerFrame3Item1IconTexture",
+ "ContainerFrame3Item1NormalTexture",
+ "ContainerFrame3Item1Stock",
+ "ContainerFrame3Item2",
+ "ContainerFrame3Item20",
+ "ContainerFrame3Item20Cooldown",
+ "ContainerFrame3Item20Count",
+ "ContainerFrame3Item20IconQuestTexture",
+ "ContainerFrame3Item20IconTexture",
+ "ContainerFrame3Item20NormalTexture",
+ "ContainerFrame3Item20Stock",
+ "ContainerFrame3Item21",
+ "ContainerFrame3Item21Cooldown",
+ "ContainerFrame3Item21Count",
+ "ContainerFrame3Item21IconQuestTexture",
+ "ContainerFrame3Item21IconTexture",
+ "ContainerFrame3Item21NormalTexture",
+ "ContainerFrame3Item21Stock",
+ "ContainerFrame3Item22",
+ "ContainerFrame3Item22Cooldown",
+ "ContainerFrame3Item22Count",
+ "ContainerFrame3Item22IconQuestTexture",
+ "ContainerFrame3Item22IconTexture",
+ "ContainerFrame3Item22NormalTexture",
+ "ContainerFrame3Item22Stock",
+ "ContainerFrame3Item23",
+ "ContainerFrame3Item23Cooldown",
+ "ContainerFrame3Item23Count",
+ "ContainerFrame3Item23IconQuestTexture",
+ "ContainerFrame3Item23IconTexture",
+ "ContainerFrame3Item23NormalTexture",
+ "ContainerFrame3Item23Stock",
+ "ContainerFrame3Item24",
+ "ContainerFrame3Item24Cooldown",
+ "ContainerFrame3Item24Count",
+ "ContainerFrame3Item24IconQuestTexture",
+ "ContainerFrame3Item24IconTexture",
+ "ContainerFrame3Item24NormalTexture",
+ "ContainerFrame3Item24Stock",
+ "ContainerFrame3Item25",
+ "ContainerFrame3Item25Cooldown",
+ "ContainerFrame3Item25Count",
+ "ContainerFrame3Item25IconQuestTexture",
+ "ContainerFrame3Item25IconTexture",
+ "ContainerFrame3Item25NormalTexture",
+ "ContainerFrame3Item25Stock",
+ "ContainerFrame3Item26",
+ "ContainerFrame3Item26Cooldown",
+ "ContainerFrame3Item26Count",
+ "ContainerFrame3Item26IconQuestTexture",
+ "ContainerFrame3Item26IconTexture",
+ "ContainerFrame3Item26NormalTexture",
+ "ContainerFrame3Item26Stock",
+ "ContainerFrame3Item27",
+ "ContainerFrame3Item27Cooldown",
+ "ContainerFrame3Item27Count",
+ "ContainerFrame3Item27IconQuestTexture",
+ "ContainerFrame3Item27IconTexture",
+ "ContainerFrame3Item27NormalTexture",
+ "ContainerFrame3Item27Stock",
+ "ContainerFrame3Item28",
+ "ContainerFrame3Item28Cooldown",
+ "ContainerFrame3Item28Count",
+ "ContainerFrame3Item28IconQuestTexture",
+ "ContainerFrame3Item28IconTexture",
+ "ContainerFrame3Item28NormalTexture",
+ "ContainerFrame3Item28Stock",
+ "ContainerFrame3Item29",
+ "ContainerFrame3Item29Cooldown",
+ "ContainerFrame3Item29Count",
+ "ContainerFrame3Item29IconQuestTexture",
+ "ContainerFrame3Item29IconTexture",
+ "ContainerFrame3Item29NormalTexture",
+ "ContainerFrame3Item29Stock",
+ "ContainerFrame3Item2Cooldown",
+ "ContainerFrame3Item2Count",
+ "ContainerFrame3Item2IconQuestTexture",
+ "ContainerFrame3Item2IconTexture",
+ "ContainerFrame3Item2NormalTexture",
+ "ContainerFrame3Item2Stock",
+ "ContainerFrame3Item3",
+ "ContainerFrame3Item30",
+ "ContainerFrame3Item30Cooldown",
+ "ContainerFrame3Item30Count",
+ "ContainerFrame3Item30IconQuestTexture",
+ "ContainerFrame3Item30IconTexture",
+ "ContainerFrame3Item30NormalTexture",
+ "ContainerFrame3Item30Stock",
+ "ContainerFrame3Item31",
+ "ContainerFrame3Item31Cooldown",
+ "ContainerFrame3Item31Count",
+ "ContainerFrame3Item31IconQuestTexture",
+ "ContainerFrame3Item31IconTexture",
+ "ContainerFrame3Item31NormalTexture",
+ "ContainerFrame3Item31Stock",
+ "ContainerFrame3Item32",
+ "ContainerFrame3Item32Cooldown",
+ "ContainerFrame3Item32Count",
+ "ContainerFrame3Item32IconQuestTexture",
+ "ContainerFrame3Item32IconTexture",
+ "ContainerFrame3Item32NormalTexture",
+ "ContainerFrame3Item32Stock",
+ "ContainerFrame3Item33",
+ "ContainerFrame3Item33Cooldown",
+ "ContainerFrame3Item33Count",
+ "ContainerFrame3Item33IconQuestTexture",
+ "ContainerFrame3Item33IconTexture",
+ "ContainerFrame3Item33NormalTexture",
+ "ContainerFrame3Item33Stock",
+ "ContainerFrame3Item34",
+ "ContainerFrame3Item34Cooldown",
+ "ContainerFrame3Item34Count",
+ "ContainerFrame3Item34IconQuestTexture",
+ "ContainerFrame3Item34IconTexture",
+ "ContainerFrame3Item34NormalTexture",
+ "ContainerFrame3Item34Stock",
+ "ContainerFrame3Item35",
+ "ContainerFrame3Item35Cooldown",
+ "ContainerFrame3Item35Count",
+ "ContainerFrame3Item35IconQuestTexture",
+ "ContainerFrame3Item35IconTexture",
+ "ContainerFrame3Item35NormalTexture",
+ "ContainerFrame3Item35Stock",
+ "ContainerFrame3Item36",
+ "ContainerFrame3Item36Cooldown",
+ "ContainerFrame3Item36Count",
+ "ContainerFrame3Item36IconQuestTexture",
+ "ContainerFrame3Item36IconTexture",
+ "ContainerFrame3Item36NormalTexture",
+ "ContainerFrame3Item36Stock",
+ "ContainerFrame3Item3Cooldown",
+ "ContainerFrame3Item3Count",
+ "ContainerFrame3Item3IconQuestTexture",
+ "ContainerFrame3Item3IconTexture",
+ "ContainerFrame3Item3NormalTexture",
+ "ContainerFrame3Item3Stock",
+ "ContainerFrame3Item4",
+ "ContainerFrame3Item4Cooldown",
+ "ContainerFrame3Item4Count",
+ "ContainerFrame3Item4IconQuestTexture",
+ "ContainerFrame3Item4IconTexture",
+ "ContainerFrame3Item4NormalTexture",
+ "ContainerFrame3Item4Stock",
+ "ContainerFrame3Item5",
+ "ContainerFrame3Item5Cooldown",
+ "ContainerFrame3Item5Count",
+ "ContainerFrame3Item5IconQuestTexture",
+ "ContainerFrame3Item5IconTexture",
+ "ContainerFrame3Item5NormalTexture",
+ "ContainerFrame3Item5Stock",
+ "ContainerFrame3Item6",
+ "ContainerFrame3Item6Cooldown",
+ "ContainerFrame3Item6Count",
+ "ContainerFrame3Item6IconQuestTexture",
+ "ContainerFrame3Item6IconTexture",
+ "ContainerFrame3Item6NormalTexture",
+ "ContainerFrame3Item6Stock",
+ "ContainerFrame3Item7",
+ "ContainerFrame3Item7Cooldown",
+ "ContainerFrame3Item7Count",
+ "ContainerFrame3Item7IconQuestTexture",
+ "ContainerFrame3Item7IconTexture",
+ "ContainerFrame3Item7NormalTexture",
+ "ContainerFrame3Item7Stock",
+ "ContainerFrame3Item8",
+ "ContainerFrame3Item8Cooldown",
+ "ContainerFrame3Item8Count",
+ "ContainerFrame3Item8IconQuestTexture",
+ "ContainerFrame3Item8IconTexture",
+ "ContainerFrame3Item8NormalTexture",
+ "ContainerFrame3Item8Stock",
+ "ContainerFrame3Item9",
+ "ContainerFrame3Item9Cooldown",
+ "ContainerFrame3Item9Count",
+ "ContainerFrame3Item9IconQuestTexture",
+ "ContainerFrame3Item9IconTexture",
+ "ContainerFrame3Item9NormalTexture",
+ "ContainerFrame3Item9Stock",
+ "ContainerFrame3MoneyFrame",
+ "ContainerFrame3MoneyFrameCopperButton",
+ "ContainerFrame3MoneyFrameCopperButtonText",
+ "ContainerFrame3MoneyFrameGoldButton",
+ "ContainerFrame3MoneyFrameGoldButtonText",
+ "ContainerFrame3MoneyFrameSilverButton",
+ "ContainerFrame3MoneyFrameSilverButtonText",
+ "ContainerFrame3Name",
+ "ContainerFrame3Portrait",
+ "ContainerFrame3PortraitButton",
+ "ContainerFrame4",
+ "ContainerFrame4Background1Slot",
+ "ContainerFrame4BackgroundBottom",
+ "ContainerFrame4BackgroundMiddle1",
+ "ContainerFrame4BackgroundMiddle2",
+ "ContainerFrame4BackgroundTop",
+ "ContainerFrame4CloseButton",
+ "ContainerFrame4Item1",
+ "ContainerFrame4Item10",
+ "ContainerFrame4Item10Cooldown",
+ "ContainerFrame4Item10Count",
+ "ContainerFrame4Item10IconQuestTexture",
+ "ContainerFrame4Item10IconTexture",
+ "ContainerFrame4Item10NormalTexture",
+ "ContainerFrame4Item10Stock",
+ "ContainerFrame4Item11",
+ "ContainerFrame4Item11Cooldown",
+ "ContainerFrame4Item11Count",
+ "ContainerFrame4Item11IconQuestTexture",
+ "ContainerFrame4Item11IconTexture",
+ "ContainerFrame4Item11NormalTexture",
+ "ContainerFrame4Item11Stock",
+ "ContainerFrame4Item12",
+ "ContainerFrame4Item12Cooldown",
+ "ContainerFrame4Item12Count",
+ "ContainerFrame4Item12IconQuestTexture",
+ "ContainerFrame4Item12IconTexture",
+ "ContainerFrame4Item12NormalTexture",
+ "ContainerFrame4Item12Stock",
+ "ContainerFrame4Item13",
+ "ContainerFrame4Item13Cooldown",
+ "ContainerFrame4Item13Count",
+ "ContainerFrame4Item13IconQuestTexture",
+ "ContainerFrame4Item13IconTexture",
+ "ContainerFrame4Item13NormalTexture",
+ "ContainerFrame4Item13Stock",
+ "ContainerFrame4Item14",
+ "ContainerFrame4Item14Cooldown",
+ "ContainerFrame4Item14Count",
+ "ContainerFrame4Item14IconQuestTexture",
+ "ContainerFrame4Item14IconTexture",
+ "ContainerFrame4Item14NormalTexture",
+ "ContainerFrame4Item14Stock",
+ "ContainerFrame4Item15",
+ "ContainerFrame4Item15Cooldown",
+ "ContainerFrame4Item15Count",
+ "ContainerFrame4Item15IconQuestTexture",
+ "ContainerFrame4Item15IconTexture",
+ "ContainerFrame4Item15NormalTexture",
+ "ContainerFrame4Item15Stock",
+ "ContainerFrame4Item16",
+ "ContainerFrame4Item16Cooldown",
+ "ContainerFrame4Item16Count",
+ "ContainerFrame4Item16IconQuestTexture",
+ "ContainerFrame4Item16IconTexture",
+ "ContainerFrame4Item16NormalTexture",
+ "ContainerFrame4Item16Stock",
+ "ContainerFrame4Item17",
+ "ContainerFrame4Item17Cooldown",
+ "ContainerFrame4Item17Count",
+ "ContainerFrame4Item17IconQuestTexture",
+ "ContainerFrame4Item17IconTexture",
+ "ContainerFrame4Item17NormalTexture",
+ "ContainerFrame4Item17Stock",
+ "ContainerFrame4Item18",
+ "ContainerFrame4Item18Cooldown",
+ "ContainerFrame4Item18Count",
+ "ContainerFrame4Item18IconQuestTexture",
+ "ContainerFrame4Item18IconTexture",
+ "ContainerFrame4Item18NormalTexture",
+ "ContainerFrame4Item18Stock",
+ "ContainerFrame4Item19",
+ "ContainerFrame4Item19Cooldown",
+ "ContainerFrame4Item19Count",
+ "ContainerFrame4Item19IconQuestTexture",
+ "ContainerFrame4Item19IconTexture",
+ "ContainerFrame4Item19NormalTexture",
+ "ContainerFrame4Item19Stock",
+ "ContainerFrame4Item1Cooldown",
+ "ContainerFrame4Item1Count",
+ "ContainerFrame4Item1IconQuestTexture",
+ "ContainerFrame4Item1IconTexture",
+ "ContainerFrame4Item1NormalTexture",
+ "ContainerFrame4Item1Stock",
+ "ContainerFrame4Item2",
+ "ContainerFrame4Item20",
+ "ContainerFrame4Item20Cooldown",
+ "ContainerFrame4Item20Count",
+ "ContainerFrame4Item20IconQuestTexture",
+ "ContainerFrame4Item20IconTexture",
+ "ContainerFrame4Item20NormalTexture",
+ "ContainerFrame4Item20Stock",
+ "ContainerFrame4Item21",
+ "ContainerFrame4Item21Cooldown",
+ "ContainerFrame4Item21Count",
+ "ContainerFrame4Item21IconQuestTexture",
+ "ContainerFrame4Item21IconTexture",
+ "ContainerFrame4Item21NormalTexture",
+ "ContainerFrame4Item21Stock",
+ "ContainerFrame4Item22",
+ "ContainerFrame4Item22Cooldown",
+ "ContainerFrame4Item22Count",
+ "ContainerFrame4Item22IconQuestTexture",
+ "ContainerFrame4Item22IconTexture",
+ "ContainerFrame4Item22NormalTexture",
+ "ContainerFrame4Item22Stock",
+ "ContainerFrame4Item23",
+ "ContainerFrame4Item23Cooldown",
+ "ContainerFrame4Item23Count",
+ "ContainerFrame4Item23IconQuestTexture",
+ "ContainerFrame4Item23IconTexture",
+ "ContainerFrame4Item23NormalTexture",
+ "ContainerFrame4Item23Stock",
+ "ContainerFrame4Item24",
+ "ContainerFrame4Item24Cooldown",
+ "ContainerFrame4Item24Count",
+ "ContainerFrame4Item24IconQuestTexture",
+ "ContainerFrame4Item24IconTexture",
+ "ContainerFrame4Item24NormalTexture",
+ "ContainerFrame4Item24Stock",
+ "ContainerFrame4Item25",
+ "ContainerFrame4Item25Cooldown",
+ "ContainerFrame4Item25Count",
+ "ContainerFrame4Item25IconQuestTexture",
+ "ContainerFrame4Item25IconTexture",
+ "ContainerFrame4Item25NormalTexture",
+ "ContainerFrame4Item25Stock",
+ "ContainerFrame4Item26",
+ "ContainerFrame4Item26Cooldown",
+ "ContainerFrame4Item26Count",
+ "ContainerFrame4Item26IconQuestTexture",
+ "ContainerFrame4Item26IconTexture",
+ "ContainerFrame4Item26NormalTexture",
+ "ContainerFrame4Item26Stock",
+ "ContainerFrame4Item27",
+ "ContainerFrame4Item27Cooldown",
+ "ContainerFrame4Item27Count",
+ "ContainerFrame4Item27IconQuestTexture",
+ "ContainerFrame4Item27IconTexture",
+ "ContainerFrame4Item27NormalTexture",
+ "ContainerFrame4Item27Stock",
+ "ContainerFrame4Item28",
+ "ContainerFrame4Item28Cooldown",
+ "ContainerFrame4Item28Count",
+ "ContainerFrame4Item28IconQuestTexture",
+ "ContainerFrame4Item28IconTexture",
+ "ContainerFrame4Item28NormalTexture",
+ "ContainerFrame4Item28Stock",
+ "ContainerFrame4Item29",
+ "ContainerFrame4Item29Cooldown",
+ "ContainerFrame4Item29Count",
+ "ContainerFrame4Item29IconQuestTexture",
+ "ContainerFrame4Item29IconTexture",
+ "ContainerFrame4Item29NormalTexture",
+ "ContainerFrame4Item29Stock",
+ "ContainerFrame4Item2Cooldown",
+ "ContainerFrame4Item2Count",
+ "ContainerFrame4Item2IconQuestTexture",
+ "ContainerFrame4Item2IconTexture",
+ "ContainerFrame4Item2NormalTexture",
+ "ContainerFrame4Item2Stock",
+ "ContainerFrame4Item3",
+ "ContainerFrame4Item30",
+ "ContainerFrame4Item30Cooldown",
+ "ContainerFrame4Item30Count",
+ "ContainerFrame4Item30IconQuestTexture",
+ "ContainerFrame4Item30IconTexture",
+ "ContainerFrame4Item30NormalTexture",
+ "ContainerFrame4Item30Stock",
+ "ContainerFrame4Item31",
+ "ContainerFrame4Item31Cooldown",
+ "ContainerFrame4Item31Count",
+ "ContainerFrame4Item31IconQuestTexture",
+ "ContainerFrame4Item31IconTexture",
+ "ContainerFrame4Item31NormalTexture",
+ "ContainerFrame4Item31Stock",
+ "ContainerFrame4Item32",
+ "ContainerFrame4Item32Cooldown",
+ "ContainerFrame4Item32Count",
+ "ContainerFrame4Item32IconQuestTexture",
+ "ContainerFrame4Item32IconTexture",
+ "ContainerFrame4Item32NormalTexture",
+ "ContainerFrame4Item32Stock",
+ "ContainerFrame4Item33",
+ "ContainerFrame4Item33Cooldown",
+ "ContainerFrame4Item33Count",
+ "ContainerFrame4Item33IconQuestTexture",
+ "ContainerFrame4Item33IconTexture",
+ "ContainerFrame4Item33NormalTexture",
+ "ContainerFrame4Item33Stock",
+ "ContainerFrame4Item34",
+ "ContainerFrame4Item34Cooldown",
+ "ContainerFrame4Item34Count",
+ "ContainerFrame4Item34IconQuestTexture",
+ "ContainerFrame4Item34IconTexture",
+ "ContainerFrame4Item34NormalTexture",
+ "ContainerFrame4Item34Stock",
+ "ContainerFrame4Item35",
+ "ContainerFrame4Item35Cooldown",
+ "ContainerFrame4Item35Count",
+ "ContainerFrame4Item35IconQuestTexture",
+ "ContainerFrame4Item35IconTexture",
+ "ContainerFrame4Item35NormalTexture",
+ "ContainerFrame4Item35Stock",
+ "ContainerFrame4Item36",
+ "ContainerFrame4Item36Cooldown",
+ "ContainerFrame4Item36Count",
+ "ContainerFrame4Item36IconQuestTexture",
+ "ContainerFrame4Item36IconTexture",
+ "ContainerFrame4Item36NormalTexture",
+ "ContainerFrame4Item36Stock",
+ "ContainerFrame4Item3Cooldown",
+ "ContainerFrame4Item3Count",
+ "ContainerFrame4Item3IconQuestTexture",
+ "ContainerFrame4Item3IconTexture",
+ "ContainerFrame4Item3NormalTexture",
+ "ContainerFrame4Item3Stock",
+ "ContainerFrame4Item4",
+ "ContainerFrame4Item4Cooldown",
+ "ContainerFrame4Item4Count",
+ "ContainerFrame4Item4IconQuestTexture",
+ "ContainerFrame4Item4IconTexture",
+ "ContainerFrame4Item4NormalTexture",
+ "ContainerFrame4Item4Stock",
+ "ContainerFrame4Item5",
+ "ContainerFrame4Item5Cooldown",
+ "ContainerFrame4Item5Count",
+ "ContainerFrame4Item5IconQuestTexture",
+ "ContainerFrame4Item5IconTexture",
+ "ContainerFrame4Item5NormalTexture",
+ "ContainerFrame4Item5Stock",
+ "ContainerFrame4Item6",
+ "ContainerFrame4Item6Cooldown",
+ "ContainerFrame4Item6Count",
+ "ContainerFrame4Item6IconQuestTexture",
+ "ContainerFrame4Item6IconTexture",
+ "ContainerFrame4Item6NormalTexture",
+ "ContainerFrame4Item6Stock",
+ "ContainerFrame4Item7",
+ "ContainerFrame4Item7Cooldown",
+ "ContainerFrame4Item7Count",
+ "ContainerFrame4Item7IconQuestTexture",
+ "ContainerFrame4Item7IconTexture",
+ "ContainerFrame4Item7NormalTexture",
+ "ContainerFrame4Item7Stock",
+ "ContainerFrame4Item8",
+ "ContainerFrame4Item8Cooldown",
+ "ContainerFrame4Item8Count",
+ "ContainerFrame4Item8IconQuestTexture",
+ "ContainerFrame4Item8IconTexture",
+ "ContainerFrame4Item8NormalTexture",
+ "ContainerFrame4Item8Stock",
+ "ContainerFrame4Item9",
+ "ContainerFrame4Item9Cooldown",
+ "ContainerFrame4Item9Count",
+ "ContainerFrame4Item9IconQuestTexture",
+ "ContainerFrame4Item9IconTexture",
+ "ContainerFrame4Item9NormalTexture",
+ "ContainerFrame4Item9Stock",
+ "ContainerFrame4MoneyFrame",
+ "ContainerFrame4MoneyFrameCopperButton",
+ "ContainerFrame4MoneyFrameCopperButtonText",
+ "ContainerFrame4MoneyFrameGoldButton",
+ "ContainerFrame4MoneyFrameGoldButtonText",
+ "ContainerFrame4MoneyFrameSilverButton",
+ "ContainerFrame4MoneyFrameSilverButtonText",
+ "ContainerFrame4Name",
+ "ContainerFrame4Portrait",
+ "ContainerFrame4PortraitButton",
+ "ContainerFrame5",
+ "ContainerFrame5Background1Slot",
+ "ContainerFrame5BackgroundBottom",
+ "ContainerFrame5BackgroundMiddle1",
+ "ContainerFrame5BackgroundMiddle2",
+ "ContainerFrame5BackgroundTop",
+ "ContainerFrame5CloseButton",
+ "ContainerFrame5Item1",
+ "ContainerFrame5Item10",
+ "ContainerFrame5Item10Cooldown",
+ "ContainerFrame5Item10Count",
+ "ContainerFrame5Item10IconQuestTexture",
+ "ContainerFrame5Item10IconTexture",
+ "ContainerFrame5Item10NormalTexture",
+ "ContainerFrame5Item10Stock",
+ "ContainerFrame5Item11",
+ "ContainerFrame5Item11Cooldown",
+ "ContainerFrame5Item11Count",
+ "ContainerFrame5Item11IconQuestTexture",
+ "ContainerFrame5Item11IconTexture",
+ "ContainerFrame5Item11NormalTexture",
+ "ContainerFrame5Item11Stock",
+ "ContainerFrame5Item12",
+ "ContainerFrame5Item12Cooldown",
+ "ContainerFrame5Item12Count",
+ "ContainerFrame5Item12IconQuestTexture",
+ "ContainerFrame5Item12IconTexture",
+ "ContainerFrame5Item12NormalTexture",
+ "ContainerFrame5Item12Stock",
+ "ContainerFrame5Item13",
+ "ContainerFrame5Item13Cooldown",
+ "ContainerFrame5Item13Count",
+ "ContainerFrame5Item13IconQuestTexture",
+ "ContainerFrame5Item13IconTexture",
+ "ContainerFrame5Item13NormalTexture",
+ "ContainerFrame5Item13Stock",
+ "ContainerFrame5Item14",
+ "ContainerFrame5Item14Cooldown",
+ "ContainerFrame5Item14Count",
+ "ContainerFrame5Item14IconQuestTexture",
+ "ContainerFrame5Item14IconTexture",
+ "ContainerFrame5Item14NormalTexture",
+ "ContainerFrame5Item14Stock",
+ "ContainerFrame5Item15",
+ "ContainerFrame5Item15Cooldown",
+ "ContainerFrame5Item15Count",
+ "ContainerFrame5Item15IconQuestTexture",
+ "ContainerFrame5Item15IconTexture",
+ "ContainerFrame5Item15NormalTexture",
+ "ContainerFrame5Item15Stock",
+ "ContainerFrame5Item16",
+ "ContainerFrame5Item16Cooldown",
+ "ContainerFrame5Item16Count",
+ "ContainerFrame5Item16IconQuestTexture",
+ "ContainerFrame5Item16IconTexture",
+ "ContainerFrame5Item16NormalTexture",
+ "ContainerFrame5Item16Stock",
+ "ContainerFrame5Item17",
+ "ContainerFrame5Item17Cooldown",
+ "ContainerFrame5Item17Count",
+ "ContainerFrame5Item17IconQuestTexture",
+ "ContainerFrame5Item17IconTexture",
+ "ContainerFrame5Item17NormalTexture",
+ "ContainerFrame5Item17Stock",
+ "ContainerFrame5Item18",
+ "ContainerFrame5Item18Cooldown",
+ "ContainerFrame5Item18Count",
+ "ContainerFrame5Item18IconQuestTexture",
+ "ContainerFrame5Item18IconTexture",
+ "ContainerFrame5Item18NormalTexture",
+ "ContainerFrame5Item18Stock",
+ "ContainerFrame5Item19",
+ "ContainerFrame5Item19Cooldown",
+ "ContainerFrame5Item19Count",
+ "ContainerFrame5Item19IconQuestTexture",
+ "ContainerFrame5Item19IconTexture",
+ "ContainerFrame5Item19NormalTexture",
+ "ContainerFrame5Item19Stock",
+ "ContainerFrame5Item1Cooldown",
+ "ContainerFrame5Item1Count",
+ "ContainerFrame5Item1IconQuestTexture",
+ "ContainerFrame5Item1IconTexture",
+ "ContainerFrame5Item1NormalTexture",
+ "ContainerFrame5Item1Stock",
+ "ContainerFrame5Item2",
+ "ContainerFrame5Item20",
+ "ContainerFrame5Item20Cooldown",
+ "ContainerFrame5Item20Count",
+ "ContainerFrame5Item20IconQuestTexture",
+ "ContainerFrame5Item20IconTexture",
+ "ContainerFrame5Item20NormalTexture",
+ "ContainerFrame5Item20Stock",
+ "ContainerFrame5Item21",
+ "ContainerFrame5Item21Cooldown",
+ "ContainerFrame5Item21Count",
+ "ContainerFrame5Item21IconQuestTexture",
+ "ContainerFrame5Item21IconTexture",
+ "ContainerFrame5Item21NormalTexture",
+ "ContainerFrame5Item21Stock",
+ "ContainerFrame5Item22",
+ "ContainerFrame5Item22Cooldown",
+ "ContainerFrame5Item22Count",
+ "ContainerFrame5Item22IconQuestTexture",
+ "ContainerFrame5Item22IconTexture",
+ "ContainerFrame5Item22NormalTexture",
+ "ContainerFrame5Item22Stock",
+ "ContainerFrame5Item23",
+ "ContainerFrame5Item23Cooldown",
+ "ContainerFrame5Item23Count",
+ "ContainerFrame5Item23IconQuestTexture",
+ "ContainerFrame5Item23IconTexture",
+ "ContainerFrame5Item23NormalTexture",
+ "ContainerFrame5Item23Stock",
+ "ContainerFrame5Item24",
+ "ContainerFrame5Item24Cooldown",
+ "ContainerFrame5Item24Count",
+ "ContainerFrame5Item24IconQuestTexture",
+ "ContainerFrame5Item24IconTexture",
+ "ContainerFrame5Item24NormalTexture",
+ "ContainerFrame5Item24Stock",
+ "ContainerFrame5Item25",
+ "ContainerFrame5Item25Cooldown",
+ "ContainerFrame5Item25Count",
+ "ContainerFrame5Item25IconQuestTexture",
+ "ContainerFrame5Item25IconTexture",
+ "ContainerFrame5Item25NormalTexture",
+ "ContainerFrame5Item25Stock",
+ "ContainerFrame5Item26",
+ "ContainerFrame5Item26Cooldown",
+ "ContainerFrame5Item26Count",
+ "ContainerFrame5Item26IconQuestTexture",
+ "ContainerFrame5Item26IconTexture",
+ "ContainerFrame5Item26NormalTexture",
+ "ContainerFrame5Item26Stock",
+ "ContainerFrame5Item27",
+ "ContainerFrame5Item27Cooldown",
+ "ContainerFrame5Item27Count",
+ "ContainerFrame5Item27IconQuestTexture",
+ "ContainerFrame5Item27IconTexture",
+ "ContainerFrame5Item27NormalTexture",
+ "ContainerFrame5Item27Stock",
+ "ContainerFrame5Item28",
+ "ContainerFrame5Item28Cooldown",
+ "ContainerFrame5Item28Count",
+ "ContainerFrame5Item28IconQuestTexture",
+ "ContainerFrame5Item28IconTexture",
+ "ContainerFrame5Item28NormalTexture",
+ "ContainerFrame5Item28Stock",
+ "ContainerFrame5Item29",
+ "ContainerFrame5Item29Cooldown",
+ "ContainerFrame5Item29Count",
+ "ContainerFrame5Item29IconQuestTexture",
+ "ContainerFrame5Item29IconTexture",
+ "ContainerFrame5Item29NormalTexture",
+ "ContainerFrame5Item29Stock",
+ "ContainerFrame5Item2Cooldown",
+ "ContainerFrame5Item2Count",
+ "ContainerFrame5Item2IconQuestTexture",
+ "ContainerFrame5Item2IconTexture",
+ "ContainerFrame5Item2NormalTexture",
+ "ContainerFrame5Item2Stock",
+ "ContainerFrame5Item3",
+ "ContainerFrame5Item30",
+ "ContainerFrame5Item30Cooldown",
+ "ContainerFrame5Item30Count",
+ "ContainerFrame5Item30IconQuestTexture",
+ "ContainerFrame5Item30IconTexture",
+ "ContainerFrame5Item30NormalTexture",
+ "ContainerFrame5Item30Stock",
+ "ContainerFrame5Item31",
+ "ContainerFrame5Item31Cooldown",
+ "ContainerFrame5Item31Count",
+ "ContainerFrame5Item31IconQuestTexture",
+ "ContainerFrame5Item31IconTexture",
+ "ContainerFrame5Item31NormalTexture",
+ "ContainerFrame5Item31Stock",
+ "ContainerFrame5Item32",
+ "ContainerFrame5Item32Cooldown",
+ "ContainerFrame5Item32Count",
+ "ContainerFrame5Item32IconQuestTexture",
+ "ContainerFrame5Item32IconTexture",
+ "ContainerFrame5Item32NormalTexture",
+ "ContainerFrame5Item32Stock",
+ "ContainerFrame5Item33",
+ "ContainerFrame5Item33Cooldown",
+ "ContainerFrame5Item33Count",
+ "ContainerFrame5Item33IconQuestTexture",
+ "ContainerFrame5Item33IconTexture",
+ "ContainerFrame5Item33NormalTexture",
+ "ContainerFrame5Item33Stock",
+ "ContainerFrame5Item34",
+ "ContainerFrame5Item34Cooldown",
+ "ContainerFrame5Item34Count",
+ "ContainerFrame5Item34IconQuestTexture",
+ "ContainerFrame5Item34IconTexture",
+ "ContainerFrame5Item34NormalTexture",
+ "ContainerFrame5Item34Stock",
+ "ContainerFrame5Item35",
+ "ContainerFrame5Item35Cooldown",
+ "ContainerFrame5Item35Count",
+ "ContainerFrame5Item35IconQuestTexture",
+ "ContainerFrame5Item35IconTexture",
+ "ContainerFrame5Item35NormalTexture",
+ "ContainerFrame5Item35Stock",
+ "ContainerFrame5Item36",
+ "ContainerFrame5Item36Cooldown",
+ "ContainerFrame5Item36Count",
+ "ContainerFrame5Item36IconQuestTexture",
+ "ContainerFrame5Item36IconTexture",
+ "ContainerFrame5Item36NormalTexture",
+ "ContainerFrame5Item36Stock",
+ "ContainerFrame5Item3Cooldown",
+ "ContainerFrame5Item3Count",
+ "ContainerFrame5Item3IconQuestTexture",
+ "ContainerFrame5Item3IconTexture",
+ "ContainerFrame5Item3NormalTexture",
+ "ContainerFrame5Item3Stock",
+ "ContainerFrame5Item4",
+ "ContainerFrame5Item4Cooldown",
+ "ContainerFrame5Item4Count",
+ "ContainerFrame5Item4IconQuestTexture",
+ "ContainerFrame5Item4IconTexture",
+ "ContainerFrame5Item4NormalTexture",
+ "ContainerFrame5Item4Stock",
+ "ContainerFrame5Item5",
+ "ContainerFrame5Item5Cooldown",
+ "ContainerFrame5Item5Count",
+ "ContainerFrame5Item5IconQuestTexture",
+ "ContainerFrame5Item5IconTexture",
+ "ContainerFrame5Item5NormalTexture",
+ "ContainerFrame5Item5Stock",
+ "ContainerFrame5Item6",
+ "ContainerFrame5Item6Cooldown",
+ "ContainerFrame5Item6Count",
+ "ContainerFrame5Item6IconQuestTexture",
+ "ContainerFrame5Item6IconTexture",
+ "ContainerFrame5Item6NormalTexture",
+ "ContainerFrame5Item6Stock",
+ "ContainerFrame5Item7",
+ "ContainerFrame5Item7Cooldown",
+ "ContainerFrame5Item7Count",
+ "ContainerFrame5Item7IconQuestTexture",
+ "ContainerFrame5Item7IconTexture",
+ "ContainerFrame5Item7NormalTexture",
+ "ContainerFrame5Item7Stock",
+ "ContainerFrame5Item8",
+ "ContainerFrame5Item8Cooldown",
+ "ContainerFrame5Item8Count",
+ "ContainerFrame5Item8IconQuestTexture",
+ "ContainerFrame5Item8IconTexture",
+ "ContainerFrame5Item8NormalTexture",
+ "ContainerFrame5Item8Stock",
+ "ContainerFrame5Item9",
+ "ContainerFrame5Item9Cooldown",
+ "ContainerFrame5Item9Count",
+ "ContainerFrame5Item9IconQuestTexture",
+ "ContainerFrame5Item9IconTexture",
+ "ContainerFrame5Item9NormalTexture",
+ "ContainerFrame5Item9Stock",
+ "ContainerFrame5MoneyFrame",
+ "ContainerFrame5MoneyFrameCopperButton",
+ "ContainerFrame5MoneyFrameCopperButtonText",
+ "ContainerFrame5MoneyFrameGoldButton",
+ "ContainerFrame5MoneyFrameGoldButtonText",
+ "ContainerFrame5MoneyFrameSilverButton",
+ "ContainerFrame5MoneyFrameSilverButtonText",
+ "ContainerFrame5Name",
+ "ContainerFrame5Portrait",
+ "ContainerFrame5PortraitButton",
+ "ContainerFrame6",
+ "ContainerFrame6Background1Slot",
+ "ContainerFrame6BackgroundBottom",
+ "ContainerFrame6BackgroundMiddle1",
+ "ContainerFrame6BackgroundMiddle2",
+ "ContainerFrame6BackgroundTop",
+ "ContainerFrame6CloseButton",
+ "ContainerFrame6Item1",
+ "ContainerFrame6Item10",
+ "ContainerFrame6Item10Cooldown",
+ "ContainerFrame6Item10Count",
+ "ContainerFrame6Item10IconQuestTexture",
+ "ContainerFrame6Item10IconTexture",
+ "ContainerFrame6Item10NormalTexture",
+ "ContainerFrame6Item10Stock",
+ "ContainerFrame6Item11",
+ "ContainerFrame6Item11Cooldown",
+ "ContainerFrame6Item11Count",
+ "ContainerFrame6Item11IconQuestTexture",
+ "ContainerFrame6Item11IconTexture",
+ "ContainerFrame6Item11NormalTexture",
+ "ContainerFrame6Item11Stock",
+ "ContainerFrame6Item12",
+ "ContainerFrame6Item12Cooldown",
+ "ContainerFrame6Item12Count",
+ "ContainerFrame6Item12IconQuestTexture",
+ "ContainerFrame6Item12IconTexture",
+ "ContainerFrame6Item12NormalTexture",
+ "ContainerFrame6Item12Stock",
+ "ContainerFrame6Item13",
+ "ContainerFrame6Item13Cooldown",
+ "ContainerFrame6Item13Count",
+ "ContainerFrame6Item13IconQuestTexture",
+ "ContainerFrame6Item13IconTexture",
+ "ContainerFrame6Item13NormalTexture",
+ "ContainerFrame6Item13Stock",
+ "ContainerFrame6Item14",
+ "ContainerFrame6Item14Cooldown",
+ "ContainerFrame6Item14Count",
+ "ContainerFrame6Item14IconQuestTexture",
+ "ContainerFrame6Item14IconTexture",
+ "ContainerFrame6Item14NormalTexture",
+ "ContainerFrame6Item14Stock",
+ "ContainerFrame6Item15",
+ "ContainerFrame6Item15Cooldown",
+ "ContainerFrame6Item15Count",
+ "ContainerFrame6Item15IconQuestTexture",
+ "ContainerFrame6Item15IconTexture",
+ "ContainerFrame6Item15NormalTexture",
+ "ContainerFrame6Item15Stock",
+ "ContainerFrame6Item16",
+ "ContainerFrame6Item16Cooldown",
+ "ContainerFrame6Item16Count",
+ "ContainerFrame6Item16IconQuestTexture",
+ "ContainerFrame6Item16IconTexture",
+ "ContainerFrame6Item16NormalTexture",
+ "ContainerFrame6Item16Stock",
+ "ContainerFrame6Item17",
+ "ContainerFrame6Item17Cooldown",
+ "ContainerFrame6Item17Count",
+ "ContainerFrame6Item17IconQuestTexture",
+ "ContainerFrame6Item17IconTexture",
+ "ContainerFrame6Item17NormalTexture",
+ "ContainerFrame6Item17Stock",
+ "ContainerFrame6Item18",
+ "ContainerFrame6Item18Cooldown",
+ "ContainerFrame6Item18Count",
+ "ContainerFrame6Item18IconQuestTexture",
+ "ContainerFrame6Item18IconTexture",
+ "ContainerFrame6Item18NormalTexture",
+ "ContainerFrame6Item18Stock",
+ "ContainerFrame6Item19",
+ "ContainerFrame6Item19Cooldown",
+ "ContainerFrame6Item19Count",
+ "ContainerFrame6Item19IconQuestTexture",
+ "ContainerFrame6Item19IconTexture",
+ "ContainerFrame6Item19NormalTexture",
+ "ContainerFrame6Item19Stock",
+ "ContainerFrame6Item1Cooldown",
+ "ContainerFrame6Item1Count",
+ "ContainerFrame6Item1IconQuestTexture",
+ "ContainerFrame6Item1IconTexture",
+ "ContainerFrame6Item1NormalTexture",
+ "ContainerFrame6Item1Stock",
+ "ContainerFrame6Item2",
+ "ContainerFrame6Item20",
+ "ContainerFrame6Item20Cooldown",
+ "ContainerFrame6Item20Count",
+ "ContainerFrame6Item20IconQuestTexture",
+ "ContainerFrame6Item20IconTexture",
+ "ContainerFrame6Item20NormalTexture",
+ "ContainerFrame6Item20Stock",
+ "ContainerFrame6Item21",
+ "ContainerFrame6Item21Cooldown",
+ "ContainerFrame6Item21Count",
+ "ContainerFrame6Item21IconQuestTexture",
+ "ContainerFrame6Item21IconTexture",
+ "ContainerFrame6Item21NormalTexture",
+ "ContainerFrame6Item21Stock",
+ "ContainerFrame6Item22",
+ "ContainerFrame6Item22Cooldown",
+ "ContainerFrame6Item22Count",
+ "ContainerFrame6Item22IconQuestTexture",
+ "ContainerFrame6Item22IconTexture",
+ "ContainerFrame6Item22NormalTexture",
+ "ContainerFrame6Item22Stock",
+ "ContainerFrame6Item23",
+ "ContainerFrame6Item23Cooldown",
+ "ContainerFrame6Item23Count",
+ "ContainerFrame6Item23IconQuestTexture",
+ "ContainerFrame6Item23IconTexture",
+ "ContainerFrame6Item23NormalTexture",
+ "ContainerFrame6Item23Stock",
+ "ContainerFrame6Item24",
+ "ContainerFrame6Item24Cooldown",
+ "ContainerFrame6Item24Count",
+ "ContainerFrame6Item24IconQuestTexture",
+ "ContainerFrame6Item24IconTexture",
+ "ContainerFrame6Item24NormalTexture",
+ "ContainerFrame6Item24Stock",
+ "ContainerFrame6Item25",
+ "ContainerFrame6Item25Cooldown",
+ "ContainerFrame6Item25Count",
+ "ContainerFrame6Item25IconQuestTexture",
+ "ContainerFrame6Item25IconTexture",
+ "ContainerFrame6Item25NormalTexture",
+ "ContainerFrame6Item25Stock",
+ "ContainerFrame6Item26",
+ "ContainerFrame6Item26Cooldown",
+ "ContainerFrame6Item26Count",
+ "ContainerFrame6Item26IconQuestTexture",
+ "ContainerFrame6Item26IconTexture",
+ "ContainerFrame6Item26NormalTexture",
+ "ContainerFrame6Item26Stock",
+ "ContainerFrame6Item27",
+ "ContainerFrame6Item27Cooldown",
+ "ContainerFrame6Item27Count",
+ "ContainerFrame6Item27IconQuestTexture",
+ "ContainerFrame6Item27IconTexture",
+ "ContainerFrame6Item27NormalTexture",
+ "ContainerFrame6Item27Stock",
+ "ContainerFrame6Item28",
+ "ContainerFrame6Item28Cooldown",
+ "ContainerFrame6Item28Count",
+ "ContainerFrame6Item28IconQuestTexture",
+ "ContainerFrame6Item28IconTexture",
+ "ContainerFrame6Item28NormalTexture",
+ "ContainerFrame6Item28Stock",
+ "ContainerFrame6Item29",
+ "ContainerFrame6Item29Cooldown",
+ "ContainerFrame6Item29Count",
+ "ContainerFrame6Item29IconQuestTexture",
+ "ContainerFrame6Item29IconTexture",
+ "ContainerFrame6Item29NormalTexture",
+ "ContainerFrame6Item29Stock",
+ "ContainerFrame6Item2Cooldown",
+ "ContainerFrame6Item2Count",
+ "ContainerFrame6Item2IconQuestTexture",
+ "ContainerFrame6Item2IconTexture",
+ "ContainerFrame6Item2NormalTexture",
+ "ContainerFrame6Item2Stock",
+ "ContainerFrame6Item3",
+ "ContainerFrame6Item30",
+ "ContainerFrame6Item30Cooldown",
+ "ContainerFrame6Item30Count",
+ "ContainerFrame6Item30IconQuestTexture",
+ "ContainerFrame6Item30IconTexture",
+ "ContainerFrame6Item30NormalTexture",
+ "ContainerFrame6Item30Stock",
+ "ContainerFrame6Item31",
+ "ContainerFrame6Item31Cooldown",
+ "ContainerFrame6Item31Count",
+ "ContainerFrame6Item31IconQuestTexture",
+ "ContainerFrame6Item31IconTexture",
+ "ContainerFrame6Item31NormalTexture",
+ "ContainerFrame6Item31Stock",
+ "ContainerFrame6Item32",
+ "ContainerFrame6Item32Cooldown",
+ "ContainerFrame6Item32Count",
+ "ContainerFrame6Item32IconQuestTexture",
+ "ContainerFrame6Item32IconTexture",
+ "ContainerFrame6Item32NormalTexture",
+ "ContainerFrame6Item32Stock",
+ "ContainerFrame6Item33",
+ "ContainerFrame6Item33Cooldown",
+ "ContainerFrame6Item33Count",
+ "ContainerFrame6Item33IconQuestTexture",
+ "ContainerFrame6Item33IconTexture",
+ "ContainerFrame6Item33NormalTexture",
+ "ContainerFrame6Item33Stock",
+ "ContainerFrame6Item34",
+ "ContainerFrame6Item34Cooldown",
+ "ContainerFrame6Item34Count",
+ "ContainerFrame6Item34IconQuestTexture",
+ "ContainerFrame6Item34IconTexture",
+ "ContainerFrame6Item34NormalTexture",
+ "ContainerFrame6Item34Stock",
+ "ContainerFrame6Item35",
+ "ContainerFrame6Item35Cooldown",
+ "ContainerFrame6Item35Count",
+ "ContainerFrame6Item35IconQuestTexture",
+ "ContainerFrame6Item35IconTexture",
+ "ContainerFrame6Item35NormalTexture",
+ "ContainerFrame6Item35Stock",
+ "ContainerFrame6Item36",
+ "ContainerFrame6Item36Cooldown",
+ "ContainerFrame6Item36Count",
+ "ContainerFrame6Item36IconQuestTexture",
+ "ContainerFrame6Item36IconTexture",
+ "ContainerFrame6Item36NormalTexture",
+ "ContainerFrame6Item36Stock",
+ "ContainerFrame6Item3Cooldown",
+ "ContainerFrame6Item3Count",
+ "ContainerFrame6Item3IconQuestTexture",
+ "ContainerFrame6Item3IconTexture",
+ "ContainerFrame6Item3NormalTexture",
+ "ContainerFrame6Item3Stock",
+ "ContainerFrame6Item4",
+ "ContainerFrame6Item4Cooldown",
+ "ContainerFrame6Item4Count",
+ "ContainerFrame6Item4IconQuestTexture",
+ "ContainerFrame6Item4IconTexture",
+ "ContainerFrame6Item4NormalTexture",
+ "ContainerFrame6Item4Stock",
+ "ContainerFrame6Item5",
+ "ContainerFrame6Item5Cooldown",
+ "ContainerFrame6Item5Count",
+ "ContainerFrame6Item5IconQuestTexture",
+ "ContainerFrame6Item5IconTexture",
+ "ContainerFrame6Item5NormalTexture",
+ "ContainerFrame6Item5Stock",
+ "ContainerFrame6Item6",
+ "ContainerFrame6Item6Cooldown",
+ "ContainerFrame6Item6Count",
+ "ContainerFrame6Item6IconQuestTexture",
+ "ContainerFrame6Item6IconTexture",
+ "ContainerFrame6Item6NormalTexture",
+ "ContainerFrame6Item6Stock",
+ "ContainerFrame6Item7",
+ "ContainerFrame6Item7Cooldown",
+ "ContainerFrame6Item7Count",
+ "ContainerFrame6Item7IconQuestTexture",
+ "ContainerFrame6Item7IconTexture",
+ "ContainerFrame6Item7NormalTexture",
+ "ContainerFrame6Item7Stock",
+ "ContainerFrame6Item8",
+ "ContainerFrame6Item8Cooldown",
+ "ContainerFrame6Item8Count",
+ "ContainerFrame6Item8IconQuestTexture",
+ "ContainerFrame6Item8IconTexture",
+ "ContainerFrame6Item8NormalTexture",
+ "ContainerFrame6Item8Stock",
+ "ContainerFrame6Item9",
+ "ContainerFrame6Item9Cooldown",
+ "ContainerFrame6Item9Count",
+ "ContainerFrame6Item9IconQuestTexture",
+ "ContainerFrame6Item9IconTexture",
+ "ContainerFrame6Item9NormalTexture",
+ "ContainerFrame6Item9Stock",
+ "ContainerFrame6MoneyFrame",
+ "ContainerFrame6MoneyFrameCopperButton",
+ "ContainerFrame6MoneyFrameCopperButtonText",
+ "ContainerFrame6MoneyFrameGoldButton",
+ "ContainerFrame6MoneyFrameGoldButtonText",
+ "ContainerFrame6MoneyFrameSilverButton",
+ "ContainerFrame6MoneyFrameSilverButtonText",
+ "ContainerFrame6Name",
+ "ContainerFrame6Portrait",
+ "ContainerFrame6PortraitButton",
+ "ContainerFrame7",
+ "ContainerFrame7Background1Slot",
+ "ContainerFrame7BackgroundBottom",
+ "ContainerFrame7BackgroundMiddle1",
+ "ContainerFrame7BackgroundMiddle2",
+ "ContainerFrame7BackgroundTop",
+ "ContainerFrame7CloseButton",
+ "ContainerFrame7Item1",
+ "ContainerFrame7Item10",
+ "ContainerFrame7Item10Cooldown",
+ "ContainerFrame7Item10Count",
+ "ContainerFrame7Item10IconQuestTexture",
+ "ContainerFrame7Item10IconTexture",
+ "ContainerFrame7Item10NormalTexture",
+ "ContainerFrame7Item10Stock",
+ "ContainerFrame7Item11",
+ "ContainerFrame7Item11Cooldown",
+ "ContainerFrame7Item11Count",
+ "ContainerFrame7Item11IconQuestTexture",
+ "ContainerFrame7Item11IconTexture",
+ "ContainerFrame7Item11NormalTexture",
+ "ContainerFrame7Item11Stock",
+ "ContainerFrame7Item12",
+ "ContainerFrame7Item12Cooldown",
+ "ContainerFrame7Item12Count",
+ "ContainerFrame7Item12IconQuestTexture",
+ "ContainerFrame7Item12IconTexture",
+ "ContainerFrame7Item12NormalTexture",
+ "ContainerFrame7Item12Stock",
+ "ContainerFrame7Item13",
+ "ContainerFrame7Item13Cooldown",
+ "ContainerFrame7Item13Count",
+ "ContainerFrame7Item13IconQuestTexture",
+ "ContainerFrame7Item13IconTexture",
+ "ContainerFrame7Item13NormalTexture",
+ "ContainerFrame7Item13Stock",
+ "ContainerFrame7Item14",
+ "ContainerFrame7Item14Cooldown",
+ "ContainerFrame7Item14Count",
+ "ContainerFrame7Item14IconQuestTexture",
+ "ContainerFrame7Item14IconTexture",
+ "ContainerFrame7Item14NormalTexture",
+ "ContainerFrame7Item14Stock",
+ "ContainerFrame7Item15",
+ "ContainerFrame7Item15Cooldown",
+ "ContainerFrame7Item15Count",
+ "ContainerFrame7Item15IconQuestTexture",
+ "ContainerFrame7Item15IconTexture",
+ "ContainerFrame7Item15NormalTexture",
+ "ContainerFrame7Item15Stock",
+ "ContainerFrame7Item16",
+ "ContainerFrame7Item16Cooldown",
+ "ContainerFrame7Item16Count",
+ "ContainerFrame7Item16IconQuestTexture",
+ "ContainerFrame7Item16IconTexture",
+ "ContainerFrame7Item16NormalTexture",
+ "ContainerFrame7Item16Stock",
+ "ContainerFrame7Item17",
+ "ContainerFrame7Item17Cooldown",
+ "ContainerFrame7Item17Count",
+ "ContainerFrame7Item17IconQuestTexture",
+ "ContainerFrame7Item17IconTexture",
+ "ContainerFrame7Item17NormalTexture",
+ "ContainerFrame7Item17Stock",
+ "ContainerFrame7Item18",
+ "ContainerFrame7Item18Cooldown",
+ "ContainerFrame7Item18Count",
+ "ContainerFrame7Item18IconQuestTexture",
+ "ContainerFrame7Item18IconTexture",
+ "ContainerFrame7Item18NormalTexture",
+ "ContainerFrame7Item18Stock",
+ "ContainerFrame7Item19",
+ "ContainerFrame7Item19Cooldown",
+ "ContainerFrame7Item19Count",
+ "ContainerFrame7Item19IconQuestTexture",
+ "ContainerFrame7Item19IconTexture",
+ "ContainerFrame7Item19NormalTexture",
+ "ContainerFrame7Item19Stock",
+ "ContainerFrame7Item1Cooldown",
+ "ContainerFrame7Item1Count",
+ "ContainerFrame7Item1IconQuestTexture",
+ "ContainerFrame7Item1IconTexture",
+ "ContainerFrame7Item1NormalTexture",
+ "ContainerFrame7Item1Stock",
+ "ContainerFrame7Item2",
+ "ContainerFrame7Item20",
+ "ContainerFrame7Item20Cooldown",
+ "ContainerFrame7Item20Count",
+ "ContainerFrame7Item20IconQuestTexture",
+ "ContainerFrame7Item20IconTexture",
+ "ContainerFrame7Item20NormalTexture",
+ "ContainerFrame7Item20Stock",
+ "ContainerFrame7Item21",
+ "ContainerFrame7Item21Cooldown",
+ "ContainerFrame7Item21Count",
+ "ContainerFrame7Item21IconQuestTexture",
+ "ContainerFrame7Item21IconTexture",
+ "ContainerFrame7Item21NormalTexture",
+ "ContainerFrame7Item21Stock",
+ "ContainerFrame7Item22",
+ "ContainerFrame7Item22Cooldown",
+ "ContainerFrame7Item22Count",
+ "ContainerFrame7Item22IconQuestTexture",
+ "ContainerFrame7Item22IconTexture",
+ "ContainerFrame7Item22NormalTexture",
+ "ContainerFrame7Item22Stock",
+ "ContainerFrame7Item23",
+ "ContainerFrame7Item23Cooldown",
+ "ContainerFrame7Item23Count",
+ "ContainerFrame7Item23IconQuestTexture",
+ "ContainerFrame7Item23IconTexture",
+ "ContainerFrame7Item23NormalTexture",
+ "ContainerFrame7Item23Stock",
+ "ContainerFrame7Item24",
+ "ContainerFrame7Item24Cooldown",
+ "ContainerFrame7Item24Count",
+ "ContainerFrame7Item24IconQuestTexture",
+ "ContainerFrame7Item24IconTexture",
+ "ContainerFrame7Item24NormalTexture",
+ "ContainerFrame7Item24Stock",
+ "ContainerFrame7Item25",
+ "ContainerFrame7Item25Cooldown",
+ "ContainerFrame7Item25Count",
+ "ContainerFrame7Item25IconQuestTexture",
+ "ContainerFrame7Item25IconTexture",
+ "ContainerFrame7Item25NormalTexture",
+ "ContainerFrame7Item25Stock",
+ "ContainerFrame7Item26",
+ "ContainerFrame7Item26Cooldown",
+ "ContainerFrame7Item26Count",
+ "ContainerFrame7Item26IconQuestTexture",
+ "ContainerFrame7Item26IconTexture",
+ "ContainerFrame7Item26NormalTexture",
+ "ContainerFrame7Item26Stock",
+ "ContainerFrame7Item27",
+ "ContainerFrame7Item27Cooldown",
+ "ContainerFrame7Item27Count",
+ "ContainerFrame7Item27IconQuestTexture",
+ "ContainerFrame7Item27IconTexture",
+ "ContainerFrame7Item27NormalTexture",
+ "ContainerFrame7Item27Stock",
+ "ContainerFrame7Item28",
+ "ContainerFrame7Item28Cooldown",
+ "ContainerFrame7Item28Count",
+ "ContainerFrame7Item28IconQuestTexture",
+ "ContainerFrame7Item28IconTexture",
+ "ContainerFrame7Item28NormalTexture",
+ "ContainerFrame7Item28Stock",
+ "ContainerFrame7Item29",
+ "ContainerFrame7Item29Cooldown",
+ "ContainerFrame7Item29Count",
+ "ContainerFrame7Item29IconQuestTexture",
+ "ContainerFrame7Item29IconTexture",
+ "ContainerFrame7Item29NormalTexture",
+ "ContainerFrame7Item29Stock",
+ "ContainerFrame7Item2Cooldown",
+ "ContainerFrame7Item2Count",
+ "ContainerFrame7Item2IconQuestTexture",
+ "ContainerFrame7Item2IconTexture",
+ "ContainerFrame7Item2NormalTexture",
+ "ContainerFrame7Item2Stock",
+ "ContainerFrame7Item3",
+ "ContainerFrame7Item30",
+ "ContainerFrame7Item30Cooldown",
+ "ContainerFrame7Item30Count",
+ "ContainerFrame7Item30IconQuestTexture",
+ "ContainerFrame7Item30IconTexture",
+ "ContainerFrame7Item30NormalTexture",
+ "ContainerFrame7Item30Stock",
+ "ContainerFrame7Item31",
+ "ContainerFrame7Item31Cooldown",
+ "ContainerFrame7Item31Count",
+ "ContainerFrame7Item31IconQuestTexture",
+ "ContainerFrame7Item31IconTexture",
+ "ContainerFrame7Item31NormalTexture",
+ "ContainerFrame7Item31Stock",
+ "ContainerFrame7Item32",
+ "ContainerFrame7Item32Cooldown",
+ "ContainerFrame7Item32Count",
+ "ContainerFrame7Item32IconQuestTexture",
+ "ContainerFrame7Item32IconTexture",
+ "ContainerFrame7Item32NormalTexture",
+ "ContainerFrame7Item32Stock",
+ "ContainerFrame7Item33",
+ "ContainerFrame7Item33Cooldown",
+ "ContainerFrame7Item33Count",
+ "ContainerFrame7Item33IconQuestTexture",
+ "ContainerFrame7Item33IconTexture",
+ "ContainerFrame7Item33NormalTexture",
+ "ContainerFrame7Item33Stock",
+ "ContainerFrame7Item34",
+ "ContainerFrame7Item34Cooldown",
+ "ContainerFrame7Item34Count",
+ "ContainerFrame7Item34IconQuestTexture",
+ "ContainerFrame7Item34IconTexture",
+ "ContainerFrame7Item34NormalTexture",
+ "ContainerFrame7Item34Stock",
+ "ContainerFrame7Item35",
+ "ContainerFrame7Item35Cooldown",
+ "ContainerFrame7Item35Count",
+ "ContainerFrame7Item35IconQuestTexture",
+ "ContainerFrame7Item35IconTexture",
+ "ContainerFrame7Item35NormalTexture",
+ "ContainerFrame7Item35Stock",
+ "ContainerFrame7Item36",
+ "ContainerFrame7Item36Cooldown",
+ "ContainerFrame7Item36Count",
+ "ContainerFrame7Item36IconQuestTexture",
+ "ContainerFrame7Item36IconTexture",
+ "ContainerFrame7Item36NormalTexture",
+ "ContainerFrame7Item36Stock",
+ "ContainerFrame7Item3Cooldown",
+ "ContainerFrame7Item3Count",
+ "ContainerFrame7Item3IconQuestTexture",
+ "ContainerFrame7Item3IconTexture",
+ "ContainerFrame7Item3NormalTexture",
+ "ContainerFrame7Item3Stock",
+ "ContainerFrame7Item4",
+ "ContainerFrame7Item4Cooldown",
+ "ContainerFrame7Item4Count",
+ "ContainerFrame7Item4IconQuestTexture",
+ "ContainerFrame7Item4IconTexture",
+ "ContainerFrame7Item4NormalTexture",
+ "ContainerFrame7Item4Stock",
+ "ContainerFrame7Item5",
+ "ContainerFrame7Item5Cooldown",
+ "ContainerFrame7Item5Count",
+ "ContainerFrame7Item5IconQuestTexture",
+ "ContainerFrame7Item5IconTexture",
+ "ContainerFrame7Item5NormalTexture",
+ "ContainerFrame7Item5Stock",
+ "ContainerFrame7Item6",
+ "ContainerFrame7Item6Cooldown",
+ "ContainerFrame7Item6Count",
+ "ContainerFrame7Item6IconQuestTexture",
+ "ContainerFrame7Item6IconTexture",
+ "ContainerFrame7Item6NormalTexture",
+ "ContainerFrame7Item6Stock",
+ "ContainerFrame7Item7",
+ "ContainerFrame7Item7Cooldown",
+ "ContainerFrame7Item7Count",
+ "ContainerFrame7Item7IconQuestTexture",
+ "ContainerFrame7Item7IconTexture",
+ "ContainerFrame7Item7NormalTexture",
+ "ContainerFrame7Item7Stock",
+ "ContainerFrame7Item8",
+ "ContainerFrame7Item8Cooldown",
+ "ContainerFrame7Item8Count",
+ "ContainerFrame7Item8IconQuestTexture",
+ "ContainerFrame7Item8IconTexture",
+ "ContainerFrame7Item8NormalTexture",
+ "ContainerFrame7Item8Stock",
+ "ContainerFrame7Item9",
+ "ContainerFrame7Item9Cooldown",
+ "ContainerFrame7Item9Count",
+ "ContainerFrame7Item9IconQuestTexture",
+ "ContainerFrame7Item9IconTexture",
+ "ContainerFrame7Item9NormalTexture",
+ "ContainerFrame7Item9Stock",
+ "ContainerFrame7MoneyFrame",
+ "ContainerFrame7MoneyFrameCopperButton",
+ "ContainerFrame7MoneyFrameCopperButtonText",
+ "ContainerFrame7MoneyFrameGoldButton",
+ "ContainerFrame7MoneyFrameGoldButtonText",
+ "ContainerFrame7MoneyFrameSilverButton",
+ "ContainerFrame7MoneyFrameSilverButtonText",
+ "ContainerFrame7Name",
+ "ContainerFrame7Portrait",
+ "ContainerFrame7PortraitButton",
+ "ContainerFrame8",
+ "ContainerFrame8Background1Slot",
+ "ContainerFrame8BackgroundBottom",
+ "ContainerFrame8BackgroundMiddle1",
+ "ContainerFrame8BackgroundMiddle2",
+ "ContainerFrame8BackgroundTop",
+ "ContainerFrame8CloseButton",
+ "ContainerFrame8Item1",
+ "ContainerFrame8Item10",
+ "ContainerFrame8Item10Cooldown",
+ "ContainerFrame8Item10Count",
+ "ContainerFrame8Item10IconQuestTexture",
+ "ContainerFrame8Item10IconTexture",
+ "ContainerFrame8Item10NormalTexture",
+ "ContainerFrame8Item10Stock",
+ "ContainerFrame8Item11",
+ "ContainerFrame8Item11Cooldown",
+ "ContainerFrame8Item11Count",
+ "ContainerFrame8Item11IconQuestTexture",
+ "ContainerFrame8Item11IconTexture",
+ "ContainerFrame8Item11NormalTexture",
+ "ContainerFrame8Item11Stock",
+ "ContainerFrame8Item12",
+ "ContainerFrame8Item12Cooldown",
+ "ContainerFrame8Item12Count",
+ "ContainerFrame8Item12IconQuestTexture",
+ "ContainerFrame8Item12IconTexture",
+ "ContainerFrame8Item12NormalTexture",
+ "ContainerFrame8Item12Stock",
+ "ContainerFrame8Item13",
+ "ContainerFrame8Item13Cooldown",
+ "ContainerFrame8Item13Count",
+ "ContainerFrame8Item13IconQuestTexture",
+ "ContainerFrame8Item13IconTexture",
+ "ContainerFrame8Item13NormalTexture",
+ "ContainerFrame8Item13Stock",
+ "ContainerFrame8Item14",
+ "ContainerFrame8Item14Cooldown",
+ "ContainerFrame8Item14Count",
+ "ContainerFrame8Item14IconQuestTexture",
+ "ContainerFrame8Item14IconTexture",
+ "ContainerFrame8Item14NormalTexture",
+ "ContainerFrame8Item14Stock",
+ "ContainerFrame8Item15",
+ "ContainerFrame8Item15Cooldown",
+ "ContainerFrame8Item15Count",
+ "ContainerFrame8Item15IconQuestTexture",
+ "ContainerFrame8Item15IconTexture",
+ "ContainerFrame8Item15NormalTexture",
+ "ContainerFrame8Item15Stock",
+ "ContainerFrame8Item16",
+ "ContainerFrame8Item16Cooldown",
+ "ContainerFrame8Item16Count",
+ "ContainerFrame8Item16IconQuestTexture",
+ "ContainerFrame8Item16IconTexture",
+ "ContainerFrame8Item16NormalTexture",
+ "ContainerFrame8Item16Stock",
+ "ContainerFrame8Item17",
+ "ContainerFrame8Item17Cooldown",
+ "ContainerFrame8Item17Count",
+ "ContainerFrame8Item17IconQuestTexture",
+ "ContainerFrame8Item17IconTexture",
+ "ContainerFrame8Item17NormalTexture",
+ "ContainerFrame8Item17Stock",
+ "ContainerFrame8Item18",
+ "ContainerFrame8Item18Cooldown",
+ "ContainerFrame8Item18Count",
+ "ContainerFrame8Item18IconQuestTexture",
+ "ContainerFrame8Item18IconTexture",
+ "ContainerFrame8Item18NormalTexture",
+ "ContainerFrame8Item18Stock",
+ "ContainerFrame8Item19",
+ "ContainerFrame8Item19Cooldown",
+ "ContainerFrame8Item19Count",
+ "ContainerFrame8Item19IconQuestTexture",
+ "ContainerFrame8Item19IconTexture",
+ "ContainerFrame8Item19NormalTexture",
+ "ContainerFrame8Item19Stock",
+ "ContainerFrame8Item1Cooldown",
+ "ContainerFrame8Item1Count",
+ "ContainerFrame8Item1IconQuestTexture",
+ "ContainerFrame8Item1IconTexture",
+ "ContainerFrame8Item1NormalTexture",
+ "ContainerFrame8Item1Stock",
+ "ContainerFrame8Item2",
+ "ContainerFrame8Item20",
+ "ContainerFrame8Item20Cooldown",
+ "ContainerFrame8Item20Count",
+ "ContainerFrame8Item20IconQuestTexture",
+ "ContainerFrame8Item20IconTexture",
+ "ContainerFrame8Item20NormalTexture",
+ "ContainerFrame8Item20Stock",
+ "ContainerFrame8Item21",
+ "ContainerFrame8Item21Cooldown",
+ "ContainerFrame8Item21Count",
+ "ContainerFrame8Item21IconQuestTexture",
+ "ContainerFrame8Item21IconTexture",
+ "ContainerFrame8Item21NormalTexture",
+ "ContainerFrame8Item21Stock",
+ "ContainerFrame8Item22",
+ "ContainerFrame8Item22Cooldown",
+ "ContainerFrame8Item22Count",
+ "ContainerFrame8Item22IconQuestTexture",
+ "ContainerFrame8Item22IconTexture",
+ "ContainerFrame8Item22NormalTexture",
+ "ContainerFrame8Item22Stock",
+ "ContainerFrame8Item23",
+ "ContainerFrame8Item23Cooldown",
+ "ContainerFrame8Item23Count",
+ "ContainerFrame8Item23IconQuestTexture",
+ "ContainerFrame8Item23IconTexture",
+ "ContainerFrame8Item23NormalTexture",
+ "ContainerFrame8Item23Stock",
+ "ContainerFrame8Item24",
+ "ContainerFrame8Item24Cooldown",
+ "ContainerFrame8Item24Count",
+ "ContainerFrame8Item24IconQuestTexture",
+ "ContainerFrame8Item24IconTexture",
+ "ContainerFrame8Item24NormalTexture",
+ "ContainerFrame8Item24Stock",
+ "ContainerFrame8Item25",
+ "ContainerFrame8Item25Cooldown",
+ "ContainerFrame8Item25Count",
+ "ContainerFrame8Item25IconQuestTexture",
+ "ContainerFrame8Item25IconTexture",
+ "ContainerFrame8Item25NormalTexture",
+ "ContainerFrame8Item25Stock",
+ "ContainerFrame8Item26",
+ "ContainerFrame8Item26Cooldown",
+ "ContainerFrame8Item26Count",
+ "ContainerFrame8Item26IconQuestTexture",
+ "ContainerFrame8Item26IconTexture",
+ "ContainerFrame8Item26NormalTexture",
+ "ContainerFrame8Item26Stock",
+ "ContainerFrame8Item27",
+ "ContainerFrame8Item27Cooldown",
+ "ContainerFrame8Item27Count",
+ "ContainerFrame8Item27IconQuestTexture",
+ "ContainerFrame8Item27IconTexture",
+ "ContainerFrame8Item27NormalTexture",
+ "ContainerFrame8Item27Stock",
+ "ContainerFrame8Item28",
+ "ContainerFrame8Item28Cooldown",
+ "ContainerFrame8Item28Count",
+ "ContainerFrame8Item28IconQuestTexture",
+ "ContainerFrame8Item28IconTexture",
+ "ContainerFrame8Item28NormalTexture",
+ "ContainerFrame8Item28Stock",
+ "ContainerFrame8Item29",
+ "ContainerFrame8Item29Cooldown",
+ "ContainerFrame8Item29Count",
+ "ContainerFrame8Item29IconQuestTexture",
+ "ContainerFrame8Item29IconTexture",
+ "ContainerFrame8Item29NormalTexture",
+ "ContainerFrame8Item29Stock",
+ "ContainerFrame8Item2Cooldown",
+ "ContainerFrame8Item2Count",
+ "ContainerFrame8Item2IconQuestTexture",
+ "ContainerFrame8Item2IconTexture",
+ "ContainerFrame8Item2NormalTexture",
+ "ContainerFrame8Item2Stock",
+ "ContainerFrame8Item3",
+ "ContainerFrame8Item30",
+ "ContainerFrame8Item30Cooldown",
+ "ContainerFrame8Item30Count",
+ "ContainerFrame8Item30IconQuestTexture",
+ "ContainerFrame8Item30IconTexture",
+ "ContainerFrame8Item30NormalTexture",
+ "ContainerFrame8Item30Stock",
+ "ContainerFrame8Item31",
+ "ContainerFrame8Item31Cooldown",
+ "ContainerFrame8Item31Count",
+ "ContainerFrame8Item31IconQuestTexture",
+ "ContainerFrame8Item31IconTexture",
+ "ContainerFrame8Item31NormalTexture",
+ "ContainerFrame8Item31Stock",
+ "ContainerFrame8Item32",
+ "ContainerFrame8Item32Cooldown",
+ "ContainerFrame8Item32Count",
+ "ContainerFrame8Item32IconQuestTexture",
+ "ContainerFrame8Item32IconTexture",
+ "ContainerFrame8Item32NormalTexture",
+ "ContainerFrame8Item32Stock",
+ "ContainerFrame8Item33",
+ "ContainerFrame8Item33Cooldown",
+ "ContainerFrame8Item33Count",
+ "ContainerFrame8Item33IconQuestTexture",
+ "ContainerFrame8Item33IconTexture",
+ "ContainerFrame8Item33NormalTexture",
+ "ContainerFrame8Item33Stock",
+ "ContainerFrame8Item34",
+ "ContainerFrame8Item34Cooldown",
+ "ContainerFrame8Item34Count",
+ "ContainerFrame8Item34IconQuestTexture",
+ "ContainerFrame8Item34IconTexture",
+ "ContainerFrame8Item34NormalTexture",
+ "ContainerFrame8Item34Stock",
+ "ContainerFrame8Item35",
+ "ContainerFrame8Item35Cooldown",
+ "ContainerFrame8Item35Count",
+ "ContainerFrame8Item35IconQuestTexture",
+ "ContainerFrame8Item35IconTexture",
+ "ContainerFrame8Item35NormalTexture",
+ "ContainerFrame8Item35Stock",
+ "ContainerFrame8Item36",
+ "ContainerFrame8Item36Cooldown",
+ "ContainerFrame8Item36Count",
+ "ContainerFrame8Item36IconQuestTexture",
+ "ContainerFrame8Item36IconTexture",
+ "ContainerFrame8Item36NormalTexture",
+ "ContainerFrame8Item36Stock",
+ "ContainerFrame8Item3Cooldown",
+ "ContainerFrame8Item3Count",
+ "ContainerFrame8Item3IconQuestTexture",
+ "ContainerFrame8Item3IconTexture",
+ "ContainerFrame8Item3NormalTexture",
+ "ContainerFrame8Item3Stock",
+ "ContainerFrame8Item4",
+ "ContainerFrame8Item4Cooldown",
+ "ContainerFrame8Item4Count",
+ "ContainerFrame8Item4IconQuestTexture",
+ "ContainerFrame8Item4IconTexture",
+ "ContainerFrame8Item4NormalTexture",
+ "ContainerFrame8Item4Stock",
+ "ContainerFrame8Item5",
+ "ContainerFrame8Item5Cooldown",
+ "ContainerFrame8Item5Count",
+ "ContainerFrame8Item5IconQuestTexture",
+ "ContainerFrame8Item5IconTexture",
+ "ContainerFrame8Item5NormalTexture",
+ "ContainerFrame8Item5Stock",
+ "ContainerFrame8Item6",
+ "ContainerFrame8Item6Cooldown",
+ "ContainerFrame8Item6Count",
+ "ContainerFrame8Item6IconQuestTexture",
+ "ContainerFrame8Item6IconTexture",
+ "ContainerFrame8Item6NormalTexture",
+ "ContainerFrame8Item6Stock",
+ "ContainerFrame8Item7",
+ "ContainerFrame8Item7Cooldown",
+ "ContainerFrame8Item7Count",
+ "ContainerFrame8Item7IconQuestTexture",
+ "ContainerFrame8Item7IconTexture",
+ "ContainerFrame8Item7NormalTexture",
+ "ContainerFrame8Item7Stock",
+ "ContainerFrame8Item8",
+ "ContainerFrame8Item8Cooldown",
+ "ContainerFrame8Item8Count",
+ "ContainerFrame8Item8IconQuestTexture",
+ "ContainerFrame8Item8IconTexture",
+ "ContainerFrame8Item8NormalTexture",
+ "ContainerFrame8Item8Stock",
+ "ContainerFrame8Item9",
+ "ContainerFrame8Item9Cooldown",
+ "ContainerFrame8Item9Count",
+ "ContainerFrame8Item9IconQuestTexture",
+ "ContainerFrame8Item9IconTexture",
+ "ContainerFrame8Item9NormalTexture",
+ "ContainerFrame8Item9Stock",
+ "ContainerFrame8MoneyFrame",
+ "ContainerFrame8MoneyFrameCopperButton",
+ "ContainerFrame8MoneyFrameCopperButtonText",
+ "ContainerFrame8MoneyFrameGoldButton",
+ "ContainerFrame8MoneyFrameGoldButtonText",
+ "ContainerFrame8MoneyFrameSilverButton",
+ "ContainerFrame8MoneyFrameSilverButtonText",
+ "ContainerFrame8Name",
+ "ContainerFrame8Portrait",
+ "ContainerFrame8PortraitButton",
+ "ContainerFrame9",
+ "ContainerFrame9Background1Slot",
+ "ContainerFrame9BackgroundBottom",
+ "ContainerFrame9BackgroundMiddle1",
+ "ContainerFrame9BackgroundMiddle2",
+ "ContainerFrame9BackgroundTop",
+ "ContainerFrame9CloseButton",
+ "ContainerFrame9Item1",
+ "ContainerFrame9Item10",
+ "ContainerFrame9Item10Cooldown",
+ "ContainerFrame9Item10Count",
+ "ContainerFrame9Item10IconQuestTexture",
+ "ContainerFrame9Item10IconTexture",
+ "ContainerFrame9Item10NormalTexture",
+ "ContainerFrame9Item10Stock",
+ "ContainerFrame9Item11",
+ "ContainerFrame9Item11Cooldown",
+ "ContainerFrame9Item11Count",
+ "ContainerFrame9Item11IconQuestTexture",
+ "ContainerFrame9Item11IconTexture",
+ "ContainerFrame9Item11NormalTexture",
+ "ContainerFrame9Item11Stock",
+ "ContainerFrame9Item12",
+ "ContainerFrame9Item12Cooldown",
+ "ContainerFrame9Item12Count",
+ "ContainerFrame9Item12IconQuestTexture",
+ "ContainerFrame9Item12IconTexture",
+ "ContainerFrame9Item12NormalTexture",
+ "ContainerFrame9Item12Stock",
+ "ContainerFrame9Item13",
+ "ContainerFrame9Item13Cooldown",
+ "ContainerFrame9Item13Count",
+ "ContainerFrame9Item13IconQuestTexture",
+ "ContainerFrame9Item13IconTexture",
+ "ContainerFrame9Item13NormalTexture",
+ "ContainerFrame9Item13Stock",
+ "ContainerFrame9Item14",
+ "ContainerFrame9Item14Cooldown",
+ "ContainerFrame9Item14Count",
+ "ContainerFrame9Item14IconQuestTexture",
+ "ContainerFrame9Item14IconTexture",
+ "ContainerFrame9Item14NormalTexture",
+ "ContainerFrame9Item14Stock",
+ "ContainerFrame9Item15",
+ "ContainerFrame9Item15Cooldown",
+ "ContainerFrame9Item15Count",
+ "ContainerFrame9Item15IconQuestTexture",
+ "ContainerFrame9Item15IconTexture",
+ "ContainerFrame9Item15NormalTexture",
+ "ContainerFrame9Item15Stock",
+ "ContainerFrame9Item16",
+ "ContainerFrame9Item16Cooldown",
+ "ContainerFrame9Item16Count",
+ "ContainerFrame9Item16IconQuestTexture",
+ "ContainerFrame9Item16IconTexture",
+ "ContainerFrame9Item16NormalTexture",
+ "ContainerFrame9Item16Stock",
+ "ContainerFrame9Item17",
+ "ContainerFrame9Item17Cooldown",
+ "ContainerFrame9Item17Count",
+ "ContainerFrame9Item17IconQuestTexture",
+ "ContainerFrame9Item17IconTexture",
+ "ContainerFrame9Item17NormalTexture",
+ "ContainerFrame9Item17Stock",
+ "ContainerFrame9Item18",
+ "ContainerFrame9Item18Cooldown",
+ "ContainerFrame9Item18Count",
+ "ContainerFrame9Item18IconQuestTexture",
+ "ContainerFrame9Item18IconTexture",
+ "ContainerFrame9Item18NormalTexture",
+ "ContainerFrame9Item18Stock",
+ "ContainerFrame9Item19",
+ "ContainerFrame9Item19Cooldown",
+ "ContainerFrame9Item19Count",
+ "ContainerFrame9Item19IconQuestTexture",
+ "ContainerFrame9Item19IconTexture",
+ "ContainerFrame9Item19NormalTexture",
+ "ContainerFrame9Item19Stock",
+ "ContainerFrame9Item1Cooldown",
+ "ContainerFrame9Item1Count",
+ "ContainerFrame9Item1IconQuestTexture",
+ "ContainerFrame9Item1IconTexture",
+ "ContainerFrame9Item1NormalTexture",
+ "ContainerFrame9Item1Stock",
+ "ContainerFrame9Item2",
+ "ContainerFrame9Item20",
+ "ContainerFrame9Item20Cooldown",
+ "ContainerFrame9Item20Count",
+ "ContainerFrame9Item20IconQuestTexture",
+ "ContainerFrame9Item20IconTexture",
+ "ContainerFrame9Item20NormalTexture",
+ "ContainerFrame9Item20Stock",
+ "ContainerFrame9Item21",
+ "ContainerFrame9Item21Cooldown",
+ "ContainerFrame9Item21Count",
+ "ContainerFrame9Item21IconQuestTexture",
+ "ContainerFrame9Item21IconTexture",
+ "ContainerFrame9Item21NormalTexture",
+ "ContainerFrame9Item21Stock",
+ "ContainerFrame9Item22",
+ "ContainerFrame9Item22Cooldown",
+ "ContainerFrame9Item22Count",
+ "ContainerFrame9Item22IconQuestTexture",
+ "ContainerFrame9Item22IconTexture",
+ "ContainerFrame9Item22NormalTexture",
+ "ContainerFrame9Item22Stock",
+ "ContainerFrame9Item23",
+ "ContainerFrame9Item23Cooldown",
+ "ContainerFrame9Item23Count",
+ "ContainerFrame9Item23IconQuestTexture",
+ "ContainerFrame9Item23IconTexture",
+ "ContainerFrame9Item23NormalTexture",
+ "ContainerFrame9Item23Stock",
+ "ContainerFrame9Item24",
+ "ContainerFrame9Item24Cooldown",
+ "ContainerFrame9Item24Count",
+ "ContainerFrame9Item24IconQuestTexture",
+ "ContainerFrame9Item24IconTexture",
+ "ContainerFrame9Item24NormalTexture",
+ "ContainerFrame9Item24Stock",
+ "ContainerFrame9Item25",
+ "ContainerFrame9Item25Cooldown",
+ "ContainerFrame9Item25Count",
+ "ContainerFrame9Item25IconQuestTexture",
+ "ContainerFrame9Item25IconTexture",
+ "ContainerFrame9Item25NormalTexture",
+ "ContainerFrame9Item25Stock",
+ "ContainerFrame9Item26",
+ "ContainerFrame9Item26Cooldown",
+ "ContainerFrame9Item26Count",
+ "ContainerFrame9Item26IconQuestTexture",
+ "ContainerFrame9Item26IconTexture",
+ "ContainerFrame9Item26NormalTexture",
+ "ContainerFrame9Item26Stock",
+ "ContainerFrame9Item27",
+ "ContainerFrame9Item27Cooldown",
+ "ContainerFrame9Item27Count",
+ "ContainerFrame9Item27IconQuestTexture",
+ "ContainerFrame9Item27IconTexture",
+ "ContainerFrame9Item27NormalTexture",
+ "ContainerFrame9Item27Stock",
+ "ContainerFrame9Item28",
+ "ContainerFrame9Item28Cooldown",
+ "ContainerFrame9Item28Count",
+ "ContainerFrame9Item28IconQuestTexture",
+ "ContainerFrame9Item28IconTexture",
+ "ContainerFrame9Item28NormalTexture",
+ "ContainerFrame9Item28Stock",
+ "ContainerFrame9Item29",
+ "ContainerFrame9Item29Cooldown",
+ "ContainerFrame9Item29Count",
+ "ContainerFrame9Item29IconQuestTexture",
+ "ContainerFrame9Item29IconTexture",
+ "ContainerFrame9Item29NormalTexture",
+ "ContainerFrame9Item29Stock",
+ "ContainerFrame9Item2Cooldown",
+ "ContainerFrame9Item2Count",
+ "ContainerFrame9Item2IconQuestTexture",
+ "ContainerFrame9Item2IconTexture",
+ "ContainerFrame9Item2NormalTexture",
+ "ContainerFrame9Item2Stock",
+ "ContainerFrame9Item3",
+ "ContainerFrame9Item30",
+ "ContainerFrame9Item30Cooldown",
+ "ContainerFrame9Item30Count",
+ "ContainerFrame9Item30IconQuestTexture",
+ "ContainerFrame9Item30IconTexture",
+ "ContainerFrame9Item30NormalTexture",
+ "ContainerFrame9Item30Stock",
+ "ContainerFrame9Item31",
+ "ContainerFrame9Item31Cooldown",
+ "ContainerFrame9Item31Count",
+ "ContainerFrame9Item31IconQuestTexture",
+ "ContainerFrame9Item31IconTexture",
+ "ContainerFrame9Item31NormalTexture",
+ "ContainerFrame9Item31Stock",
+ "ContainerFrame9Item32",
+ "ContainerFrame9Item32Cooldown",
+ "ContainerFrame9Item32Count",
+ "ContainerFrame9Item32IconQuestTexture",
+ "ContainerFrame9Item32IconTexture",
+ "ContainerFrame9Item32NormalTexture",
+ "ContainerFrame9Item32Stock",
+ "ContainerFrame9Item33",
+ "ContainerFrame9Item33Cooldown",
+ "ContainerFrame9Item33Count",
+ "ContainerFrame9Item33IconQuestTexture",
+ "ContainerFrame9Item33IconTexture",
+ "ContainerFrame9Item33NormalTexture",
+ "ContainerFrame9Item33Stock",
+ "ContainerFrame9Item34",
+ "ContainerFrame9Item34Cooldown",
+ "ContainerFrame9Item34Count",
+ "ContainerFrame9Item34IconQuestTexture",
+ "ContainerFrame9Item34IconTexture",
+ "ContainerFrame9Item34NormalTexture",
+ "ContainerFrame9Item34Stock",
+ "ContainerFrame9Item35",
+ "ContainerFrame9Item35Cooldown",
+ "ContainerFrame9Item35Count",
+ "ContainerFrame9Item35IconQuestTexture",
+ "ContainerFrame9Item35IconTexture",
+ "ContainerFrame9Item35NormalTexture",
+ "ContainerFrame9Item35Stock",
+ "ContainerFrame9Item36",
+ "ContainerFrame9Item36Cooldown",
+ "ContainerFrame9Item36Count",
+ "ContainerFrame9Item36IconQuestTexture",
+ "ContainerFrame9Item36IconTexture",
+ "ContainerFrame9Item36NormalTexture",
+ "ContainerFrame9Item36Stock",
+ "ContainerFrame9Item3Cooldown",
+ "ContainerFrame9Item3Count",
+ "ContainerFrame9Item3IconQuestTexture",
+ "ContainerFrame9Item3IconTexture",
+ "ContainerFrame9Item3NormalTexture",
+ "ContainerFrame9Item3Stock",
+ "ContainerFrame9Item4",
+ "ContainerFrame9Item4Cooldown",
+ "ContainerFrame9Item4Count",
+ "ContainerFrame9Item4IconQuestTexture",
+ "ContainerFrame9Item4IconTexture",
+ "ContainerFrame9Item4NormalTexture",
+ "ContainerFrame9Item4Stock",
+ "ContainerFrame9Item5",
+ "ContainerFrame9Item5Cooldown",
+ "ContainerFrame9Item5Count",
+ "ContainerFrame9Item5IconQuestTexture",
+ "ContainerFrame9Item5IconTexture",
+ "ContainerFrame9Item5NormalTexture",
+ "ContainerFrame9Item5Stock",
+ "ContainerFrame9Item6",
+ "ContainerFrame9Item6Cooldown",
+ "ContainerFrame9Item6Count",
+ "ContainerFrame9Item6IconQuestTexture",
+ "ContainerFrame9Item6IconTexture",
+ "ContainerFrame9Item6NormalTexture",
+ "ContainerFrame9Item6Stock",
+ "ContainerFrame9Item7",
+ "ContainerFrame9Item7Cooldown",
+ "ContainerFrame9Item7Count",
+ "ContainerFrame9Item7IconQuestTexture",
+ "ContainerFrame9Item7IconTexture",
+ "ContainerFrame9Item7NormalTexture",
+ "ContainerFrame9Item7Stock",
+ "ContainerFrame9Item8",
+ "ContainerFrame9Item8Cooldown",
+ "ContainerFrame9Item8Count",
+ "ContainerFrame9Item8IconQuestTexture",
+ "ContainerFrame9Item8IconTexture",
+ "ContainerFrame9Item8NormalTexture",
+ "ContainerFrame9Item8Stock",
+ "ContainerFrame9Item9",
+ "ContainerFrame9Item9Cooldown",
+ "ContainerFrame9Item9Count",
+ "ContainerFrame9Item9IconQuestTexture",
+ "ContainerFrame9Item9IconTexture",
+ "ContainerFrame9Item9NormalTexture",
+ "ContainerFrame9Item9Stock",
+ "ContainerFrame9MoneyFrame",
+ "ContainerFrame9MoneyFrameCopperButton",
+ "ContainerFrame9MoneyFrameCopperButtonText",
+ "ContainerFrame9MoneyFrameGoldButton",
+ "ContainerFrame9MoneyFrameGoldButtonText",
+ "ContainerFrame9MoneyFrameSilverButton",
+ "ContainerFrame9MoneyFrameSilverButtonText",
+ "ContainerFrame9Name",
+ "ContainerFrame9Portrait",
+ "ContainerFrame9PortraitButton",
+ "ContainerFrameItemButton_OnClick",
+ "ContainerFrameItemButton_OnDrag",
+ "ContainerFrameItemButton_OnEnter",
+ "ContainerFrameItemButton_OnLoad",
+ "ContainerFrameItemButton_OnModifiedClick",
+ "ContainerFrame_GenerateFrame",
+ "ContainerFrame_GetExtendedPriceString",
+ "ContainerFrame_GetOpenFrame",
+ "ContainerFrame_OnEvent",
+ "ContainerFrame_OnHide",
+ "ContainerFrame_OnLoad",
+ "ContainerFrame_OnShow",
+ "ContainerFrame_Update",
+ "ContainerFrame_UpdateCooldown",
+ "ContainerFrame_UpdateCooldowns",
+ "ContainerFrame_UpdateLocked",
+ "ContainerFrame_UpdateLockedItem",
+ "ContainerIDToInventoryID",
+ "ContainerRefundItemPurchase",
+ "ControlsPanelOptions",
+ "ConvertToRaid",
+ "CooldownFrame_SetTimer",
+ "CopyTable",
+ "CreateActorPool",
+ "CreateChatChannelList",
+ "CreateFixedSizeFramePoolCollection",
+ "CreateFont",
+ "CreateFontStringPool",
+ "CreateForbiddenFrame",
+ "CreateFrame",
+ "CreateFramePool",
+ "CreateFramePoolCollection",
+ "CreateFromMixins",
+ "CreateMacro",
+ "CreateMiniWorldMapArrowFrame",
+ "CreateObjectPool",
+ "CreateTexturePool",
+ "CreateWorldMapArrowFrame",
+ "CurrentQuestsText",
+ "CursorCanGoInSlot",
+ "CursorHasItem",
+ "CursorHasMacro",
+ "CursorHasMoney",
+ "CursorHasSpell",
+ "CursorOnUpdate",
+ "CursorUpdate",
+ "CustomClassLayouts",
+ "DEFAULT_CHATFRAME_COLOR",
+ "DEFAULT_CHAT_FRAME",
+ "DEFAULT_COMBATLOG_FILTER_TEMPLATE",
+ "DEFAULT_TAB_SELECTED_COLOR_TABLE",
+ "DOCKED_CHAT_FRAMES",
+ "DOCK_COPY",
+ "DamageColor_OpenColorPicker",
+ "DeathKnniggetThrobFunction",
+ "DebuffButton_UpdateAnchors",
+ "DebuffTypeColor",
+ "DebuffTypeSymbol",
+ "DebugTooltip_OnLoad",
+ "DeclensionFrame",
+ "DeclensionFrameCancelButton",
+ "DeclensionFrameOkayButton",
+ "DeclensionFrameSetNext",
+ "DeclensionFrameSetPrev",
+ "DeclineArenaTeam",
+ "DeclineGroup",
+ "DeclineGuild",
+ "DeclineInvite",
+ "DeclineLevelGrant",
+ "DeclineName",
+ "DeclineQuest",
+ "DeclineResurrect",
+ "DelIgnore",
+ "DelMute",
+ "DeleteCursorItem",
+ "DeleteEquipmentSet",
+ "DeleteFile",
+ "DeleteGMTicket",
+ "DeleteInboxItem",
+ "DeleteMacro",
+ "DemoteAssistant",
+ "DepositGuildBankMoney",
+ "DescendStop",
+ "DestroyTotem",
+ "DetectWowMouse",
+ "DevTools_Dump",
+ "DevTools_DumpCommand",
+ "DevTools_RunDump",
+ "DialogButtonHighlightText",
+ "DialogButtonNormalText",
+ "DisableAddOn",
+ "DisableAllAddOns",
+ "DisablePagingButton",
+ "DisableSpellAutocast",
+ "Disable_BagButtons",
+ "DismissCompanion",
+ "Dismount",
+ "DisplayChannelOwner",
+ "DisplayChannelVoiceOff",
+ "DisplayChannelVoiceOn",
+ "DisplayPanelOptions",
+ "DoEmote",
+ "DoReadyCheck",
+ "DoTradeSkill",
+ "DownloadSettings",
+ "DrawOneHopLines",
+ "DrawRouteLine",
+ "DressUpBackgroundBotLeft",
+ "DressUpBackgroundBotRight",
+ "DressUpBackgroundTopLeft",
+ "DressUpBackgroundTopRight",
+ "DressUpFrame",
+ "DressUpFrameCancelButton",
+ "DressUpFrameCancelButtonText",
+ "DressUpFrameCloseButton",
+ "DressUpFrameDescriptionText",
+ "DressUpFramePortrait",
+ "DressUpFrameResetButton",
+ "DressUpFrameResetButtonText",
+ "DressUpFrameTitleText",
+ "DressUpItemLink",
+ "DressUpModel",
+ "DressUpModelRotateLeftButton",
+ "DressUpModelRotateRightButton",
+ "DressUpTexturePath",
+ "DropCursorMoney",
+ "DropDownList1",
+ "DropDownList1Backdrop",
+ "DropDownList1Button1",
+ "DropDownList1Button10",
+ "DropDownList1Button10Check",
+ "DropDownList1Button10ColorSwatch",
+ "DropDownList1Button10ColorSwatchNormalTexture",
+ "DropDownList1Button10ColorSwatchSwatchBg",
+ "DropDownList1Button10ExpandArrow",
+ "DropDownList1Button10Highlight",
+ "DropDownList1Button10Icon",
+ "DropDownList1Button10InvisibleButton",
+ "DropDownList1Button10NormalText",
+ "DropDownList1Button11",
+ "DropDownList1Button11Check",
+ "DropDownList1Button11ColorSwatch",
+ "DropDownList1Button11ColorSwatchNormalTexture",
+ "DropDownList1Button11ColorSwatchSwatchBg",
+ "DropDownList1Button11ExpandArrow",
+ "DropDownList1Button11Highlight",
+ "DropDownList1Button11Icon",
+ "DropDownList1Button11InvisibleButton",
+ "DropDownList1Button11NormalText",
+ "DropDownList1Button12",
+ "DropDownList1Button12Check",
+ "DropDownList1Button12ColorSwatch",
+ "DropDownList1Button12ColorSwatchNormalTexture",
+ "DropDownList1Button12ColorSwatchSwatchBg",
+ "DropDownList1Button12ExpandArrow",
+ "DropDownList1Button12Highlight",
+ "DropDownList1Button12Icon",
+ "DropDownList1Button12InvisibleButton",
+ "DropDownList1Button12NormalText",
+ "DropDownList1Button13",
+ "DropDownList1Button13Check",
+ "DropDownList1Button13ColorSwatch",
+ "DropDownList1Button13ColorSwatchNormalTexture",
+ "DropDownList1Button13ColorSwatchSwatchBg",
+ "DropDownList1Button13ExpandArrow",
+ "DropDownList1Button13Highlight",
+ "DropDownList1Button13Icon",
+ "DropDownList1Button13InvisibleButton",
+ "DropDownList1Button13NormalText",
+ "DropDownList1Button14",
+ "DropDownList1Button14Check",
+ "DropDownList1Button14ColorSwatch",
+ "DropDownList1Button14ColorSwatchNormalTexture",
+ "DropDownList1Button14ColorSwatchSwatchBg",
+ "DropDownList1Button14ExpandArrow",
+ "DropDownList1Button14Highlight",
+ "DropDownList1Button14Icon",
+ "DropDownList1Button14InvisibleButton",
+ "DropDownList1Button14NormalText",
+ "DropDownList1Button15",
+ "DropDownList1Button15Check",
+ "DropDownList1Button15ColorSwatch",
+ "DropDownList1Button15ColorSwatchNormalTexture",
+ "DropDownList1Button15ColorSwatchSwatchBg",
+ "DropDownList1Button15ExpandArrow",
+ "DropDownList1Button15Highlight",
+ "DropDownList1Button15Icon",
+ "DropDownList1Button15InvisibleButton",
+ "DropDownList1Button15NormalText",
+ "DropDownList1Button16",
+ "DropDownList1Button16Check",
+ "DropDownList1Button16ColorSwatch",
+ "DropDownList1Button16ColorSwatchNormalTexture",
+ "DropDownList1Button16ColorSwatchSwatchBg",
+ "DropDownList1Button16ExpandArrow",
+ "DropDownList1Button16Highlight",
+ "DropDownList1Button16Icon",
+ "DropDownList1Button16InvisibleButton",
+ "DropDownList1Button16NormalText",
+ "DropDownList1Button17",
+ "DropDownList1Button17Check",
+ "DropDownList1Button17ColorSwatch",
+ "DropDownList1Button17ColorSwatchNormalTexture",
+ "DropDownList1Button17ColorSwatchSwatchBg",
+ "DropDownList1Button17ExpandArrow",
+ "DropDownList1Button17Highlight",
+ "DropDownList1Button17Icon",
+ "DropDownList1Button17InvisibleButton",
+ "DropDownList1Button17NormalText",
+ "DropDownList1Button18",
+ "DropDownList1Button18Check",
+ "DropDownList1Button18ColorSwatch",
+ "DropDownList1Button18ColorSwatchNormalTexture",
+ "DropDownList1Button18ColorSwatchSwatchBg",
+ "DropDownList1Button18ExpandArrow",
+ "DropDownList1Button18Highlight",
+ "DropDownList1Button18Icon",
+ "DropDownList1Button18InvisibleButton",
+ "DropDownList1Button18NormalText",
+ "DropDownList1Button19",
+ "DropDownList1Button19Check",
+ "DropDownList1Button19ColorSwatch",
+ "DropDownList1Button19ColorSwatchNormalTexture",
+ "DropDownList1Button19ColorSwatchSwatchBg",
+ "DropDownList1Button19ExpandArrow",
+ "DropDownList1Button19Highlight",
+ "DropDownList1Button19Icon",
+ "DropDownList1Button19InvisibleButton",
+ "DropDownList1Button19NormalText",
+ "DropDownList1Button1Check",
+ "DropDownList1Button1ColorSwatch",
+ "DropDownList1Button1ColorSwatchNormalTexture",
+ "DropDownList1Button1ColorSwatchSwatchBg",
+ "DropDownList1Button1ExpandArrow",
+ "DropDownList1Button1Highlight",
+ "DropDownList1Button1Icon",
+ "DropDownList1Button1InvisibleButton",
+ "DropDownList1Button1NormalText",
+ "DropDownList1Button2",
+ "DropDownList1Button20",
+ "DropDownList1Button20Check",
+ "DropDownList1Button20ColorSwatch",
+ "DropDownList1Button20ColorSwatchNormalTexture",
+ "DropDownList1Button20ColorSwatchSwatchBg",
+ "DropDownList1Button20ExpandArrow",
+ "DropDownList1Button20Highlight",
+ "DropDownList1Button20Icon",
+ "DropDownList1Button20InvisibleButton",
+ "DropDownList1Button20NormalText",
+ "DropDownList1Button21",
+ "DropDownList1Button21Check",
+ "DropDownList1Button21ColorSwatch",
+ "DropDownList1Button21ColorSwatchNormalTexture",
+ "DropDownList1Button21ColorSwatchSwatchBg",
+ "DropDownList1Button21ExpandArrow",
+ "DropDownList1Button21Highlight",
+ "DropDownList1Button21Icon",
+ "DropDownList1Button21InvisibleButton",
+ "DropDownList1Button21NormalText",
+ "DropDownList1Button22",
+ "DropDownList1Button22Check",
+ "DropDownList1Button22ColorSwatch",
+ "DropDownList1Button22ColorSwatchNormalTexture",
+ "DropDownList1Button22ColorSwatchSwatchBg",
+ "DropDownList1Button22ExpandArrow",
+ "DropDownList1Button22Highlight",
+ "DropDownList1Button22Icon",
+ "DropDownList1Button22InvisibleButton",
+ "DropDownList1Button22NormalText",
+ "DropDownList1Button23",
+ "DropDownList1Button23Check",
+ "DropDownList1Button23ColorSwatch",
+ "DropDownList1Button23ColorSwatchNormalTexture",
+ "DropDownList1Button23ColorSwatchSwatchBg",
+ "DropDownList1Button23ExpandArrow",
+ "DropDownList1Button23Highlight",
+ "DropDownList1Button23Icon",
+ "DropDownList1Button23InvisibleButton",
+ "DropDownList1Button23NormalText",
+ "DropDownList1Button24",
+ "DropDownList1Button24Check",
+ "DropDownList1Button24ColorSwatch",
+ "DropDownList1Button24ColorSwatchNormalTexture",
+ "DropDownList1Button24ColorSwatchSwatchBg",
+ "DropDownList1Button24ExpandArrow",
+ "DropDownList1Button24Highlight",
+ "DropDownList1Button24Icon",
+ "DropDownList1Button24InvisibleButton",
+ "DropDownList1Button24NormalText",
+ "DropDownList1Button2Check",
+ "DropDownList1Button2ColorSwatch",
+ "DropDownList1Button2ColorSwatchNormalTexture",
+ "DropDownList1Button2ColorSwatchSwatchBg",
+ "DropDownList1Button2ExpandArrow",
+ "DropDownList1Button2Highlight",
+ "DropDownList1Button2Icon",
+ "DropDownList1Button2InvisibleButton",
+ "DropDownList1Button2NormalText",
+ "DropDownList1Button3",
+ "DropDownList1Button3Check",
+ "DropDownList1Button3ColorSwatch",
+ "DropDownList1Button3ColorSwatchNormalTexture",
+ "DropDownList1Button3ColorSwatchSwatchBg",
+ "DropDownList1Button3ExpandArrow",
+ "DropDownList1Button3Highlight",
+ "DropDownList1Button3Icon",
+ "DropDownList1Button3InvisibleButton",
+ "DropDownList1Button3NormalText",
+ "DropDownList1Button4",
+ "DropDownList1Button4Check",
+ "DropDownList1Button4ColorSwatch",
+ "DropDownList1Button4ColorSwatchNormalTexture",
+ "DropDownList1Button4ColorSwatchSwatchBg",
+ "DropDownList1Button4ExpandArrow",
+ "DropDownList1Button4Highlight",
+ "DropDownList1Button4Icon",
+ "DropDownList1Button4InvisibleButton",
+ "DropDownList1Button4NormalText",
+ "DropDownList1Button5",
+ "DropDownList1Button5Check",
+ "DropDownList1Button5ColorSwatch",
+ "DropDownList1Button5ColorSwatchNormalTexture",
+ "DropDownList1Button5ColorSwatchSwatchBg",
+ "DropDownList1Button5ExpandArrow",
+ "DropDownList1Button5Highlight",
+ "DropDownList1Button5Icon",
+ "DropDownList1Button5InvisibleButton",
+ "DropDownList1Button5NormalText",
+ "DropDownList1Button6",
+ "DropDownList1Button6Check",
+ "DropDownList1Button6ColorSwatch",
+ "DropDownList1Button6ColorSwatchNormalTexture",
+ "DropDownList1Button6ColorSwatchSwatchBg",
+ "DropDownList1Button6ExpandArrow",
+ "DropDownList1Button6Highlight",
+ "DropDownList1Button6Icon",
+ "DropDownList1Button6InvisibleButton",
+ "DropDownList1Button6NormalText",
+ "DropDownList1Button7",
+ "DropDownList1Button7Check",
+ "DropDownList1Button7ColorSwatch",
+ "DropDownList1Button7ColorSwatchNormalTexture",
+ "DropDownList1Button7ColorSwatchSwatchBg",
+ "DropDownList1Button7ExpandArrow",
+ "DropDownList1Button7Highlight",
+ "DropDownList1Button7Icon",
+ "DropDownList1Button7InvisibleButton",
+ "DropDownList1Button7NormalText",
+ "DropDownList1Button8",
+ "DropDownList1Button8Check",
+ "DropDownList1Button8ColorSwatch",
+ "DropDownList1Button8ColorSwatchNormalTexture",
+ "DropDownList1Button8ColorSwatchSwatchBg",
+ "DropDownList1Button8ExpandArrow",
+ "DropDownList1Button8Highlight",
+ "DropDownList1Button8Icon",
+ "DropDownList1Button8InvisibleButton",
+ "DropDownList1Button8NormalText",
+ "DropDownList1Button9",
+ "DropDownList1Button9Check",
+ "DropDownList1Button9ColorSwatch",
+ "DropDownList1Button9ColorSwatchNormalTexture",
+ "DropDownList1Button9ColorSwatchSwatchBg",
+ "DropDownList1Button9ExpandArrow",
+ "DropDownList1Button9Highlight",
+ "DropDownList1Button9Icon",
+ "DropDownList1Button9InvisibleButton",
+ "DropDownList1Button9NormalText",
+ "DropDownList1MenuBackdrop",
+ "DropDownList2",
+ "DropDownList2Backdrop",
+ "DropDownList2Button1",
+ "DropDownList2Button10",
+ "DropDownList2Button10Check",
+ "DropDownList2Button10ColorSwatch",
+ "DropDownList2Button10ColorSwatchNormalTexture",
+ "DropDownList2Button10ColorSwatchSwatchBg",
+ "DropDownList2Button10ExpandArrow",
+ "DropDownList2Button10Highlight",
+ "DropDownList2Button10Icon",
+ "DropDownList2Button10InvisibleButton",
+ "DropDownList2Button10NormalText",
+ "DropDownList2Button11",
+ "DropDownList2Button11Check",
+ "DropDownList2Button11ColorSwatch",
+ "DropDownList2Button11ColorSwatchNormalTexture",
+ "DropDownList2Button11ColorSwatchSwatchBg",
+ "DropDownList2Button11ExpandArrow",
+ "DropDownList2Button11Highlight",
+ "DropDownList2Button11Icon",
+ "DropDownList2Button11InvisibleButton",
+ "DropDownList2Button11NormalText",
+ "DropDownList2Button12",
+ "DropDownList2Button12Check",
+ "DropDownList2Button12ColorSwatch",
+ "DropDownList2Button12ColorSwatchNormalTexture",
+ "DropDownList2Button12ColorSwatchSwatchBg",
+ "DropDownList2Button12ExpandArrow",
+ "DropDownList2Button12Highlight",
+ "DropDownList2Button12Icon",
+ "DropDownList2Button12InvisibleButton",
+ "DropDownList2Button12NormalText",
+ "DropDownList2Button13",
+ "DropDownList2Button13Check",
+ "DropDownList2Button13ColorSwatch",
+ "DropDownList2Button13ColorSwatchNormalTexture",
+ "DropDownList2Button13ColorSwatchSwatchBg",
+ "DropDownList2Button13ExpandArrow",
+ "DropDownList2Button13Highlight",
+ "DropDownList2Button13Icon",
+ "DropDownList2Button13InvisibleButton",
+ "DropDownList2Button13NormalText",
+ "DropDownList2Button14",
+ "DropDownList2Button14Check",
+ "DropDownList2Button14ColorSwatch",
+ "DropDownList2Button14ColorSwatchNormalTexture",
+ "DropDownList2Button14ColorSwatchSwatchBg",
+ "DropDownList2Button14ExpandArrow",
+ "DropDownList2Button14Highlight",
+ "DropDownList2Button14Icon",
+ "DropDownList2Button14InvisibleButton",
+ "DropDownList2Button14NormalText",
+ "DropDownList2Button15",
+ "DropDownList2Button15Check",
+ "DropDownList2Button15ColorSwatch",
+ "DropDownList2Button15ColorSwatchNormalTexture",
+ "DropDownList2Button15ColorSwatchSwatchBg",
+ "DropDownList2Button15ExpandArrow",
+ "DropDownList2Button15Highlight",
+ "DropDownList2Button15Icon",
+ "DropDownList2Button15InvisibleButton",
+ "DropDownList2Button15NormalText",
+ "DropDownList2Button16",
+ "DropDownList2Button16Check",
+ "DropDownList2Button16ColorSwatch",
+ "DropDownList2Button16ColorSwatchNormalTexture",
+ "DropDownList2Button16ColorSwatchSwatchBg",
+ "DropDownList2Button16ExpandArrow",
+ "DropDownList2Button16Highlight",
+ "DropDownList2Button16Icon",
+ "DropDownList2Button16InvisibleButton",
+ "DropDownList2Button16NormalText",
+ "DropDownList2Button17",
+ "DropDownList2Button17Check",
+ "DropDownList2Button17ColorSwatch",
+ "DropDownList2Button17ColorSwatchNormalTexture",
+ "DropDownList2Button17ColorSwatchSwatchBg",
+ "DropDownList2Button17ExpandArrow",
+ "DropDownList2Button17Highlight",
+ "DropDownList2Button17Icon",
+ "DropDownList2Button17InvisibleButton",
+ "DropDownList2Button17NormalText",
+ "DropDownList2Button18",
+ "DropDownList2Button18Check",
+ "DropDownList2Button18ColorSwatch",
+ "DropDownList2Button18ColorSwatchNormalTexture",
+ "DropDownList2Button18ColorSwatchSwatchBg",
+ "DropDownList2Button18ExpandArrow",
+ "DropDownList2Button18Highlight",
+ "DropDownList2Button18Icon",
+ "DropDownList2Button18InvisibleButton",
+ "DropDownList2Button18NormalText",
+ "DropDownList2Button19",
+ "DropDownList2Button19Check",
+ "DropDownList2Button19ColorSwatch",
+ "DropDownList2Button19ColorSwatchNormalTexture",
+ "DropDownList2Button19ColorSwatchSwatchBg",
+ "DropDownList2Button19ExpandArrow",
+ "DropDownList2Button19Highlight",
+ "DropDownList2Button19Icon",
+ "DropDownList2Button19InvisibleButton",
+ "DropDownList2Button19NormalText",
+ "DropDownList2Button1Check",
+ "DropDownList2Button1ColorSwatch",
+ "DropDownList2Button1ColorSwatchNormalTexture",
+ "DropDownList2Button1ColorSwatchSwatchBg",
+ "DropDownList2Button1ExpandArrow",
+ "DropDownList2Button1Highlight",
+ "DropDownList2Button1Icon",
+ "DropDownList2Button1InvisibleButton",
+ "DropDownList2Button1NormalText",
+ "DropDownList2Button2",
+ "DropDownList2Button20",
+ "DropDownList2Button20Check",
+ "DropDownList2Button20ColorSwatch",
+ "DropDownList2Button20ColorSwatchNormalTexture",
+ "DropDownList2Button20ColorSwatchSwatchBg",
+ "DropDownList2Button20ExpandArrow",
+ "DropDownList2Button20Highlight",
+ "DropDownList2Button20Icon",
+ "DropDownList2Button20InvisibleButton",
+ "DropDownList2Button20NormalText",
+ "DropDownList2Button21",
+ "DropDownList2Button21Check",
+ "DropDownList2Button21ColorSwatch",
+ "DropDownList2Button21ColorSwatchNormalTexture",
+ "DropDownList2Button21ColorSwatchSwatchBg",
+ "DropDownList2Button21ExpandArrow",
+ "DropDownList2Button21Highlight",
+ "DropDownList2Button21Icon",
+ "DropDownList2Button21InvisibleButton",
+ "DropDownList2Button21NormalText",
+ "DropDownList2Button22",
+ "DropDownList2Button22Check",
+ "DropDownList2Button22ColorSwatch",
+ "DropDownList2Button22ColorSwatchNormalTexture",
+ "DropDownList2Button22ColorSwatchSwatchBg",
+ "DropDownList2Button22ExpandArrow",
+ "DropDownList2Button22Highlight",
+ "DropDownList2Button22Icon",
+ "DropDownList2Button22InvisibleButton",
+ "DropDownList2Button22NormalText",
+ "DropDownList2Button23",
+ "DropDownList2Button23Check",
+ "DropDownList2Button23ColorSwatch",
+ "DropDownList2Button23ColorSwatchNormalTexture",
+ "DropDownList2Button23ColorSwatchSwatchBg",
+ "DropDownList2Button23ExpandArrow",
+ "DropDownList2Button23Highlight",
+ "DropDownList2Button23Icon",
+ "DropDownList2Button23InvisibleButton",
+ "DropDownList2Button23NormalText",
+ "DropDownList2Button24",
+ "DropDownList2Button24Check",
+ "DropDownList2Button24ColorSwatch",
+ "DropDownList2Button24ColorSwatchNormalTexture",
+ "DropDownList2Button24ColorSwatchSwatchBg",
+ "DropDownList2Button24ExpandArrow",
+ "DropDownList2Button24Highlight",
+ "DropDownList2Button24Icon",
+ "DropDownList2Button24InvisibleButton",
+ "DropDownList2Button24NormalText",
+ "DropDownList2Button2Check",
+ "DropDownList2Button2ColorSwatch",
+ "DropDownList2Button2ColorSwatchNormalTexture",
+ "DropDownList2Button2ColorSwatchSwatchBg",
+ "DropDownList2Button2ExpandArrow",
+ "DropDownList2Button2Highlight",
+ "DropDownList2Button2Icon",
+ "DropDownList2Button2InvisibleButton",
+ "DropDownList2Button2NormalText",
+ "DropDownList2Button3",
+ "DropDownList2Button3Check",
+ "DropDownList2Button3ColorSwatch",
+ "DropDownList2Button3ColorSwatchNormalTexture",
+ "DropDownList2Button3ColorSwatchSwatchBg",
+ "DropDownList2Button3ExpandArrow",
+ "DropDownList2Button3Highlight",
+ "DropDownList2Button3Icon",
+ "DropDownList2Button3InvisibleButton",
+ "DropDownList2Button3NormalText",
+ "DropDownList2Button4",
+ "DropDownList2Button4Check",
+ "DropDownList2Button4ColorSwatch",
+ "DropDownList2Button4ColorSwatchNormalTexture",
+ "DropDownList2Button4ColorSwatchSwatchBg",
+ "DropDownList2Button4ExpandArrow",
+ "DropDownList2Button4Highlight",
+ "DropDownList2Button4Icon",
+ "DropDownList2Button4InvisibleButton",
+ "DropDownList2Button4NormalText",
+ "DropDownList2Button5",
+ "DropDownList2Button5Check",
+ "DropDownList2Button5ColorSwatch",
+ "DropDownList2Button5ColorSwatchNormalTexture",
+ "DropDownList2Button5ColorSwatchSwatchBg",
+ "DropDownList2Button5ExpandArrow",
+ "DropDownList2Button5Highlight",
+ "DropDownList2Button5Icon",
+ "DropDownList2Button5InvisibleButton",
+ "DropDownList2Button5NormalText",
+ "DropDownList2Button6",
+ "DropDownList2Button6Check",
+ "DropDownList2Button6ColorSwatch",
+ "DropDownList2Button6ColorSwatchNormalTexture",
+ "DropDownList2Button6ColorSwatchSwatchBg",
+ "DropDownList2Button6ExpandArrow",
+ "DropDownList2Button6Highlight",
+ "DropDownList2Button6Icon",
+ "DropDownList2Button6InvisibleButton",
+ "DropDownList2Button6NormalText",
+ "DropDownList2Button7",
+ "DropDownList2Button7Check",
+ "DropDownList2Button7ColorSwatch",
+ "DropDownList2Button7ColorSwatchNormalTexture",
+ "DropDownList2Button7ColorSwatchSwatchBg",
+ "DropDownList2Button7ExpandArrow",
+ "DropDownList2Button7Highlight",
+ "DropDownList2Button7Icon",
+ "DropDownList2Button7InvisibleButton",
+ "DropDownList2Button7NormalText",
+ "DropDownList2Button8",
+ "DropDownList2Button8Check",
+ "DropDownList2Button8ColorSwatch",
+ "DropDownList2Button8ColorSwatchNormalTexture",
+ "DropDownList2Button8ColorSwatchSwatchBg",
+ "DropDownList2Button8ExpandArrow",
+ "DropDownList2Button8Highlight",
+ "DropDownList2Button8Icon",
+ "DropDownList2Button8InvisibleButton",
+ "DropDownList2Button8NormalText",
+ "DropDownList2Button9",
+ "DropDownList2Button9Check",
+ "DropDownList2Button9ColorSwatch",
+ "DropDownList2Button9ColorSwatchNormalTexture",
+ "DropDownList2Button9ColorSwatchSwatchBg",
+ "DropDownList2Button9ExpandArrow",
+ "DropDownList2Button9Highlight",
+ "DropDownList2Button9Icon",
+ "DropDownList2Button9InvisibleButton",
+ "DropDownList2Button9NormalText",
+ "DropDownList2MenuBackdrop",
+ "DropItemOnUnit",
+ "DungeonCompletionAlertFrame1",
+ "DungeonCompletionAlertFrame1AnimIn",
+ "DungeonCompletionAlertFrame1DungeonTexture",
+ "DungeonCompletionAlertFrame1GlowFrame",
+ "DungeonCompletionAlertFrame1GlowFrameGlow",
+ "DungeonCompletionAlertFrame1GlowFrameGlowAnimIn",
+ "DungeonCompletionAlertFrame1HeroicIcon",
+ "DungeonCompletionAlertFrame1InstanceName",
+ "DungeonCompletionAlertFrame1Reward1",
+ "DungeonCompletionAlertFrame1Reward1Border",
+ "DungeonCompletionAlertFrame1Reward1Texture",
+ "DungeonCompletionAlertFrame1Shine",
+ "DungeonCompletionAlertFrame1ShineAnimIn",
+ "DungeonCompletionAlertFrame1WaitAndAnimOut",
+ "DungeonCompletionAlertFrameReward_OnEnter",
+ "DungeonCompletionAlertFrameReward_OnLeave",
+ "DungeonCompletionAlertFrameReward_SetReward",
+ "DungeonCompletionAlertFrame_FixAnchors",
+ "DungeonCompletionAlertFrame_OnLoad",
+ "DungeonCompletionAlertFrame_ShowAlert",
+ "DungeonUsesTerrainMap",
+ "DurabilityChest",
+ "DurabilityFeet",
+ "DurabilityFrame",
+ "DurabilityFrame_SetAlerts",
+ "DurabilityHands",
+ "DurabilityHead",
+ "DurabilityLegs",
+ "DurabilityOffWeapon",
+ "DurabilityRanged",
+ "DurabilityShield",
+ "DurabilityShoulders",
+ "DurabilityWaist",
+ "DurabilityWeapon",
+ "DurabilityWrists",
+ "DurationDropDown",
+ "DurationDropDownButton",
+ "DurationDropDownButtonDisabledTexture",
+ "DurationDropDownButtonHighlightTexture",
+ "DurationDropDownButtonNormalTexture",
+ "DurationDropDownButtonPushedTexture",
+ "DurationDropDownLeft",
+ "DurationDropDownMiddle",
+ "DurationDropDownRight",
+ "DurationDropDownText",
+ "DurationDropDown_Initialize",
+ "DurationDropDown_OnClick",
+ "DurationDropDown_OnLoad",
+ "DynamicScrollFrame_CreateButtons",
+ "DynamicScrollFrame_OnVerticalScroll",
+ "DynamicScrollFrame_UnlockAllHighlights",
+ "DynamicScrollFrame_Update",
+ "EQUIPMENTMANAGER_BAGSLOTS",
+ "EQUIPMENTMANAGER_INVENTORYSLOTS",
+ "EVENT_TEMPLATE_FORMATS",
+ "EVENT_TRACE_EVENT_COLORS",
+ "EVENT_TRACE_SYSTEM_TIMES",
+ "EasyMenu",
+ "EasyMenu_Initialize",
+ "EditBox_ClearFocus",
+ "EditBox_ClearHighlight",
+ "EditBox_HandleTabbing",
+ "EditBox_HighlightText",
+ "EditBox_SetFocus",
+ "EditMacro",
+ "EffectsPanelOptions",
+ "EjectPassengerFromSeat",
+ "EmoteList",
+ "EmoteMenu",
+ "EmoteMenuButton1",
+ "EmoteMenuButton10",
+ "EmoteMenuButton10ShortcutText",
+ "EmoteMenuButton11",
+ "EmoteMenuButton11ShortcutText",
+ "EmoteMenuButton12",
+ "EmoteMenuButton12ShortcutText",
+ "EmoteMenuButton13",
+ "EmoteMenuButton13ShortcutText",
+ "EmoteMenuButton14",
+ "EmoteMenuButton14ShortcutText",
+ "EmoteMenuButton15",
+ "EmoteMenuButton15ShortcutText",
+ "EmoteMenuButton16",
+ "EmoteMenuButton16ShortcutText",
+ "EmoteMenuButton17",
+ "EmoteMenuButton17ShortcutText",
+ "EmoteMenuButton18",
+ "EmoteMenuButton18ShortcutText",
+ "EmoteMenuButton19",
+ "EmoteMenuButton19ShortcutText",
+ "EmoteMenuButton1ShortcutText",
+ "EmoteMenuButton2",
+ "EmoteMenuButton20",
+ "EmoteMenuButton20ShortcutText",
+ "EmoteMenuButton21",
+ "EmoteMenuButton21ShortcutText",
+ "EmoteMenuButton22",
+ "EmoteMenuButton22ShortcutText",
+ "EmoteMenuButton23",
+ "EmoteMenuButton23ShortcutText",
+ "EmoteMenuButton24",
+ "EmoteMenuButton24ShortcutText",
+ "EmoteMenuButton25",
+ "EmoteMenuButton25ShortcutText",
+ "EmoteMenuButton26",
+ "EmoteMenuButton26ShortcutText",
+ "EmoteMenuButton27",
+ "EmoteMenuButton27ShortcutText",
+ "EmoteMenuButton28",
+ "EmoteMenuButton28ShortcutText",
+ "EmoteMenuButton29",
+ "EmoteMenuButton29ShortcutText",
+ "EmoteMenuButton2ShortcutText",
+ "EmoteMenuButton3",
+ "EmoteMenuButton30",
+ "EmoteMenuButton30ShortcutText",
+ "EmoteMenuButton31",
+ "EmoteMenuButton31ShortcutText",
+ "EmoteMenuButton32",
+ "EmoteMenuButton32ShortcutText",
+ "EmoteMenuButton3ShortcutText",
+ "EmoteMenuButton4",
+ "EmoteMenuButton4ShortcutText",
+ "EmoteMenuButton5",
+ "EmoteMenuButton5ShortcutText",
+ "EmoteMenuButton6",
+ "EmoteMenuButton6ShortcutText",
+ "EmoteMenuButton7",
+ "EmoteMenuButton7ShortcutText",
+ "EmoteMenuButton8",
+ "EmoteMenuButton8ShortcutText",
+ "EmoteMenuButton9",
+ "EmoteMenuButton9ShortcutText",
+ "EmoteMenu_Click",
+ "EmoteMenu_OnLoad",
+ "EmptyQuestLogFrame",
+ "EmptyQuestLogFrameBackgroundBottomLeft",
+ "EmptyQuestLogFrameBackgroundBottomRight",
+ "EmptyQuestLogFrameBackgroundTopLeft",
+ "EmptyQuestLogFrameBackgroundTopRight",
+ "EnableAddOn",
+ "EnableAllAddOns",
+ "EnablePagingButton",
+ "EnableSpellAutocast",
+ "Enable_BagButtons",
+ "EndBoundTradeable",
+ "EndRefund",
+ "EnumerateFrames",
+ "EnumerateServerChannels",
+ "EquipCursorItem",
+ "EquipItemByName",
+ "EquipPendingItem",
+ "EquipmentManager",
+ "EquipmentManagerClearIgnoredSlotsForSave",
+ "EquipmentManagerIgnoreSlotForSave",
+ "EquipmentManagerIsSlotIgnoredForSave",
+ "EquipmentManagerUnignoreSlotForSave",
+ "EquipmentManager_EquipContainerItem",
+ "EquipmentManager_EquipInventoryItem",
+ "EquipmentManager_EquipItemByLocation",
+ "EquipmentManager_EquipSet",
+ "EquipmentManager_GetItemInfoByLocation",
+ "EquipmentManager_OnEvent",
+ "EquipmentManager_PutItemInInventory",
+ "EquipmentManager_RunAction",
+ "EquipmentManager_UnequipItemInSlot",
+ "EquipmentManager_UnpackLocation",
+ "EquipmentManager_UpdateFreeBagSpace",
+ "EquipmentSetContainsLockedItems",
+ "ErrorFont",
+ "EventTraceFrame",
+ "EventTraceFrameBottom",
+ "EventTraceFrameBottomLeft",
+ "EventTraceFrameBottomRight",
+ "EventTraceFrameButton1",
+ "EventTraceFrameButton10",
+ "EventTraceFrameButton11",
+ "EventTraceFrameButton12",
+ "EventTraceFrameButton13",
+ "EventTraceFrameButton14",
+ "EventTraceFrameButton15",
+ "EventTraceFrameButton16",
+ "EventTraceFrameButton17",
+ "EventTraceFrameButton18",
+ "EventTraceFrameButton19",
+ "EventTraceFrameButton2",
+ "EventTraceFrameButton20",
+ "EventTraceFrameButton21",
+ "EventTraceFrameButton22",
+ "EventTraceFrameButton23",
+ "EventTraceFrameButton24",
+ "EventTraceFrameButton25",
+ "EventTraceFrameButton26",
+ "EventTraceFrameButton27",
+ "EventTraceFrameButton28",
+ "EventTraceFrameButton29",
+ "EventTraceFrameButton3",
+ "EventTraceFrameButton4",
+ "EventTraceFrameButton5",
+ "EventTraceFrameButton6",
+ "EventTraceFrameButton7",
+ "EventTraceFrameButton8",
+ "EventTraceFrameButton9",
+ "EventTraceFrameCloseButton",
+ "EventTraceFrameDialogBG",
+ "EventTraceFrameEvent_DisplayTooltip",
+ "EventTraceFrameEvent_OnClick",
+ "EventTraceFrameEvent_OnEnter",
+ "EventTraceFrameEvent_OnLeave",
+ "EventTraceFrameLeft",
+ "EventTraceFrameRight",
+ "EventTraceFrameScroll",
+ "EventTraceFrameScrollBG",
+ "EventTraceFrameTitle",
+ "EventTraceFrameTitleBG",
+ "EventTraceFrameTitleButton",
+ "EventTraceFrameTitleButtonHighlight",
+ "EventTraceFrameTop",
+ "EventTraceFrameTopLeft",
+ "EventTraceFrameTopRight",
+ "EventTraceFrame_HandleSlashCmd",
+ "EventTraceFrame_OnEvent",
+ "EventTraceFrame_OnKeyUp",
+ "EventTraceFrame_OnLoad",
+ "EventTraceFrame_OnMouseWheel",
+ "EventTraceFrame_OnSizeChanged",
+ "EventTraceFrame_OnUpdate",
+ "EventTraceFrame_StartEventCapture",
+ "EventTraceFrame_StopEventCapture",
+ "EventTraceFrame_Update",
+ "EventTraceFrame_UpdateKeyboardStatus",
+ "EventTraceTooltip",
+ "EventTraceTooltipStatusBar",
+ "EventTraceTooltipStatusBarTexture",
+ "EventTraceTooltipTextLeft1",
+ "EventTraceTooltipTextLeft2",
+ "EventTraceTooltipTextLeft3",
+ "EventTraceTooltipTextLeft4",
+ "EventTraceTooltipTextLeft5",
+ "EventTraceTooltipTextLeft6",
+ "EventTraceTooltipTextLeft7",
+ "EventTraceTooltipTextLeft8",
+ "EventTraceTooltipTextRight1",
+ "EventTraceTooltipTextRight2",
+ "EventTraceTooltipTextRight3",
+ "EventTraceTooltipTextRight4",
+ "EventTraceTooltipTextRight5",
+ "EventTraceTooltipTextRight6",
+ "EventTraceTooltipTextRight7",
+ "EventTraceTooltipTextRight8",
+ "EventTraceTooltipTexture1",
+ "EventTraceTooltipTexture10",
+ "EventTraceTooltipTexture2",
+ "EventTraceTooltipTexture3",
+ "EventTraceTooltipTexture4",
+ "EventTraceTooltipTexture5",
+ "EventTraceTooltipTexture6",
+ "EventTraceTooltipTexture7",
+ "EventTraceTooltipTexture8",
+ "EventTraceTooltipTexture9",
+ "ExhaustionLevelFillBar",
+ "ExhaustionTick",
+ "ExhaustionTickHighlight",
+ "ExhaustionTickNormal",
+ "ExhaustionTick_OnEvent",
+ "ExhaustionTick_OnLoad",
+ "ExhaustionTick_OnUpdate",
+ "ExhaustionToolTipText",
+ "ExpandAllFactionHeaders",
+ "ExpandChannelHeader",
+ "ExpandCurrencyList",
+ "ExpandFactionHeader",
+ "ExpandQuestHeader",
+ "ExpandSkillHeader",
+ "ExpandTradeSkillSubClass",
+ "ExpandTrainerSkillLine",
+ "ExtendedUI",
+ "EyeTemplate_OnUpdate",
+ "EyeTemplate_StartAnimating",
+ "EyeTemplate_StopAnimating",
+ "FACTION_BAR_COLORS",
+ "FADEFRAMES",
+ "FCFChannelDropDown_OnClick",
+ "FCFClickAnywhereButton_OnEvent",
+ "FCFClickAnywhereButton_OnLoad",
+ "FCFClickAnywhereButton_UpdateState",
+ "FCFDockOverflowButton_OnClick",
+ "FCFDockOverflowButton_OnEvent",
+ "FCFDockOverflowButton_UpdatePulseState",
+ "FCFDockOverflowListButton_OnClick",
+ "FCFDockOverflowListButton_SetValue",
+ "FCFDockOverflowList_Update",
+ "FCFDockOverflow_CloseLists",
+ "FCFDockScrollFrame_GetLeftmostTab",
+ "FCFDockScrollFrame_GetScrollDistanceNeeded",
+ "FCFDockScrollFrame_JumpToTab",
+ "FCFDockScrollFrame_OnUpdate",
+ "FCFDock_AddChatFrame",
+ "FCFDock_CalculateTabSize",
+ "FCFDock_ForceReanchoring",
+ "FCFDock_GetChatFrames",
+ "FCFDock_GetInsertIndex",
+ "FCFDock_GetSelectedWindow",
+ "FCFDock_HasDockedChatFrame",
+ "FCFDock_HideInsertHighlight",
+ "FCFDock_OnEvent",
+ "FCFDock_OnLoad",
+ "FCFDock_OnPrimarySizeChanged",
+ "FCFDock_OnUpdate",
+ "FCFDock_PlaceInsertHighlight",
+ "FCFDock_RemoveChatFrame",
+ "FCFDock_ScrollToSelectedTab",
+ "FCFDock_SelectWindow",
+ "FCFDock_SetDirty",
+ "FCFDock_SetPrimary",
+ "FCFDock_UpdateTabs",
+ "FCFDropDown_LoadChannels",
+ "FCFDropDown_LoadChatTypes",
+ "FCFManager_GetNumDedicatedFrames",
+ "FCFManager_RegisterDedicatedFrame",
+ "FCFManager_ShouldSuppressMessage",
+ "FCFManager_UnregisterDedicatedFrame",
+ "FCFMessageTypeDropDown_OnClick",
+ "FCFMin_UpdateColors",
+ "FCFOptionsDropDown_Initialize",
+ "FCFOptionsDropDown_OnLoad",
+ "FCFTab_OnDragStop",
+ "FCFTab_OnUpdate",
+ "FCFTab_UpdateAlpha",
+ "FCFTab_UpdateColors",
+ "FCF_CancelFontColorSettings",
+ "FCF_CancelWindowColorSettings",
+ "FCF_Close",
+ "FCF_CopyChatSettings",
+ "FCF_CreateMinimizedFrame",
+ "FCF_DockFrame",
+ "FCF_DockUpdate",
+ "FCF_FadeInChatFrame",
+ "FCF_FadeOutChatFrame",
+ "FCF_FlagMinimizedPositionReset",
+ "FCF_FlashTab",
+ "FCF_GetButtonSide",
+ "FCF_GetChatWindowInfo",
+ "FCF_GetCurrentChatFrame",
+ "FCF_GetCurrentChatFrameID",
+ "FCF_GetNumActiveChatFrames",
+ "FCF_HideOnFadeFinished",
+ "FCF_IsValidChatFrame",
+ "FCF_LeaveConversation",
+ "FCF_LoadChatSubTypes",
+ "FCF_MaximizeFrame",
+ "FCF_MinimizeFrame",
+ "FCF_NewChatWindow",
+ "FCF_OnUpdate",
+ "FCF_OpenNewWindow",
+ "FCF_OpenTemporaryWindow",
+ "FCF_PopInWindow",
+ "FCF_RenameChatWindow_Popup",
+ "FCF_ResetAllWindows",
+ "FCF_ResetChatWindows",
+ "FCF_RestoreChatsToFrame",
+ "FCF_RestorePositionAndDimensions",
+ "FCF_SaveDock",
+ "FCF_SavePositionAndDimensions",
+ "FCF_SelectDockFrame",
+ "FCF_SetButtonSide",
+ "FCF_SetChatTypeColor",
+ "FCF_SetChatWindowBackGroundColor",
+ "FCF_SetChatWindowFontSize",
+ "FCF_SetChatWindowOpacity",
+ "FCF_SetExpandedUninteractable",
+ "FCF_SetLocked",
+ "FCF_SetTabPosition",
+ "FCF_SetTemporaryWindowType",
+ "FCF_SetUninteractable",
+ "FCF_SetWindowAlpha",
+ "FCF_SetWindowColor",
+ "FCF_SetWindowName",
+ "FCF_Set_NormalChat",
+ "FCF_StartAlertFlash",
+ "FCF_StopAlertFlash",
+ "FCF_StopDragging",
+ "FCF_StripChatMsg",
+ "FCF_TabCompare",
+ "FCF_Tab_OnClick",
+ "FCF_ToggleLock",
+ "FCF_ToggleUninteractable",
+ "FCF_UnDockFrame",
+ "FCF_UpdateButtonSide",
+ "FCF_UpdateDockPosition",
+ "FCTPanelOptions",
+ "FILTERED_BG_CHAT_ADD",
+ "FILTERED_BG_CHAT_ADD_GLOBALS",
+ "FILTERED_BG_CHAT_END",
+ "FILTERED_BG_CHAT_END_GLOBALS",
+ "FILTERED_BG_CHAT_SUBTRACT",
+ "FILTERED_BG_CHAT_SUBTRACT_GLOBALS",
+ "FLASHFRAMES",
+ "FRIENDSFRAME_SUBFRAMES",
+ "FRIENDS_BNET_BACKGROUND_COLOR",
+ "FRIENDS_BNET_NAME_COLOR",
+ "FRIENDS_GRAY_COLOR",
+ "FRIENDS_OFFLINE_BACKGROUND_COLOR",
+ "FRIENDS_WOW_BACKGROUND_COLOR",
+ "FRIENDS_WOW_NAME_COLOR",
+ "FactionMouseOver",
+ "FactionToggleAtWar",
+ "FadingFrame_OnLoad",
+ "FadingFrame_OnUpdate",
+ "FadingFrame_SetFadeInTime",
+ "FadingFrame_SetFadeOutTime",
+ "FadingFrame_SetHoldTime",
+ "FadingFrame_Show",
+ "FauxScrollFrame_GetOffset",
+ "FauxScrollFrame_OnVerticalScroll",
+ "FauxScrollFrame_SetOffset",
+ "FauxScrollFrame_Update",
+ "FeaturesPanelOptions",
+ "FillLocalizedClassList",
+ "FilterButton_SetType",
+ "FindSpellBookSlotByID",
+ "FixedSizeFramePoolCollectionMixin",
+ "FlagTutorial",
+ "FlipCameraYaw",
+ "FloatingChatFrameManager",
+ "FloatingChatFrameManager_OnEvent",
+ "FloatingChatFrameManager_OnLoad",
+ "FloatingChatFrame_OnEvent",
+ "FloatingChatFrame_OnLoad",
+ "FloatingChatFrame_OnMouseScroll",
+ "FloatingChatFrame_Update",
+ "FocusFontSmall",
+ "FocusFrame",
+ "FocusFrameBackground",
+ "FocusFrameBuffs",
+ "FocusFrameDebuffs",
+ "FocusFrameDropDown",
+ "FocusFrameDropDownButton",
+ "FocusFrameDropDownButtonDisabledTexture",
+ "FocusFrameDropDownButtonHighlightTexture",
+ "FocusFrameDropDownButtonNormalTexture",
+ "FocusFrameDropDownButtonPushedTexture",
+ "FocusFrameDropDownLeft",
+ "FocusFrameDropDownMiddle",
+ "FocusFrameDropDownRight",
+ "FocusFrameDropDownText",
+ "FocusFrameDropDown_Initialize",
+ "FocusFrameFlash",
+ "FocusFrameHealthBar",
+ "FocusFrameManaBar",
+ "FocusFrameNameBackground",
+ "FocusFrameNumericalThreat",
+ "FocusFrameNumericalThreatBG",
+ "FocusFrameNumericalThreatValue",
+ "FocusFramePortrait",
+ "FocusFrameSpellBar",
+ "FocusFrameSpellBarBorder",
+ "FocusFrameSpellBarBorderShield",
+ "FocusFrameSpellBarFlash",
+ "FocusFrameSpellBarIcon",
+ "FocusFrameSpellBarSpark",
+ "FocusFrameSpellBarText",
+ "FocusFrameTextureFrame",
+ "FocusFrameTextureFrameDeadText",
+ "FocusFrameTextureFrameHealthBarText",
+ "FocusFrameTextureFrameHighLevelTexture",
+ "FocusFrameTextureFrameLeaderIcon",
+ "FocusFrameTextureFrameLevelText",
+ "FocusFrameTextureFrameManaBarText",
+ "FocusFrameTextureFrameName",
+ "FocusFrameTextureFramePVPIcon",
+ "FocusFrameTextureFrameRaidTargetIcon",
+ "FocusFrameTextureFrameTexture",
+ "FocusFrameToT",
+ "FocusFrameToTBackground",
+ "FocusFrameToTDebuff1",
+ "FocusFrameToTDebuff1Border",
+ "FocusFrameToTDebuff1Cooldown",
+ "FocusFrameToTDebuff1Icon",
+ "FocusFrameToTDebuff2",
+ "FocusFrameToTDebuff2Border",
+ "FocusFrameToTDebuff2Cooldown",
+ "FocusFrameToTDebuff2Icon",
+ "FocusFrameToTDebuff3",
+ "FocusFrameToTDebuff3Border",
+ "FocusFrameToTDebuff3Cooldown",
+ "FocusFrameToTDebuff3Icon",
+ "FocusFrameToTDebuff4",
+ "FocusFrameToTDebuff4Border",
+ "FocusFrameToTDebuff4Cooldown",
+ "FocusFrameToTDebuff4Icon",
+ "FocusFrameToTHealthBar",
+ "FocusFrameToTManaBar",
+ "FocusFrameToTPortrait",
+ "FocusFrameToTTextureFrame",
+ "FocusFrameToTTextureFrameDeadText",
+ "FocusFrameToTTextureFrameName",
+ "FocusFrameToTTextureFrameTexture",
+ "FocusFrame_IsLocked",
+ "FocusFrame_OnDragStart",
+ "FocusFrame_OnDragStop",
+ "FocusFrame_SetLock",
+ "FocusFrame_SetSmallSize",
+ "FocusUnit",
+ "FolderPicker",
+ "FolderPickerButton01",
+ "FolderPickerButton01Name",
+ "FolderPickerHeader",
+ "FollowUnit",
+ "FontStringPoolMixin",
+ "FontStringPool_Hide",
+ "FontStringPool_HideAndClearAnchors",
+ "ForceGossip",
+ "ForceLogout",
+ "ForceQuit",
+ "FormatPaperDollTooltipStat",
+ "FramePoolCollectionMixin",
+ "FramePoolMixin",
+ "FramePool_Hide",
+ "FramePool_HideAndClearAnchors",
+ "FrameStackTooltip",
+ "FrameStackTooltipStatusBar",
+ "FrameStackTooltipStatusBarTexture",
+ "FrameStackTooltipTextLeft1",
+ "FrameStackTooltipTextLeft2",
+ "FrameStackTooltipTextLeft3",
+ "FrameStackTooltipTextLeft4",
+ "FrameStackTooltipTextLeft5",
+ "FrameStackTooltipTextLeft6",
+ "FrameStackTooltipTextLeft7",
+ "FrameStackTooltipTextLeft8",
+ "FrameStackTooltipTextRight1",
+ "FrameStackTooltipTextRight2",
+ "FrameStackTooltipTextRight3",
+ "FrameStackTooltipTextRight4",
+ "FrameStackTooltipTextRight5",
+ "FrameStackTooltipTextRight6",
+ "FrameStackTooltipTextRight7",
+ "FrameStackTooltipTextRight8",
+ "FrameStackTooltipTexture1",
+ "FrameStackTooltipTexture10",
+ "FrameStackTooltipTexture2",
+ "FrameStackTooltipTexture3",
+ "FrameStackTooltipTexture4",
+ "FrameStackTooltipTexture5",
+ "FrameStackTooltipTexture6",
+ "FrameStackTooltipTexture7",
+ "FrameStackTooltipTexture8",
+ "FrameStackTooltipTexture9",
+ "FrameStackTooltip_OnEnter",
+ "FrameStackTooltip_OnUpdate",
+ "FrameStackTooltip_Toggle",
+ "FrameXML_Debug",
+ "FramerateLabel",
+ "FramerateText",
+ "FriendsDropDown",
+ "FriendsDropDownButton",
+ "FriendsDropDownButtonDisabledTexture",
+ "FriendsDropDownButtonHighlightTexture",
+ "FriendsDropDownButtonNormalTexture",
+ "FriendsDropDownButtonPushedTexture",
+ "FriendsDropDownLeft",
+ "FriendsDropDownMiddle",
+ "FriendsDropDownRight",
+ "FriendsDropDownText",
+ "FriendsFont_Large",
+ "FriendsFont_Normal",
+ "FriendsFont_Small",
+ "FriendsFont_UserText",
+ "FriendsFrame",
+ "FriendsFrameAddFriendButton",
+ "FriendsFrameAddFriendButtonLeft",
+ "FriendsFrameAddFriendButtonMiddle",
+ "FriendsFrameAddFriendButtonRight",
+ "FriendsFrameAddFriendButtonText",
+ "FriendsFrameAddFriendButton_OnClick",
+ "FriendsFrameBNDropDown_Initialize",
+ "FriendsFrameBNOfflineDropDown_Initialize",
+ "FriendsFrameBattlenetStatus",
+ "FriendsFrameBattlenetStatusInfoButton",
+ "FriendsFrameBattlenetStatusInfoButtonTexture",
+ "FriendsFrameBattlenetStatusText",
+ "FriendsFrameBlockedInviteHeader",
+ "FriendsFrameBlockedInviteHeaderTitle",
+ "FriendsFrameBlockedToonHeader",
+ "FriendsFrameBlockedToonHeaderTitle",
+ "FriendsFrameBottomLeft",
+ "FriendsFrameBottomRight",
+ "FriendsFrameBroadcastInput",
+ "FriendsFrameBroadcastInputClearButton",
+ "FriendsFrameBroadcastInputFill",
+ "FriendsFrameBroadcastInputLeft",
+ "FriendsFrameBroadcastInputMiddle",
+ "FriendsFrameBroadcastInputRight",
+ "FriendsFrameBroadcastInputTooltipButton",
+ "FriendsFrameBroadcastInput_OnClearPressed",
+ "FriendsFrameBroadcastInput_OnEnterPressed",
+ "FriendsFrameBroadcastInput_OnEscapePressed",
+ "FriendsFrameBroadcastInput_UpdateDisplay",
+ "FriendsFrameCloseButton",
+ "FriendsFrameDropDown_Initialize",
+ "FriendsFrameFriendButton_OnClick",
+ "FriendsFrameFriendsScrollFrame",
+ "FriendsFrameFriendsScrollFrameButton1",
+ "FriendsFrameFriendsScrollFrameButton10",
+ "FriendsFrameFriendsScrollFrameButton10Background",
+ "FriendsFrameFriendsScrollFrameButton10BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton10BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton10CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton10GameIcon",
+ "FriendsFrameFriendsScrollFrameButton10Info",
+ "FriendsFrameFriendsScrollFrameButton10Name",
+ "FriendsFrameFriendsScrollFrameButton10Status",
+ "FriendsFrameFriendsScrollFrameButton10SummonButton",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton10SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton11",
+ "FriendsFrameFriendsScrollFrameButton11Background",
+ "FriendsFrameFriendsScrollFrameButton11BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton11BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton11CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton11GameIcon",
+ "FriendsFrameFriendsScrollFrameButton11Info",
+ "FriendsFrameFriendsScrollFrameButton11Name",
+ "FriendsFrameFriendsScrollFrameButton11Status",
+ "FriendsFrameFriendsScrollFrameButton11SummonButton",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton11SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton12",
+ "FriendsFrameFriendsScrollFrameButton12Background",
+ "FriendsFrameFriendsScrollFrameButton12BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton12BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton12CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton12GameIcon",
+ "FriendsFrameFriendsScrollFrameButton12Info",
+ "FriendsFrameFriendsScrollFrameButton12Name",
+ "FriendsFrameFriendsScrollFrameButton12Status",
+ "FriendsFrameFriendsScrollFrameButton12SummonButton",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton12SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton13",
+ "FriendsFrameFriendsScrollFrameButton13Background",
+ "FriendsFrameFriendsScrollFrameButton13BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton13BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton13CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton13GameIcon",
+ "FriendsFrameFriendsScrollFrameButton13Info",
+ "FriendsFrameFriendsScrollFrameButton13Name",
+ "FriendsFrameFriendsScrollFrameButton13Status",
+ "FriendsFrameFriendsScrollFrameButton13SummonButton",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton13SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton14",
+ "FriendsFrameFriendsScrollFrameButton14Background",
+ "FriendsFrameFriendsScrollFrameButton14BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton14BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton14CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton14GameIcon",
+ "FriendsFrameFriendsScrollFrameButton14Info",
+ "FriendsFrameFriendsScrollFrameButton14Name",
+ "FriendsFrameFriendsScrollFrameButton14Status",
+ "FriendsFrameFriendsScrollFrameButton14SummonButton",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton14SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton15",
+ "FriendsFrameFriendsScrollFrameButton15Background",
+ "FriendsFrameFriendsScrollFrameButton15BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton15BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton15CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton15GameIcon",
+ "FriendsFrameFriendsScrollFrameButton15Info",
+ "FriendsFrameFriendsScrollFrameButton15Name",
+ "FriendsFrameFriendsScrollFrameButton15Status",
+ "FriendsFrameFriendsScrollFrameButton15SummonButton",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton15SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton16",
+ "FriendsFrameFriendsScrollFrameButton16Background",
+ "FriendsFrameFriendsScrollFrameButton16BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton16BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton16CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton16GameIcon",
+ "FriendsFrameFriendsScrollFrameButton16Info",
+ "FriendsFrameFriendsScrollFrameButton16Name",
+ "FriendsFrameFriendsScrollFrameButton16Status",
+ "FriendsFrameFriendsScrollFrameButton16SummonButton",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton16SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton17",
+ "FriendsFrameFriendsScrollFrameButton17Background",
+ "FriendsFrameFriendsScrollFrameButton17BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton17BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton17CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton17GameIcon",
+ "FriendsFrameFriendsScrollFrameButton17Info",
+ "FriendsFrameFriendsScrollFrameButton17Name",
+ "FriendsFrameFriendsScrollFrameButton17Status",
+ "FriendsFrameFriendsScrollFrameButton17SummonButton",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton17SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton18",
+ "FriendsFrameFriendsScrollFrameButton18Background",
+ "FriendsFrameFriendsScrollFrameButton18BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton18BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton18CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton18GameIcon",
+ "FriendsFrameFriendsScrollFrameButton18Info",
+ "FriendsFrameFriendsScrollFrameButton18Name",
+ "FriendsFrameFriendsScrollFrameButton18Status",
+ "FriendsFrameFriendsScrollFrameButton18SummonButton",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton18SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton19",
+ "FriendsFrameFriendsScrollFrameButton19Background",
+ "FriendsFrameFriendsScrollFrameButton19BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton19BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton19CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton19GameIcon",
+ "FriendsFrameFriendsScrollFrameButton19Info",
+ "FriendsFrameFriendsScrollFrameButton19Name",
+ "FriendsFrameFriendsScrollFrameButton19Status",
+ "FriendsFrameFriendsScrollFrameButton19SummonButton",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton19SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton1Background",
+ "FriendsFrameFriendsScrollFrameButton1BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton1BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton1CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton1GameIcon",
+ "FriendsFrameFriendsScrollFrameButton1Info",
+ "FriendsFrameFriendsScrollFrameButton1Name",
+ "FriendsFrameFriendsScrollFrameButton1Status",
+ "FriendsFrameFriendsScrollFrameButton1SummonButton",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton1SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton2",
+ "FriendsFrameFriendsScrollFrameButton20",
+ "FriendsFrameFriendsScrollFrameButton20Background",
+ "FriendsFrameFriendsScrollFrameButton20BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton20BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton20CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton20GameIcon",
+ "FriendsFrameFriendsScrollFrameButton20Info",
+ "FriendsFrameFriendsScrollFrameButton20Name",
+ "FriendsFrameFriendsScrollFrameButton20Status",
+ "FriendsFrameFriendsScrollFrameButton20SummonButton",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton20SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton21",
+ "FriendsFrameFriendsScrollFrameButton21Background",
+ "FriendsFrameFriendsScrollFrameButton21BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton21BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton21CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton21GameIcon",
+ "FriendsFrameFriendsScrollFrameButton21Info",
+ "FriendsFrameFriendsScrollFrameButton21Name",
+ "FriendsFrameFriendsScrollFrameButton21Status",
+ "FriendsFrameFriendsScrollFrameButton21SummonButton",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton21SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton22",
+ "FriendsFrameFriendsScrollFrameButton22Background",
+ "FriendsFrameFriendsScrollFrameButton22BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton22BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton22CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton22GameIcon",
+ "FriendsFrameFriendsScrollFrameButton22Info",
+ "FriendsFrameFriendsScrollFrameButton22Name",
+ "FriendsFrameFriendsScrollFrameButton22Status",
+ "FriendsFrameFriendsScrollFrameButton22SummonButton",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton22SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton23",
+ "FriendsFrameFriendsScrollFrameButton23Background",
+ "FriendsFrameFriendsScrollFrameButton23BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton23BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton23CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton23GameIcon",
+ "FriendsFrameFriendsScrollFrameButton23Info",
+ "FriendsFrameFriendsScrollFrameButton23Name",
+ "FriendsFrameFriendsScrollFrameButton23Status",
+ "FriendsFrameFriendsScrollFrameButton23SummonButton",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton23SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton2Background",
+ "FriendsFrameFriendsScrollFrameButton2BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton2BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton2CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton2GameIcon",
+ "FriendsFrameFriendsScrollFrameButton2Info",
+ "FriendsFrameFriendsScrollFrameButton2Name",
+ "FriendsFrameFriendsScrollFrameButton2Status",
+ "FriendsFrameFriendsScrollFrameButton2SummonButton",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton2SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton3",
+ "FriendsFrameFriendsScrollFrameButton3Background",
+ "FriendsFrameFriendsScrollFrameButton3BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton3BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton3CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton3GameIcon",
+ "FriendsFrameFriendsScrollFrameButton3Info",
+ "FriendsFrameFriendsScrollFrameButton3Name",
+ "FriendsFrameFriendsScrollFrameButton3Status",
+ "FriendsFrameFriendsScrollFrameButton3SummonButton",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton3SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton4",
+ "FriendsFrameFriendsScrollFrameButton4Background",
+ "FriendsFrameFriendsScrollFrameButton4BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton4BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton4CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton4GameIcon",
+ "FriendsFrameFriendsScrollFrameButton4Info",
+ "FriendsFrameFriendsScrollFrameButton4Name",
+ "FriendsFrameFriendsScrollFrameButton4Status",
+ "FriendsFrameFriendsScrollFrameButton4SummonButton",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton4SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton5",
+ "FriendsFrameFriendsScrollFrameButton5Background",
+ "FriendsFrameFriendsScrollFrameButton5BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton5BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton5CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton5GameIcon",
+ "FriendsFrameFriendsScrollFrameButton5Info",
+ "FriendsFrameFriendsScrollFrameButton5Name",
+ "FriendsFrameFriendsScrollFrameButton5Status",
+ "FriendsFrameFriendsScrollFrameButton5SummonButton",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton5SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton6",
+ "FriendsFrameFriendsScrollFrameButton6Background",
+ "FriendsFrameFriendsScrollFrameButton6BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton6BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton6CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton6GameIcon",
+ "FriendsFrameFriendsScrollFrameButton6Info",
+ "FriendsFrameFriendsScrollFrameButton6Name",
+ "FriendsFrameFriendsScrollFrameButton6Status",
+ "FriendsFrameFriendsScrollFrameButton6SummonButton",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton6SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton7",
+ "FriendsFrameFriendsScrollFrameButton7Background",
+ "FriendsFrameFriendsScrollFrameButton7BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton7BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton7CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton7GameIcon",
+ "FriendsFrameFriendsScrollFrameButton7Info",
+ "FriendsFrameFriendsScrollFrameButton7Name",
+ "FriendsFrameFriendsScrollFrameButton7Status",
+ "FriendsFrameFriendsScrollFrameButton7SummonButton",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton7SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton8",
+ "FriendsFrameFriendsScrollFrameButton8Background",
+ "FriendsFrameFriendsScrollFrameButton8BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton8BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton8CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton8GameIcon",
+ "FriendsFrameFriendsScrollFrameButton8Info",
+ "FriendsFrameFriendsScrollFrameButton8Name",
+ "FriendsFrameFriendsScrollFrameButton8Status",
+ "FriendsFrameFriendsScrollFrameButton8SummonButton",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton8SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameButton9",
+ "FriendsFrameFriendsScrollFrameButton9Background",
+ "FriendsFrameFriendsScrollFrameButton9BroadcastIcon",
+ "FriendsFrameFriendsScrollFrameButton9BroadcastMessage",
+ "FriendsFrameFriendsScrollFrameButton9CompactInfo",
+ "FriendsFrameFriendsScrollFrameButton9GameIcon",
+ "FriendsFrameFriendsScrollFrameButton9Info",
+ "FriendsFrameFriendsScrollFrameButton9Name",
+ "FriendsFrameFriendsScrollFrameButton9Status",
+ "FriendsFrameFriendsScrollFrameButton9SummonButton",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonBorder",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonCooldown",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonCount",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonFlash",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonHotKey",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonIcon",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonName",
+ "FriendsFrameFriendsScrollFrameButton9SummonButtonNormalTexture",
+ "FriendsFrameFriendsScrollFrameScrollBar",
+ "FriendsFrameFriendsScrollFrameScrollBarScrollDownButton",
+ "FriendsFrameFriendsScrollFrameScrollBarScrollUpButton",
+ "FriendsFrameFriendsScrollFrameScrollBarThumbTexture",
+ "FriendsFrameFriendsScrollFrameScrollChild",
+ "FriendsFrameGuildStatusButton_OnClick",
+ "FriendsFrameIgnoreButton1",
+ "FriendsFrameIgnoreButton10",
+ "FriendsFrameIgnoreButton10Name",
+ "FriendsFrameIgnoreButton11",
+ "FriendsFrameIgnoreButton11Name",
+ "FriendsFrameIgnoreButton12",
+ "FriendsFrameIgnoreButton12Name",
+ "FriendsFrameIgnoreButton13",
+ "FriendsFrameIgnoreButton13Name",
+ "FriendsFrameIgnoreButton14",
+ "FriendsFrameIgnoreButton14Name",
+ "FriendsFrameIgnoreButton15",
+ "FriendsFrameIgnoreButton15Name",
+ "FriendsFrameIgnoreButton16",
+ "FriendsFrameIgnoreButton16Name",
+ "FriendsFrameIgnoreButton17",
+ "FriendsFrameIgnoreButton17Name",
+ "FriendsFrameIgnoreButton18",
+ "FriendsFrameIgnoreButton18Name",
+ "FriendsFrameIgnoreButton19",
+ "FriendsFrameIgnoreButton19Name",
+ "FriendsFrameIgnoreButton1Name",
+ "FriendsFrameIgnoreButton2",
+ "FriendsFrameIgnoreButton2Name",
+ "FriendsFrameIgnoreButton3",
+ "FriendsFrameIgnoreButton3Name",
+ "FriendsFrameIgnoreButton4",
+ "FriendsFrameIgnoreButton4Name",
+ "FriendsFrameIgnoreButton5",
+ "FriendsFrameIgnoreButton5Name",
+ "FriendsFrameIgnoreButton6",
+ "FriendsFrameIgnoreButton6Name",
+ "FriendsFrameIgnoreButton7",
+ "FriendsFrameIgnoreButton7Name",
+ "FriendsFrameIgnoreButton8",
+ "FriendsFrameIgnoreButton8Name",
+ "FriendsFrameIgnoreButton9",
+ "FriendsFrameIgnoreButton9Name",
+ "FriendsFrameIgnoreButton_OnClick",
+ "FriendsFrameIgnorePlayerButton",
+ "FriendsFrameIgnorePlayerButtonLeft",
+ "FriendsFrameIgnorePlayerButtonMiddle",
+ "FriendsFrameIgnorePlayerButtonRight",
+ "FriendsFrameIgnorePlayerButtonText",
+ "FriendsFrameIgnoreScrollFrame",
+ "FriendsFrameIgnoreScrollFrameScrollBar",
+ "FriendsFrameIgnoreScrollFrameScrollBarScrollDownButton",
+ "FriendsFrameIgnoreScrollFrameScrollBarScrollUpButton",
+ "FriendsFrameIgnoreScrollFrameScrollBarThumbTexture",
+ "FriendsFrameIgnoreScrollFrameScrollChildFrame",
+ "FriendsFrameIgnoredHeader",
+ "FriendsFrameIgnoredHeaderTitle",
+ "FriendsFrameMuteButton_OnClick",
+ "FriendsFrameMutePlayerButton",
+ "FriendsFrameMutePlayerButtonLeft",
+ "FriendsFrameMutePlayerButtonMiddle",
+ "FriendsFrameMutePlayerButtonRight",
+ "FriendsFrameMutePlayerButtonText",
+ "FriendsFrameMutedHeader",
+ "FriendsFrameMutedHeaderTitle",
+ "FriendsFrameOfflineDropDown_Initialize",
+ "FriendsFrameOfflineHeader",
+ "FriendsFramePendingButton1",
+ "FriendsFramePendingButton1AcceptButton",
+ "FriendsFramePendingButton1AcceptButtonLeft",
+ "FriendsFramePendingButton1AcceptButtonMiddle",
+ "FriendsFramePendingButton1AcceptButtonRight",
+ "FriendsFramePendingButton1AcceptButtonText",
+ "FriendsFramePendingButton1Background",
+ "FriendsFramePendingButton1BlockButton",
+ "FriendsFramePendingButton1DeclineButton",
+ "FriendsFramePendingButton1DeclineButtonLeft",
+ "FriendsFramePendingButton1DeclineButtonMiddle",
+ "FriendsFramePendingButton1DeclineButtonRight",
+ "FriendsFramePendingButton1DeclineButtonText",
+ "FriendsFramePendingButton1Highlight",
+ "FriendsFramePendingButton1Message",
+ "FriendsFramePendingButton1Name",
+ "FriendsFramePendingButton1ReportButton",
+ "FriendsFramePendingButton1Sent",
+ "FriendsFramePendingButton2",
+ "FriendsFramePendingButton2AcceptButton",
+ "FriendsFramePendingButton2AcceptButtonLeft",
+ "FriendsFramePendingButton2AcceptButtonMiddle",
+ "FriendsFramePendingButton2AcceptButtonRight",
+ "FriendsFramePendingButton2AcceptButtonText",
+ "FriendsFramePendingButton2Background",
+ "FriendsFramePendingButton2BlockButton",
+ "FriendsFramePendingButton2DeclineButton",
+ "FriendsFramePendingButton2DeclineButtonLeft",
+ "FriendsFramePendingButton2DeclineButtonMiddle",
+ "FriendsFramePendingButton2DeclineButtonRight",
+ "FriendsFramePendingButton2DeclineButtonText",
+ "FriendsFramePendingButton2Highlight",
+ "FriendsFramePendingButton2Message",
+ "FriendsFramePendingButton2Name",
+ "FriendsFramePendingButton2ReportButton",
+ "FriendsFramePendingButton2Sent",
+ "FriendsFramePendingButton3",
+ "FriendsFramePendingButton3AcceptButton",
+ "FriendsFramePendingButton3AcceptButtonLeft",
+ "FriendsFramePendingButton3AcceptButtonMiddle",
+ "FriendsFramePendingButton3AcceptButtonRight",
+ "FriendsFramePendingButton3AcceptButtonText",
+ "FriendsFramePendingButton3Background",
+ "FriendsFramePendingButton3BlockButton",
+ "FriendsFramePendingButton3DeclineButton",
+ "FriendsFramePendingButton3DeclineButtonLeft",
+ "FriendsFramePendingButton3DeclineButtonMiddle",
+ "FriendsFramePendingButton3DeclineButtonRight",
+ "FriendsFramePendingButton3DeclineButtonText",
+ "FriendsFramePendingButton3Highlight",
+ "FriendsFramePendingButton3Message",
+ "FriendsFramePendingButton3Name",
+ "FriendsFramePendingButton3ReportButton",
+ "FriendsFramePendingButton3Sent",
+ "FriendsFramePendingButton4",
+ "FriendsFramePendingButton4AcceptButton",
+ "FriendsFramePendingButton4AcceptButtonLeft",
+ "FriendsFramePendingButton4AcceptButtonMiddle",
+ "FriendsFramePendingButton4AcceptButtonRight",
+ "FriendsFramePendingButton4AcceptButtonText",
+ "FriendsFramePendingButton4Background",
+ "FriendsFramePendingButton4BlockButton",
+ "FriendsFramePendingButton4DeclineButton",
+ "FriendsFramePendingButton4DeclineButtonLeft",
+ "FriendsFramePendingButton4DeclineButtonMiddle",
+ "FriendsFramePendingButton4DeclineButtonRight",
+ "FriendsFramePendingButton4DeclineButtonText",
+ "FriendsFramePendingButton4Highlight",
+ "FriendsFramePendingButton4Message",
+ "FriendsFramePendingButton4Name",
+ "FriendsFramePendingButton4ReportButton",
+ "FriendsFramePendingButton4Sent",
+ "FriendsFramePendingScrollFrame",
+ "FriendsFramePendingScrollFrameScrollBar",
+ "FriendsFramePendingScrollFrameScrollBarScrollDownButton",
+ "FriendsFramePendingScrollFrameScrollBarScrollUpButton",
+ "FriendsFramePendingScrollFrameScrollBarThumbTexture",
+ "FriendsFramePendingScrollFrameScrollChild",
+ "FriendsFramePendingScrollFrame_AdjustScroll",
+ "FriendsFrameSendMessageButton",
+ "FriendsFrameSendMessageButtonLeft",
+ "FriendsFrameSendMessageButtonMiddle",
+ "FriendsFrameSendMessageButtonRight",
+ "FriendsFrameSendMessageButtonText",
+ "FriendsFrameSendMessageButton_OnClick",
+ "FriendsFrameStatusDropDown",
+ "FriendsFrameStatusDropDownButton",
+ "FriendsFrameStatusDropDownButtonDisabledTexture",
+ "FriendsFrameStatusDropDownButtonHighlightTexture",
+ "FriendsFrameStatusDropDownButtonNormalTexture",
+ "FriendsFrameStatusDropDownButtonPushedTexture",
+ "FriendsFrameStatusDropDownLeft",
+ "FriendsFrameStatusDropDownMiddle",
+ "FriendsFrameStatusDropDownMouseOver",
+ "FriendsFrameStatusDropDownRight",
+ "FriendsFrameStatusDropDownStatus",
+ "FriendsFrameStatusDropDownText",
+ "FriendsFrameStatusDropDown_Initialize",
+ "FriendsFrameStatusDropDown_OnLoad",
+ "FriendsFrameStatusDropDown_OnShow",
+ "FriendsFrameStatusDropDown_ShowTooltip",
+ "FriendsFrameStatusDropDown_Update",
+ "FriendsFrameTab1",
+ "FriendsFrameTab1HighlightTexture",
+ "FriendsFrameTab1Left",
+ "FriendsFrameTab1LeftDisabled",
+ "FriendsFrameTab1Middle",
+ "FriendsFrameTab1MiddleDisabled",
+ "FriendsFrameTab1Right",
+ "FriendsFrameTab1RightDisabled",
+ "FriendsFrameTab1Text",
+ "FriendsFrameTab2",
+ "FriendsFrameTab2HighlightTexture",
+ "FriendsFrameTab2Left",
+ "FriendsFrameTab2LeftDisabled",
+ "FriendsFrameTab2Middle",
+ "FriendsFrameTab2MiddleDisabled",
+ "FriendsFrameTab2Right",
+ "FriendsFrameTab2RightDisabled",
+ "FriendsFrameTab2Text",
+ "FriendsFrameTab3",
+ "FriendsFrameTab3HighlightTexture",
+ "FriendsFrameTab3Left",
+ "FriendsFrameTab3LeftDisabled",
+ "FriendsFrameTab3Middle",
+ "FriendsFrameTab3MiddleDisabled",
+ "FriendsFrameTab3Right",
+ "FriendsFrameTab3RightDisabled",
+ "FriendsFrameTab3Text",
+ "FriendsFrameTab4",
+ "FriendsFrameTab4HighlightTexture",
+ "FriendsFrameTab4Left",
+ "FriendsFrameTab4LeftDisabled",
+ "FriendsFrameTab4Middle",
+ "FriendsFrameTab4MiddleDisabled",
+ "FriendsFrameTab4Right",
+ "FriendsFrameTab4RightDisabled",
+ "FriendsFrameTab4Text",
+ "FriendsFrameTab5",
+ "FriendsFrameTab5HighlightTexture",
+ "FriendsFrameTab5Left",
+ "FriendsFrameTab5LeftDisabled",
+ "FriendsFrameTab5Middle",
+ "FriendsFrameTab5MiddleDisabled",
+ "FriendsFrameTab5Right",
+ "FriendsFrameTab5RightDisabled",
+ "FriendsFrameTab5Text",
+ "FriendsFrameTitleText",
+ "FriendsFrameTooltip_SetLine",
+ "FriendsFrameTooltip_Show",
+ "FriendsFrameTopLeft",
+ "FriendsFrameTopRight",
+ "FriendsFrameUnsquelchButton",
+ "FriendsFrameUnsquelchButtonLeft",
+ "FriendsFrameUnsquelchButtonMiddle",
+ "FriendsFrameUnsquelchButtonRight",
+ "FriendsFrameUnsquelchButtonText",
+ "FriendsFrameUnsquelchButton_OnClick",
+ "FriendsFrameWhoButton_OnClick",
+ "FriendsFrame_CheckBattlenetStatus",
+ "FriendsFrame_ClickSummonButton",
+ "FriendsFrame_GetLastOnline",
+ "FriendsFrame_GetTopButton",
+ "FriendsFrame_GroupInvite",
+ "FriendsFrame_OnEvent",
+ "FriendsFrame_OnHide",
+ "FriendsFrame_OnLoad",
+ "FriendsFrame_OnShow",
+ "FriendsFrame_RemoveFriend",
+ "FriendsFrame_SelectFriend",
+ "FriendsFrame_SelectSquelched",
+ "FriendsFrame_SendMessage",
+ "FriendsFrame_SetButton",
+ "FriendsFrame_SetOnlineStatus",
+ "FriendsFrame_ShowBNDropdown",
+ "FriendsFrame_ShowDropdown",
+ "FriendsFrame_ShowSubFrame",
+ "FriendsFrame_SummonButton_OnEvent",
+ "FriendsFrame_SummonButton_OnShow",
+ "FriendsFrame_SummonButton_Update",
+ "FriendsFrame_UnBlock",
+ "FriendsFrame_UnIgnore",
+ "FriendsFrame_UnMute",
+ "FriendsFrame_Update",
+ "FriendsFriendsButton1",
+ "FriendsFriendsButton10",
+ "FriendsFriendsButton10Name",
+ "FriendsFriendsButton11",
+ "FriendsFriendsButton11Name",
+ "FriendsFriendsButton1Name",
+ "FriendsFriendsButton2",
+ "FriendsFriendsButton2Name",
+ "FriendsFriendsButton3",
+ "FriendsFriendsButton3Name",
+ "FriendsFriendsButton4",
+ "FriendsFriendsButton4Name",
+ "FriendsFriendsButton5",
+ "FriendsFriendsButton5Name",
+ "FriendsFriendsButton6",
+ "FriendsFriendsButton6Name",
+ "FriendsFriendsButton7",
+ "FriendsFriendsButton7Name",
+ "FriendsFriendsButton8",
+ "FriendsFriendsButton8Name",
+ "FriendsFriendsButton9",
+ "FriendsFriendsButton9Name",
+ "FriendsFriendsButton_OnClick",
+ "FriendsFriendsCloseButton",
+ "FriendsFriendsCloseButtonLeft",
+ "FriendsFriendsCloseButtonMiddle",
+ "FriendsFriendsCloseButtonRight",
+ "FriendsFriendsCloseButtonText",
+ "FriendsFriendsFrame",
+ "FriendsFriendsFrameDropDown",
+ "FriendsFriendsFrameDropDownButton",
+ "FriendsFriendsFrameDropDownButtonDisabledTexture",
+ "FriendsFriendsFrameDropDownButtonHighlightTexture",
+ "FriendsFriendsFrameDropDownButtonNormalTexture",
+ "FriendsFriendsFrameDropDownButtonPushedTexture",
+ "FriendsFriendsFrameDropDownLeft",
+ "FriendsFriendsFrameDropDownMiddle",
+ "FriendsFriendsFrameDropDownRight",
+ "FriendsFriendsFrameDropDownText",
+ "FriendsFriendsFrameDropDown_Initialize",
+ "FriendsFriendsFrameDropDown_OnClick",
+ "FriendsFriendsFrameTitle",
+ "FriendsFriendsFrame_Close",
+ "FriendsFriendsFrame_OnEvent",
+ "FriendsFriendsFrame_Reset",
+ "FriendsFriendsFrame_SendRequest",
+ "FriendsFriendsFrame_Show",
+ "FriendsFriendsList",
+ "FriendsFriendsList_Update",
+ "FriendsFriendsNoteEditBox",
+ "FriendsFriendsNoteEditBoxFill",
+ "FriendsFriendsNoteFrame",
+ "FriendsFriendsNoteFrameBottom",
+ "FriendsFriendsNoteFrameBottomLeft",
+ "FriendsFriendsNoteFrameBottomRight",
+ "FriendsFriendsNoteFrameLeft",
+ "FriendsFriendsNoteFrameMiddle",
+ "FriendsFriendsNoteFrameRight",
+ "FriendsFriendsNoteFrameScrollFrame",
+ "FriendsFriendsNoteFrameScrollFrameFocusButton",
+ "FriendsFriendsNoteFrameScrollFrameScrollBar",
+ "FriendsFriendsNoteFrameScrollFrameScrollBarScrollDownButton",
+ "FriendsFriendsNoteFrameScrollFrameScrollBarScrollUpButton",
+ "FriendsFriendsNoteFrameScrollFrameScrollBarThumbTexture",
+ "FriendsFriendsNoteFrameTop",
+ "FriendsFriendsNoteFrameTopLeft",
+ "FriendsFriendsNoteFrameTopRight",
+ "FriendsFriendsScrollFrame",
+ "FriendsFriendsScrollFrameScrollBar",
+ "FriendsFriendsScrollFrameScrollBarScrollDownButton",
+ "FriendsFriendsScrollFrameScrollBarScrollUpButton",
+ "FriendsFriendsScrollFrameScrollBarThumbTexture",
+ "FriendsFriendsScrollFrameScrollChildFrame",
+ "FriendsFriendsSendRequestButton",
+ "FriendsFriendsSendRequestButtonLeft",
+ "FriendsFriendsSendRequestButtonMiddle",
+ "FriendsFriendsSendRequestButtonRight",
+ "FriendsFriendsSendRequestButtonText",
+ "FriendsFriendsWaitFrame",
+ "FriendsListFrame",
+ "FriendsList_Update",
+ "FriendsMicroButton",
+ "FriendsMicroButtonCount",
+ "FriendsTabHeader",
+ "FriendsTabHeaderInviteAlert",
+ "FriendsTabHeaderTab1",
+ "FriendsTabHeaderTab1HighlightTexture",
+ "FriendsTabHeaderTab1Left",
+ "FriendsTabHeaderTab1LeftDisabled",
+ "FriendsTabHeaderTab1Middle",
+ "FriendsTabHeaderTab1MiddleDisabled",
+ "FriendsTabHeaderTab1Right",
+ "FriendsTabHeaderTab1RightDisabled",
+ "FriendsTabHeaderTab1Text",
+ "FriendsTabHeaderTab2",
+ "FriendsTabHeaderTab2HighlightTexture",
+ "FriendsTabHeaderTab2Left",
+ "FriendsTabHeaderTab2LeftDisabled",
+ "FriendsTabHeaderTab2Middle",
+ "FriendsTabHeaderTab2MiddleDisabled",
+ "FriendsTabHeaderTab2Right",
+ "FriendsTabHeaderTab2RightDisabled",
+ "FriendsTabHeaderTab2Text",
+ "FriendsTabHeaderTab3",
+ "FriendsTabHeaderTab3HighlightTexture",
+ "FriendsTabHeaderTab3Left",
+ "FriendsTabHeaderTab3LeftDisabled",
+ "FriendsTabHeaderTab3Middle",
+ "FriendsTabHeaderTab3MiddleDisabled",
+ "FriendsTabHeaderTab3Right",
+ "FriendsTabHeaderTab3RightDisabled",
+ "FriendsTabHeaderTab3Text",
+ "FriendsTooltip",
+ "FriendsTooltipBroadcastIcon",
+ "FriendsTooltipBroadcastText",
+ "FriendsTooltipHeader",
+ "FriendsTooltipLastOnline",
+ "FriendsTooltipNoteIcon",
+ "FriendsTooltipNoteText",
+ "FriendsTooltipOtherToons",
+ "FriendsTooltipToon1Info",
+ "FriendsTooltipToon1Name",
+ "FriendsTooltipToon2Info",
+ "FriendsTooltipToon2Name",
+ "FriendsTooltipToon3Info",
+ "FriendsTooltipToon3Name",
+ "FriendsTooltipToon4Info",
+ "FriendsTooltipToon4Name",
+ "FriendsTooltipToon5Info",
+ "FriendsTooltipToon5Name",
+ "FriendsTooltipToonMany",
+ "GEM_TYPE_INFO",
+ "GLYPH_MAJOR",
+ "GLYPH_MINOR",
+ "GLYPH_SLOTS",
+ "GMBlock",
+ "GMBlockText",
+ "GMChatFrame",
+ "GMChatFrameBackground",
+ "GMChatFrameBottomLeftTexture",
+ "GMChatFrameBottomRightTexture",
+ "GMChatFrameBottomTexture",
+ "GMChatFrameButtonFrame",
+ "GMChatFrameButtonFrameBackground",
+ "GMChatFrameButtonFrameBottomButton",
+ "GMChatFrameButtonFrameBottomButtonFlash",
+ "GMChatFrameButtonFrameBottomLeftTexture",
+ "GMChatFrameButtonFrameBottomRightTexture",
+ "GMChatFrameButtonFrameBottomTexture",
+ "GMChatFrameButtonFrameDownButton",
+ "GMChatFrameButtonFrameLeftTexture",
+ "GMChatFrameButtonFrameMinimizeButton",
+ "GMChatFrameButtonFrameRightTexture",
+ "GMChatFrameButtonFrameTopLeftTexture",
+ "GMChatFrameButtonFrameTopRightTexture",
+ "GMChatFrameButtonFrameTopTexture",
+ "GMChatFrameButtonFrameUpButton",
+ "GMChatFrameClickAnywhereButton",
+ "GMChatFrameCloseButton",
+ "GMChatFrameEditBox",
+ "GMChatFrameEditBoxFocusLeft",
+ "GMChatFrameEditBoxFocusMid",
+ "GMChatFrameEditBoxFocusRight",
+ "GMChatFrameEditBoxHeader",
+ "GMChatFrameEditBoxLanguage",
+ "GMChatFrameEditBoxLeft",
+ "GMChatFrameEditBoxMid",
+ "GMChatFrameEditBoxRight",
+ "GMChatFrameLeftTexture",
+ "GMChatFrameResizeButton",
+ "GMChatFrameRightTexture",
+ "GMChatFrameTopLeftTexture",
+ "GMChatFrameTopRightTexture",
+ "GMChatFrameTopTexture",
+ "GMChatFrame_Close",
+ "GMChatFrame_IsGM",
+ "GMChatFrame_LoadUI",
+ "GMChatFrame_OnEvent",
+ "GMChatFrame_OnHide",
+ "GMChatFrame_OnLoad",
+ "GMChatFrame_OnShow",
+ "GMChatFrame_OnUpdate",
+ "GMChatFrame_Show",
+ "GMChatOpenLog",
+ "GMChatOpenLogText",
+ "GMChatStatusFrame",
+ "GMChatStatusFrameButton",
+ "GMChatStatusFrameDescription",
+ "GMChatStatusFramePulse",
+ "GMChatStatusFrameTitleText",
+ "GMChatStatusFrame_OnClick",
+ "GMChatStatusFrame_Pulse",
+ "GMChatTab",
+ "GMChatTabFlash",
+ "GMChatTabLeft",
+ "GMChatTabMiddle",
+ "GMChatTabRight",
+ "GMChatTabText",
+ "GMReportLag",
+ "GMRequestPlayerInfo",
+ "GMResponseNeedMoreHelp",
+ "GMResponseResolve",
+ "GMSurveyAdditionalCommentsText",
+ "GMSurveyAnswer",
+ "GMSurveyAnswerSubmit",
+ "GMSurveyBottom",
+ "GMSurveyBottomFiller",
+ "GMSurveyBottomLeft",
+ "GMSurveyBottomRight",
+ "GMSurveyCancelButton",
+ "GMSurveyCancelButtonText",
+ "GMSurveyCloseButton",
+ "GMSurveyCommentFrame",
+ "GMSurveyCommentScrollFrame",
+ "GMSurveyCommentScrollFrameScrollBar",
+ "GMSurveyCommentScrollFrameScrollBarScrollDownButton",
+ "GMSurveyCommentScrollFrameScrollBarScrollUpButton",
+ "GMSurveyCommentScrollFrameScrollBarThumbTexture",
+ "GMSurveyCommentScrollFrame_OnEvent",
+ "GMSurveyCommentScrollFrame_OnLoad",
+ "GMSurveyCommentSubmit",
+ "GMSurveyFrame",
+ "GMSurveyFrameComment",
+ "GMSurveyFrame_LoadUI",
+ "GMSurveyFrame_Update",
+ "GMSurveyHeader",
+ "GMSurveyHeaderCenter",
+ "GMSurveyHeaderLeft",
+ "GMSurveyHeaderRight",
+ "GMSurveyHeaderText",
+ "GMSurveyLeft",
+ "GMSurveyMiddle",
+ "GMSurveyMiddleFiller",
+ "GMSurveyNumAnswers",
+ "GMSurveyQuestion",
+ "GMSurveyQuestion1",
+ "GMSurveyQuestion10",
+ "GMSurveyQuestion10RadioButton0",
+ "GMSurveyQuestion10RadioButton0Score",
+ "GMSurveyQuestion10RadioButton0Text",
+ "GMSurveyQuestion10RadioButton1",
+ "GMSurveyQuestion10RadioButton10",
+ "GMSurveyQuestion10RadioButton10Score",
+ "GMSurveyQuestion10RadioButton10Text",
+ "GMSurveyQuestion10RadioButton11",
+ "GMSurveyQuestion10RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion10RadioButton11Score",
+ "GMSurveyQuestion10RadioButton11Text",
+ "GMSurveyQuestion10RadioButton1NetPromoterLow",
+ "GMSurveyQuestion10RadioButton1Score",
+ "GMSurveyQuestion10RadioButton1Text",
+ "GMSurveyQuestion10RadioButton2",
+ "GMSurveyQuestion10RadioButton2Score",
+ "GMSurveyQuestion10RadioButton2Text",
+ "GMSurveyQuestion10RadioButton3",
+ "GMSurveyQuestion10RadioButton3Score",
+ "GMSurveyQuestion10RadioButton3Text",
+ "GMSurveyQuestion10RadioButton4",
+ "GMSurveyQuestion10RadioButton4Score",
+ "GMSurveyQuestion10RadioButton4Text",
+ "GMSurveyQuestion10RadioButton5",
+ "GMSurveyQuestion10RadioButton5Score",
+ "GMSurveyQuestion10RadioButton5Text",
+ "GMSurveyQuestion10RadioButton6",
+ "GMSurveyQuestion10RadioButton6Score",
+ "GMSurveyQuestion10RadioButton6Text",
+ "GMSurveyQuestion10RadioButton7",
+ "GMSurveyQuestion10RadioButton7Score",
+ "GMSurveyQuestion10RadioButton7Text",
+ "GMSurveyQuestion10RadioButton8",
+ "GMSurveyQuestion10RadioButton8Score",
+ "GMSurveyQuestion10RadioButton8Text",
+ "GMSurveyQuestion10RadioButton9",
+ "GMSurveyQuestion10RadioButton9Score",
+ "GMSurveyQuestion10RadioButton9Text",
+ "GMSurveyQuestion10Text",
+ "GMSurveyQuestion1RadioButton0",
+ "GMSurveyQuestion1RadioButton0Score",
+ "GMSurveyQuestion1RadioButton0Text",
+ "GMSurveyQuestion1RadioButton1",
+ "GMSurveyQuestion1RadioButton10",
+ "GMSurveyQuestion1RadioButton10Score",
+ "GMSurveyQuestion1RadioButton10Text",
+ "GMSurveyQuestion1RadioButton11",
+ "GMSurveyQuestion1RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion1RadioButton11Score",
+ "GMSurveyQuestion1RadioButton11Text",
+ "GMSurveyQuestion1RadioButton1NetPromoterLow",
+ "GMSurveyQuestion1RadioButton1Score",
+ "GMSurveyQuestion1RadioButton1Text",
+ "GMSurveyQuestion1RadioButton2",
+ "GMSurveyQuestion1RadioButton2Score",
+ "GMSurveyQuestion1RadioButton2Text",
+ "GMSurveyQuestion1RadioButton3",
+ "GMSurveyQuestion1RadioButton3Score",
+ "GMSurveyQuestion1RadioButton3Text",
+ "GMSurveyQuestion1RadioButton4",
+ "GMSurveyQuestion1RadioButton4Score",
+ "GMSurveyQuestion1RadioButton4Text",
+ "GMSurveyQuestion1RadioButton5",
+ "GMSurveyQuestion1RadioButton5Score",
+ "GMSurveyQuestion1RadioButton5Text",
+ "GMSurveyQuestion1RadioButton6",
+ "GMSurveyQuestion1RadioButton6Score",
+ "GMSurveyQuestion1RadioButton6Text",
+ "GMSurveyQuestion1RadioButton7",
+ "GMSurveyQuestion1RadioButton7Score",
+ "GMSurveyQuestion1RadioButton7Text",
+ "GMSurveyQuestion1RadioButton8",
+ "GMSurveyQuestion1RadioButton8Score",
+ "GMSurveyQuestion1RadioButton8Text",
+ "GMSurveyQuestion1RadioButton9",
+ "GMSurveyQuestion1RadioButton9Score",
+ "GMSurveyQuestion1RadioButton9Text",
+ "GMSurveyQuestion1Text",
+ "GMSurveyQuestion2",
+ "GMSurveyQuestion2RadioButton0",
+ "GMSurveyQuestion2RadioButton0Score",
+ "GMSurveyQuestion2RadioButton0Text",
+ "GMSurveyQuestion2RadioButton1",
+ "GMSurveyQuestion2RadioButton10",
+ "GMSurveyQuestion2RadioButton10Score",
+ "GMSurveyQuestion2RadioButton10Text",
+ "GMSurveyQuestion2RadioButton11",
+ "GMSurveyQuestion2RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion2RadioButton11Score",
+ "GMSurveyQuestion2RadioButton11Text",
+ "GMSurveyQuestion2RadioButton1NetPromoterLow",
+ "GMSurveyQuestion2RadioButton1Score",
+ "GMSurveyQuestion2RadioButton1Text",
+ "GMSurveyQuestion2RadioButton2",
+ "GMSurveyQuestion2RadioButton2Score",
+ "GMSurveyQuestion2RadioButton2Text",
+ "GMSurveyQuestion2RadioButton3",
+ "GMSurveyQuestion2RadioButton3Score",
+ "GMSurveyQuestion2RadioButton3Text",
+ "GMSurveyQuestion2RadioButton4",
+ "GMSurveyQuestion2RadioButton4Score",
+ "GMSurveyQuestion2RadioButton4Text",
+ "GMSurveyQuestion2RadioButton5",
+ "GMSurveyQuestion2RadioButton5Score",
+ "GMSurveyQuestion2RadioButton5Text",
+ "GMSurveyQuestion2RadioButton6",
+ "GMSurveyQuestion2RadioButton6Score",
+ "GMSurveyQuestion2RadioButton6Text",
+ "GMSurveyQuestion2RadioButton7",
+ "GMSurveyQuestion2RadioButton7Score",
+ "GMSurveyQuestion2RadioButton7Text",
+ "GMSurveyQuestion2RadioButton8",
+ "GMSurveyQuestion2RadioButton8Score",
+ "GMSurveyQuestion2RadioButton8Text",
+ "GMSurveyQuestion2RadioButton9",
+ "GMSurveyQuestion2RadioButton9Score",
+ "GMSurveyQuestion2RadioButton9Text",
+ "GMSurveyQuestion2Text",
+ "GMSurveyQuestion3",
+ "GMSurveyQuestion3RadioButton0",
+ "GMSurveyQuestion3RadioButton0Score",
+ "GMSurveyQuestion3RadioButton0Text",
+ "GMSurveyQuestion3RadioButton1",
+ "GMSurveyQuestion3RadioButton10",
+ "GMSurveyQuestion3RadioButton10Score",
+ "GMSurveyQuestion3RadioButton10Text",
+ "GMSurveyQuestion3RadioButton11",
+ "GMSurveyQuestion3RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion3RadioButton11Score",
+ "GMSurveyQuestion3RadioButton11Text",
+ "GMSurveyQuestion3RadioButton1NetPromoterLow",
+ "GMSurveyQuestion3RadioButton1Score",
+ "GMSurveyQuestion3RadioButton1Text",
+ "GMSurveyQuestion3RadioButton2",
+ "GMSurveyQuestion3RadioButton2Score",
+ "GMSurveyQuestion3RadioButton2Text",
+ "GMSurveyQuestion3RadioButton3",
+ "GMSurveyQuestion3RadioButton3Score",
+ "GMSurveyQuestion3RadioButton3Text",
+ "GMSurveyQuestion3RadioButton4",
+ "GMSurveyQuestion3RadioButton4Score",
+ "GMSurveyQuestion3RadioButton4Text",
+ "GMSurveyQuestion3RadioButton5",
+ "GMSurveyQuestion3RadioButton5Score",
+ "GMSurveyQuestion3RadioButton5Text",
+ "GMSurveyQuestion3RadioButton6",
+ "GMSurveyQuestion3RadioButton6Score",
+ "GMSurveyQuestion3RadioButton6Text",
+ "GMSurveyQuestion3RadioButton7",
+ "GMSurveyQuestion3RadioButton7Score",
+ "GMSurveyQuestion3RadioButton7Text",
+ "GMSurveyQuestion3RadioButton8",
+ "GMSurveyQuestion3RadioButton8Score",
+ "GMSurveyQuestion3RadioButton8Text",
+ "GMSurveyQuestion3RadioButton9",
+ "GMSurveyQuestion3RadioButton9Score",
+ "GMSurveyQuestion3RadioButton9Text",
+ "GMSurveyQuestion3Text",
+ "GMSurveyQuestion4",
+ "GMSurveyQuestion4RadioButton0",
+ "GMSurveyQuestion4RadioButton0Score",
+ "GMSurveyQuestion4RadioButton0Text",
+ "GMSurveyQuestion4RadioButton1",
+ "GMSurveyQuestion4RadioButton10",
+ "GMSurveyQuestion4RadioButton10Score",
+ "GMSurveyQuestion4RadioButton10Text",
+ "GMSurveyQuestion4RadioButton11",
+ "GMSurveyQuestion4RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion4RadioButton11Score",
+ "GMSurveyQuestion4RadioButton11Text",
+ "GMSurveyQuestion4RadioButton1NetPromoterLow",
+ "GMSurveyQuestion4RadioButton1Score",
+ "GMSurveyQuestion4RadioButton1Text",
+ "GMSurveyQuestion4RadioButton2",
+ "GMSurveyQuestion4RadioButton2Score",
+ "GMSurveyQuestion4RadioButton2Text",
+ "GMSurveyQuestion4RadioButton3",
+ "GMSurveyQuestion4RadioButton3Score",
+ "GMSurveyQuestion4RadioButton3Text",
+ "GMSurveyQuestion4RadioButton4",
+ "GMSurveyQuestion4RadioButton4Score",
+ "GMSurveyQuestion4RadioButton4Text",
+ "GMSurveyQuestion4RadioButton5",
+ "GMSurveyQuestion4RadioButton5Score",
+ "GMSurveyQuestion4RadioButton5Text",
+ "GMSurveyQuestion4RadioButton6",
+ "GMSurveyQuestion4RadioButton6Score",
+ "GMSurveyQuestion4RadioButton6Text",
+ "GMSurveyQuestion4RadioButton7",
+ "GMSurveyQuestion4RadioButton7Score",
+ "GMSurveyQuestion4RadioButton7Text",
+ "GMSurveyQuestion4RadioButton8",
+ "GMSurveyQuestion4RadioButton8Score",
+ "GMSurveyQuestion4RadioButton8Text",
+ "GMSurveyQuestion4RadioButton9",
+ "GMSurveyQuestion4RadioButton9Score",
+ "GMSurveyQuestion4RadioButton9Text",
+ "GMSurveyQuestion4Text",
+ "GMSurveyQuestion5",
+ "GMSurveyQuestion5RadioButton0",
+ "GMSurveyQuestion5RadioButton0Score",
+ "GMSurveyQuestion5RadioButton0Text",
+ "GMSurveyQuestion5RadioButton1",
+ "GMSurveyQuestion5RadioButton10",
+ "GMSurveyQuestion5RadioButton10Score",
+ "GMSurveyQuestion5RadioButton10Text",
+ "GMSurveyQuestion5RadioButton11",
+ "GMSurveyQuestion5RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion5RadioButton11Score",
+ "GMSurveyQuestion5RadioButton11Text",
+ "GMSurveyQuestion5RadioButton1NetPromoterLow",
+ "GMSurveyQuestion5RadioButton1Score",
+ "GMSurveyQuestion5RadioButton1Text",
+ "GMSurveyQuestion5RadioButton2",
+ "GMSurveyQuestion5RadioButton2Score",
+ "GMSurveyQuestion5RadioButton2Text",
+ "GMSurveyQuestion5RadioButton3",
+ "GMSurveyQuestion5RadioButton3Score",
+ "GMSurveyQuestion5RadioButton3Text",
+ "GMSurveyQuestion5RadioButton4",
+ "GMSurveyQuestion5RadioButton4Score",
+ "GMSurveyQuestion5RadioButton4Text",
+ "GMSurveyQuestion5RadioButton5",
+ "GMSurveyQuestion5RadioButton5Score",
+ "GMSurveyQuestion5RadioButton5Text",
+ "GMSurveyQuestion5RadioButton6",
+ "GMSurveyQuestion5RadioButton6Score",
+ "GMSurveyQuestion5RadioButton6Text",
+ "GMSurveyQuestion5RadioButton7",
+ "GMSurveyQuestion5RadioButton7Score",
+ "GMSurveyQuestion5RadioButton7Text",
+ "GMSurveyQuestion5RadioButton8",
+ "GMSurveyQuestion5RadioButton8Score",
+ "GMSurveyQuestion5RadioButton8Text",
+ "GMSurveyQuestion5RadioButton9",
+ "GMSurveyQuestion5RadioButton9Score",
+ "GMSurveyQuestion5RadioButton9Text",
+ "GMSurveyQuestion5Text",
+ "GMSurveyQuestion6",
+ "GMSurveyQuestion6RadioButton0",
+ "GMSurveyQuestion6RadioButton0Score",
+ "GMSurveyQuestion6RadioButton0Text",
+ "GMSurveyQuestion6RadioButton1",
+ "GMSurveyQuestion6RadioButton10",
+ "GMSurveyQuestion6RadioButton10Score",
+ "GMSurveyQuestion6RadioButton10Text",
+ "GMSurveyQuestion6RadioButton11",
+ "GMSurveyQuestion6RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion6RadioButton11Score",
+ "GMSurveyQuestion6RadioButton11Text",
+ "GMSurveyQuestion6RadioButton1NetPromoterLow",
+ "GMSurveyQuestion6RadioButton1Score",
+ "GMSurveyQuestion6RadioButton1Text",
+ "GMSurveyQuestion6RadioButton2",
+ "GMSurveyQuestion6RadioButton2Score",
+ "GMSurveyQuestion6RadioButton2Text",
+ "GMSurveyQuestion6RadioButton3",
+ "GMSurveyQuestion6RadioButton3Score",
+ "GMSurveyQuestion6RadioButton3Text",
+ "GMSurveyQuestion6RadioButton4",
+ "GMSurveyQuestion6RadioButton4Score",
+ "GMSurveyQuestion6RadioButton4Text",
+ "GMSurveyQuestion6RadioButton5",
+ "GMSurveyQuestion6RadioButton5Score",
+ "GMSurveyQuestion6RadioButton5Text",
+ "GMSurveyQuestion6RadioButton6",
+ "GMSurveyQuestion6RadioButton6Score",
+ "GMSurveyQuestion6RadioButton6Text",
+ "GMSurveyQuestion6RadioButton7",
+ "GMSurveyQuestion6RadioButton7Score",
+ "GMSurveyQuestion6RadioButton7Text",
+ "GMSurveyQuestion6RadioButton8",
+ "GMSurveyQuestion6RadioButton8Score",
+ "GMSurveyQuestion6RadioButton8Text",
+ "GMSurveyQuestion6RadioButton9",
+ "GMSurveyQuestion6RadioButton9Score",
+ "GMSurveyQuestion6RadioButton9Text",
+ "GMSurveyQuestion6Text",
+ "GMSurveyQuestion7",
+ "GMSurveyQuestion7RadioButton0",
+ "GMSurveyQuestion7RadioButton0Score",
+ "GMSurveyQuestion7RadioButton0Text",
+ "GMSurveyQuestion7RadioButton1",
+ "GMSurveyQuestion7RadioButton10",
+ "GMSurveyQuestion7RadioButton10Score",
+ "GMSurveyQuestion7RadioButton10Text",
+ "GMSurveyQuestion7RadioButton11",
+ "GMSurveyQuestion7RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion7RadioButton11Score",
+ "GMSurveyQuestion7RadioButton11Text",
+ "GMSurveyQuestion7RadioButton1NetPromoterLow",
+ "GMSurveyQuestion7RadioButton1Score",
+ "GMSurveyQuestion7RadioButton1Text",
+ "GMSurveyQuestion7RadioButton2",
+ "GMSurveyQuestion7RadioButton2Score",
+ "GMSurveyQuestion7RadioButton2Text",
+ "GMSurveyQuestion7RadioButton3",
+ "GMSurveyQuestion7RadioButton3Score",
+ "GMSurveyQuestion7RadioButton3Text",
+ "GMSurveyQuestion7RadioButton4",
+ "GMSurveyQuestion7RadioButton4Score",
+ "GMSurveyQuestion7RadioButton4Text",
+ "GMSurveyQuestion7RadioButton5",
+ "GMSurveyQuestion7RadioButton5Score",
+ "GMSurveyQuestion7RadioButton5Text",
+ "GMSurveyQuestion7RadioButton6",
+ "GMSurveyQuestion7RadioButton6Score",
+ "GMSurveyQuestion7RadioButton6Text",
+ "GMSurveyQuestion7RadioButton7",
+ "GMSurveyQuestion7RadioButton7Score",
+ "GMSurveyQuestion7RadioButton7Text",
+ "GMSurveyQuestion7RadioButton8",
+ "GMSurveyQuestion7RadioButton8Score",
+ "GMSurveyQuestion7RadioButton8Text",
+ "GMSurveyQuestion7RadioButton9",
+ "GMSurveyQuestion7RadioButton9Score",
+ "GMSurveyQuestion7RadioButton9Text",
+ "GMSurveyQuestion7Text",
+ "GMSurveyQuestion8",
+ "GMSurveyQuestion8RadioButton0",
+ "GMSurveyQuestion8RadioButton0Score",
+ "GMSurveyQuestion8RadioButton0Text",
+ "GMSurveyQuestion8RadioButton1",
+ "GMSurveyQuestion8RadioButton10",
+ "GMSurveyQuestion8RadioButton10Score",
+ "GMSurveyQuestion8RadioButton10Text",
+ "GMSurveyQuestion8RadioButton11",
+ "GMSurveyQuestion8RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion8RadioButton11Score",
+ "GMSurveyQuestion8RadioButton11Text",
+ "GMSurveyQuestion8RadioButton1NetPromoterLow",
+ "GMSurveyQuestion8RadioButton1Score",
+ "GMSurveyQuestion8RadioButton1Text",
+ "GMSurveyQuestion8RadioButton2",
+ "GMSurveyQuestion8RadioButton2Score",
+ "GMSurveyQuestion8RadioButton2Text",
+ "GMSurveyQuestion8RadioButton3",
+ "GMSurveyQuestion8RadioButton3Score",
+ "GMSurveyQuestion8RadioButton3Text",
+ "GMSurveyQuestion8RadioButton4",
+ "GMSurveyQuestion8RadioButton4Score",
+ "GMSurveyQuestion8RadioButton4Text",
+ "GMSurveyQuestion8RadioButton5",
+ "GMSurveyQuestion8RadioButton5Score",
+ "GMSurveyQuestion8RadioButton5Text",
+ "GMSurveyQuestion8RadioButton6",
+ "GMSurveyQuestion8RadioButton6Score",
+ "GMSurveyQuestion8RadioButton6Text",
+ "GMSurveyQuestion8RadioButton7",
+ "GMSurveyQuestion8RadioButton7Score",
+ "GMSurveyQuestion8RadioButton7Text",
+ "GMSurveyQuestion8RadioButton8",
+ "GMSurveyQuestion8RadioButton8Score",
+ "GMSurveyQuestion8RadioButton8Text",
+ "GMSurveyQuestion8RadioButton9",
+ "GMSurveyQuestion8RadioButton9Score",
+ "GMSurveyQuestion8RadioButton9Text",
+ "GMSurveyQuestion8Text",
+ "GMSurveyQuestion9",
+ "GMSurveyQuestion9RadioButton0",
+ "GMSurveyQuestion9RadioButton0Score",
+ "GMSurveyQuestion9RadioButton0Text",
+ "GMSurveyQuestion9RadioButton1",
+ "GMSurveyQuestion9RadioButton10",
+ "GMSurveyQuestion9RadioButton10Score",
+ "GMSurveyQuestion9RadioButton10Text",
+ "GMSurveyQuestion9RadioButton11",
+ "GMSurveyQuestion9RadioButton11NetPromoterHigh",
+ "GMSurveyQuestion9RadioButton11Score",
+ "GMSurveyQuestion9RadioButton11Text",
+ "GMSurveyQuestion9RadioButton1NetPromoterLow",
+ "GMSurveyQuestion9RadioButton1Score",
+ "GMSurveyQuestion9RadioButton1Text",
+ "GMSurveyQuestion9RadioButton2",
+ "GMSurveyQuestion9RadioButton2Score",
+ "GMSurveyQuestion9RadioButton2Text",
+ "GMSurveyQuestion9RadioButton3",
+ "GMSurveyQuestion9RadioButton3Score",
+ "GMSurveyQuestion9RadioButton3Text",
+ "GMSurveyQuestion9RadioButton4",
+ "GMSurveyQuestion9RadioButton4Score",
+ "GMSurveyQuestion9RadioButton4Text",
+ "GMSurveyQuestion9RadioButton5",
+ "GMSurveyQuestion9RadioButton5Score",
+ "GMSurveyQuestion9RadioButton5Text",
+ "GMSurveyQuestion9RadioButton6",
+ "GMSurveyQuestion9RadioButton6Score",
+ "GMSurveyQuestion9RadioButton6Text",
+ "GMSurveyQuestion9RadioButton7",
+ "GMSurveyQuestion9RadioButton7Score",
+ "GMSurveyQuestion9RadioButton7Text",
+ "GMSurveyQuestion9RadioButton8",
+ "GMSurveyQuestion9RadioButton8Score",
+ "GMSurveyQuestion9RadioButton8Text",
+ "GMSurveyQuestion9RadioButton9",
+ "GMSurveyQuestion9RadioButton9Score",
+ "GMSurveyQuestion9RadioButton9Text",
+ "GMSurveyQuestion9Text",
+ "GMSurveyQuestion_OnLoad",
+ "GMSurveyQuestion_OnShow",
+ "GMSurveyQuestion_SpaceAnswers",
+ "GMSurveyRadioButton_OnClick",
+ "GMSurveyRight",
+ "GMSurveyScrollChildFrame",
+ "GMSurveyScrollFrame",
+ "GMSurveyScrollFrameBottom",
+ "GMSurveyScrollFrameMiddle",
+ "GMSurveyScrollFrameScrollBar",
+ "GMSurveyScrollFrameScrollBarScrollDownButton",
+ "GMSurveyScrollFrameScrollBarScrollUpButton",
+ "GMSurveyScrollFrameScrollBarThumbTexture",
+ "GMSurveyScrollFrameTop",
+ "GMSurveyScrollFrame_OnEvent",
+ "GMSurveyScrollFrame_OnLoad",
+ "GMSurveySubmit",
+ "GMSurveySubmitButton",
+ "GMSurveySubmitButtonText",
+ "GMSurveySubmitButton_OnClick",
+ "GMSurveyTop",
+ "GMSurveyTopFiller",
+ "GMSurveyTopLeft",
+ "GMSurveyTopRight",
+ "GRAY_FONT_COLOR",
+ "GREEN_FONT_COLOR",
+ "GUILDFRAME_POPUPS",
+ "GameFontBlack",
+ "GameFontBlackMedium",
+ "GameFontBlackSmall",
+ "GameFontBlackTiny",
+ "GameFontDarkGraySmall",
+ "GameFontDisable",
+ "GameFontDisableLarge",
+ "GameFontDisableLeft",
+ "GameFontDisableSmall",
+ "GameFontDisableSmallLeft",
+ "GameFontGreen",
+ "GameFontGreenLarge",
+ "GameFontGreenSmall",
+ "GameFontHighlight",
+ "GameFontHighlightCenter",
+ "GameFontHighlightExtraSmall",
+ "GameFontHighlightExtraSmallLeft",
+ "GameFontHighlightExtraSmallLeftTop",
+ "GameFontHighlightLarge",
+ "GameFontHighlightLeft",
+ "GameFontHighlightMedium",
+ "GameFontHighlightRight",
+ "GameFontHighlightSmall",
+ "GameFontHighlightSmallLeft",
+ "GameFontHighlightSmallLeftTop",
+ "GameFontHighlightSmallOutline",
+ "GameFontHighlightSmallRight",
+ "GameFontNormal",
+ "GameFontNormalCenter",
+ "GameFontNormalHuge",
+ "GameFontNormalHugeBlack",
+ "GameFontNormalLarge",
+ "GameFontNormalLargeLeft",
+ "GameFontNormalLargeLeftTop",
+ "GameFontNormalLeft",
+ "GameFontNormalLeftBottom",
+ "GameFontNormalLeftGreen",
+ "GameFontNormalLeftGrey",
+ "GameFontNormalLeftLightGreen",
+ "GameFontNormalLeftOrange",
+ "GameFontNormalLeftRed",
+ "GameFontNormalLeftYellow",
+ "GameFontNormalMed3",
+ "GameFontNormalRight",
+ "GameFontNormalSmall",
+ "GameFontNormalSmallLeft",
+ "GameFontRed",
+ "GameFontRedLarge",
+ "GameFontRedSmall",
+ "GameFontWhite",
+ "GameFontWhiteSmall",
+ "GameFontWhiteTiny",
+ "GameMenuButtonContinue",
+ "GameMenuButtonContinueText",
+ "GameMenuButtonKeybindings",
+ "GameMenuButtonKeybindingsText",
+ "GameMenuButtonLogout",
+ "GameMenuButtonLogoutText",
+ "GameMenuButtonMacOptions",
+ "GameMenuButtonMacOptionsText",
+ "GameMenuButtonMacros",
+ "GameMenuButtonMacrosText",
+ "GameMenuButtonOptions",
+ "GameMenuButtonOptionsText",
+ "GameMenuButtonQuit",
+ "GameMenuButtonQuitText",
+ "GameMenuButtonRatings",
+ "GameMenuButtonRatingsText",
+ "GameMenuButtonSoundOptions",
+ "GameMenuButtonSoundOptionsText",
+ "GameMenuButtonUIOptions",
+ "GameMenuButtonUIOptionsText",
+ "GameMenuFrame",
+ "GameMenuFrameHeader",
+ "GameMovieFinished",
+ "GameTimeCalendarEventAlarmTexture",
+ "GameTimeCalendarInvitesGlow",
+ "GameTimeCalendarInvitesTexture",
+ "GameTimeFrame",
+ "GameTimeFrame_OnClick",
+ "GameTimeFrame_OnEnter",
+ "GameTimeFrame_OnEvent",
+ "GameTimeFrame_OnLoad",
+ "GameTimeFrame_OnUpdate",
+ "GameTimeFrame_SetDate",
+ "GameTimeTexture",
+ "GameTime_ComputeMilitaryTime",
+ "GameTime_ComputeMinutes",
+ "GameTime_ComputeStandardTime",
+ "GameTime_GetFormattedTime",
+ "GameTime_GetGameTime",
+ "GameTime_GetLocalTime",
+ "GameTime_GetTime",
+ "GameTime_UpdateTooltip",
+ "GameTooltip",
+ "GameTooltipHeader",
+ "GameTooltipHeaderText",
+ "GameTooltipStatusBar",
+ "GameTooltipStatusBarTexture",
+ "GameTooltipText",
+ "GameTooltipTextLeft1",
+ "GameTooltipTextLeft2",
+ "GameTooltipTextLeft3",
+ "GameTooltipTextLeft4",
+ "GameTooltipTextLeft5",
+ "GameTooltipTextLeft6",
+ "GameTooltipTextLeft7",
+ "GameTooltipTextLeft8",
+ "GameTooltipTextLeft9",
+ "GameTooltipTextRight1",
+ "GameTooltipTextRight2",
+ "GameTooltipTextRight3",
+ "GameTooltipTextRight4",
+ "GameTooltipTextRight5",
+ "GameTooltipTextRight6",
+ "GameTooltipTextRight7",
+ "GameTooltipTextRight8",
+ "GameTooltipTextRight9",
+ "GameTooltipTextSmall",
+ "GameTooltipTexture1",
+ "GameTooltipTexture10",
+ "GameTooltipTexture2",
+ "GameTooltipTexture3",
+ "GameTooltipTexture4",
+ "GameTooltipTexture5",
+ "GameTooltipTexture6",
+ "GameTooltipTexture7",
+ "GameTooltipTexture8",
+ "GameTooltipTexture9",
+ "GameTooltip_AddNewbieTip",
+ "GameTooltip_ClearMoney",
+ "GameTooltip_ClearStatusBars",
+ "GameTooltip_Hide",
+ "GameTooltip_HideResetCursor",
+ "GameTooltip_OnHide",
+ "GameTooltip_OnLoad",
+ "GameTooltip_OnTooltipAddMoney",
+ "GameTooltip_OnUpdate",
+ "GameTooltip_SetDefaultAnchor",
+ "GameTooltip_ShowCompareItem",
+ "GameTooltip_ShowStatusBar",
+ "GameTooltip_UnitColor",
+ "GearManagerDialog",
+ "GearManagerDialogBottom",
+ "GearManagerDialogBottomLeft",
+ "GearManagerDialogBottomRight",
+ "GearManagerDialogClose",
+ "GearManagerDialogDeleteSet",
+ "GearManagerDialogDeleteSetText",
+ "GearManagerDialogDeleteSet_OnClick",
+ "GearManagerDialogDialogBG",
+ "GearManagerDialogEquipSet",
+ "GearManagerDialogEquipSetText",
+ "GearManagerDialogEquipSet_OnClick",
+ "GearManagerDialogLeft",
+ "GearManagerDialogPopup",
+ "GearManagerDialogPopupButton1",
+ "GearManagerDialogPopupButton10",
+ "GearManagerDialogPopupButton10Icon",
+ "GearManagerDialogPopupButton10Name",
+ "GearManagerDialogPopupButton11",
+ "GearManagerDialogPopupButton11Icon",
+ "GearManagerDialogPopupButton11Name",
+ "GearManagerDialogPopupButton12",
+ "GearManagerDialogPopupButton12Icon",
+ "GearManagerDialogPopupButton12Name",
+ "GearManagerDialogPopupButton13",
+ "GearManagerDialogPopupButton13Icon",
+ "GearManagerDialogPopupButton13Name",
+ "GearManagerDialogPopupButton14",
+ "GearManagerDialogPopupButton14Icon",
+ "GearManagerDialogPopupButton14Name",
+ "GearManagerDialogPopupButton15",
+ "GearManagerDialogPopupButton15Icon",
+ "GearManagerDialogPopupButton15Name",
+ "GearManagerDialogPopupButton1Icon",
+ "GearManagerDialogPopupButton1Name",
+ "GearManagerDialogPopupButton2",
+ "GearManagerDialogPopupButton2Icon",
+ "GearManagerDialogPopupButton2Name",
+ "GearManagerDialogPopupButton3",
+ "GearManagerDialogPopupButton3Icon",
+ "GearManagerDialogPopupButton3Name",
+ "GearManagerDialogPopupButton4",
+ "GearManagerDialogPopupButton4Icon",
+ "GearManagerDialogPopupButton4Name",
+ "GearManagerDialogPopupButton5",
+ "GearManagerDialogPopupButton5Icon",
+ "GearManagerDialogPopupButton5Name",
+ "GearManagerDialogPopupButton6",
+ "GearManagerDialogPopupButton6Icon",
+ "GearManagerDialogPopupButton6Name",
+ "GearManagerDialogPopupButton7",
+ "GearManagerDialogPopupButton7Icon",
+ "GearManagerDialogPopupButton7Name",
+ "GearManagerDialogPopupButton8",
+ "GearManagerDialogPopupButton8Icon",
+ "GearManagerDialogPopupButton8Name",
+ "GearManagerDialogPopupButton9",
+ "GearManagerDialogPopupButton9Icon",
+ "GearManagerDialogPopupButton9Name",
+ "GearManagerDialogPopupCancel",
+ "GearManagerDialogPopupCancelText",
+ "GearManagerDialogPopupCancel_OnClick",
+ "GearManagerDialogPopupEditBox",
+ "GearManagerDialogPopupEditBoxLeft",
+ "GearManagerDialogPopupEditBoxMiddle",
+ "GearManagerDialogPopupEditBoxRight",
+ "GearManagerDialogPopupOkay",
+ "GearManagerDialogPopupOkayText",
+ "GearManagerDialogPopupOkay_OnClick",
+ "GearManagerDialogPopupOkay_Update",
+ "GearManagerDialogPopupScrollFrame",
+ "GearManagerDialogPopupScrollFrameScrollBar",
+ "GearManagerDialogPopupScrollFrameScrollBarScrollDownButton",
+ "GearManagerDialogPopupScrollFrameScrollBarScrollUpButton",
+ "GearManagerDialogPopupScrollFrameScrollBarThumbTexture",
+ "GearManagerDialogPopupScrollFrameScrollChildFrame",
+ "GearManagerDialogPopup_OnHide",
+ "GearManagerDialogPopup_OnLoad",
+ "GearManagerDialogPopup_OnShow",
+ "GearManagerDialogPopup_Update",
+ "GearManagerDialogRight",
+ "GearManagerDialogSaveSet",
+ "GearManagerDialogSaveSetText",
+ "GearManagerDialogSaveSet_OnClick",
+ "GearManagerDialogTitleBG",
+ "GearManagerDialogTop",
+ "GearManagerDialogTopLeft",
+ "GearManagerDialogTopRight",
+ "GearManagerDialog_OnEvent",
+ "GearManagerDialog_OnHide",
+ "GearManagerDialog_OnLoad",
+ "GearManagerDialog_OnShow",
+ "GearManagerDialog_Update",
+ "GearManagerToggleButton",
+ "GearSetButton1",
+ "GearSetButton10",
+ "GearSetButton10Icon",
+ "GearSetButton10Name",
+ "GearSetButton1Icon",
+ "GearSetButton1Name",
+ "GearSetButton2",
+ "GearSetButton2Icon",
+ "GearSetButton2Name",
+ "GearSetButton3",
+ "GearSetButton3Icon",
+ "GearSetButton3Name",
+ "GearSetButton4",
+ "GearSetButton4Icon",
+ "GearSetButton4Name",
+ "GearSetButton5",
+ "GearSetButton5Icon",
+ "GearSetButton5Name",
+ "GearSetButton6",
+ "GearSetButton6Icon",
+ "GearSetButton6Name",
+ "GearSetButton7",
+ "GearSetButton7Icon",
+ "GearSetButton7Name",
+ "GearSetButton8",
+ "GearSetButton8Icon",
+ "GearSetButton8Name",
+ "GearSetButton9",
+ "GearSetButton9Icon",
+ "GearSetButton9Name",
+ "GearSetButton_OnClick",
+ "GearSetButton_OnEnter",
+ "GearSetPopupButton_OnClick",
+ "GeneralDockManager",
+ "GeneralDockManagerInsertHighlight",
+ "GeneralDockManagerOverflowButton",
+ "GeneralDockManagerOverflowButtonList",
+ "GeneralDockManagerOverflowButtonListNumTabs",
+ "GeneralDockManagerScrollFrame",
+ "GeneralDockManagerScrollFrameChild",
+ "GetAbandonQuestItems",
+ "GetAbandonQuestName",
+ "GetAccountExpansionLevel",
+ "GetAchievementCategory",
+ "GetAchievementComparisonInfo",
+ "GetAchievementCriteriaInfo",
+ "GetAchievementInfo",
+ "GetAchievementInfoFromCriteria",
+ "GetAchievementLink",
+ "GetAchievementNumCriteria",
+ "GetAchievementNumRewards",
+ "GetAchievementReward",
+ "GetActionAutocast",
+ "GetActionBarPage",
+ "GetActionBarToggles",
+ "GetActionCooldown",
+ "GetActionCount",
+ "GetActionInfo",
+ "GetActionText",
+ "GetActionTexture",
+ "GetActiveLevel",
+ "GetActiveTalentGroup",
+ "GetActiveTitle",
+ "GetActiveVoiceChannel",
+ "GetAddOnCPUUsage",
+ "GetAddOnDependencies",
+ "GetAddOnInfo",
+ "GetAddOnMemoryUsage",
+ "GetAddOnMetadata",
+ "GetAdjustedSkillPoints",
+ "GetAllowLowLevelRaid",
+ "GetAreaSpiritHealerTime",
+ "GetArenaCurrency",
+ "GetArenaTeam",
+ "GetArenaTeamGdfInfo",
+ "GetArenaTeamRosterInfo",
+ "GetArenaTeamRosterSelection",
+ "GetArenaTeamRosterShowOffline",
+ "GetArmorPenetration",
+ "GetAttackPowerForStat",
+ "GetAuctionHouseDepositRate",
+ "GetAuctionInvTypes",
+ "GetAuctionItemClasses",
+ "GetAuctionItemInfo",
+ "GetAuctionItemLink",
+ "GetAuctionItemSubClasses",
+ "GetAuctionItemTimeLeft",
+ "GetAuctionSellItemInfo",
+ "GetAuctionSort",
+ "GetAutoCompletePresenceID",
+ "GetAutoCompleteResults",
+ "GetAvailableLevel",
+ "GetAvailableQuestInfo",
+ "GetAvailableRoles",
+ "GetAvailableTitle",
+ "GetBackgroundTexCoordsForRole",
+ "GetBackpackCurrencyInfo",
+ "GetBackpackFrame",
+ "GetBagName",
+ "GetBankSlotCost",
+ "GetBarberShopStyleInfo",
+ "GetBarberShopTotalCost",
+ "GetBaseMip",
+ "GetBattlefieldArenaFaction",
+ "GetBattlefieldEstimatedWaitTime",
+ "GetBattlefieldFlagPosition",
+ "GetBattlefieldInfo",
+ "GetBattlefieldInstanceExpiration",
+ "GetBattlefieldInstanceInfo",
+ "GetBattlefieldInstanceRunTime",
+ "GetBattlefieldMapIconScale",
+ "GetBattlefieldPortExpiration",
+ "GetBattlefieldPosition",
+ "GetBattlefieldScore",
+ "GetBattlefieldStatData",
+ "GetBattlefieldStatInfo",
+ "GetBattlefieldStatus",
+ "GetBattlefieldTeamInfo",
+ "GetBattlefieldTimeWaited",
+ "GetBattlefieldVehicleInfo",
+ "GetBattlefieldWinner",
+ "GetBattlegroundInfo",
+ "GetBidderAuctionItems",
+ "GetBillingTimeRested",
+ "GetBindLocation",
+ "GetBinding",
+ "GetBindingAction",
+ "GetBindingByKey",
+ "GetBindingFromClick",
+ "GetBindingKey",
+ "GetBindingText",
+ "GetBlockChance",
+ "GetBonusBarOffset",
+ "GetBuildInfo",
+ "GetBuybackItemInfo",
+ "GetBuybackItemLink",
+ "GetCVar",
+ "GetCVarAbsoluteMax",
+ "GetCVarAbsoluteMin",
+ "GetCVarBool",
+ "GetCVarDefault",
+ "GetCVarInfo",
+ "GetCVarMax",
+ "GetCVarMin",
+ "GetCategoryInfo",
+ "GetCategoryList",
+ "GetCategoryNumAchievements",
+ "GetChannelDisplayInfo",
+ "GetChannelList",
+ "GetChannelName",
+ "GetChannelRosterInfo",
+ "GetChatTypeIndex",
+ "GetChatUnitColor",
+ "GetChatWindowChannels",
+ "GetChatWindowInfo",
+ "GetChatWindowMessages",
+ "GetChatWindowSavedDimensions",
+ "GetChatWindowSavedPosition",
+ "GetClickFrame",
+ "GetCoinIcon",
+ "GetCoinText",
+ "GetCoinTextureString",
+ "GetColoredName",
+ "GetCombatRating",
+ "GetCombatRatingBonus",
+ "GetComboPoints",
+ "GetCompanionCooldown",
+ "GetCompanionInfo",
+ "GetComparisonAchievementPoints",
+ "GetComparisonCategoryNumAchievements",
+ "GetComparisonStatistic",
+ "GetContainerFreeSlots",
+ "GetContainerItemCooldown",
+ "GetContainerItemDurability",
+ "GetContainerItemGems",
+ "GetContainerItemID",
+ "GetContainerItemInfo",
+ "GetContainerItemLink",
+ "GetContainerItemPurchaseInfo",
+ "GetContainerItemPurchaseItem",
+ "GetContainerItemQuestInfo",
+ "GetContainerNumFreeSlots",
+ "GetContainerNumSlots",
+ "GetCorpseMapPosition",
+ "GetCorpseRecoveryDelay",
+ "GetCritChance",
+ "GetCritChanceFromAgility",
+ "GetCurrencyListInfo",
+ "GetCurrencyListSize",
+ "GetCurrentArenaSeason",
+ "GetCurrentBindingSet",
+ "GetCurrentGuildBankTab",
+ "GetCurrentKeyBoardFocus",
+ "GetCurrentMapAreaID",
+ "GetCurrentMapContinent",
+ "GetCurrentMapDungeonLevel",
+ "GetCurrentMapZone",
+ "GetCurrentMultisampleFormat",
+ "GetCurrentResolution",
+ "GetCurrentTitle",
+ "GetCursorInfo",
+ "GetCursorMoney",
+ "GetCursorPosition",
+ "GetDailyQuestsCompleted",
+ "GetDamageBonusStat",
+ "GetDeathReleasePosition",
+ "GetDebugStats",
+ "GetDebugZoneMap",
+ "GetDefaultLanguage",
+ "GetDenominationsFromCopper",
+ "GetDodgeBlockParryChanceFromDefense",
+ "GetDodgeChance",
+ "GetDungeonDifficulty",
+ "GetDungeonNameWithDifficulty",
+ "GetEquipmentSetIconInfo",
+ "GetEquipmentSetInfo",
+ "GetEquipmentSetInfoByName",
+ "GetEquipmentSetItemIDs",
+ "GetEquipmentSetLocations",
+ "GetEventCPUUsage",
+ "GetExistingLocales",
+ "GetExistingSocketInfo",
+ "GetExistingSocketLink",
+ "GetExpansionLevel",
+ "GetExpertise",
+ "GetExpertisePercent",
+ "GetExtendedItemInfo",
+ "GetFacialHairCustomization",
+ "GetFactionInfo",
+ "GetFactionInfoByID",
+ "GetFarclip",
+ "GetFirstTradeSkill",
+ "GetFixedLink",
+ "GetFrameCPUUsage",
+ "GetFrameHandle",
+ "GetFrameHandleFrame",
+ "GetFramerate",
+ "GetFramesRegisteredForEvent",
+ "GetFriendInfo",
+ "GetFullRaidList",
+ "GetFunctionCPUUsage",
+ "GetGMStatus",
+ "GetGMTicket",
+ "GetGMTicketCategories",
+ "GetGameTime",
+ "GetGamma",
+ "GetGlyphLink",
+ "GetGlyphSocketInfo",
+ "GetGossipActiveQuests",
+ "GetGossipAvailableQuests",
+ "GetGossipOptions",
+ "GetGossipText",
+ "GetGreetingText",
+ "GetGroupPreviewTalentPointsSpent",
+ "GetGuildBankItemInfo",
+ "GetGuildBankItemLink",
+ "GetGuildBankMoney",
+ "GetGuildBankMoneyTransaction",
+ "GetGuildBankTabCost",
+ "GetGuildBankTabInfo",
+ "GetGuildBankTabPermissions",
+ "GetGuildBankText",
+ "GetGuildBankTransaction",
+ "GetGuildBankWithdrawLimit",
+ "GetGuildBankWithdrawMoney",
+ "GetGuildCharterCost",
+ "GetGuildEventInfo",
+ "GetGuildInfo",
+ "GetGuildInfoText",
+ "GetGuildRosterInfo",
+ "GetGuildRosterLastOnline",
+ "GetGuildRosterMOTD",
+ "GetGuildRosterSelection",
+ "GetGuildRosterShowOffline",
+ "GetGuildTabardFileNames",
+ "GetHairCustomization",
+ "GetHolidayBGHonorCurrencyBonuses",
+ "GetHonorCurrency",
+ "GetIgnoreName",
+ "GetInboxHeaderInfo",
+ "GetInboxInvoiceInfo",
+ "GetInboxItem",
+ "GetInboxItemLink",
+ "GetInboxNumItems",
+ "GetInboxText",
+ "GetInspectArenaTeamData",
+ "GetInspectHonorData",
+ "GetInstanceBootTimeRemaining",
+ "GetInstanceDifficulty",
+ "GetInstanceInfo",
+ "GetInstanceLockTimeRemaining",
+ "GetInstanceLockTimeRemainingEncounter",
+ "GetInventoryAlertStatus",
+ "GetInventoryItemBroken",
+ "GetInventoryItemCooldown",
+ "GetInventoryItemCount",
+ "GetInventoryItemDurability",
+ "GetInventoryItemGems",
+ "GetInventoryItemID",
+ "GetInventoryItemLink",
+ "GetInventoryItemQuality",
+ "GetInventoryItemTexture",
+ "GetInventoryItemsForSlot",
+ "GetInventorySlotInfo",
+ "GetItemCooldown",
+ "GetItemCount",
+ "GetItemFamily",
+ "GetItemGem",
+ "GetItemIcon",
+ "GetItemInfo",
+ "GetItemQualityColor",
+ "GetItemSpell",
+ "GetItemStatDelta",
+ "GetItemStats",
+ "GetItemUniqueness",
+ "GetKeyRingSize",
+ "GetKnownSlotFromHighestRankSlot",
+ "GetLFDChoiceCollapseState",
+ "GetLFDChoiceEnabledState",
+ "GetLFDChoiceInfo",
+ "GetLFDChoiceLockedState",
+ "GetLFDChoiceOrder",
+ "GetLFDLockInfo",
+ "GetLFDLockPlayerCount",
+ "GetLFGBootProposal",
+ "GetLFGCompletionReward",
+ "GetLFGCompletionRewardItem",
+ "GetLFGDeserterExpiration",
+ "GetLFGDungeonInfo",
+ "GetLFGDungeonRewardInfo",
+ "GetLFGDungeonRewardLink",
+ "GetLFGDungeonRewards",
+ "GetLFGInfoLocal",
+ "GetLFGInfoServer",
+ "GetLFGMode",
+ "GetLFGProposal",
+ "GetLFGProposalEncounter",
+ "GetLFGProposalMember",
+ "GetLFGQueueStats",
+ "GetLFGQueuedList",
+ "GetLFGRandomCooldownExpiration",
+ "GetLFGRandomDungeonInfo",
+ "GetLFGRoleUpdate",
+ "GetLFGRoleUpdateMember",
+ "GetLFGRoleUpdateSlot",
+ "GetLFGRoles",
+ "GetLFGTypes",
+ "GetLFRChoiceOrder",
+ "GetLanguageByIndex",
+ "GetLastQueueStatusIndex",
+ "GetLatestCompletedAchievements",
+ "GetLatestCompletedComparisonAchievements",
+ "GetLatestThreeSenders",
+ "GetLatestUpdatedComparisonStats",
+ "GetLatestUpdatedStats",
+ "GetLocale",
+ "GetLootMethod",
+ "GetLootRollItemInfo",
+ "GetLootRollItemLink",
+ "GetLootRollTimeLeft",
+ "GetLootSlotInfo",
+ "GetLootSlotLink",
+ "GetLootThreshold",
+ "GetMacroBody",
+ "GetMacroIconInfo",
+ "GetMacroIndexByName",
+ "GetMacroInfo",
+ "GetMacroItem",
+ "GetMacroItemIconInfo",
+ "GetMacroSpell",
+ "GetManaRegen",
+ "GetManagedEnvironment",
+ "GetMapContinents",
+ "GetMapDebugObjectInfo",
+ "GetMapInfo",
+ "GetMapLandmarkInfo",
+ "GetMapOverlayInfo",
+ "GetMapZones",
+ "GetMasterLootCandidate",
+ "GetMaterialTextColors",
+ "GetMaxArenaCurrency",
+ "GetMaxCombatRatingBonus",
+ "GetMaxDailyQuests",
+ "GetMaxUIPanelsWidth",
+ "GetMerchantItemCostInfo",
+ "GetMerchantItemCostItem",
+ "GetMerchantItemInfo",
+ "GetMerchantItemLink",
+ "GetMerchantItemMaxStack",
+ "GetMerchantNumItems",
+ "GetMessageTypeColor",
+ "GetMessageTypeState",
+ "GetMinigameState",
+ "GetMinigameType",
+ "GetMinimapZoneText",
+ "GetMirrorTimerInfo",
+ "GetMirrorTimerProgress",
+ "GetModifiedClick",
+ "GetModifiedClickAction",
+ "GetMoney",
+ "GetMoneyString",
+ "GetMouseButtonClicked",
+ "GetMouseButtonName",
+ "GetMouseFocus",
+ "GetMovieResolution",
+ "GetMultiCastBarOffset",
+ "GetMultiCastTotemSpells",
+ "GetMultisampleFormats",
+ "GetMuteName",
+ "GetMuteStatus",
+ "GetNetStats",
+ "GetNewSocketInfo",
+ "GetNewSocketLink",
+ "GetNextAchievement",
+ "GetNextCompleatedTutorial",
+ "GetNextStableSlotCost",
+ "GetNumActiveQuests",
+ "GetNumAddOns",
+ "GetNumArenaOpponents",
+ "GetNumArenaTeamMembers",
+ "GetNumAuctionItems",
+ "GetNumAvailableQuests",
+ "GetNumBankSlots",
+ "GetNumBattlefieldFlagPositions",
+ "GetNumBattlefieldPositions",
+ "GetNumBattlefieldScores",
+ "GetNumBattlefieldStats",
+ "GetNumBattlefieldVehicles",
+ "GetNumBattlefields",
+ "GetNumBattlegroundTypes",
+ "GetNumBindings",
+ "GetNumBuybackItems",
+ "GetNumChannelMembers",
+ "GetNumCompanions",
+ "GetNumComparisonCompletedAchievements",
+ "GetNumCompletedAchievements",
+ "GetNumDeclensionSets",
+ "GetNumDisplayChannels",
+ "GetNumDungeonMapLevels",
+ "GetNumEquipmentSets",
+ "GetNumFactions",
+ "GetNumFrames",
+ "GetNumFriends",
+ "GetNumGlyphSockets",
+ "GetNumGossipActiveQuests",
+ "GetNumGossipAvailableQuests",
+ "GetNumGossipOptions",
+ "GetNumGroupMembers",
+ "GetNumGuildBankMoneyTransactions",
+ "GetNumGuildBankTabs",
+ "GetNumGuildBankTransactions",
+ "GetNumGuildEvents",
+ "GetNumGuildMembers",
+ "GetNumIgnores",
+ "GetNumLanguages",
+ "GetNumLootItems",
+ "GetNumMacroIcons",
+ "GetNumMacroItemIcons",
+ "GetNumMacros",
+ "GetNumMapDebugObjects",
+ "GetNumMapLandmarks",
+ "GetNumMapOverlays",
+ "GetNumModifiedClickActions",
+ "GetNumMutes",
+ "GetNumPackages",
+ "GetNumPartyMembers",
+ "GetNumPetitionItems",
+ "GetNumPetitionNames",
+ "GetNumQuestChoices",
+ "GetNumQuestItemDrops",
+ "GetNumQuestItems",
+ "GetNumQuestLeaderBoards",
+ "GetNumQuestLogChoices",
+ "GetNumQuestLogEntries",
+ "GetNumQuestLogRewardFactions",
+ "GetNumQuestLogRewards",
+ "GetNumQuestRewards",
+ "GetNumQuestWatches",
+ "GetNumRaidMembers",
+ "GetNumRandomDungeons",
+ "GetNumRoutes",
+ "GetNumSavedInstances",
+ "GetNumShapeshiftForms",
+ "GetNumSkillLines",
+ "GetNumSockets",
+ "GetNumSpellTabs",
+ "GetNumStablePets",
+ "GetNumStableSlots",
+ "GetNumStationeries",
+ "GetNumSubgroupMembers",
+ "GetNumTalentGroups",
+ "GetNumTalentTabs",
+ "GetNumTalents",
+ "GetNumTitles",
+ "GetNumTrackedAchievements",
+ "GetNumTrackingTypes",
+ "GetNumTradeSkills",
+ "GetNumTrainerServices",
+ "GetNumVoiceSessionMembersBySessionID",
+ "GetNumVoiceSessions",
+ "GetNumWatchedTokens",
+ "GetNumWhoResults",
+ "GetNumWorldStateUI",
+ "GetObjectiveText",
+ "GetOptOutOfLoot",
+ "GetOwnerAuctionItems",
+ "GetPVPDesired",
+ "GetPVPLifetimeStats",
+ "GetPVPRankInfo",
+ "GetPVPRankProgress",
+ "GetPVPSessionStats",
+ "GetPVPTimer",
+ "GetPVPYesterdayStats",
+ "GetPackageInfo",
+ "GetParryChance",
+ "GetPartyAssignment",
+ "GetPartyLFGBackfillInfo",
+ "GetPartyLeaderIndex",
+ "GetPartyMember",
+ "GetPetActionCooldown",
+ "GetPetActionInfo",
+ "GetPetActionSlotUsable",
+ "GetPetActionsUsable",
+ "GetPetExperience",
+ "GetPetFoodTypes",
+ "GetPetHappiness",
+ "GetPetIcon",
+ "GetPetSpellBonusDamage",
+ "GetPetTalentTree",
+ "GetPetTimeRemaining",
+ "GetPetitionInfo",
+ "GetPetitionItemInfo",
+ "GetPetitionNameInfo",
+ "GetPlayerFacing",
+ "GetPlayerInfoByGUID",
+ "GetPlayerMapPosition",
+ "GetPlayerTradeMoney",
+ "GetPossessInfo",
+ "GetPowerRegen",
+ "GetPrevCompleatedTutorial",
+ "GetPreviewTalentPointsSpent",
+ "GetPreviousAchievement",
+ "GetPreviousArenaSeason",
+ "GetProgressText",
+ "GetQuestBackgroundMaterial",
+ "GetQuestDifficultyColor",
+ "GetQuestGreenRange",
+ "GetQuestIndexForTimer",
+ "GetQuestIndexForWatch",
+ "GetQuestItemInfo",
+ "GetQuestItemLink",
+ "GetQuestLink",
+ "GetQuestLogChoiceInfo",
+ "GetQuestLogCompletionText",
+ "GetQuestLogGroupNum",
+ "GetQuestLogItemDrop",
+ "GetQuestLogItemLink",
+ "GetQuestLogLeaderBoard",
+ "GetQuestLogPushable",
+ "GetQuestLogQuestText",
+ "GetQuestLogRequiredMoney",
+ "GetQuestLogRewardArenaPoints",
+ "GetQuestLogRewardFactionInfo",
+ "GetQuestLogRewardHonor",
+ "GetQuestLogRewardInfo",
+ "GetQuestLogRewardMoney",
+ "GetQuestLogRewardSpell",
+ "GetQuestLogRewardTalents",
+ "GetQuestLogRewardTitle",
+ "GetQuestLogRewardXP",
+ "GetQuestLogSelection",
+ "GetQuestLogSpecialItemCooldown",
+ "GetQuestLogSpecialItemInfo",
+ "GetQuestLogSpellLink",
+ "GetQuestLogTimeLeft",
+ "GetQuestLogTitle",
+ "GetQuestMoneyToGet",
+ "GetQuestPOILeaderBoard",
+ "GetQuestResetTime",
+ "GetQuestReward",
+ "GetQuestSortIndex",
+ "GetQuestSpellLink",
+ "GetQuestText",
+ "GetQuestTimers",
+ "GetQuestWatchIndex",
+ "GetQuestWorldMapAreaID",
+ "GetQuestsCompleted",
+ "GetRaidDifficultyID",
+ "GetRaidRosterInfo",
+ "GetRaidRosterSelection",
+ "GetRaidTargetIndex",
+ "GetRandomArgument",
+ "GetRandomBGHonorCurrencyBonuses",
+ "GetRandomDungeonBestChoice",
+ "GetRangedCritChance",
+ "GetReadonlyRestrictedTable",
+ "GetReadyCheckStatus",
+ "GetReadyCheckTimeLeft",
+ "GetRealNumPartyMembers",
+ "GetRealNumRaidMembers",
+ "GetRealZoneText",
+ "GetRealmName",
+ "GetRefreshRates",
+ "GetReleaseTimeRemaining",
+ "GetRepairAllCost",
+ "GetResSicknessDuration",
+ "GetRestState",
+ "GetRewardArenaPoints",
+ "GetRewardHonor",
+ "GetRewardMoney",
+ "GetRewardSpell",
+ "GetRewardTalents",
+ "GetRewardText",
+ "GetRewardTitle",
+ "GetRewardXP",
+ "GetRuneCooldown",
+ "GetRuneCount",
+ "GetRuneType",
+ "GetRunningMacro",
+ "GetRunningMacroButton",
+ "GetSavedInstanceInfo",
+ "GetScreenHeight",
+ "GetScreenHeightScale",
+ "GetScreenResolutions",
+ "GetScreenWidth",
+ "GetScreenWidthScale",
+ "GetScriptCPUUsage",
+ "GetSelectedAuctionItem",
+ "GetSelectedBattlefield",
+ "GetSelectedDisplayChannel",
+ "GetSelectedFaction",
+ "GetSelectedFriend",
+ "GetSelectedIgnore",
+ "GetSelectedMute",
+ "GetSelectedSkill",
+ "GetSelectedStablePet",
+ "GetSelectedStationeryTexture",
+ "GetSendMailCOD",
+ "GetSendMailItem",
+ "GetSendMailItemLink",
+ "GetSendMailMoney",
+ "GetSendMailPrice",
+ "GetShapeshiftForm",
+ "GetShapeshiftFormCooldown",
+ "GetShapeshiftFormInfo",
+ "GetShieldBlock",
+ "GetSkillLineInfo",
+ "GetSocketItemBoundTradeable",
+ "GetSocketItemInfo",
+ "GetSocketItemRefundable",
+ "GetSocketTypes",
+ "GetSpellAutocast",
+ "GetSpellBonusDamage",
+ "GetSpellBonusHealing",
+ "GetSpellCooldown",
+ "GetSpellCount",
+ "GetSpellCritChance",
+ "GetSpellCritChanceFromIntellect",
+ "GetSpellInfo",
+ "GetSpellLink",
+ "GetSpellName",
+ "GetSpellNameColor",
+ "GetSpellPenetration",
+ "GetSpellTabInfo",
+ "GetSpellTexture",
+ "GetStablePetFoodTypes",
+ "GetStablePetInfo",
+ "GetStationeryInfo",
+ "GetStatistic",
+ "GetStatisticsCategoryList",
+ "GetSubZoneText",
+ "GetSuggestedGroupNum",
+ "GetSummonConfirmAreaName",
+ "GetSummonConfirmSummoner",
+ "GetSummonConfirmTimeLeft",
+ "GetSummonFriendCooldown",
+ "GetTabardCreationCost",
+ "GetTabardInfo",
+ "GetTableColor",
+ "GetTalentInfo",
+ "GetTalentLink",
+ "GetTalentPrereqs",
+ "GetTalentTabInfo",
+ "GetTargetTradeMoney",
+ "GetTaxiBenchmarkMode",
+ "GetTerrainMip",
+ "GetTexCoordsByGrid",
+ "GetTexCoordsForRole",
+ "GetTexLodBias",
+ "GetText",
+ "GetThreatStatusColor",
+ "GetTime",
+ "GetTimeToWellRested",
+ "GetTimerTextColor",
+ "GetTitleName",
+ "GetTitleText",
+ "GetTotalAchievementPoints",
+ "GetTotemInfo",
+ "GetTotemTimeLeft",
+ "GetTrackedAchievements",
+ "GetTrackingInfo",
+ "GetTrackingTexture",
+ "GetTradePlayerItemInfo",
+ "GetTradePlayerItemLink",
+ "GetTradeSkillCooldown",
+ "GetTradeSkillDescription",
+ "GetTradeSkillIcon",
+ "GetTradeSkillInfo",
+ "GetTradeSkillInvSlotFilter",
+ "GetTradeSkillInvSlots",
+ "GetTradeSkillItemLevelFilter",
+ "GetTradeSkillItemLink",
+ "GetTradeSkillItemNameFilter",
+ "GetTradeSkillLine",
+ "GetTradeSkillListLink",
+ "GetTradeSkillNumMade",
+ "GetTradeSkillNumReagents",
+ "GetTradeSkillReagentInfo",
+ "GetTradeSkillReagentItemLink",
+ "GetTradeSkillRecipeLink",
+ "GetTradeSkillSelectionIndex",
+ "GetTradeSkillSubClassFilter",
+ "GetTradeSkillSubClasses",
+ "GetTradeSkillTools",
+ "GetTradeTargetItemInfo",
+ "GetTradeTargetItemLink",
+ "GetTradeskillRepeatCount",
+ "GetTrainerGreetingText",
+ "GetTrainerSelectionIndex",
+ "GetTrainerServiceAbilityReq",
+ "GetTrainerServiceCost",
+ "GetTrainerServiceDescription",
+ "GetTrainerServiceIcon",
+ "GetTrainerServiceInfo",
+ "GetTrainerServiceItemLink",
+ "GetTrainerServiceLevelReq",
+ "GetTrainerServiceNumAbilityReq",
+ "GetTrainerServiceSkillLine",
+ "GetTrainerServiceSkillReq",
+ "GetTrainerServiceStepIncrease",
+ "GetTrainerServiceStepReq",
+ "GetTrainerServiceTypeFilter",
+ "GetTrainerSkillLineFilter",
+ "GetTrainerSkillLines",
+ "GetUIPanel",
+ "GetUIPanelWidth",
+ "GetUnitHealthModifier",
+ "GetUnitHealthRegenRateFromSpirit",
+ "GetUnitManaRegenRateFromSpirit",
+ "GetUnitMaxHealthModifier",
+ "GetUnitName",
+ "GetUnitPitch",
+ "GetUnitPowerModifier",
+ "GetUnitSpeed",
+ "GetUnspentTalentPoints",
+ "GetVehicleUIIndicator",
+ "GetVehicleUIIndicatorSeat",
+ "GetVideoCaps",
+ "GetVoiceCurrentSessionID",
+ "GetVoiceSessionInfo",
+ "GetVoiceSessionMemberInfoBySessionID",
+ "GetVoiceStatus",
+ "GetWatchedFactionInfo",
+ "GetWaterDetail",
+ "GetWeaponEnchantInfo",
+ "GetWhoInfo",
+ "GetWintergraspWaitTime",
+ "GetWorldPVPQueueStatus",
+ "GetWorldStateUIInfo",
+ "GetXPExhaustion",
+ "GetZonePVPInfo",
+ "GetZoneText",
+ "GiveMasterLoot",
+ "GlobalCollectorDB",
+ "GlyphFrame",
+ "GlyphFrameBackground",
+ "GlyphFrameGlow",
+ "GlyphFrameGlowPulse",
+ "GlyphFrameGlowPulseIn",
+ "GlyphFrameGlowPulseOut",
+ "GlyphFrameGlyph1",
+ "GlyphFrameGlyph1Background",
+ "GlyphFrameGlyph1Glyph",
+ "GlyphFrameGlyph1Highlight",
+ "GlyphFrameGlyph1Ring",
+ "GlyphFrameGlyph1Setting",
+ "GlyphFrameGlyph1Shine",
+ "GlyphFrameGlyph2",
+ "GlyphFrameGlyph2Background",
+ "GlyphFrameGlyph2Glyph",
+ "GlyphFrameGlyph2Highlight",
+ "GlyphFrameGlyph2Ring",
+ "GlyphFrameGlyph2Setting",
+ "GlyphFrameGlyph2Shine",
+ "GlyphFrameGlyph3",
+ "GlyphFrameGlyph3Background",
+ "GlyphFrameGlyph3Glyph",
+ "GlyphFrameGlyph3Highlight",
+ "GlyphFrameGlyph3Ring",
+ "GlyphFrameGlyph3Setting",
+ "GlyphFrameGlyph3Shine",
+ "GlyphFrameGlyph4",
+ "GlyphFrameGlyph4Background",
+ "GlyphFrameGlyph4Glyph",
+ "GlyphFrameGlyph4Highlight",
+ "GlyphFrameGlyph4Ring",
+ "GlyphFrameGlyph4Setting",
+ "GlyphFrameGlyph4Shine",
+ "GlyphFrameGlyph5",
+ "GlyphFrameGlyph5Background",
+ "GlyphFrameGlyph5Glyph",
+ "GlyphFrameGlyph5Highlight",
+ "GlyphFrameGlyph5Ring",
+ "GlyphFrameGlyph5Setting",
+ "GlyphFrameGlyph5Shine",
+ "GlyphFrameGlyph6",
+ "GlyphFrameGlyph6Background",
+ "GlyphFrameGlyph6Glyph",
+ "GlyphFrameGlyph6Highlight",
+ "GlyphFrameGlyph6Ring",
+ "GlyphFrameGlyph6Setting",
+ "GlyphFrameGlyph6Shine",
+ "GlyphFrameGlyph_OnClick",
+ "GlyphFrameGlyph_OnEnter",
+ "GlyphFrameGlyph_OnLeave",
+ "GlyphFrameGlyph_OnLoad",
+ "GlyphFrameGlyph_OnUpdate",
+ "GlyphFrameGlyph_SetGlyphType",
+ "GlyphFrameGlyph_UpdateSlot",
+ "GlyphFrameSparkleFrame",
+ "GlyphFrameTitleText",
+ "GlyphFrame_LoadUI",
+ "GlyphFrame_OnEnter",
+ "GlyphFrame_OnEvent",
+ "GlyphFrame_OnLeave",
+ "GlyphFrame_OnLoad",
+ "GlyphFrame_OnShow",
+ "GlyphFrame_OnUpdate",
+ "GlyphFrame_Open",
+ "GlyphFrame_PulseGlow",
+ "GlyphFrame_StartSlotAnimation",
+ "GlyphFrame_StopSlotAnimation",
+ "GlyphFrame_Toggle",
+ "GlyphFrame_Update",
+ "GlyphMatchesSocket",
+ "GossipFrame",
+ "GossipFrameActiveQuestsUpdate",
+ "GossipFrameAvailableQuestsUpdate",
+ "GossipFrameCloseButton",
+ "GossipFrameGreetingGoodbyeButton",
+ "GossipFrameGreetingGoodbyeButtonText",
+ "GossipFrameGreetingPanel",
+ "GossipFrameGreetingPanelMaterialBotLeft",
+ "GossipFrameGreetingPanelMaterialBotRight",
+ "GossipFrameGreetingPanelMaterialTopLeft",
+ "GossipFrameGreetingPanelMaterialTopRight",
+ "GossipFrameNpcNameText",
+ "GossipFrameOptionsUpdate",
+ "GossipFramePortrait",
+ "GossipFrameUpdate",
+ "GossipFrame_OnEvent",
+ "GossipFrame_OnLoad",
+ "GossipGreetingScrollChildFrame",
+ "GossipGreetingScrollFrame",
+ "GossipGreetingScrollFrameScrollBar",
+ "GossipGreetingScrollFrameScrollBarScrollDownButton",
+ "GossipGreetingScrollFrameScrollBarScrollUpButton",
+ "GossipGreetingScrollFrameScrollBarThumbTexture",
+ "GossipGreetingText",
+ "GossipNpcNameFrame",
+ "GossipResize",
+ "GossipSpacerFrame",
+ "GossipTitleButton1",
+ "GossipTitleButton10",
+ "GossipTitleButton10GossipIcon",
+ "GossipTitleButton11",
+ "GossipTitleButton11GossipIcon",
+ "GossipTitleButton12",
+ "GossipTitleButton12GossipIcon",
+ "GossipTitleButton13",
+ "GossipTitleButton13GossipIcon",
+ "GossipTitleButton14",
+ "GossipTitleButton14GossipIcon",
+ "GossipTitleButton15",
+ "GossipTitleButton15GossipIcon",
+ "GossipTitleButton16",
+ "GossipTitleButton16GossipIcon",
+ "GossipTitleButton17",
+ "GossipTitleButton17GossipIcon",
+ "GossipTitleButton18",
+ "GossipTitleButton18GossipIcon",
+ "GossipTitleButton19",
+ "GossipTitleButton19GossipIcon",
+ "GossipTitleButton1GossipIcon",
+ "GossipTitleButton2",
+ "GossipTitleButton20",
+ "GossipTitleButton20GossipIcon",
+ "GossipTitleButton21",
+ "GossipTitleButton21GossipIcon",
+ "GossipTitleButton22",
+ "GossipTitleButton22GossipIcon",
+ "GossipTitleButton23",
+ "GossipTitleButton23GossipIcon",
+ "GossipTitleButton24",
+ "GossipTitleButton24GossipIcon",
+ "GossipTitleButton25",
+ "GossipTitleButton25GossipIcon",
+ "GossipTitleButton26",
+ "GossipTitleButton26GossipIcon",
+ "GossipTitleButton27",
+ "GossipTitleButton27GossipIcon",
+ "GossipTitleButton28",
+ "GossipTitleButton28GossipIcon",
+ "GossipTitleButton29",
+ "GossipTitleButton29GossipIcon",
+ "GossipTitleButton2GossipIcon",
+ "GossipTitleButton3",
+ "GossipTitleButton30",
+ "GossipTitleButton30GossipIcon",
+ "GossipTitleButton31",
+ "GossipTitleButton31GossipIcon",
+ "GossipTitleButton32",
+ "GossipTitleButton32GossipIcon",
+ "GossipTitleButton3GossipIcon",
+ "GossipTitleButton4",
+ "GossipTitleButton4GossipIcon",
+ "GossipTitleButton5",
+ "GossipTitleButton5GossipIcon",
+ "GossipTitleButton6",
+ "GossipTitleButton6GossipIcon",
+ "GossipTitleButton7",
+ "GossipTitleButton7GossipIcon",
+ "GossipTitleButton8",
+ "GossipTitleButton8GossipIcon",
+ "GossipTitleButton9",
+ "GossipTitleButton9GossipIcon",
+ "GossipTitleButton_OnClick",
+ "GrantLevel",
+ "GraphicsQualityLevels",
+ "GreetingText",
+ "GroupLootDropDown",
+ "GroupLootDropDownButton",
+ "GroupLootDropDownButtonDisabledTexture",
+ "GroupLootDropDownButtonHighlightTexture",
+ "GroupLootDropDownButtonNormalTexture",
+ "GroupLootDropDownButtonPushedTexture",
+ "GroupLootDropDownLeft",
+ "GroupLootDropDownMiddle",
+ "GroupLootDropDownRight",
+ "GroupLootDropDownText",
+ "GroupLootDropDown_GiveLoot",
+ "GroupLootDropDown_Initialize",
+ "GroupLootDropDown_OnLoad",
+ "GroupLootFrame1",
+ "GroupLootFrame1Corner",
+ "GroupLootFrame1Decoration",
+ "GroupLootFrame1DisenchantButton",
+ "GroupLootFrame1GreedButton",
+ "GroupLootFrame1IconFrame",
+ "GroupLootFrame1IconFrameCount",
+ "GroupLootFrame1IconFrameIcon",
+ "GroupLootFrame1Name",
+ "GroupLootFrame1NameFrame",
+ "GroupLootFrame1PassButton",
+ "GroupLootFrame1RollButton",
+ "GroupLootFrame1SlotTexture",
+ "GroupLootFrame1Timer",
+ "GroupLootFrame1TimerBar",
+ "GroupLootFrame2",
+ "GroupLootFrame2Corner",
+ "GroupLootFrame2Decoration",
+ "GroupLootFrame2DisenchantButton",
+ "GroupLootFrame2GreedButton",
+ "GroupLootFrame2IconFrame",
+ "GroupLootFrame2IconFrameCount",
+ "GroupLootFrame2IconFrameIcon",
+ "GroupLootFrame2Name",
+ "GroupLootFrame2NameFrame",
+ "GroupLootFrame2PassButton",
+ "GroupLootFrame2RollButton",
+ "GroupLootFrame2SlotTexture",
+ "GroupLootFrame2Timer",
+ "GroupLootFrame2TimerBar",
+ "GroupLootFrame3",
+ "GroupLootFrame3Corner",
+ "GroupLootFrame3Decoration",
+ "GroupLootFrame3DisenchantButton",
+ "GroupLootFrame3GreedButton",
+ "GroupLootFrame3IconFrame",
+ "GroupLootFrame3IconFrameCount",
+ "GroupLootFrame3IconFrameIcon",
+ "GroupLootFrame3Name",
+ "GroupLootFrame3NameFrame",
+ "GroupLootFrame3PassButton",
+ "GroupLootFrame3RollButton",
+ "GroupLootFrame3SlotTexture",
+ "GroupLootFrame3Timer",
+ "GroupLootFrame3TimerBar",
+ "GroupLootFrame4",
+ "GroupLootFrame4Corner",
+ "GroupLootFrame4Decoration",
+ "GroupLootFrame4DisenchantButton",
+ "GroupLootFrame4GreedButton",
+ "GroupLootFrame4IconFrame",
+ "GroupLootFrame4IconFrameCount",
+ "GroupLootFrame4IconFrameIcon",
+ "GroupLootFrame4Name",
+ "GroupLootFrame4NameFrame",
+ "GroupLootFrame4PassButton",
+ "GroupLootFrame4RollButton",
+ "GroupLootFrame4SlotTexture",
+ "GroupLootFrame4Timer",
+ "GroupLootFrame4TimerBar",
+ "GroupLootFrame_DisableLootButton",
+ "GroupLootFrame_EnableLootButton",
+ "GroupLootFrame_OnEvent",
+ "GroupLootFrame_OnHide",
+ "GroupLootFrame_OnShow",
+ "GroupLootFrame_OnUpdate",
+ "GroupLootFrame_OpenNewFrame",
+ "GuildBankColumn1",
+ "GuildBankColumn1Background",
+ "GuildBankColumn1Button1",
+ "GuildBankColumn1Button10",
+ "GuildBankColumn1Button10Cooldown",
+ "GuildBankColumn1Button10Count",
+ "GuildBankColumn1Button10IconTexture",
+ "GuildBankColumn1Button10NormalTexture",
+ "GuildBankColumn1Button10Stock",
+ "GuildBankColumn1Button11",
+ "GuildBankColumn1Button11Cooldown",
+ "GuildBankColumn1Button11Count",
+ "GuildBankColumn1Button11IconTexture",
+ "GuildBankColumn1Button11NormalTexture",
+ "GuildBankColumn1Button11Stock",
+ "GuildBankColumn1Button12",
+ "GuildBankColumn1Button12Cooldown",
+ "GuildBankColumn1Button12Count",
+ "GuildBankColumn1Button12IconTexture",
+ "GuildBankColumn1Button12NormalTexture",
+ "GuildBankColumn1Button12Stock",
+ "GuildBankColumn1Button13",
+ "GuildBankColumn1Button13Cooldown",
+ "GuildBankColumn1Button13Count",
+ "GuildBankColumn1Button13IconTexture",
+ "GuildBankColumn1Button13NormalTexture",
+ "GuildBankColumn1Button13Stock",
+ "GuildBankColumn1Button14",
+ "GuildBankColumn1Button14Cooldown",
+ "GuildBankColumn1Button14Count",
+ "GuildBankColumn1Button14IconTexture",
+ "GuildBankColumn1Button14NormalTexture",
+ "GuildBankColumn1Button14Stock",
+ "GuildBankColumn1Button1Cooldown",
+ "GuildBankColumn1Button1Count",
+ "GuildBankColumn1Button1IconTexture",
+ "GuildBankColumn1Button1NormalTexture",
+ "GuildBankColumn1Button1Stock",
+ "GuildBankColumn1Button2",
+ "GuildBankColumn1Button2Cooldown",
+ "GuildBankColumn1Button2Count",
+ "GuildBankColumn1Button2IconTexture",
+ "GuildBankColumn1Button2NormalTexture",
+ "GuildBankColumn1Button2Stock",
+ "GuildBankColumn1Button3",
+ "GuildBankColumn1Button3Cooldown",
+ "GuildBankColumn1Button3Count",
+ "GuildBankColumn1Button3IconTexture",
+ "GuildBankColumn1Button3NormalTexture",
+ "GuildBankColumn1Button3Stock",
+ "GuildBankColumn1Button4",
+ "GuildBankColumn1Button4Cooldown",
+ "GuildBankColumn1Button4Count",
+ "GuildBankColumn1Button4IconTexture",
+ "GuildBankColumn1Button4NormalTexture",
+ "GuildBankColumn1Button4Stock",
+ "GuildBankColumn1Button5",
+ "GuildBankColumn1Button5Cooldown",
+ "GuildBankColumn1Button5Count",
+ "GuildBankColumn1Button5IconTexture",
+ "GuildBankColumn1Button5NormalTexture",
+ "GuildBankColumn1Button5Stock",
+ "GuildBankColumn1Button6",
+ "GuildBankColumn1Button6Cooldown",
+ "GuildBankColumn1Button6Count",
+ "GuildBankColumn1Button6IconTexture",
+ "GuildBankColumn1Button6NormalTexture",
+ "GuildBankColumn1Button6Stock",
+ "GuildBankColumn1Button7",
+ "GuildBankColumn1Button7Cooldown",
+ "GuildBankColumn1Button7Count",
+ "GuildBankColumn1Button7IconTexture",
+ "GuildBankColumn1Button7NormalTexture",
+ "GuildBankColumn1Button7Stock",
+ "GuildBankColumn1Button8",
+ "GuildBankColumn1Button8Cooldown",
+ "GuildBankColumn1Button8Count",
+ "GuildBankColumn1Button8IconTexture",
+ "GuildBankColumn1Button8NormalTexture",
+ "GuildBankColumn1Button8Stock",
+ "GuildBankColumn1Button9",
+ "GuildBankColumn1Button9Cooldown",
+ "GuildBankColumn1Button9Count",
+ "GuildBankColumn1Button9IconTexture",
+ "GuildBankColumn1Button9NormalTexture",
+ "GuildBankColumn1Button9Stock",
+ "GuildBankColumn2",
+ "GuildBankColumn2Background",
+ "GuildBankColumn2Button1",
+ "GuildBankColumn2Button10",
+ "GuildBankColumn2Button10Cooldown",
+ "GuildBankColumn2Button10Count",
+ "GuildBankColumn2Button10IconTexture",
+ "GuildBankColumn2Button10NormalTexture",
+ "GuildBankColumn2Button10Stock",
+ "GuildBankColumn2Button11",
+ "GuildBankColumn2Button11Cooldown",
+ "GuildBankColumn2Button11Count",
+ "GuildBankColumn2Button11IconTexture",
+ "GuildBankColumn2Button11NormalTexture",
+ "GuildBankColumn2Button11Stock",
+ "GuildBankColumn2Button12",
+ "GuildBankColumn2Button12Cooldown",
+ "GuildBankColumn2Button12Count",
+ "GuildBankColumn2Button12IconTexture",
+ "GuildBankColumn2Button12NormalTexture",
+ "GuildBankColumn2Button12Stock",
+ "GuildBankColumn2Button13",
+ "GuildBankColumn2Button13Cooldown",
+ "GuildBankColumn2Button13Count",
+ "GuildBankColumn2Button13IconTexture",
+ "GuildBankColumn2Button13NormalTexture",
+ "GuildBankColumn2Button13Stock",
+ "GuildBankColumn2Button14",
+ "GuildBankColumn2Button14Cooldown",
+ "GuildBankColumn2Button14Count",
+ "GuildBankColumn2Button14IconTexture",
+ "GuildBankColumn2Button14NormalTexture",
+ "GuildBankColumn2Button14Stock",
+ "GuildBankColumn2Button1Cooldown",
+ "GuildBankColumn2Button1Count",
+ "GuildBankColumn2Button1IconTexture",
+ "GuildBankColumn2Button1NormalTexture",
+ "GuildBankColumn2Button1Stock",
+ "GuildBankColumn2Button2",
+ "GuildBankColumn2Button2Cooldown",
+ "GuildBankColumn2Button2Count",
+ "GuildBankColumn2Button2IconTexture",
+ "GuildBankColumn2Button2NormalTexture",
+ "GuildBankColumn2Button2Stock",
+ "GuildBankColumn2Button3",
+ "GuildBankColumn2Button3Cooldown",
+ "GuildBankColumn2Button3Count",
+ "GuildBankColumn2Button3IconTexture",
+ "GuildBankColumn2Button3NormalTexture",
+ "GuildBankColumn2Button3Stock",
+ "GuildBankColumn2Button4",
+ "GuildBankColumn2Button4Cooldown",
+ "GuildBankColumn2Button4Count",
+ "GuildBankColumn2Button4IconTexture",
+ "GuildBankColumn2Button4NormalTexture",
+ "GuildBankColumn2Button4Stock",
+ "GuildBankColumn2Button5",
+ "GuildBankColumn2Button5Cooldown",
+ "GuildBankColumn2Button5Count",
+ "GuildBankColumn2Button5IconTexture",
+ "GuildBankColumn2Button5NormalTexture",
+ "GuildBankColumn2Button5Stock",
+ "GuildBankColumn2Button6",
+ "GuildBankColumn2Button6Cooldown",
+ "GuildBankColumn2Button6Count",
+ "GuildBankColumn2Button6IconTexture",
+ "GuildBankColumn2Button6NormalTexture",
+ "GuildBankColumn2Button6Stock",
+ "GuildBankColumn2Button7",
+ "GuildBankColumn2Button7Cooldown",
+ "GuildBankColumn2Button7Count",
+ "GuildBankColumn2Button7IconTexture",
+ "GuildBankColumn2Button7NormalTexture",
+ "GuildBankColumn2Button7Stock",
+ "GuildBankColumn2Button8",
+ "GuildBankColumn2Button8Cooldown",
+ "GuildBankColumn2Button8Count",
+ "GuildBankColumn2Button8IconTexture",
+ "GuildBankColumn2Button8NormalTexture",
+ "GuildBankColumn2Button8Stock",
+ "GuildBankColumn2Button9",
+ "GuildBankColumn2Button9Cooldown",
+ "GuildBankColumn2Button9Count",
+ "GuildBankColumn2Button9IconTexture",
+ "GuildBankColumn2Button9NormalTexture",
+ "GuildBankColumn2Button9Stock",
+ "GuildBankColumn3",
+ "GuildBankColumn3Background",
+ "GuildBankColumn3Button1",
+ "GuildBankColumn3Button10",
+ "GuildBankColumn3Button10Cooldown",
+ "GuildBankColumn3Button10Count",
+ "GuildBankColumn3Button10IconTexture",
+ "GuildBankColumn3Button10NormalTexture",
+ "GuildBankColumn3Button10Stock",
+ "GuildBankColumn3Button11",
+ "GuildBankColumn3Button11Cooldown",
+ "GuildBankColumn3Button11Count",
+ "GuildBankColumn3Button11IconTexture",
+ "GuildBankColumn3Button11NormalTexture",
+ "GuildBankColumn3Button11Stock",
+ "GuildBankColumn3Button12",
+ "GuildBankColumn3Button12Cooldown",
+ "GuildBankColumn3Button12Count",
+ "GuildBankColumn3Button12IconTexture",
+ "GuildBankColumn3Button12NormalTexture",
+ "GuildBankColumn3Button12Stock",
+ "GuildBankColumn3Button13",
+ "GuildBankColumn3Button13Cooldown",
+ "GuildBankColumn3Button13Count",
+ "GuildBankColumn3Button13IconTexture",
+ "GuildBankColumn3Button13NormalTexture",
+ "GuildBankColumn3Button13Stock",
+ "GuildBankColumn3Button14",
+ "GuildBankColumn3Button14Cooldown",
+ "GuildBankColumn3Button14Count",
+ "GuildBankColumn3Button14IconTexture",
+ "GuildBankColumn3Button14NormalTexture",
+ "GuildBankColumn3Button14Stock",
+ "GuildBankColumn3Button1Cooldown",
+ "GuildBankColumn3Button1Count",
+ "GuildBankColumn3Button1IconTexture",
+ "GuildBankColumn3Button1NormalTexture",
+ "GuildBankColumn3Button1Stock",
+ "GuildBankColumn3Button2",
+ "GuildBankColumn3Button2Cooldown",
+ "GuildBankColumn3Button2Count",
+ "GuildBankColumn3Button2IconTexture",
+ "GuildBankColumn3Button2NormalTexture",
+ "GuildBankColumn3Button2Stock",
+ "GuildBankColumn3Button3",
+ "GuildBankColumn3Button3Cooldown",
+ "GuildBankColumn3Button3Count",
+ "GuildBankColumn3Button3IconTexture",
+ "GuildBankColumn3Button3NormalTexture",
+ "GuildBankColumn3Button3Stock",
+ "GuildBankColumn3Button4",
+ "GuildBankColumn3Button4Cooldown",
+ "GuildBankColumn3Button4Count",
+ "GuildBankColumn3Button4IconTexture",
+ "GuildBankColumn3Button4NormalTexture",
+ "GuildBankColumn3Button4Stock",
+ "GuildBankColumn3Button5",
+ "GuildBankColumn3Button5Cooldown",
+ "GuildBankColumn3Button5Count",
+ "GuildBankColumn3Button5IconTexture",
+ "GuildBankColumn3Button5NormalTexture",
+ "GuildBankColumn3Button5Stock",
+ "GuildBankColumn3Button6",
+ "GuildBankColumn3Button6Cooldown",
+ "GuildBankColumn3Button6Count",
+ "GuildBankColumn3Button6IconTexture",
+ "GuildBankColumn3Button6NormalTexture",
+ "GuildBankColumn3Button6Stock",
+ "GuildBankColumn3Button7",
+ "GuildBankColumn3Button7Cooldown",
+ "GuildBankColumn3Button7Count",
+ "GuildBankColumn3Button7IconTexture",
+ "GuildBankColumn3Button7NormalTexture",
+ "GuildBankColumn3Button7Stock",
+ "GuildBankColumn3Button8",
+ "GuildBankColumn3Button8Cooldown",
+ "GuildBankColumn3Button8Count",
+ "GuildBankColumn3Button8IconTexture",
+ "GuildBankColumn3Button8NormalTexture",
+ "GuildBankColumn3Button8Stock",
+ "GuildBankColumn3Button9",
+ "GuildBankColumn3Button9Cooldown",
+ "GuildBankColumn3Button9Count",
+ "GuildBankColumn3Button9IconTexture",
+ "GuildBankColumn3Button9NormalTexture",
+ "GuildBankColumn3Button9Stock",
+ "GuildBankColumn4",
+ "GuildBankColumn4Background",
+ "GuildBankColumn4Button1",
+ "GuildBankColumn4Button10",
+ "GuildBankColumn4Button10Cooldown",
+ "GuildBankColumn4Button10Count",
+ "GuildBankColumn4Button10IconTexture",
+ "GuildBankColumn4Button10NormalTexture",
+ "GuildBankColumn4Button10Stock",
+ "GuildBankColumn4Button11",
+ "GuildBankColumn4Button11Cooldown",
+ "GuildBankColumn4Button11Count",
+ "GuildBankColumn4Button11IconTexture",
+ "GuildBankColumn4Button11NormalTexture",
+ "GuildBankColumn4Button11Stock",
+ "GuildBankColumn4Button12",
+ "GuildBankColumn4Button12Cooldown",
+ "GuildBankColumn4Button12Count",
+ "GuildBankColumn4Button12IconTexture",
+ "GuildBankColumn4Button12NormalTexture",
+ "GuildBankColumn4Button12Stock",
+ "GuildBankColumn4Button13",
+ "GuildBankColumn4Button13Cooldown",
+ "GuildBankColumn4Button13Count",
+ "GuildBankColumn4Button13IconTexture",
+ "GuildBankColumn4Button13NormalTexture",
+ "GuildBankColumn4Button13Stock",
+ "GuildBankColumn4Button14",
+ "GuildBankColumn4Button14Cooldown",
+ "GuildBankColumn4Button14Count",
+ "GuildBankColumn4Button14IconTexture",
+ "GuildBankColumn4Button14NormalTexture",
+ "GuildBankColumn4Button14Stock",
+ "GuildBankColumn4Button1Cooldown",
+ "GuildBankColumn4Button1Count",
+ "GuildBankColumn4Button1IconTexture",
+ "GuildBankColumn4Button1NormalTexture",
+ "GuildBankColumn4Button1Stock",
+ "GuildBankColumn4Button2",
+ "GuildBankColumn4Button2Cooldown",
+ "GuildBankColumn4Button2Count",
+ "GuildBankColumn4Button2IconTexture",
+ "GuildBankColumn4Button2NormalTexture",
+ "GuildBankColumn4Button2Stock",
+ "GuildBankColumn4Button3",
+ "GuildBankColumn4Button3Cooldown",
+ "GuildBankColumn4Button3Count",
+ "GuildBankColumn4Button3IconTexture",
+ "GuildBankColumn4Button3NormalTexture",
+ "GuildBankColumn4Button3Stock",
+ "GuildBankColumn4Button4",
+ "GuildBankColumn4Button4Cooldown",
+ "GuildBankColumn4Button4Count",
+ "GuildBankColumn4Button4IconTexture",
+ "GuildBankColumn4Button4NormalTexture",
+ "GuildBankColumn4Button4Stock",
+ "GuildBankColumn4Button5",
+ "GuildBankColumn4Button5Cooldown",
+ "GuildBankColumn4Button5Count",
+ "GuildBankColumn4Button5IconTexture",
+ "GuildBankColumn4Button5NormalTexture",
+ "GuildBankColumn4Button5Stock",
+ "GuildBankColumn4Button6",
+ "GuildBankColumn4Button6Cooldown",
+ "GuildBankColumn4Button6Count",
+ "GuildBankColumn4Button6IconTexture",
+ "GuildBankColumn4Button6NormalTexture",
+ "GuildBankColumn4Button6Stock",
+ "GuildBankColumn4Button7",
+ "GuildBankColumn4Button7Cooldown",
+ "GuildBankColumn4Button7Count",
+ "GuildBankColumn4Button7IconTexture",
+ "GuildBankColumn4Button7NormalTexture",
+ "GuildBankColumn4Button7Stock",
+ "GuildBankColumn4Button8",
+ "GuildBankColumn4Button8Cooldown",
+ "GuildBankColumn4Button8Count",
+ "GuildBankColumn4Button8IconTexture",
+ "GuildBankColumn4Button8NormalTexture",
+ "GuildBankColumn4Button8Stock",
+ "GuildBankColumn4Button9",
+ "GuildBankColumn4Button9Cooldown",
+ "GuildBankColumn4Button9Count",
+ "GuildBankColumn4Button9IconTexture",
+ "GuildBankColumn4Button9NormalTexture",
+ "GuildBankColumn4Button9Stock",
+ "GuildBankColumn5",
+ "GuildBankColumn5Background",
+ "GuildBankColumn5Button1",
+ "GuildBankColumn5Button10",
+ "GuildBankColumn5Button10Cooldown",
+ "GuildBankColumn5Button10Count",
+ "GuildBankColumn5Button10IconTexture",
+ "GuildBankColumn5Button10NormalTexture",
+ "GuildBankColumn5Button10Stock",
+ "GuildBankColumn5Button11",
+ "GuildBankColumn5Button11Cooldown",
+ "GuildBankColumn5Button11Count",
+ "GuildBankColumn5Button11IconTexture",
+ "GuildBankColumn5Button11NormalTexture",
+ "GuildBankColumn5Button11Stock",
+ "GuildBankColumn5Button12",
+ "GuildBankColumn5Button12Cooldown",
+ "GuildBankColumn5Button12Count",
+ "GuildBankColumn5Button12IconTexture",
+ "GuildBankColumn5Button12NormalTexture",
+ "GuildBankColumn5Button12Stock",
+ "GuildBankColumn5Button13",
+ "GuildBankColumn5Button13Cooldown",
+ "GuildBankColumn5Button13Count",
+ "GuildBankColumn5Button13IconTexture",
+ "GuildBankColumn5Button13NormalTexture",
+ "GuildBankColumn5Button13Stock",
+ "GuildBankColumn5Button14",
+ "GuildBankColumn5Button14Cooldown",
+ "GuildBankColumn5Button14Count",
+ "GuildBankColumn5Button14IconTexture",
+ "GuildBankColumn5Button14NormalTexture",
+ "GuildBankColumn5Button14Stock",
+ "GuildBankColumn5Button1Cooldown",
+ "GuildBankColumn5Button1Count",
+ "GuildBankColumn5Button1IconTexture",
+ "GuildBankColumn5Button1NormalTexture",
+ "GuildBankColumn5Button1Stock",
+ "GuildBankColumn5Button2",
+ "GuildBankColumn5Button2Cooldown",
+ "GuildBankColumn5Button2Count",
+ "GuildBankColumn5Button2IconTexture",
+ "GuildBankColumn5Button2NormalTexture",
+ "GuildBankColumn5Button2Stock",
+ "GuildBankColumn5Button3",
+ "GuildBankColumn5Button3Cooldown",
+ "GuildBankColumn5Button3Count",
+ "GuildBankColumn5Button3IconTexture",
+ "GuildBankColumn5Button3NormalTexture",
+ "GuildBankColumn5Button3Stock",
+ "GuildBankColumn5Button4",
+ "GuildBankColumn5Button4Cooldown",
+ "GuildBankColumn5Button4Count",
+ "GuildBankColumn5Button4IconTexture",
+ "GuildBankColumn5Button4NormalTexture",
+ "GuildBankColumn5Button4Stock",
+ "GuildBankColumn5Button5",
+ "GuildBankColumn5Button5Cooldown",
+ "GuildBankColumn5Button5Count",
+ "GuildBankColumn5Button5IconTexture",
+ "GuildBankColumn5Button5NormalTexture",
+ "GuildBankColumn5Button5Stock",
+ "GuildBankColumn5Button6",
+ "GuildBankColumn5Button6Cooldown",
+ "GuildBankColumn5Button6Count",
+ "GuildBankColumn5Button6IconTexture",
+ "GuildBankColumn5Button6NormalTexture",
+ "GuildBankColumn5Button6Stock",
+ "GuildBankColumn5Button7",
+ "GuildBankColumn5Button7Cooldown",
+ "GuildBankColumn5Button7Count",
+ "GuildBankColumn5Button7IconTexture",
+ "GuildBankColumn5Button7NormalTexture",
+ "GuildBankColumn5Button7Stock",
+ "GuildBankColumn5Button8",
+ "GuildBankColumn5Button8Cooldown",
+ "GuildBankColumn5Button8Count",
+ "GuildBankColumn5Button8IconTexture",
+ "GuildBankColumn5Button8NormalTexture",
+ "GuildBankColumn5Button8Stock",
+ "GuildBankColumn5Button9",
+ "GuildBankColumn5Button9Cooldown",
+ "GuildBankColumn5Button9Count",
+ "GuildBankColumn5Button9IconTexture",
+ "GuildBankColumn5Button9NormalTexture",
+ "GuildBankColumn5Button9Stock",
+ "GuildBankColumn6",
+ "GuildBankColumn6Background",
+ "GuildBankColumn6Button1",
+ "GuildBankColumn6Button10",
+ "GuildBankColumn6Button10Cooldown",
+ "GuildBankColumn6Button10Count",
+ "GuildBankColumn6Button10IconTexture",
+ "GuildBankColumn6Button10NormalTexture",
+ "GuildBankColumn6Button10Stock",
+ "GuildBankColumn6Button11",
+ "GuildBankColumn6Button11Cooldown",
+ "GuildBankColumn6Button11Count",
+ "GuildBankColumn6Button11IconTexture",
+ "GuildBankColumn6Button11NormalTexture",
+ "GuildBankColumn6Button11Stock",
+ "GuildBankColumn6Button12",
+ "GuildBankColumn6Button12Cooldown",
+ "GuildBankColumn6Button12Count",
+ "GuildBankColumn6Button12IconTexture",
+ "GuildBankColumn6Button12NormalTexture",
+ "GuildBankColumn6Button12Stock",
+ "GuildBankColumn6Button13",
+ "GuildBankColumn6Button13Cooldown",
+ "GuildBankColumn6Button13Count",
+ "GuildBankColumn6Button13IconTexture",
+ "GuildBankColumn6Button13NormalTexture",
+ "GuildBankColumn6Button13Stock",
+ "GuildBankColumn6Button14",
+ "GuildBankColumn6Button14Cooldown",
+ "GuildBankColumn6Button14Count",
+ "GuildBankColumn6Button14IconTexture",
+ "GuildBankColumn6Button14NormalTexture",
+ "GuildBankColumn6Button14Stock",
+ "GuildBankColumn6Button1Cooldown",
+ "GuildBankColumn6Button1Count",
+ "GuildBankColumn6Button1IconTexture",
+ "GuildBankColumn6Button1NormalTexture",
+ "GuildBankColumn6Button1Stock",
+ "GuildBankColumn6Button2",
+ "GuildBankColumn6Button2Cooldown",
+ "GuildBankColumn6Button2Count",
+ "GuildBankColumn6Button2IconTexture",
+ "GuildBankColumn6Button2NormalTexture",
+ "GuildBankColumn6Button2Stock",
+ "GuildBankColumn6Button3",
+ "GuildBankColumn6Button3Cooldown",
+ "GuildBankColumn6Button3Count",
+ "GuildBankColumn6Button3IconTexture",
+ "GuildBankColumn6Button3NormalTexture",
+ "GuildBankColumn6Button3Stock",
+ "GuildBankColumn6Button4",
+ "GuildBankColumn6Button4Cooldown",
+ "GuildBankColumn6Button4Count",
+ "GuildBankColumn6Button4IconTexture",
+ "GuildBankColumn6Button4NormalTexture",
+ "GuildBankColumn6Button4Stock",
+ "GuildBankColumn6Button5",
+ "GuildBankColumn6Button5Cooldown",
+ "GuildBankColumn6Button5Count",
+ "GuildBankColumn6Button5IconTexture",
+ "GuildBankColumn6Button5NormalTexture",
+ "GuildBankColumn6Button5Stock",
+ "GuildBankColumn6Button6",
+ "GuildBankColumn6Button6Cooldown",
+ "GuildBankColumn6Button6Count",
+ "GuildBankColumn6Button6IconTexture",
+ "GuildBankColumn6Button6NormalTexture",
+ "GuildBankColumn6Button6Stock",
+ "GuildBankColumn6Button7",
+ "GuildBankColumn6Button7Cooldown",
+ "GuildBankColumn6Button7Count",
+ "GuildBankColumn6Button7IconTexture",
+ "GuildBankColumn6Button7NormalTexture",
+ "GuildBankColumn6Button7Stock",
+ "GuildBankColumn6Button8",
+ "GuildBankColumn6Button8Cooldown",
+ "GuildBankColumn6Button8Count",
+ "GuildBankColumn6Button8IconTexture",
+ "GuildBankColumn6Button8NormalTexture",
+ "GuildBankColumn6Button8Stock",
+ "GuildBankColumn6Button9",
+ "GuildBankColumn6Button9Cooldown",
+ "GuildBankColumn6Button9Count",
+ "GuildBankColumn6Button9IconTexture",
+ "GuildBankColumn6Button9NormalTexture",
+ "GuildBankColumn6Button9Stock",
+ "GuildBankColumn7",
+ "GuildBankColumn7Background",
+ "GuildBankColumn7Button1",
+ "GuildBankColumn7Button10",
+ "GuildBankColumn7Button10Cooldown",
+ "GuildBankColumn7Button10Count",
+ "GuildBankColumn7Button10IconTexture",
+ "GuildBankColumn7Button10NormalTexture",
+ "GuildBankColumn7Button10Stock",
+ "GuildBankColumn7Button11",
+ "GuildBankColumn7Button11Cooldown",
+ "GuildBankColumn7Button11Count",
+ "GuildBankColumn7Button11IconTexture",
+ "GuildBankColumn7Button11NormalTexture",
+ "GuildBankColumn7Button11Stock",
+ "GuildBankColumn7Button12",
+ "GuildBankColumn7Button12Cooldown",
+ "GuildBankColumn7Button12Count",
+ "GuildBankColumn7Button12IconTexture",
+ "GuildBankColumn7Button12NormalTexture",
+ "GuildBankColumn7Button12Stock",
+ "GuildBankColumn7Button13",
+ "GuildBankColumn7Button13Cooldown",
+ "GuildBankColumn7Button13Count",
+ "GuildBankColumn7Button13IconTexture",
+ "GuildBankColumn7Button13NormalTexture",
+ "GuildBankColumn7Button13Stock",
+ "GuildBankColumn7Button14",
+ "GuildBankColumn7Button14Cooldown",
+ "GuildBankColumn7Button14Count",
+ "GuildBankColumn7Button14IconTexture",
+ "GuildBankColumn7Button14NormalTexture",
+ "GuildBankColumn7Button14Stock",
+ "GuildBankColumn7Button1Cooldown",
+ "GuildBankColumn7Button1Count",
+ "GuildBankColumn7Button1IconTexture",
+ "GuildBankColumn7Button1NormalTexture",
+ "GuildBankColumn7Button1Stock",
+ "GuildBankColumn7Button2",
+ "GuildBankColumn7Button2Cooldown",
+ "GuildBankColumn7Button2Count",
+ "GuildBankColumn7Button2IconTexture",
+ "GuildBankColumn7Button2NormalTexture",
+ "GuildBankColumn7Button2Stock",
+ "GuildBankColumn7Button3",
+ "GuildBankColumn7Button3Cooldown",
+ "GuildBankColumn7Button3Count",
+ "GuildBankColumn7Button3IconTexture",
+ "GuildBankColumn7Button3NormalTexture",
+ "GuildBankColumn7Button3Stock",
+ "GuildBankColumn7Button4",
+ "GuildBankColumn7Button4Cooldown",
+ "GuildBankColumn7Button4Count",
+ "GuildBankColumn7Button4IconTexture",
+ "GuildBankColumn7Button4NormalTexture",
+ "GuildBankColumn7Button4Stock",
+ "GuildBankColumn7Button5",
+ "GuildBankColumn7Button5Cooldown",
+ "GuildBankColumn7Button5Count",
+ "GuildBankColumn7Button5IconTexture",
+ "GuildBankColumn7Button5NormalTexture",
+ "GuildBankColumn7Button5Stock",
+ "GuildBankColumn7Button6",
+ "GuildBankColumn7Button6Cooldown",
+ "GuildBankColumn7Button6Count",
+ "GuildBankColumn7Button6IconTexture",
+ "GuildBankColumn7Button6NormalTexture",
+ "GuildBankColumn7Button6Stock",
+ "GuildBankColumn7Button7",
+ "GuildBankColumn7Button7Cooldown",
+ "GuildBankColumn7Button7Count",
+ "GuildBankColumn7Button7IconTexture",
+ "GuildBankColumn7Button7NormalTexture",
+ "GuildBankColumn7Button7Stock",
+ "GuildBankColumn7Button8",
+ "GuildBankColumn7Button8Cooldown",
+ "GuildBankColumn7Button8Count",
+ "GuildBankColumn7Button8IconTexture",
+ "GuildBankColumn7Button8NormalTexture",
+ "GuildBankColumn7Button8Stock",
+ "GuildBankColumn7Button9",
+ "GuildBankColumn7Button9Cooldown",
+ "GuildBankColumn7Button9Count",
+ "GuildBankColumn7Button9IconTexture",
+ "GuildBankColumn7Button9NormalTexture",
+ "GuildBankColumn7Button9Stock",
+ "GuildBankEmblemBL",
+ "GuildBankEmblemBR",
+ "GuildBankEmblemBackgroundBL",
+ "GuildBankEmblemBackgroundBR",
+ "GuildBankEmblemBackgroundUL",
+ "GuildBankEmblemBackgroundUR",
+ "GuildBankEmblemBorderBL",
+ "GuildBankEmblemBorderBR",
+ "GuildBankEmblemBorderUL",
+ "GuildBankEmblemBorderUR",
+ "GuildBankEmblemFrame",
+ "GuildBankEmblemFrameLeft",
+ "GuildBankEmblemFrameRight",
+ "GuildBankEmblemUL",
+ "GuildBankEmblemUR",
+ "GuildBankErrorMessage",
+ "GuildBankFrame",
+ "GuildBankFrameBuyInfo",
+ "GuildBankFrameBuyInfoNumTabsPurchasedText",
+ "GuildBankFrameBuyInfoText",
+ "GuildBankFrameDepositButton",
+ "GuildBankFrameDepositButtonText",
+ "GuildBankFrameLeft",
+ "GuildBankFrameLog",
+ "GuildBankFramePortrait",
+ "GuildBankFramePurchaseButton",
+ "GuildBankFramePurchaseButtonText",
+ "GuildBankFrameRight",
+ "GuildBankFrameTab1",
+ "GuildBankFrameTab1HighlightTexture",
+ "GuildBankFrameTab1Left",
+ "GuildBankFrameTab1LeftDisabled",
+ "GuildBankFrameTab1Middle",
+ "GuildBankFrameTab1MiddleDisabled",
+ "GuildBankFrameTab1Right",
+ "GuildBankFrameTab1RightDisabled",
+ "GuildBankFrameTab1Text",
+ "GuildBankFrameTab2",
+ "GuildBankFrameTab2HighlightTexture",
+ "GuildBankFrameTab2Left",
+ "GuildBankFrameTab2LeftDisabled",
+ "GuildBankFrameTab2Middle",
+ "GuildBankFrameTab2MiddleDisabled",
+ "GuildBankFrameTab2Right",
+ "GuildBankFrameTab2RightDisabled",
+ "GuildBankFrameTab2Text",
+ "GuildBankFrameTab3",
+ "GuildBankFrameTab3HighlightTexture",
+ "GuildBankFrameTab3Left",
+ "GuildBankFrameTab3LeftDisabled",
+ "GuildBankFrameTab3Middle",
+ "GuildBankFrameTab3MiddleDisabled",
+ "GuildBankFrameTab3Right",
+ "GuildBankFrameTab3RightDisabled",
+ "GuildBankFrameTab3Text",
+ "GuildBankFrameTab4",
+ "GuildBankFrameTab4HighlightTexture",
+ "GuildBankFrameTab4Left",
+ "GuildBankFrameTab4LeftDisabled",
+ "GuildBankFrameTab4Middle",
+ "GuildBankFrameTab4MiddleDisabled",
+ "GuildBankFrameTab4Right",
+ "GuildBankFrameTab4RightDisabled",
+ "GuildBankFrameTab4Text",
+ "GuildBankFrameTabCost",
+ "GuildBankFrameTabCostMoneyFrame",
+ "GuildBankFrameTabCostMoneyFrameCopperButton",
+ "GuildBankFrameTabCostMoneyFrameCopperButtonText",
+ "GuildBankFrameTabCostMoneyFrameGoldButton",
+ "GuildBankFrameTabCostMoneyFrameGoldButtonText",
+ "GuildBankFrameTabCostMoneyFrameSilverButton",
+ "GuildBankFrameTabCostMoneyFrameSilverButtonText",
+ "GuildBankFrameTab_OnClick",
+ "GuildBankFrameWithdrawButton",
+ "GuildBankFrameWithdrawButtonText",
+ "GuildBankFrame_ChangeBackground",
+ "GuildBankFrame_ChangeBorder",
+ "GuildBankFrame_ChangeEmblem",
+ "GuildBankFrame_DesaturateColumns",
+ "GuildBankFrame_HideColumns",
+ "GuildBankFrame_LoadUI",
+ "GuildBankFrame_OnEvent",
+ "GuildBankFrame_OnLoad",
+ "GuildBankFrame_OnShow",
+ "GuildBankFrame_SelectAvailableTab",
+ "GuildBankFrame_ShowColumns",
+ "GuildBankFrame_Update",
+ "GuildBankFrame_UpdateEmblem",
+ "GuildBankFrame_UpdateLog",
+ "GuildBankFrame_UpdateMoneyLog",
+ "GuildBankFrame_UpdateTabBuyingInfo",
+ "GuildBankFrame_UpdateTabInfo",
+ "GuildBankFrame_UpdateTabard",
+ "GuildBankFrame_UpdateTabs",
+ "GuildBankFrame_UpdateWithdrawMoney",
+ "GuildBankInfo",
+ "GuildBankInfoSaveButton",
+ "GuildBankInfoSaveButtonText",
+ "GuildBankInfoScrollFrame",
+ "GuildBankInfoScrollFrameScrollBar",
+ "GuildBankInfoScrollFrameScrollBarScrollDownButton",
+ "GuildBankInfoScrollFrameScrollBarScrollUpButton",
+ "GuildBankInfoScrollFrameScrollBarThumbTexture",
+ "GuildBankItemButton_OnEnter",
+ "GuildBankItemButton_OnLoad",
+ "GuildBankLimitLabel",
+ "GuildBankLogScroll",
+ "GuildBankMessageFrame",
+ "GuildBankMoneyFrame",
+ "GuildBankMoneyFrameCopperButton",
+ "GuildBankMoneyFrameCopperButtonText",
+ "GuildBankMoneyFrameGoldButton",
+ "GuildBankMoneyFrameGoldButtonText",
+ "GuildBankMoneyFrameSilverButton",
+ "GuildBankMoneyFrameSilverButtonText",
+ "GuildBankMoneyLimitLabel",
+ "GuildBankMoneyUnlimitedLabel",
+ "GuildBankPopupButton1",
+ "GuildBankPopupButton10",
+ "GuildBankPopupButton10Icon",
+ "GuildBankPopupButton10Name",
+ "GuildBankPopupButton11",
+ "GuildBankPopupButton11Icon",
+ "GuildBankPopupButton11Name",
+ "GuildBankPopupButton12",
+ "GuildBankPopupButton12Icon",
+ "GuildBankPopupButton12Name",
+ "GuildBankPopupButton13",
+ "GuildBankPopupButton13Icon",
+ "GuildBankPopupButton13Name",
+ "GuildBankPopupButton14",
+ "GuildBankPopupButton14Icon",
+ "GuildBankPopupButton14Name",
+ "GuildBankPopupButton15",
+ "GuildBankPopupButton15Icon",
+ "GuildBankPopupButton15Name",
+ "GuildBankPopupButton16",
+ "GuildBankPopupButton16Icon",
+ "GuildBankPopupButton16Name",
+ "GuildBankPopupButton1Icon",
+ "GuildBankPopupButton1Name",
+ "GuildBankPopupButton2",
+ "GuildBankPopupButton2Icon",
+ "GuildBankPopupButton2Name",
+ "GuildBankPopupButton3",
+ "GuildBankPopupButton3Icon",
+ "GuildBankPopupButton3Name",
+ "GuildBankPopupButton4",
+ "GuildBankPopupButton4Icon",
+ "GuildBankPopupButton4Name",
+ "GuildBankPopupButton5",
+ "GuildBankPopupButton5Icon",
+ "GuildBankPopupButton5Name",
+ "GuildBankPopupButton6",
+ "GuildBankPopupButton6Icon",
+ "GuildBankPopupButton6Name",
+ "GuildBankPopupButton7",
+ "GuildBankPopupButton7Icon",
+ "GuildBankPopupButton7Name",
+ "GuildBankPopupButton8",
+ "GuildBankPopupButton8Icon",
+ "GuildBankPopupButton8Name",
+ "GuildBankPopupButton9",
+ "GuildBankPopupButton9Icon",
+ "GuildBankPopupButton9Name",
+ "GuildBankPopupButton_OnClick",
+ "GuildBankPopupCancelButton",
+ "GuildBankPopupCancelButtonText",
+ "GuildBankPopupEditBox",
+ "GuildBankPopupFrame",
+ "GuildBankPopupFrameBottomLeft",
+ "GuildBankPopupFrameTopLeft",
+ "GuildBankPopupFrame_CancelEdit",
+ "GuildBankPopupFrame_OnShow",
+ "GuildBankPopupFrame_Update",
+ "GuildBankPopupNameLeft",
+ "GuildBankPopupNameMiddle",
+ "GuildBankPopupNameRight",
+ "GuildBankPopupOkayButton",
+ "GuildBankPopupOkayButtonText",
+ "GuildBankPopupOkayButton_OnClick",
+ "GuildBankPopupScrollFrame",
+ "GuildBankPopupScrollFrameScrollBar",
+ "GuildBankPopupScrollFrameScrollBarScrollDownButton",
+ "GuildBankPopupScrollFrameScrollBarScrollUpButton",
+ "GuildBankPopupScrollFrameScrollBarThumbTexture",
+ "GuildBankPopupScrollFrameScrollChildFrame",
+ "GuildBankTab1",
+ "GuildBankTab1Button",
+ "GuildBankTab1ButtonCount",
+ "GuildBankTab1ButtonIconTexture",
+ "GuildBankTab1ButtonNormalTexture",
+ "GuildBankTab2",
+ "GuildBankTab2Button",
+ "GuildBankTab2ButtonCount",
+ "GuildBankTab2ButtonIconTexture",
+ "GuildBankTab2ButtonNormalTexture",
+ "GuildBankTab3",
+ "GuildBankTab3Button",
+ "GuildBankTab3ButtonCount",
+ "GuildBankTab3ButtonIconTexture",
+ "GuildBankTab3ButtonNormalTexture",
+ "GuildBankTab4",
+ "GuildBankTab4Button",
+ "GuildBankTab4ButtonCount",
+ "GuildBankTab4ButtonIconTexture",
+ "GuildBankTab4ButtonNormalTexture",
+ "GuildBankTab5",
+ "GuildBankTab5Button",
+ "GuildBankTab5ButtonCount",
+ "GuildBankTab5ButtonIconTexture",
+ "GuildBankTab5ButtonNormalTexture",
+ "GuildBankTab6",
+ "GuildBankTab6Button",
+ "GuildBankTab6ButtonCount",
+ "GuildBankTab6ButtonIconTexture",
+ "GuildBankTab6ButtonNormalTexture",
+ "GuildBankTabInfoEditBox",
+ "GuildBankTabLabel",
+ "GuildBankTabLimitBackground",
+ "GuildBankTabLimitBackgroundLeft",
+ "GuildBankTabLimitBackgroundRight",
+ "GuildBankTabPermissionsTab1",
+ "GuildBankTabPermissionsTab1Background",
+ "GuildBankTabPermissionsTab1Text",
+ "GuildBankTabPermissionsTab2",
+ "GuildBankTabPermissionsTab2Background",
+ "GuildBankTabPermissionsTab2Text",
+ "GuildBankTabPermissionsTab3",
+ "GuildBankTabPermissionsTab3Background",
+ "GuildBankTabPermissionsTab3Text",
+ "GuildBankTabPermissionsTab4",
+ "GuildBankTabPermissionsTab4Background",
+ "GuildBankTabPermissionsTab4Text",
+ "GuildBankTabPermissionsTab5",
+ "GuildBankTabPermissionsTab5Background",
+ "GuildBankTabPermissionsTab5Text",
+ "GuildBankTabPermissionsTab6",
+ "GuildBankTabPermissionsTab6Background",
+ "GuildBankTabPermissionsTab6Text",
+ "GuildBankTabPermissionsTab_OnClick",
+ "GuildBankTabTitle",
+ "GuildBankTabTitleBackground",
+ "GuildBankTabTitleBackgroundLeft",
+ "GuildBankTabTitleBackgroundRight",
+ "GuildBankTab_OnClick",
+ "GuildBankTransactionsScrollFrame",
+ "GuildBankTransactionsScrollFrameScrollBar",
+ "GuildBankTransactionsScrollFrameScrollBarScrollDownButton",
+ "GuildBankTransactionsScrollFrameScrollBarScrollUpButton",
+ "GuildBankTransactionsScrollFrameScrollBarThumbTexture",
+ "GuildBankTransactionsScrollFrameScrollChildFrame",
+ "GuildBankWithdrawMoneyFrame",
+ "GuildBankWithdrawMoneyFrameCopperButton",
+ "GuildBankWithdrawMoneyFrameCopperButtonText",
+ "GuildBankWithdrawMoneyFrameGoldButton",
+ "GuildBankWithdrawMoneyFrameGoldButtonText",
+ "GuildBankWithdrawMoneyFrameSilverButton",
+ "GuildBankWithdrawMoneyFrameSilverButtonText",
+ "GuildControlAddRank",
+ "GuildControlCheckboxUpdate",
+ "GuildControlDelRank",
+ "GuildControlGetNumRanks",
+ "GuildControlGetRankFlags",
+ "GuildControlGetRankName",
+ "GuildControlPopupAcceptButton",
+ "GuildControlPopupAcceptButtonText",
+ "GuildControlPopupAcceptButton_OnClick",
+ "GuildControlPopupFrame",
+ "GuildControlPopupFrameAddRankButton",
+ "GuildControlPopupFrameAddRankButton_OnUpdate",
+ "GuildControlPopupFrameCancelButton",
+ "GuildControlPopupFrameCancelButtonText",
+ "GuildControlPopupFrameCheckbox1",
+ "GuildControlPopupFrameCheckbox10",
+ "GuildControlPopupFrameCheckbox10Text",
+ "GuildControlPopupFrameCheckbox11",
+ "GuildControlPopupFrameCheckbox11Text",
+ "GuildControlPopupFrameCheckbox12",
+ "GuildControlPopupFrameCheckbox12Text",
+ "GuildControlPopupFrameCheckbox13",
+ "GuildControlPopupFrameCheckbox13Text",
+ "GuildControlPopupFrameCheckbox15",
+ "GuildControlPopupFrameCheckbox15Text",
+ "GuildControlPopupFrameCheckbox16",
+ "GuildControlPopupFrameCheckbox16Text",
+ "GuildControlPopupFrameCheckbox17",
+ "GuildControlPopupFrameCheckbox17Text",
+ "GuildControlPopupFrameCheckbox1Text",
+ "GuildControlPopupFrameCheckbox2",
+ "GuildControlPopupFrameCheckbox2Text",
+ "GuildControlPopupFrameCheckbox3",
+ "GuildControlPopupFrameCheckbox3Text",
+ "GuildControlPopupFrameCheckbox4",
+ "GuildControlPopupFrameCheckbox4Text",
+ "GuildControlPopupFrameCheckbox5",
+ "GuildControlPopupFrameCheckbox5Text",
+ "GuildControlPopupFrameCheckbox6",
+ "GuildControlPopupFrameCheckbox6Text",
+ "GuildControlPopupFrameCheckbox7",
+ "GuildControlPopupFrameCheckbox7Text",
+ "GuildControlPopupFrameCheckbox8",
+ "GuildControlPopupFrameCheckbox8Text",
+ "GuildControlPopupFrameCheckbox9",
+ "GuildControlPopupFrameCheckbox9Text",
+ "GuildControlPopupFrameCheckboxes",
+ "GuildControlPopupFrameDropDown",
+ "GuildControlPopupFrameDropDownButton",
+ "GuildControlPopupFrameDropDownButtonDisabledTexture",
+ "GuildControlPopupFrameDropDownButtonHighlightTexture",
+ "GuildControlPopupFrameDropDownButtonNormalTexture",
+ "GuildControlPopupFrameDropDownButtonPushedTexture",
+ "GuildControlPopupFrameDropDownButton_OnClick",
+ "GuildControlPopupFrameDropDownLeft",
+ "GuildControlPopupFrameDropDownMiddle",
+ "GuildControlPopupFrameDropDownRight",
+ "GuildControlPopupFrameDropDownText",
+ "GuildControlPopupFrameDropDown_Initialize",
+ "GuildControlPopupFrameDropDown_OnLoad",
+ "GuildControlPopupFrameEditBox",
+ "GuildControlPopupFrameEditBoxLeft",
+ "GuildControlPopupFrameEditBoxMiddle",
+ "GuildControlPopupFrameEditBoxRight",
+ "GuildControlPopupFrameRemoveRankButton",
+ "GuildControlPopupFrameRemoveRankButton_OnClick",
+ "GuildControlPopupFrameRemoveRankButton_OnUpdate",
+ "GuildControlPopupFrameTabPermissions",
+ "GuildControlPopupFrame_Initialize",
+ "GuildControlPopupFrame_OnEvent",
+ "GuildControlPopupFrame_OnHide",
+ "GuildControlPopupFrame_OnLoad",
+ "GuildControlPopupFrame_OnShow",
+ "GuildControlPopup_UpdateDepositCheckBox",
+ "GuildControlPopupframe_Update",
+ "GuildControlSaveRank",
+ "GuildControlSetRank",
+ "GuildControlSetRankFlag",
+ "GuildControlTabPermissionsDepositItems",
+ "GuildControlTabPermissionsDepositItemsText",
+ "GuildControlTabPermissionsUpdateText",
+ "GuildControlTabPermissionsUpdateTextText",
+ "GuildControlTabPermissionsViewTab",
+ "GuildControlTabPermissionsViewTabText",
+ "GuildControlTabPermissionsWithdrawItems",
+ "GuildControlTabPermissionsWithdrawItemsText",
+ "GuildControlWithdrawGold",
+ "GuildControlWithdrawGoldAmountText",
+ "GuildControlWithdrawGoldEditBox",
+ "GuildControlWithdrawGoldEditBoxLeft",
+ "GuildControlWithdrawGoldEditBoxMask",
+ "GuildControlWithdrawGoldEditBoxMiddle",
+ "GuildControlWithdrawGoldEditBoxRight",
+ "GuildControlWithdrawGoldText",
+ "GuildControlWithdrawItemsEditBox",
+ "GuildControlWithdrawItemsEditBoxLeft",
+ "GuildControlWithdrawItemsEditBoxMask",
+ "GuildControlWithdrawItemsEditBoxMiddle",
+ "GuildControlWithdrawItemsEditBoxRight",
+ "GuildDemote",
+ "GuildDisband",
+ "GuildEventFrame",
+ "GuildEventLogCancelButton",
+ "GuildEventLogCancelButtonText",
+ "GuildEventLogCloseButton",
+ "GuildEventLogFrame",
+ "GuildEventLogScrollChildFrame",
+ "GuildEventLogScrollFrame",
+ "GuildEventLogScrollFrameScrollBar",
+ "GuildEventLogScrollFrameScrollBarScrollDownButton",
+ "GuildEventLogScrollFrameScrollBarScrollUpButton",
+ "GuildEventLogScrollFrameScrollBarThumbTexture",
+ "GuildEventLogTitle",
+ "GuildEventLog_Update",
+ "GuildEventMessage",
+ "GuildFrame",
+ "GuildFrameAddMemberButton",
+ "GuildFrameAddMemberButtonText",
+ "GuildFrameButton1",
+ "GuildFrameButton10",
+ "GuildFrameButton10Class",
+ "GuildFrameButton10Group",
+ "GuildFrameButton10Level",
+ "GuildFrameButton10Name",
+ "GuildFrameButton10Zone",
+ "GuildFrameButton11",
+ "GuildFrameButton11Class",
+ "GuildFrameButton11Group",
+ "GuildFrameButton11Level",
+ "GuildFrameButton11Name",
+ "GuildFrameButton11Zone",
+ "GuildFrameButton12",
+ "GuildFrameButton12Class",
+ "GuildFrameButton12Group",
+ "GuildFrameButton12Level",
+ "GuildFrameButton12Name",
+ "GuildFrameButton12Zone",
+ "GuildFrameButton13",
+ "GuildFrameButton13Class",
+ "GuildFrameButton13Group",
+ "GuildFrameButton13Level",
+ "GuildFrameButton13Name",
+ "GuildFrameButton13Zone",
+ "GuildFrameButton1Class",
+ "GuildFrameButton1Group",
+ "GuildFrameButton1Level",
+ "GuildFrameButton1Name",
+ "GuildFrameButton1Zone",
+ "GuildFrameButton2",
+ "GuildFrameButton2Class",
+ "GuildFrameButton2Group",
+ "GuildFrameButton2Level",
+ "GuildFrameButton2Name",
+ "GuildFrameButton2Zone",
+ "GuildFrameButton3",
+ "GuildFrameButton3Class",
+ "GuildFrameButton3Group",
+ "GuildFrameButton3Level",
+ "GuildFrameButton3Name",
+ "GuildFrameButton3Zone",
+ "GuildFrameButton4",
+ "GuildFrameButton4Class",
+ "GuildFrameButton4Group",
+ "GuildFrameButton4Level",
+ "GuildFrameButton4Name",
+ "GuildFrameButton4Zone",
+ "GuildFrameButton5",
+ "GuildFrameButton5Class",
+ "GuildFrameButton5Group",
+ "GuildFrameButton5Level",
+ "GuildFrameButton5Name",
+ "GuildFrameButton5Zone",
+ "GuildFrameButton6",
+ "GuildFrameButton6Class",
+ "GuildFrameButton6Group",
+ "GuildFrameButton6Level",
+ "GuildFrameButton6Name",
+ "GuildFrameButton6Zone",
+ "GuildFrameButton7",
+ "GuildFrameButton7Class",
+ "GuildFrameButton7Group",
+ "GuildFrameButton7Level",
+ "GuildFrameButton7Name",
+ "GuildFrameButton7Zone",
+ "GuildFrameButton8",
+ "GuildFrameButton8Class",
+ "GuildFrameButton8Group",
+ "GuildFrameButton8Level",
+ "GuildFrameButton8Name",
+ "GuildFrameButton8Zone",
+ "GuildFrameButton9",
+ "GuildFrameButton9Class",
+ "GuildFrameButton9Group",
+ "GuildFrameButton9Level",
+ "GuildFrameButton9Name",
+ "GuildFrameButton9Zone",
+ "GuildFrameColumnHeader1",
+ "GuildFrameColumnHeader1HighlightTexture",
+ "GuildFrameColumnHeader1Left",
+ "GuildFrameColumnHeader1Middle",
+ "GuildFrameColumnHeader1Right",
+ "GuildFrameColumnHeader2",
+ "GuildFrameColumnHeader2HighlightTexture",
+ "GuildFrameColumnHeader2Left",
+ "GuildFrameColumnHeader2Middle",
+ "GuildFrameColumnHeader2Right",
+ "GuildFrameColumnHeader3",
+ "GuildFrameColumnHeader3HighlightTexture",
+ "GuildFrameColumnHeader3Left",
+ "GuildFrameColumnHeader3Middle",
+ "GuildFrameColumnHeader3Right",
+ "GuildFrameColumnHeader4",
+ "GuildFrameColumnHeader4HighlightTexture",
+ "GuildFrameColumnHeader4Left",
+ "GuildFrameColumnHeader4Middle",
+ "GuildFrameColumnHeader4Right",
+ "GuildFrameControlButton",
+ "GuildFrameControlButtonText",
+ "GuildFrameControlButton_OnUpdate",
+ "GuildFrameDemoteButton",
+ "GuildFrameGuildInformationButton",
+ "GuildFrameGuildInformationButtonText",
+ "GuildFrameGuildListToggleButton",
+ "GuildFrameGuildListToggleButton_OnClick",
+ "GuildFrameGuildStatusButton1",
+ "GuildFrameGuildStatusButton10",
+ "GuildFrameGuildStatusButton10Name",
+ "GuildFrameGuildStatusButton10Note",
+ "GuildFrameGuildStatusButton10Online",
+ "GuildFrameGuildStatusButton10Rank",
+ "GuildFrameGuildStatusButton11",
+ "GuildFrameGuildStatusButton11Name",
+ "GuildFrameGuildStatusButton11Note",
+ "GuildFrameGuildStatusButton11Online",
+ "GuildFrameGuildStatusButton11Rank",
+ "GuildFrameGuildStatusButton12",
+ "GuildFrameGuildStatusButton12Name",
+ "GuildFrameGuildStatusButton12Note",
+ "GuildFrameGuildStatusButton12Online",
+ "GuildFrameGuildStatusButton12Rank",
+ "GuildFrameGuildStatusButton13",
+ "GuildFrameGuildStatusButton13Name",
+ "GuildFrameGuildStatusButton13Note",
+ "GuildFrameGuildStatusButton13Online",
+ "GuildFrameGuildStatusButton13Rank",
+ "GuildFrameGuildStatusButton1Name",
+ "GuildFrameGuildStatusButton1Note",
+ "GuildFrameGuildStatusButton1Online",
+ "GuildFrameGuildStatusButton1Rank",
+ "GuildFrameGuildStatusButton2",
+ "GuildFrameGuildStatusButton2Name",
+ "GuildFrameGuildStatusButton2Note",
+ "GuildFrameGuildStatusButton2Online",
+ "GuildFrameGuildStatusButton2Rank",
+ "GuildFrameGuildStatusButton3",
+ "GuildFrameGuildStatusButton3Name",
+ "GuildFrameGuildStatusButton3Note",
+ "GuildFrameGuildStatusButton3Online",
+ "GuildFrameGuildStatusButton3Rank",
+ "GuildFrameGuildStatusButton4",
+ "GuildFrameGuildStatusButton4Name",
+ "GuildFrameGuildStatusButton4Note",
+ "GuildFrameGuildStatusButton4Online",
+ "GuildFrameGuildStatusButton4Rank",
+ "GuildFrameGuildStatusButton5",
+ "GuildFrameGuildStatusButton5Name",
+ "GuildFrameGuildStatusButton5Note",
+ "GuildFrameGuildStatusButton5Online",
+ "GuildFrameGuildStatusButton5Rank",
+ "GuildFrameGuildStatusButton6",
+ "GuildFrameGuildStatusButton6Name",
+ "GuildFrameGuildStatusButton6Note",
+ "GuildFrameGuildStatusButton6Online",
+ "GuildFrameGuildStatusButton6Rank",
+ "GuildFrameGuildStatusButton7",
+ "GuildFrameGuildStatusButton7Name",
+ "GuildFrameGuildStatusButton7Note",
+ "GuildFrameGuildStatusButton7Online",
+ "GuildFrameGuildStatusButton7Rank",
+ "GuildFrameGuildStatusButton8",
+ "GuildFrameGuildStatusButton8Name",
+ "GuildFrameGuildStatusButton8Note",
+ "GuildFrameGuildStatusButton8Online",
+ "GuildFrameGuildStatusButton8Rank",
+ "GuildFrameGuildStatusButton9",
+ "GuildFrameGuildStatusButton9Name",
+ "GuildFrameGuildStatusButton9Note",
+ "GuildFrameGuildStatusButton9Online",
+ "GuildFrameGuildStatusButton9Rank",
+ "GuildFrameGuildStatusColumnHeader1",
+ "GuildFrameGuildStatusColumnHeader1HighlightTexture",
+ "GuildFrameGuildStatusColumnHeader1Left",
+ "GuildFrameGuildStatusColumnHeader1Middle",
+ "GuildFrameGuildStatusColumnHeader1Right",
+ "GuildFrameGuildStatusColumnHeader2",
+ "GuildFrameGuildStatusColumnHeader2HighlightTexture",
+ "GuildFrameGuildStatusColumnHeader2Left",
+ "GuildFrameGuildStatusColumnHeader2Middle",
+ "GuildFrameGuildStatusColumnHeader2Right",
+ "GuildFrameGuildStatusColumnHeader3",
+ "GuildFrameGuildStatusColumnHeader3HighlightTexture",
+ "GuildFrameGuildStatusColumnHeader3Left",
+ "GuildFrameGuildStatusColumnHeader3Middle",
+ "GuildFrameGuildStatusColumnHeader3Right",
+ "GuildFrameGuildStatusColumnHeader4",
+ "GuildFrameGuildStatusColumnHeader4HighlightTexture",
+ "GuildFrameGuildStatusColumnHeader4Left",
+ "GuildFrameGuildStatusColumnHeader4Middle",
+ "GuildFrameGuildStatusColumnHeader4Right",
+ "GuildFrameLFGButton",
+ "GuildFrameLFGButtonText",
+ "GuildFrameLFGFrame",
+ "GuildFrameLFGFrameLeft",
+ "GuildFrameLFGFrameMiddle",
+ "GuildFrameLFGFrameRight",
+ "GuildFrameNotesLabel",
+ "GuildFrameNotesText",
+ "GuildFrameOnlineTotals",
+ "GuildFramePopup_HideAll",
+ "GuildFramePopup_Show",
+ "GuildFramePromoteButton",
+ "GuildFrameTotals",
+ "GuildFrame_GetLastOnline",
+ "GuildInfo",
+ "GuildInfoCancelButton",
+ "GuildInfoCancelButtonText",
+ "GuildInfoCloseButton",
+ "GuildInfoCorner",
+ "GuildInfoEditBox",
+ "GuildInfoFrame",
+ "GuildInfoFrameScrollFrame",
+ "GuildInfoFrameScrollFrameScrollBar",
+ "GuildInfoFrameScrollFrameScrollBarScrollDownButton",
+ "GuildInfoFrameScrollFrameScrollBarScrollUpButton",
+ "GuildInfoFrameScrollFrameScrollBarThumbTexture",
+ "GuildInfoGuildEventButton",
+ "GuildInfoGuildEventButtonText",
+ "GuildInfoSaveButton",
+ "GuildInfoSaveButtonText",
+ "GuildInfoTextBackground",
+ "GuildInfoTitle",
+ "GuildInvite",
+ "GuildLeave",
+ "GuildListScrollFrame",
+ "GuildListScrollFrameScrollBar",
+ "GuildListScrollFrameScrollBarScrollDownButton",
+ "GuildListScrollFrameScrollBarScrollUpButton",
+ "GuildListScrollFrameScrollBarThumbTexture",
+ "GuildListScrollFrameScrollChildFrame",
+ "GuildMOTDEditButton",
+ "GuildMemberDetailCloseButton",
+ "GuildMemberDetailCorner",
+ "GuildMemberDetailFrame",
+ "GuildMemberDetailLevel",
+ "GuildMemberDetailName",
+ "GuildMemberDetailNoteLabel",
+ "GuildMemberDetailOfficerNoteLabel",
+ "GuildMemberDetailOnlineLabel",
+ "GuildMemberDetailOnlineText",
+ "GuildMemberDetailRankLabel",
+ "GuildMemberDetailRankText",
+ "GuildMemberDetailZoneLabel",
+ "GuildMemberDetailZoneText",
+ "GuildMemberGroupInviteButton",
+ "GuildMemberGroupInviteButtonText",
+ "GuildMemberNoteBackground",
+ "GuildMemberOfficerNoteBackground",
+ "GuildMemberRemoveButton",
+ "GuildMemberRemoveButtonText",
+ "GuildPlayerStatusFrame",
+ "GuildPromote",
+ "GuildRegistrarButton1",
+ "GuildRegistrarButton1QuestIcon",
+ "GuildRegistrarButton2",
+ "GuildRegistrarButton2QuestIcon",
+ "GuildRegistrarCostLabel",
+ "GuildRegistrarFrame",
+ "GuildRegistrarFrameCancelButton",
+ "GuildRegistrarFrameCancelButtonText",
+ "GuildRegistrarFrameCloseButton",
+ "GuildRegistrarFrameEditBox",
+ "GuildRegistrarFrameGoodbyeButton",
+ "GuildRegistrarFrameGoodbyeButtonText",
+ "GuildRegistrarFrameNpcNameText",
+ "GuildRegistrarFramePortrait",
+ "GuildRegistrarFramePurchaseButton",
+ "GuildRegistrarFramePurchaseButtonText",
+ "GuildRegistrarGreetingFrame",
+ "GuildRegistrarMoneyFrame",
+ "GuildRegistrarMoneyFrameCopperButton",
+ "GuildRegistrarMoneyFrameCopperButtonText",
+ "GuildRegistrarMoneyFrameGoldButton",
+ "GuildRegistrarMoneyFrameGoldButtonText",
+ "GuildRegistrarMoneyFrameSilverButton",
+ "GuildRegistrarMoneyFrameSilverButtonText",
+ "GuildRegistrarNpcNameFrame",
+ "GuildRegistrarPurchaseFrame",
+ "GuildRegistrarPurchaseText",
+ "GuildRegistrarText",
+ "GuildRegistrar_OnShow",
+ "GuildRegistrar_ShowPurchaseFrame",
+ "GuildRoster",
+ "GuildRosterSetOfficerNote",
+ "GuildRosterSetPublicNote",
+ "GuildSetLeader",
+ "GuildSetMOTD",
+ "GuildStatusFrame",
+ "GuildStatus_Update",
+ "GuildUninvite",
+ "HIGHLIGHT_FONT_COLOR",
+ "HUNTER_PET_BONUS",
+ "HandleModifiedItemClick",
+ "HasAction",
+ "HasCompletedAnyAchievement",
+ "HasDebugZoneMap",
+ "HasFilledPetition",
+ "HasFullControl",
+ "HasInspectHonorData",
+ "HasKey",
+ "HasLFGRestrictions",
+ "HasMessageType",
+ "HasMessageTypeGroup",
+ "HasMultiCastActionBar",
+ "HasMultiCastActionPage",
+ "HasNewMail",
+ "HasPetSpells",
+ "HasPetUI",
+ "HasSoulstone",
+ "HasWandEquipped",
+ "HealthBar_OnValueChanged",
+ "HearthAndResurrectFromArea",
+ "HelpFrame",
+ "HelpFrameCloseButton",
+ "HelpFrameGMTalk",
+ "HelpFrameGMTalkCancel",
+ "HelpFrameGMTalkCancelText",
+ "HelpFrameGMTalkIssue1",
+ "HelpFrameGMTalkIssue1Header",
+ "HelpFrameGMTalkIssue2",
+ "HelpFrameGMTalkIssue2Header",
+ "HelpFrameGMTalkIssue3",
+ "HelpFrameGMTalkIssue3Header",
+ "HelpFrameGMTalkOpenTicket",
+ "HelpFrameGMTalkOpenTicketLeft",
+ "HelpFrameGMTalkOpenTicketMiddle",
+ "HelpFrameGMTalkOpenTicketRight",
+ "HelpFrameGMTalkOpenTicketText",
+ "HelpFrameGMTalkPvpPolicyUrl",
+ "HelpFrameGMTalkText1",
+ "HelpFrameGMTalkText2",
+ "HelpFrameGMTalkTitle",
+ "HelpFrameGMTalk_OnShow",
+ "HelpFrameHeader",
+ "HelpFrameLag",
+ "HelpFrameLagAuctionHouse",
+ "HelpFrameLagAuctionHouseLeft",
+ "HelpFrameLagAuctionHouseMiddle",
+ "HelpFrameLagAuctionHouseRight",
+ "HelpFrameLagAuctionHouseText",
+ "HelpFrameLagCancel",
+ "HelpFrameLagCancelText",
+ "HelpFrameLagChat",
+ "HelpFrameLagChatLeft",
+ "HelpFrameLagChatMiddle",
+ "HelpFrameLagChatRight",
+ "HelpFrameLagChatText",
+ "HelpFrameLagLoot",
+ "HelpFrameLagLootLeft",
+ "HelpFrameLagLootMiddle",
+ "HelpFrameLagLootRight",
+ "HelpFrameLagLootText",
+ "HelpFrameLagMail",
+ "HelpFrameLagMailLeft",
+ "HelpFrameLagMailMiddle",
+ "HelpFrameLagMailRight",
+ "HelpFrameLagMailText",
+ "HelpFrameLagMovement",
+ "HelpFrameLagMovementLeft",
+ "HelpFrameLagMovementMiddle",
+ "HelpFrameLagMovementRight",
+ "HelpFrameLagMovementText",
+ "HelpFrameLagSpell",
+ "HelpFrameLagSpellLeft",
+ "HelpFrameLagSpellMiddle",
+ "HelpFrameLagSpellRight",
+ "HelpFrameLagSpellText",
+ "HelpFrameLagText1",
+ "HelpFrameLagTitle",
+ "HelpFrameOpenTicket",
+ "HelpFrameOpenTicketCancel",
+ "HelpFrameOpenTicketCancelText",
+ "HelpFrameOpenTicketCancel_OnClick",
+ "HelpFrameOpenTicketDivider",
+ "HelpFrameOpenTicketDividerLeft",
+ "HelpFrameOpenTicketDividerMiddle",
+ "HelpFrameOpenTicketDividerRight",
+ "HelpFrameOpenTicketEditBox",
+ "HelpFrameOpenTicketLabel",
+ "HelpFrameOpenTicketScrollFrame",
+ "HelpFrameOpenTicketScrollFrameScrollBar",
+ "HelpFrameOpenTicketScrollFrameScrollBarBottom",
+ "HelpFrameOpenTicketScrollFrameScrollBarMiddle",
+ "HelpFrameOpenTicketScrollFrameScrollBarScrollDownButton",
+ "HelpFrameOpenTicketScrollFrameScrollBarScrollUpButton",
+ "HelpFrameOpenTicketScrollFrameScrollBarThumbTexture",
+ "HelpFrameOpenTicketScrollFrameScrollBarTop",
+ "HelpFrameOpenTicketSubmit",
+ "HelpFrameOpenTicketSubmitText",
+ "HelpFrameOpenTicketSubmit_OnClick",
+ "HelpFrameReportIssue",
+ "HelpFrameReportIssueBullet1",
+ "HelpFrameReportIssueBullet1Text",
+ "HelpFrameReportIssueBullet2",
+ "HelpFrameReportIssueBullet2Text",
+ "HelpFrameReportIssueBulletTitle1",
+ "HelpFrameReportIssueCancel",
+ "HelpFrameReportIssueCancelText",
+ "HelpFrameReportIssueOpenTicket",
+ "HelpFrameReportIssueOpenTicketLeft",
+ "HelpFrameReportIssueOpenTicketMiddle",
+ "HelpFrameReportIssueOpenTicketRight",
+ "HelpFrameReportIssueOpenTicketText",
+ "HelpFrameReportIssueText1",
+ "HelpFrameReportIssueText2",
+ "HelpFrameReportIssueTitle",
+ "HelpFrameReportIssue_OnShow",
+ "HelpFrameStuck",
+ "HelpFrameStuckCancel",
+ "HelpFrameStuckCancelText",
+ "HelpFrameStuckOpenTicket",
+ "HelpFrameStuckOpenTicketLeft",
+ "HelpFrameStuckOpenTicketMiddle",
+ "HelpFrameStuckOpenTicketRight",
+ "HelpFrameStuckOpenTicketText",
+ "HelpFrameStuckStuck",
+ "HelpFrameStuckStuckLeft",
+ "HelpFrameStuckStuckMiddle",
+ "HelpFrameStuckStuckRight",
+ "HelpFrameStuckStuckText",
+ "HelpFrameStuckText1",
+ "HelpFrameStuckTitle",
+ "HelpFrameStuck_OnShow",
+ "HelpFrameViewResponse",
+ "HelpFrameViewResponseButton_OnLoad",
+ "HelpFrameViewResponseCancel",
+ "HelpFrameViewResponseCancelText",
+ "HelpFrameViewResponseDivider",
+ "HelpFrameViewResponseDividerLeft",
+ "HelpFrameViewResponseDividerMiddle",
+ "HelpFrameViewResponseDividerRight",
+ "HelpFrameViewResponseIssueBody",
+ "HelpFrameViewResponseIssueHeader",
+ "HelpFrameViewResponseIssueResolved",
+ "HelpFrameViewResponseIssueResolvedText",
+ "HelpFrameViewResponseIssueResolved_OnClick",
+ "HelpFrameViewResponseIssueScrollFrame",
+ "HelpFrameViewResponseIssueScrollFrameScrollBar",
+ "HelpFrameViewResponseIssueScrollFrameScrollBarBottom",
+ "HelpFrameViewResponseIssueScrollFrameScrollBarMiddle",
+ "HelpFrameViewResponseIssueScrollFrameScrollBarScrollDownButton",
+ "HelpFrameViewResponseIssueScrollFrameScrollBarScrollUpButton",
+ "HelpFrameViewResponseIssueScrollFrameScrollBarThumbTexture",
+ "HelpFrameViewResponseIssueScrollFrameScrollBarTop",
+ "HelpFrameViewResponseIssueScrollFrameScrollChild",
+ "HelpFrameViewResponseMessageBody",
+ "HelpFrameViewResponseMessageHeader",
+ "HelpFrameViewResponseMessageScrollFrame",
+ "HelpFrameViewResponseMessageScrollFrameScrollBar",
+ "HelpFrameViewResponseMessageScrollFrameScrollBarBottom",
+ "HelpFrameViewResponseMessageScrollFrameScrollBarMiddle",
+ "HelpFrameViewResponseMessageScrollFrameScrollBarScrollDownButton",
+ "HelpFrameViewResponseMessageScrollFrameScrollBarScrollUpButton",
+ "HelpFrameViewResponseMessageScrollFrameScrollBarThumbTexture",
+ "HelpFrameViewResponseMessageScrollFrameScrollBarTop",
+ "HelpFrameViewResponseMessageScrollFrameScrollChild",
+ "HelpFrameViewResponseMoreHelp",
+ "HelpFrameViewResponseMoreHelpText",
+ "HelpFrameViewResponseMoreHelp_OnClick",
+ "HelpFrameWelcome",
+ "HelpFrameWelcomeCancel",
+ "HelpFrameWelcomeCancelText",
+ "HelpFrameWelcomeGMTalk",
+ "HelpFrameWelcomeGMTalkLeft",
+ "HelpFrameWelcomeGMTalkMiddle",
+ "HelpFrameWelcomeGMTalkRight",
+ "HelpFrameWelcomeGMTalkText",
+ "HelpFrameWelcomeReportIssue",
+ "HelpFrameWelcomeReportIssueLeft",
+ "HelpFrameWelcomeReportIssueMiddle",
+ "HelpFrameWelcomeReportIssueRight",
+ "HelpFrameWelcomeReportIssueText",
+ "HelpFrameWelcomeStuck",
+ "HelpFrameWelcomeStuckLeft",
+ "HelpFrameWelcomeStuckMiddle",
+ "HelpFrameWelcomeStuckRight",
+ "HelpFrameWelcomeStuckText",
+ "HelpFrameWelcomeText1",
+ "HelpFrameWelcomeTitle",
+ "HelpFrame_HaveGMResponse",
+ "HelpFrame_HaveGMTicket",
+ "HelpFrame_IsGMTicketQueueActive",
+ "HelpFrame_OnEvent",
+ "HelpFrame_OnHide",
+ "HelpFrame_OnLoad",
+ "HelpFrame_OnShow",
+ "HelpFrame_PopAllFrames",
+ "HelpFrame_PopFrame",
+ "HelpFrame_ShowFrame",
+ "HelpMicroButton",
+ "HelpPanelOptions",
+ "HelpReportLag",
+ "HideBonusActionBar",
+ "HideDropDownMenu",
+ "HideMultiCastActionBar",
+ "HideParentPanel",
+ "HidePartyFrame",
+ "HidePetActionBar",
+ "HideRepairCursor",
+ "HideTextStatusBarText",
+ "HideUIPanel",
+ "HideWatchedReputationBarText",
+ "HonorFrame",
+ "HonorFrameCurrentDK",
+ "HonorFrameCurrentDKText",
+ "HonorFrameCurrentDKValue",
+ "HonorFrameCurrentHK",
+ "HonorFrameCurrentHKText",
+ "HonorFrameCurrentHKValue",
+ "HonorFrameCurrentPVPRank",
+ "HonorFrameCurrentPVPTitle",
+ "HonorFrameCurrentSessionTitle",
+ "HonorFrameLastWeekContribution",
+ "HonorFrameLastWeekContributionText",
+ "HonorFrameLastWeekContributionValue",
+ "HonorFrameLastWeekHK",
+ "HonorFrameLastWeekHKText",
+ "HonorFrameLastWeekHKValue",
+ "HonorFrameLastWeekStanding",
+ "HonorFrameLastWeekStandingText",
+ "HonorFrameLastWeekStandingValue",
+ "HonorFrameLastWeekTitle",
+ "HonorFrameLifeTimeDK",
+ "HonorFrameLifeTimeDKText",
+ "HonorFrameLifeTimeDKValue",
+ "HonorFrameLifeTimeHK",
+ "HonorFrameLifeTimeHKText",
+ "HonorFrameLifeTimeHKValue",
+ "HonorFrameLifeTimeRank",
+ "HonorFrameLifeTimeRankText",
+ "HonorFrameLifeTimeRankValue",
+ "HonorFrameLifeTimeTitle",
+ "HonorFrameProgressBar",
+ "HonorFrameProgressBarBar",
+ "HonorFrameProgressButton",
+ "HonorFramePvPIcon",
+ "HonorFrameRankButton",
+ "HonorFrameThisWeekContribution",
+ "HonorFrameThisWeekContributionText",
+ "HonorFrameThisWeekContributionValue",
+ "HonorFrameThisWeekHK",
+ "HonorFrameThisWeekHKText",
+ "HonorFrameThisWeekHKValue",
+ "HonorFrameThisWeekTitle",
+ "HonorFrameYesterdayContribution",
+ "HonorFrameYesterdayContributionText",
+ "HonorFrameYesterdayContributionValue",
+ "HonorFrameYesterdayHK",
+ "HonorFrameYesterdayHKText",
+ "HonorFrameYesterdayHKValue",
+ "HonorFrameYesterdayTitle",
+ "HonorFrame_OnEvent",
+ "HonorFrame_OnLoad",
+ "HonorFrame_Update",
+ "HonorGuildText",
+ "HonorLevelText",
+ "HybridScrollFrameScrollButton_OnClick",
+ "HybridScrollFrameScrollButton_OnUpdate",
+ "HybridScrollFrameScrollChild_OnLoad",
+ "HybridScrollFrame_CollapseButton",
+ "HybridScrollFrame_CreateButtons",
+ "HybridScrollFrame_ExpandButton",
+ "HybridScrollFrame_GetOffset",
+ "HybridScrollFrame_OnLoad",
+ "HybridScrollFrame_OnMouseWheel",
+ "HybridScrollFrame_OnValueChanged",
+ "HybridScrollFrame_SetOffset",
+ "HybridScrollFrame_Update",
+ "HybridScrollFrame_UpdateButtonStates",
+ "ICON_LIST",
+ "ICON_TAG_LIST",
+ "INSPECTFRAME_SUBFRAMES",
+ "INTERFACEOPTIONS_ADDONCATEGORIES",
+ "INVENTORY_ALERT_COLORS",
+ "INVENTORY_ALERT_STATUS_SLOTS",
+ "INVSLOTS_EQUIPABLE_IN_COMBAT",
+ "ITEM_QUALITY_COLORS",
+ "IgnoreListFrame",
+ "IgnoreList_SetHeader",
+ "IgnoreList_Update",
+ "InCinematic",
+ "InCombatLockdown",
+ "InGuildCheck",
+ "InRepairMode",
+ "InboxCloseButton",
+ "InboxCurrentPage",
+ "InboxFrame",
+ "InboxFrameItem_OnEnter",
+ "InboxFrame_OnClick",
+ "InboxFrame_OnModifiedClick",
+ "InboxFrame_Update",
+ "InboxGetMoreMail",
+ "InboxItemCanDelete",
+ "InboxNextPage",
+ "InboxNextPageButton",
+ "InboxPrevPage",
+ "InboxPrevPageButton",
+ "InboxTitleText",
+ "InboxTooMuchMail",
+ "InboxTooMuchMailText",
+ "InitWorldMapPing",
+ "InitiateTrade",
+ "InspectAchievements",
+ "InspectBackSlot",
+ "InspectBackSlotCount",
+ "InspectBackSlotIconTexture",
+ "InspectBackSlotStock",
+ "InspectChestSlot",
+ "InspectChestSlotCount",
+ "InspectChestSlotIconTexture",
+ "InspectChestSlotStock",
+ "InspectFeetSlot",
+ "InspectFeetSlotCount",
+ "InspectFeetSlotIconTexture",
+ "InspectFeetSlotStock",
+ "InspectFinger0Slot",
+ "InspectFinger0SlotCount",
+ "InspectFinger0SlotIconTexture",
+ "InspectFinger0SlotStock",
+ "InspectFinger1Slot",
+ "InspectFinger1SlotCount",
+ "InspectFinger1SlotIconTexture",
+ "InspectFinger1SlotStock",
+ "InspectFrame",
+ "InspectFrameCloseButton",
+ "InspectFramePortrait",
+ "InspectFrameTab1",
+ "InspectFrameTab1HighlightTexture",
+ "InspectFrameTab1Left",
+ "InspectFrameTab1LeftDisabled",
+ "InspectFrameTab1Middle",
+ "InspectFrameTab1MiddleDisabled",
+ "InspectFrameTab1Right",
+ "InspectFrameTab1RightDisabled",
+ "InspectFrameTab1Text",
+ "InspectFrameTab2",
+ "InspectFrameTab2HighlightTexture",
+ "InspectFrameTab2Left",
+ "InspectFrameTab2LeftDisabled",
+ "InspectFrameTab2Middle",
+ "InspectFrameTab2MiddleDisabled",
+ "InspectFrameTab2Right",
+ "InspectFrameTab2RightDisabled",
+ "InspectFrameTab2Text",
+ "InspectFrameTab3",
+ "InspectFrameTab3HighlightTexture",
+ "InspectFrameTab3Left",
+ "InspectFrameTab3LeftDisabled",
+ "InspectFrameTab3Middle",
+ "InspectFrameTab3MiddleDisabled",
+ "InspectFrameTab3Right",
+ "InspectFrameTab3RightDisabled",
+ "InspectFrameTab3Text",
+ "InspectFrameTab_OnClick",
+ "InspectFrame_LoadUI",
+ "InspectFrame_OnEvent",
+ "InspectFrame_OnHide",
+ "InspectFrame_OnLoad",
+ "InspectFrame_OnShow",
+ "InspectFrame_OnUpdate",
+ "InspectFrame_Show",
+ "InspectFrame_UnitChanged",
+ "InspectFrame_UpdateTalentTab",
+ "InspectGuildText",
+ "InspectHandsSlot",
+ "InspectHandsSlotCount",
+ "InspectHandsSlotIconTexture",
+ "InspectHandsSlotStock",
+ "InspectHeadSlot",
+ "InspectHeadSlotCount",
+ "InspectHeadSlotIconTexture",
+ "InspectHeadSlotStock",
+ "InspectLegsSlot",
+ "InspectLegsSlotCount",
+ "InspectLegsSlotIconTexture",
+ "InspectLegsSlotStock",
+ "InspectLevelText",
+ "InspectMainHandSlot",
+ "InspectMainHandSlotCount",
+ "InspectMainHandSlotIconTexture",
+ "InspectMainHandSlotStock",
+ "InspectModelFrame",
+ "InspectModelFrame_OnLoad",
+ "InspectModelFrame_OnUpdate",
+ "InspectModelRotateLeftButton",
+ "InspectModelRotateLeftButton_OnClick",
+ "InspectModelRotateRightButton",
+ "InspectModelRotateRightButton_OnClick",
+ "InspectNameFrame",
+ "InspectNameText",
+ "InspectNeckSlot",
+ "InspectNeckSlotCount",
+ "InspectNeckSlotIconTexture",
+ "InspectNeckSlotStock",
+ "InspectPVPFrame",
+ "InspectPVPFrameArena",
+ "InspectPVPFrameArenaIcon",
+ "InspectPVPFrameArenaLabel",
+ "InspectPVPFrameArenaPoints",
+ "InspectPVPFrameBackground",
+ "InspectPVPFrameHonor",
+ "InspectPVPFrameHonorIcon",
+ "InspectPVPFrameHonorLabel",
+ "InspectPVPFrameHonorPoints",
+ "InspectPVPFrameLine1",
+ "InspectPVPFrame_OnEvent",
+ "InspectPVPFrame_OnLoad",
+ "InspectPVPFrame_OnShow",
+ "InspectPVPFrame_SetFaction",
+ "InspectPVPFrame_Update",
+ "InspectPVPHonor",
+ "InspectPVPHonorHonorLabel",
+ "InspectPVPHonorKillsLabel",
+ "InspectPVPHonorLifetimeHonor",
+ "InspectPVPHonorLifetimeKills",
+ "InspectPVPHonorLifetimeLabel",
+ "InspectPVPHonorTodayHonor",
+ "InspectPVPHonorTodayKills",
+ "InspectPVPHonorTodayLabel",
+ "InspectPVPHonorYesterdayHonor",
+ "InspectPVPHonorYesterdayKills",
+ "InspectPVPHonorYesterdayLabel",
+ "InspectPVPHonor_Update",
+ "InspectPVPTeam1",
+ "InspectPVPTeam1Background",
+ "InspectPVPTeam1Bottom",
+ "InspectPVPTeam1Data",
+ "InspectPVPTeam1Data-",
+ "InspectPVPTeam1DataGames",
+ "InspectPVPTeam1DataGamesLabel",
+ "InspectPVPTeam1DataLoss",
+ "InspectPVPTeam1DataName",
+ "InspectPVPTeam1DataPlayed",
+ "InspectPVPTeam1DataPlayedLabel",
+ "InspectPVPTeam1DataRating",
+ "InspectPVPTeam1DataRatingLabel",
+ "InspectPVPTeam1DataTypeLabel",
+ "InspectPVPTeam1DataWinLossLabel",
+ "InspectPVPTeam1DataWins",
+ "InspectPVPTeam1Highlight",
+ "InspectPVPTeam1Left",
+ "InspectPVPTeam1Right",
+ "InspectPVPTeam1Standard",
+ "InspectPVPTeam1StandardBanner",
+ "InspectPVPTeam1StandardBar",
+ "InspectPVPTeam1StandardBorder",
+ "InspectPVPTeam1StandardEmblem",
+ "InspectPVPTeam1TeamType",
+ "InspectPVPTeam1Top",
+ "InspectPVPTeam2",
+ "InspectPVPTeam2Background",
+ "InspectPVPTeam2Bottom",
+ "InspectPVPTeam2Data",
+ "InspectPVPTeam2Data-",
+ "InspectPVPTeam2DataGames",
+ "InspectPVPTeam2DataGamesLabel",
+ "InspectPVPTeam2DataLoss",
+ "InspectPVPTeam2DataName",
+ "InspectPVPTeam2DataPlayed",
+ "InspectPVPTeam2DataPlayedLabel",
+ "InspectPVPTeam2DataRating",
+ "InspectPVPTeam2DataRatingLabel",
+ "InspectPVPTeam2DataTypeLabel",
+ "InspectPVPTeam2DataWinLossLabel",
+ "InspectPVPTeam2DataWins",
+ "InspectPVPTeam2Highlight",
+ "InspectPVPTeam2Left",
+ "InspectPVPTeam2Right",
+ "InspectPVPTeam2Standard",
+ "InspectPVPTeam2StandardBanner",
+ "InspectPVPTeam2StandardBar",
+ "InspectPVPTeam2StandardBorder",
+ "InspectPVPTeam2StandardEmblem",
+ "InspectPVPTeam2TeamType",
+ "InspectPVPTeam2Top",
+ "InspectPVPTeam3",
+ "InspectPVPTeam3Background",
+ "InspectPVPTeam3Bottom",
+ "InspectPVPTeam3Data",
+ "InspectPVPTeam3Data-",
+ "InspectPVPTeam3DataGames",
+ "InspectPVPTeam3DataGamesLabel",
+ "InspectPVPTeam3DataLoss",
+ "InspectPVPTeam3DataName",
+ "InspectPVPTeam3DataPlayed",
+ "InspectPVPTeam3DataPlayedLabel",
+ "InspectPVPTeam3DataRating",
+ "InspectPVPTeam3DataRatingLabel",
+ "InspectPVPTeam3DataTypeLabel",
+ "InspectPVPTeam3DataWinLossLabel",
+ "InspectPVPTeam3DataWins",
+ "InspectPVPTeam3Highlight",
+ "InspectPVPTeam3Left",
+ "InspectPVPTeam3Right",
+ "InspectPVPTeam3Standard",
+ "InspectPVPTeam3StandardBanner",
+ "InspectPVPTeam3StandardBar",
+ "InspectPVPTeam3StandardBorder",
+ "InspectPVPTeam3StandardEmblem",
+ "InspectPVPTeam3TeamType",
+ "InspectPVPTeam3Top",
+ "InspectPVPTeam_Update",
+ "InspectPaperDollFrame",
+ "InspectPaperDollFrame_OnEvent",
+ "InspectPaperDollFrame_OnLoad",
+ "InspectPaperDollFrame_OnShow",
+ "InspectPaperDollFrame_SetLevel",
+ "InspectPaperDollItemSlotButton_OnEnter",
+ "InspectPaperDollItemSlotButton_OnEvent",
+ "InspectPaperDollItemSlotButton_OnLoad",
+ "InspectPaperDollItemSlotButton_Update",
+ "InspectRangedSlot",
+ "InspectRangedSlotCount",
+ "InspectRangedSlotIconTexture",
+ "InspectRangedSlotStock",
+ "InspectSecondaryHandSlot",
+ "InspectSecondaryHandSlotCount",
+ "InspectSecondaryHandSlotIconTexture",
+ "InspectSecondaryHandSlotStock",
+ "InspectShirtSlot",
+ "InspectShirtSlotCount",
+ "InspectShirtSlotIconTexture",
+ "InspectShirtSlotStock",
+ "InspectShoulderSlot",
+ "InspectShoulderSlotCount",
+ "InspectShoulderSlotIconTexture",
+ "InspectShoulderSlotStock",
+ "InspectSwitchTabs",
+ "InspectTabardSlot",
+ "InspectTabardSlotCount",
+ "InspectTabardSlotIconTexture",
+ "InspectTabardSlotStock",
+ "InspectTalentFrame",
+ "InspectTalentFrameArrow1",
+ "InspectTalentFrameArrow10",
+ "InspectTalentFrameArrow11",
+ "InspectTalentFrameArrow12",
+ "InspectTalentFrameArrow13",
+ "InspectTalentFrameArrow14",
+ "InspectTalentFrameArrow15",
+ "InspectTalentFrameArrow16",
+ "InspectTalentFrameArrow17",
+ "InspectTalentFrameArrow18",
+ "InspectTalentFrameArrow19",
+ "InspectTalentFrameArrow2",
+ "InspectTalentFrameArrow20",
+ "InspectTalentFrameArrow21",
+ "InspectTalentFrameArrow22",
+ "InspectTalentFrameArrow23",
+ "InspectTalentFrameArrow24",
+ "InspectTalentFrameArrow25",
+ "InspectTalentFrameArrow26",
+ "InspectTalentFrameArrow27",
+ "InspectTalentFrameArrow28",
+ "InspectTalentFrameArrow29",
+ "InspectTalentFrameArrow3",
+ "InspectTalentFrameArrow30",
+ "InspectTalentFrameArrow4",
+ "InspectTalentFrameArrow5",
+ "InspectTalentFrameArrow6",
+ "InspectTalentFrameArrow7",
+ "InspectTalentFrameArrow8",
+ "InspectTalentFrameArrow9",
+ "InspectTalentFrameArrowFrame",
+ "InspectTalentFrameBackgroundBottomLeft",
+ "InspectTalentFrameBackgroundBottomRight",
+ "InspectTalentFrameBackgroundTopLeft",
+ "InspectTalentFrameBackgroundTopRight",
+ "InspectTalentFrameBranch1",
+ "InspectTalentFrameBranch10",
+ "InspectTalentFrameBranch11",
+ "InspectTalentFrameBranch12",
+ "InspectTalentFrameBranch13",
+ "InspectTalentFrameBranch14",
+ "InspectTalentFrameBranch15",
+ "InspectTalentFrameBranch16",
+ "InspectTalentFrameBranch17",
+ "InspectTalentFrameBranch18",
+ "InspectTalentFrameBranch19",
+ "InspectTalentFrameBranch2",
+ "InspectTalentFrameBranch20",
+ "InspectTalentFrameBranch21",
+ "InspectTalentFrameBranch22",
+ "InspectTalentFrameBranch23",
+ "InspectTalentFrameBranch24",
+ "InspectTalentFrameBranch25",
+ "InspectTalentFrameBranch26",
+ "InspectTalentFrameBranch27",
+ "InspectTalentFrameBranch28",
+ "InspectTalentFrameBranch29",
+ "InspectTalentFrameBranch3",
+ "InspectTalentFrameBranch30",
+ "InspectTalentFrameBranch4",
+ "InspectTalentFrameBranch5",
+ "InspectTalentFrameBranch6",
+ "InspectTalentFrameBranch7",
+ "InspectTalentFrameBranch8",
+ "InspectTalentFrameBranch9",
+ "InspectTalentFrameCloseButton",
+ "InspectTalentFrameDownArrow_OnClick",
+ "InspectTalentFramePointsBar",
+ "InspectTalentFramePointsBarBackground",
+ "InspectTalentFramePointsBarBorderLeft",
+ "InspectTalentFramePointsBarBorderMiddle",
+ "InspectTalentFramePointsBarBorderRight",
+ "InspectTalentFramePointsBar_OnEnter",
+ "InspectTalentFramePortrait",
+ "InspectTalentFrameScrollButtonOverlay",
+ "InspectTalentFrameScrollChildFrame",
+ "InspectTalentFrameScrollFrame",
+ "InspectTalentFrameScrollFrameScrollBar",
+ "InspectTalentFrameScrollFrameScrollBarScrollDownButton",
+ "InspectTalentFrameScrollFrameScrollBarScrollUpButton",
+ "InspectTalentFrameScrollFrameScrollBarThumbTexture",
+ "InspectTalentFrameSpentPointsText",
+ "InspectTalentFrameTab1",
+ "InspectTalentFrameTab1HighlightTexture",
+ "InspectTalentFrameTab1Left",
+ "InspectTalentFrameTab1LeftDisabled",
+ "InspectTalentFrameTab1Middle",
+ "InspectTalentFrameTab1MiddleDisabled",
+ "InspectTalentFrameTab1Right",
+ "InspectTalentFrameTab1RightDisabled",
+ "InspectTalentFrameTab1Text",
+ "InspectTalentFrameTab2",
+ "InspectTalentFrameTab2HighlightTexture",
+ "InspectTalentFrameTab2Left",
+ "InspectTalentFrameTab2LeftDisabled",
+ "InspectTalentFrameTab2Middle",
+ "InspectTalentFrameTab2MiddleDisabled",
+ "InspectTalentFrameTab2Right",
+ "InspectTalentFrameTab2RightDisabled",
+ "InspectTalentFrameTab2Text",
+ "InspectTalentFrameTab3",
+ "InspectTalentFrameTab3HighlightTexture",
+ "InspectTalentFrameTab3Left",
+ "InspectTalentFrameTab3LeftDisabled",
+ "InspectTalentFrameTab3Middle",
+ "InspectTalentFrameTab3MiddleDisabled",
+ "InspectTalentFrameTab3Right",
+ "InspectTalentFrameTab3RightDisabled",
+ "InspectTalentFrameTab3Text",
+ "InspectTalentFrameTalent1",
+ "InspectTalentFrameTalent10",
+ "InspectTalentFrameTalent10Count",
+ "InspectTalentFrameTalent10IconTexture",
+ "InspectTalentFrameTalent10NormalTexture",
+ "InspectTalentFrameTalent10Rank",
+ "InspectTalentFrameTalent10RankBorder",
+ "InspectTalentFrameTalent10Slot",
+ "InspectTalentFrameTalent10Stock",
+ "InspectTalentFrameTalent11",
+ "InspectTalentFrameTalent11Count",
+ "InspectTalentFrameTalent11IconTexture",
+ "InspectTalentFrameTalent11NormalTexture",
+ "InspectTalentFrameTalent11Rank",
+ "InspectTalentFrameTalent11RankBorder",
+ "InspectTalentFrameTalent11Slot",
+ "InspectTalentFrameTalent11Stock",
+ "InspectTalentFrameTalent12",
+ "InspectTalentFrameTalent12Count",
+ "InspectTalentFrameTalent12IconTexture",
+ "InspectTalentFrameTalent12NormalTexture",
+ "InspectTalentFrameTalent12Rank",
+ "InspectTalentFrameTalent12RankBorder",
+ "InspectTalentFrameTalent12Slot",
+ "InspectTalentFrameTalent12Stock",
+ "InspectTalentFrameTalent13",
+ "InspectTalentFrameTalent13Count",
+ "InspectTalentFrameTalent13IconTexture",
+ "InspectTalentFrameTalent13NormalTexture",
+ "InspectTalentFrameTalent13Rank",
+ "InspectTalentFrameTalent13RankBorder",
+ "InspectTalentFrameTalent13Slot",
+ "InspectTalentFrameTalent13Stock",
+ "InspectTalentFrameTalent14",
+ "InspectTalentFrameTalent14Count",
+ "InspectTalentFrameTalent14IconTexture",
+ "InspectTalentFrameTalent14NormalTexture",
+ "InspectTalentFrameTalent14Rank",
+ "InspectTalentFrameTalent14RankBorder",
+ "InspectTalentFrameTalent14Slot",
+ "InspectTalentFrameTalent14Stock",
+ "InspectTalentFrameTalent15",
+ "InspectTalentFrameTalent15Count",
+ "InspectTalentFrameTalent15IconTexture",
+ "InspectTalentFrameTalent15NormalTexture",
+ "InspectTalentFrameTalent15Rank",
+ "InspectTalentFrameTalent15RankBorder",
+ "InspectTalentFrameTalent15Slot",
+ "InspectTalentFrameTalent15Stock",
+ "InspectTalentFrameTalent16",
+ "InspectTalentFrameTalent16Count",
+ "InspectTalentFrameTalent16IconTexture",
+ "InspectTalentFrameTalent16NormalTexture",
+ "InspectTalentFrameTalent16Rank",
+ "InspectTalentFrameTalent16RankBorder",
+ "InspectTalentFrameTalent16Slot",
+ "InspectTalentFrameTalent16Stock",
+ "InspectTalentFrameTalent17",
+ "InspectTalentFrameTalent17Count",
+ "InspectTalentFrameTalent17IconTexture",
+ "InspectTalentFrameTalent17NormalTexture",
+ "InspectTalentFrameTalent17Rank",
+ "InspectTalentFrameTalent17RankBorder",
+ "InspectTalentFrameTalent17Slot",
+ "InspectTalentFrameTalent17Stock",
+ "InspectTalentFrameTalent18",
+ "InspectTalentFrameTalent18Count",
+ "InspectTalentFrameTalent18IconTexture",
+ "InspectTalentFrameTalent18NormalTexture",
+ "InspectTalentFrameTalent18Rank",
+ "InspectTalentFrameTalent18RankBorder",
+ "InspectTalentFrameTalent18Slot",
+ "InspectTalentFrameTalent18Stock",
+ "InspectTalentFrameTalent19",
+ "InspectTalentFrameTalent19Count",
+ "InspectTalentFrameTalent19IconTexture",
+ "InspectTalentFrameTalent19NormalTexture",
+ "InspectTalentFrameTalent19Rank",
+ "InspectTalentFrameTalent19RankBorder",
+ "InspectTalentFrameTalent19Slot",
+ "InspectTalentFrameTalent19Stock",
+ "InspectTalentFrameTalent1Count",
+ "InspectTalentFrameTalent1IconTexture",
+ "InspectTalentFrameTalent1NormalTexture",
+ "InspectTalentFrameTalent1Rank",
+ "InspectTalentFrameTalent1RankBorder",
+ "InspectTalentFrameTalent1Slot",
+ "InspectTalentFrameTalent1Stock",
+ "InspectTalentFrameTalent2",
+ "InspectTalentFrameTalent20",
+ "InspectTalentFrameTalent20Count",
+ "InspectTalentFrameTalent20IconTexture",
+ "InspectTalentFrameTalent20NormalTexture",
+ "InspectTalentFrameTalent20Rank",
+ "InspectTalentFrameTalent20RankBorder",
+ "InspectTalentFrameTalent20Slot",
+ "InspectTalentFrameTalent20Stock",
+ "InspectTalentFrameTalent21",
+ "InspectTalentFrameTalent21Count",
+ "InspectTalentFrameTalent21IconTexture",
+ "InspectTalentFrameTalent21NormalTexture",
+ "InspectTalentFrameTalent21Rank",
+ "InspectTalentFrameTalent21RankBorder",
+ "InspectTalentFrameTalent21Slot",
+ "InspectTalentFrameTalent21Stock",
+ "InspectTalentFrameTalent22",
+ "InspectTalentFrameTalent22Count",
+ "InspectTalentFrameTalent22IconTexture",
+ "InspectTalentFrameTalent22NormalTexture",
+ "InspectTalentFrameTalent22Rank",
+ "InspectTalentFrameTalent22RankBorder",
+ "InspectTalentFrameTalent22Slot",
+ "InspectTalentFrameTalent22Stock",
+ "InspectTalentFrameTalent23",
+ "InspectTalentFrameTalent23Count",
+ "InspectTalentFrameTalent23IconTexture",
+ "InspectTalentFrameTalent23NormalTexture",
+ "InspectTalentFrameTalent23Rank",
+ "InspectTalentFrameTalent23RankBorder",
+ "InspectTalentFrameTalent23Slot",
+ "InspectTalentFrameTalent23Stock",
+ "InspectTalentFrameTalent24",
+ "InspectTalentFrameTalent24Count",
+ "InspectTalentFrameTalent24IconTexture",
+ "InspectTalentFrameTalent24NormalTexture",
+ "InspectTalentFrameTalent24Rank",
+ "InspectTalentFrameTalent24RankBorder",
+ "InspectTalentFrameTalent24Slot",
+ "InspectTalentFrameTalent24Stock",
+ "InspectTalentFrameTalent25",
+ "InspectTalentFrameTalent25Count",
+ "InspectTalentFrameTalent25IconTexture",
+ "InspectTalentFrameTalent25NormalTexture",
+ "InspectTalentFrameTalent25Rank",
+ "InspectTalentFrameTalent25RankBorder",
+ "InspectTalentFrameTalent25Slot",
+ "InspectTalentFrameTalent25Stock",
+ "InspectTalentFrameTalent26",
+ "InspectTalentFrameTalent26Count",
+ "InspectTalentFrameTalent26IconTexture",
+ "InspectTalentFrameTalent26NormalTexture",
+ "InspectTalentFrameTalent26Rank",
+ "InspectTalentFrameTalent26RankBorder",
+ "InspectTalentFrameTalent26Slot",
+ "InspectTalentFrameTalent26Stock",
+ "InspectTalentFrameTalent27",
+ "InspectTalentFrameTalent27Count",
+ "InspectTalentFrameTalent27IconTexture",
+ "InspectTalentFrameTalent27NormalTexture",
+ "InspectTalentFrameTalent27Rank",
+ "InspectTalentFrameTalent27RankBorder",
+ "InspectTalentFrameTalent27Slot",
+ "InspectTalentFrameTalent27Stock",
+ "InspectTalentFrameTalent28",
+ "InspectTalentFrameTalent28Count",
+ "InspectTalentFrameTalent28IconTexture",
+ "InspectTalentFrameTalent28NormalTexture",
+ "InspectTalentFrameTalent28Rank",
+ "InspectTalentFrameTalent28RankBorder",
+ "InspectTalentFrameTalent28Slot",
+ "InspectTalentFrameTalent28Stock",
+ "InspectTalentFrameTalent29",
+ "InspectTalentFrameTalent29Count",
+ "InspectTalentFrameTalent29IconTexture",
+ "InspectTalentFrameTalent29NormalTexture",
+ "InspectTalentFrameTalent29Rank",
+ "InspectTalentFrameTalent29RankBorder",
+ "InspectTalentFrameTalent29Slot",
+ "InspectTalentFrameTalent29Stock",
+ "InspectTalentFrameTalent2Count",
+ "InspectTalentFrameTalent2IconTexture",
+ "InspectTalentFrameTalent2NormalTexture",
+ "InspectTalentFrameTalent2Rank",
+ "InspectTalentFrameTalent2RankBorder",
+ "InspectTalentFrameTalent2Slot",
+ "InspectTalentFrameTalent2Stock",
+ "InspectTalentFrameTalent3",
+ "InspectTalentFrameTalent30",
+ "InspectTalentFrameTalent30Count",
+ "InspectTalentFrameTalent30IconTexture",
+ "InspectTalentFrameTalent30NormalTexture",
+ "InspectTalentFrameTalent30Rank",
+ "InspectTalentFrameTalent30RankBorder",
+ "InspectTalentFrameTalent30Slot",
+ "InspectTalentFrameTalent30Stock",
+ "InspectTalentFrameTalent31",
+ "InspectTalentFrameTalent31Count",
+ "InspectTalentFrameTalent31IconTexture",
+ "InspectTalentFrameTalent31NormalTexture",
+ "InspectTalentFrameTalent31Rank",
+ "InspectTalentFrameTalent31RankBorder",
+ "InspectTalentFrameTalent31Slot",
+ "InspectTalentFrameTalent31Stock",
+ "InspectTalentFrameTalent32",
+ "InspectTalentFrameTalent32Count",
+ "InspectTalentFrameTalent32IconTexture",
+ "InspectTalentFrameTalent32NormalTexture",
+ "InspectTalentFrameTalent32Rank",
+ "InspectTalentFrameTalent32RankBorder",
+ "InspectTalentFrameTalent32Slot",
+ "InspectTalentFrameTalent32Stock",
+ "InspectTalentFrameTalent33",
+ "InspectTalentFrameTalent33Count",
+ "InspectTalentFrameTalent33IconTexture",
+ "InspectTalentFrameTalent33NormalTexture",
+ "InspectTalentFrameTalent33Rank",
+ "InspectTalentFrameTalent33RankBorder",
+ "InspectTalentFrameTalent33Slot",
+ "InspectTalentFrameTalent33Stock",
+ "InspectTalentFrameTalent34",
+ "InspectTalentFrameTalent34Count",
+ "InspectTalentFrameTalent34IconTexture",
+ "InspectTalentFrameTalent34NormalTexture",
+ "InspectTalentFrameTalent34Rank",
+ "InspectTalentFrameTalent34RankBorder",
+ "InspectTalentFrameTalent34Slot",
+ "InspectTalentFrameTalent34Stock",
+ "InspectTalentFrameTalent35",
+ "InspectTalentFrameTalent35Count",
+ "InspectTalentFrameTalent35IconTexture",
+ "InspectTalentFrameTalent35NormalTexture",
+ "InspectTalentFrameTalent35Rank",
+ "InspectTalentFrameTalent35RankBorder",
+ "InspectTalentFrameTalent35Slot",
+ "InspectTalentFrameTalent35Stock",
+ "InspectTalentFrameTalent36",
+ "InspectTalentFrameTalent36Count",
+ "InspectTalentFrameTalent36IconTexture",
+ "InspectTalentFrameTalent36NormalTexture",
+ "InspectTalentFrameTalent36Rank",
+ "InspectTalentFrameTalent36RankBorder",
+ "InspectTalentFrameTalent36Slot",
+ "InspectTalentFrameTalent36Stock",
+ "InspectTalentFrameTalent37",
+ "InspectTalentFrameTalent37Count",
+ "InspectTalentFrameTalent37IconTexture",
+ "InspectTalentFrameTalent37NormalTexture",
+ "InspectTalentFrameTalent37Rank",
+ "InspectTalentFrameTalent37RankBorder",
+ "InspectTalentFrameTalent37Slot",
+ "InspectTalentFrameTalent37Stock",
+ "InspectTalentFrameTalent38",
+ "InspectTalentFrameTalent38Count",
+ "InspectTalentFrameTalent38IconTexture",
+ "InspectTalentFrameTalent38NormalTexture",
+ "InspectTalentFrameTalent38Rank",
+ "InspectTalentFrameTalent38RankBorder",
+ "InspectTalentFrameTalent38Slot",
+ "InspectTalentFrameTalent38Stock",
+ "InspectTalentFrameTalent39",
+ "InspectTalentFrameTalent39Count",
+ "InspectTalentFrameTalent39IconTexture",
+ "InspectTalentFrameTalent39NormalTexture",
+ "InspectTalentFrameTalent39Rank",
+ "InspectTalentFrameTalent39RankBorder",
+ "InspectTalentFrameTalent39Slot",
+ "InspectTalentFrameTalent39Stock",
+ "InspectTalentFrameTalent3Count",
+ "InspectTalentFrameTalent3IconTexture",
+ "InspectTalentFrameTalent3NormalTexture",
+ "InspectTalentFrameTalent3Rank",
+ "InspectTalentFrameTalent3RankBorder",
+ "InspectTalentFrameTalent3Slot",
+ "InspectTalentFrameTalent3Stock",
+ "InspectTalentFrameTalent4",
+ "InspectTalentFrameTalent40",
+ "InspectTalentFrameTalent40Count",
+ "InspectTalentFrameTalent40IconTexture",
+ "InspectTalentFrameTalent40NormalTexture",
+ "InspectTalentFrameTalent40Rank",
+ "InspectTalentFrameTalent40RankBorder",
+ "InspectTalentFrameTalent40Slot",
+ "InspectTalentFrameTalent40Stock",
+ "InspectTalentFrameTalent4Count",
+ "InspectTalentFrameTalent4IconTexture",
+ "InspectTalentFrameTalent4NormalTexture",
+ "InspectTalentFrameTalent4Rank",
+ "InspectTalentFrameTalent4RankBorder",
+ "InspectTalentFrameTalent4Slot",
+ "InspectTalentFrameTalent4Stock",
+ "InspectTalentFrameTalent5",
+ "InspectTalentFrameTalent5Count",
+ "InspectTalentFrameTalent5IconTexture",
+ "InspectTalentFrameTalent5NormalTexture",
+ "InspectTalentFrameTalent5Rank",
+ "InspectTalentFrameTalent5RankBorder",
+ "InspectTalentFrameTalent5Slot",
+ "InspectTalentFrameTalent5Stock",
+ "InspectTalentFrameTalent6",
+ "InspectTalentFrameTalent6Count",
+ "InspectTalentFrameTalent6IconTexture",
+ "InspectTalentFrameTalent6NormalTexture",
+ "InspectTalentFrameTalent6Rank",
+ "InspectTalentFrameTalent6RankBorder",
+ "InspectTalentFrameTalent6Slot",
+ "InspectTalentFrameTalent6Stock",
+ "InspectTalentFrameTalent7",
+ "InspectTalentFrameTalent7Count",
+ "InspectTalentFrameTalent7IconTexture",
+ "InspectTalentFrameTalent7NormalTexture",
+ "InspectTalentFrameTalent7Rank",
+ "InspectTalentFrameTalent7RankBorder",
+ "InspectTalentFrameTalent7Slot",
+ "InspectTalentFrameTalent7Stock",
+ "InspectTalentFrameTalent8",
+ "InspectTalentFrameTalent8Count",
+ "InspectTalentFrameTalent8IconTexture",
+ "InspectTalentFrameTalent8NormalTexture",
+ "InspectTalentFrameTalent8Rank",
+ "InspectTalentFrameTalent8RankBorder",
+ "InspectTalentFrameTalent8Slot",
+ "InspectTalentFrameTalent8Stock",
+ "InspectTalentFrameTalent9",
+ "InspectTalentFrameTalent9Count",
+ "InspectTalentFrameTalent9IconTexture",
+ "InspectTalentFrameTalent9NormalTexture",
+ "InspectTalentFrameTalent9Rank",
+ "InspectTalentFrameTalent9RankBorder",
+ "InspectTalentFrameTalent9Slot",
+ "InspectTalentFrameTalent9Stock",
+ "InspectTalentFrameTalentPointsText",
+ "InspectTalentFrameTalent_OnClick",
+ "InspectTalentFrameTalent_OnEnter",
+ "InspectTalentFrameTalent_OnEvent",
+ "InspectTalentFrame_OnEvent",
+ "InspectTalentFrame_OnHide",
+ "InspectTalentFrame_OnLoad",
+ "InspectTalentFrame_OnShow",
+ "InspectTalentFrame_Refresh",
+ "InspectTalentFrame_Update",
+ "InspectTalentFrame_UpdateTabs",
+ "InspectTitleText",
+ "InspectTrinket0Slot",
+ "InspectTrinket0SlotCount",
+ "InspectTrinket0SlotIconTexture",
+ "InspectTrinket0SlotStock",
+ "InspectTrinket1Slot",
+ "InspectTrinket1SlotCount",
+ "InspectTrinket1SlotIconTexture",
+ "InspectTrinket1SlotStock",
+ "InspectUnit",
+ "InspectWaistSlot",
+ "InspectWaistSlotCount",
+ "InspectWaistSlotIconTexture",
+ "InspectWaistSlotStock",
+ "InspectWristSlot",
+ "InspectWristSlotCount",
+ "InspectWristSlotIconTexture",
+ "InspectWristSlotStock",
+ "InstanceLock_OnEnter",
+ "InteractUnit",
+ "InterfaceAddOnsList_Update",
+ "InterfaceCategoryList_Update",
+ "InterfaceOptionsActionBarsPanel",
+ "InterfaceOptionsActionBarsPanelAlwaysShowActionBars",
+ "InterfaceOptionsActionBarsPanelAlwaysShowActionBarsText",
+ "InterfaceOptionsActionBarsPanelBottomLeft",
+ "InterfaceOptionsActionBarsPanelBottomLeftText",
+ "InterfaceOptionsActionBarsPanelBottomRight",
+ "InterfaceOptionsActionBarsPanelBottomRightText",
+ "InterfaceOptionsActionBarsPanelLockActionBars",
+ "InterfaceOptionsActionBarsPanelLockActionBarsText",
+ "InterfaceOptionsActionBarsPanelRight",
+ "InterfaceOptionsActionBarsPanelRightText",
+ "InterfaceOptionsActionBarsPanelRightTwo",
+ "InterfaceOptionsActionBarsPanelRightTwoText",
+ "InterfaceOptionsActionBarsPanelSecureAbilityToggle",
+ "InterfaceOptionsActionBarsPanelSecureAbilityToggleText",
+ "InterfaceOptionsActionBarsPanelSubText",
+ "InterfaceOptionsActionBarsPanelTitle",
+ "InterfaceOptionsActionBarsPanel_OnEvent",
+ "InterfaceOptionsActionBarsPanel_OnLoad",
+ "InterfaceOptionsBattlenetPanel",
+ "InterfaceOptionsBattlenetPanelBroadcasts",
+ "InterfaceOptionsBattlenetPanelBroadcastsText",
+ "InterfaceOptionsBattlenetPanelConversations",
+ "InterfaceOptionsBattlenetPanelConversationsText",
+ "InterfaceOptionsBattlenetPanelFriendRequests",
+ "InterfaceOptionsBattlenetPanelFriendRequestsText",
+ "InterfaceOptionsBattlenetPanelOfflineFriends",
+ "InterfaceOptionsBattlenetPanelOfflineFriendsText",
+ "InterfaceOptionsBattlenetPanelOnlineFriends",
+ "InterfaceOptionsBattlenetPanelOnlineFriendsText",
+ "InterfaceOptionsBattlenetPanelShowToastWindow",
+ "InterfaceOptionsBattlenetPanelShowToastWindowText",
+ "InterfaceOptionsBattlenetPanelSubText",
+ "InterfaceOptionsBattlenetPanelTitle",
+ "InterfaceOptionsBattlenetPanelToastDurationSlider",
+ "InterfaceOptionsBattlenetPanelToastDurationSliderHigh",
+ "InterfaceOptionsBattlenetPanelToastDurationSliderLow",
+ "InterfaceOptionsBattlenetPanelToastDurationSliderText",
+ "InterfaceOptionsBattlenetPanelToastDurationSliderThumb",
+ "InterfaceOptionsBattlenetPanel_OnLoad",
+ "InterfaceOptionsBuffsPanel",
+ "InterfaceOptionsBuffsPanelBuffDurations",
+ "InterfaceOptionsBuffsPanelBuffDurationsText",
+ "InterfaceOptionsBuffsPanelCastableBuffs",
+ "InterfaceOptionsBuffsPanelCastableBuffsText",
+ "InterfaceOptionsBuffsPanelConsolidateBuffs",
+ "InterfaceOptionsBuffsPanelConsolidateBuffsText",
+ "InterfaceOptionsBuffsPanelDispellableDebuffs",
+ "InterfaceOptionsBuffsPanelDispellableDebuffsText",
+ "InterfaceOptionsBuffsPanelShowCastableDebuffs",
+ "InterfaceOptionsBuffsPanelShowCastableDebuffsText",
+ "InterfaceOptionsBuffsPanelSubText",
+ "InterfaceOptionsBuffsPanelTitle",
+ "InterfaceOptionsBuffsPanel_OnEvent",
+ "InterfaceOptionsBuffsPanel_OnLoad",
+ "InterfaceOptionsCameraPanel",
+ "InterfaceOptionsCameraPanelFollowSpeedSlider",
+ "InterfaceOptionsCameraPanelFollowSpeedSliderHigh",
+ "InterfaceOptionsCameraPanelFollowSpeedSliderLow",
+ "InterfaceOptionsCameraPanelFollowSpeedSliderText",
+ "InterfaceOptionsCameraPanelFollowSpeedSliderThumb",
+ "InterfaceOptionsCameraPanelFollowTerrain",
+ "InterfaceOptionsCameraPanelFollowTerrainText",
+ "InterfaceOptionsCameraPanelHeadBob",
+ "InterfaceOptionsCameraPanelHeadBobText",
+ "InterfaceOptionsCameraPanelMaxDistanceSlider",
+ "InterfaceOptionsCameraPanelMaxDistanceSliderHigh",
+ "InterfaceOptionsCameraPanelMaxDistanceSliderLow",
+ "InterfaceOptionsCameraPanelMaxDistanceSliderText",
+ "InterfaceOptionsCameraPanelMaxDistanceSliderThumb",
+ "InterfaceOptionsCameraPanelSmartPivot",
+ "InterfaceOptionsCameraPanelSmartPivotText",
+ "InterfaceOptionsCameraPanelStyleDropDown",
+ "InterfaceOptionsCameraPanelStyleDropDownButton",
+ "InterfaceOptionsCameraPanelStyleDropDownButtonDisabledTexture",
+ "InterfaceOptionsCameraPanelStyleDropDownButtonHighlightTexture",
+ "InterfaceOptionsCameraPanelStyleDropDownButtonNormalTexture",
+ "InterfaceOptionsCameraPanelStyleDropDownButtonPushedTexture",
+ "InterfaceOptionsCameraPanelStyleDropDownLabel",
+ "InterfaceOptionsCameraPanelStyleDropDownLeft",
+ "InterfaceOptionsCameraPanelStyleDropDownMiddle",
+ "InterfaceOptionsCameraPanelStyleDropDownRight",
+ "InterfaceOptionsCameraPanelStyleDropDownText",
+ "InterfaceOptionsCameraPanelStyleDropDown_Initialize",
+ "InterfaceOptionsCameraPanelStyleDropDown_OnClick",
+ "InterfaceOptionsCameraPanelStyleDropDown_OnEvent",
+ "InterfaceOptionsCameraPanelSubText",
+ "InterfaceOptionsCameraPanelTitle",
+ "InterfaceOptionsCameraPanelWaterCollision",
+ "InterfaceOptionsCameraPanelWaterCollisionText",
+ "InterfaceOptionsCameraPanel_OnEvent",
+ "InterfaceOptionsCameraPanel_OnLoad",
+ "InterfaceOptionsCombatPanel",
+ "InterfaceOptionsCombatPanelAttackOnAssist",
+ "InterfaceOptionsCombatPanelAttackOnAssistText",
+ "InterfaceOptionsCombatPanelAutoRange",
+ "InterfaceOptionsCombatPanelAutoRangeText",
+ "InterfaceOptionsCombatPanelAutoSelfCast",
+ "InterfaceOptionsCombatPanelAutoSelfCastText",
+ "InterfaceOptionsCombatPanelEnemyCastBars",
+ "InterfaceOptionsCombatPanelEnemyCastBarsLabel",
+ "InterfaceOptionsCombatPanelEnemyCastBarsOnNameplates",
+ "InterfaceOptionsCombatPanelEnemyCastBarsOnNameplatesText",
+ "InterfaceOptionsCombatPanelEnemyCastBarsOnPortrait",
+ "InterfaceOptionsCombatPanelEnemyCastBarsOnPortraitText",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDown",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownButton",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownButtonDisabledTexture",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownButtonHighlightTexture",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownButtonNormalTexture",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownButtonPushedTexture",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownLabel",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownLeft",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownMiddle",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownRight",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDownText",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDown_Initialize",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDown_OnClick",
+ "InterfaceOptionsCombatPanelFocusCastKeyDropDown_OnEvent",
+ "InterfaceOptionsCombatPanelNameplateClassColors",
+ "InterfaceOptionsCombatPanelNameplateClassColorsText",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDown",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownButton",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownButtonDisabledTexture",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownButtonHighlightTexture",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownButtonNormalTexture",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownButtonPushedTexture",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownLabel",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownLeft",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownMiddle",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownRight",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDownText",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDown_Initialize",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDown_OnClick",
+ "InterfaceOptionsCombatPanelSelfCastKeyDropDown_OnEvent",
+ "InterfaceOptionsCombatPanelStopAutoAttack",
+ "InterfaceOptionsCombatPanelStopAutoAttackText",
+ "InterfaceOptionsCombatPanelSubText",
+ "InterfaceOptionsCombatPanelTOTDropDown",
+ "InterfaceOptionsCombatPanelTOTDropDownButton",
+ "InterfaceOptionsCombatPanelTOTDropDownButtonDisabledTexture",
+ "InterfaceOptionsCombatPanelTOTDropDownButtonHighlightTexture",
+ "InterfaceOptionsCombatPanelTOTDropDownButtonNormalTexture",
+ "InterfaceOptionsCombatPanelTOTDropDownButtonPushedTexture",
+ "InterfaceOptionsCombatPanelTOTDropDownLeft",
+ "InterfaceOptionsCombatPanelTOTDropDownMiddle",
+ "InterfaceOptionsCombatPanelTOTDropDownRight",
+ "InterfaceOptionsCombatPanelTOTDropDownText",
+ "InterfaceOptionsCombatPanelTOTDropDown_Initialize",
+ "InterfaceOptionsCombatPanelTOTDropDown_OnClick",
+ "InterfaceOptionsCombatPanelTOTDropDown_OnEvent",
+ "InterfaceOptionsCombatPanelTargetOfTarget",
+ "InterfaceOptionsCombatPanelTargetOfTargetText",
+ "InterfaceOptionsCombatPanelTitle",
+ "InterfaceOptionsCombatTextPanel",
+ "InterfaceOptionsCombatTextPanelAuras",
+ "InterfaceOptionsCombatTextPanelAurasText",
+ "InterfaceOptionsCombatTextPanelCombatState",
+ "InterfaceOptionsCombatTextPanelCombatStateText",
+ "InterfaceOptionsCombatTextPanelComboPoints",
+ "InterfaceOptionsCombatTextPanelComboPointsText",
+ "InterfaceOptionsCombatTextPanelDamageReduction",
+ "InterfaceOptionsCombatTextPanelDamageReductionText",
+ "InterfaceOptionsCombatTextPanelDodgeParryMiss",
+ "InterfaceOptionsCombatTextPanelDodgeParryMissText",
+ "InterfaceOptionsCombatTextPanelEnableFCT",
+ "InterfaceOptionsCombatTextPanelEnableFCTText",
+ "InterfaceOptionsCombatTextPanelEnergyGains",
+ "InterfaceOptionsCombatTextPanelEnergyGainsText",
+ "InterfaceOptionsCombatTextPanelFCTDropDown",
+ "InterfaceOptionsCombatTextPanelFCTDropDownButton",
+ "InterfaceOptionsCombatTextPanelFCTDropDownButtonDisabledTexture",
+ "InterfaceOptionsCombatTextPanelFCTDropDownButtonHighlightTexture",
+ "InterfaceOptionsCombatTextPanelFCTDropDownButtonNormalTexture",
+ "InterfaceOptionsCombatTextPanelFCTDropDownButtonPushedTexture",
+ "InterfaceOptionsCombatTextPanelFCTDropDownLabel",
+ "InterfaceOptionsCombatTextPanelFCTDropDownLeft",
+ "InterfaceOptionsCombatTextPanelFCTDropDownMiddle",
+ "InterfaceOptionsCombatTextPanelFCTDropDownRight",
+ "InterfaceOptionsCombatTextPanelFCTDropDownText",
+ "InterfaceOptionsCombatTextPanelFCTDropDown_Initialize",
+ "InterfaceOptionsCombatTextPanelFCTDropDown_OnClick",
+ "InterfaceOptionsCombatTextPanelFCTDropDown_OnEvent",
+ "InterfaceOptionsCombatTextPanelFriendlyHealerNames",
+ "InterfaceOptionsCombatTextPanelFriendlyHealerNamesText",
+ "InterfaceOptionsCombatTextPanelHealing",
+ "InterfaceOptionsCombatTextPanelHealingText",
+ "InterfaceOptionsCombatTextPanelHonorGains",
+ "InterfaceOptionsCombatTextPanelHonorGainsText",
+ "InterfaceOptionsCombatTextPanelLowManaHealth",
+ "InterfaceOptionsCombatTextPanelLowManaHealthText",
+ "InterfaceOptionsCombatTextPanelOtherTargetEffects",
+ "InterfaceOptionsCombatTextPanelOtherTargetEffectsText",
+ "InterfaceOptionsCombatTextPanelPeriodicDamage",
+ "InterfaceOptionsCombatTextPanelPeriodicDamageText",
+ "InterfaceOptionsCombatTextPanelPeriodicEnergyGains",
+ "InterfaceOptionsCombatTextPanelPeriodicEnergyGainsText",
+ "InterfaceOptionsCombatTextPanelPetDamage",
+ "InterfaceOptionsCombatTextPanelPetDamageText",
+ "InterfaceOptionsCombatTextPanelReactiveAbilities",
+ "InterfaceOptionsCombatTextPanelReactiveAbilitiesText",
+ "InterfaceOptionsCombatTextPanelRepChanges",
+ "InterfaceOptionsCombatTextPanelRepChangesText",
+ "InterfaceOptionsCombatTextPanelSubText",
+ "InterfaceOptionsCombatTextPanelTargetDamage",
+ "InterfaceOptionsCombatTextPanelTargetDamageText",
+ "InterfaceOptionsCombatTextPanelTargetEffects",
+ "InterfaceOptionsCombatTextPanelTargetEffectsText",
+ "InterfaceOptionsCombatTextPanelTitle",
+ "InterfaceOptionsCombatTextPanel_OnEvent",
+ "InterfaceOptionsCombatTextPanel_OnLoad",
+ "InterfaceOptionsControlsPanel",
+ "InterfaceOptionsControlsPanelAutoClearAFK",
+ "InterfaceOptionsControlsPanelAutoClearAFKText",
+ "InterfaceOptionsControlsPanelAutoDismount",
+ "InterfaceOptionsControlsPanelAutoDismountText",
+ "InterfaceOptionsControlsPanelAutoLootCorpse",
+ "InterfaceOptionsControlsPanelAutoLootCorpseText",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDown",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownButton",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownButtonDisabledTexture",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownButtonHighlightTexture",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownButtonNormalTexture",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownButtonPushedTexture",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownLabel",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownLeft",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownMiddle",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownRight",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDownText",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDown_Initialize",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDown_OnClick",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDown_OnEvent",
+ "InterfaceOptionsControlsPanelAutoLootKeyDropDown_Update",
+ "InterfaceOptionsControlsPanelBlockTrades",
+ "InterfaceOptionsControlsPanelBlockTradesText",
+ "InterfaceOptionsControlsPanelLootAtMouse",
+ "InterfaceOptionsControlsPanelLootAtMouseText",
+ "InterfaceOptionsControlsPanelStickyTargeting",
+ "InterfaceOptionsControlsPanelStickyTargetingText",
+ "InterfaceOptionsControlsPanelSubText",
+ "InterfaceOptionsControlsPanelTitle",
+ "InterfaceOptionsDisplayPanel",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplay",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayButton",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayButtonDisabledTexture",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayButtonHighlightTexture",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayButtonNormalTexture",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayButtonPushedTexture",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayLabel",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayLeft",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayMiddle",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayRight",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplayText",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplay_Initialize",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplay_OnClick",
+ "InterfaceOptionsDisplayPanelAggroWarningDisplay_OnEvent",
+ "InterfaceOptionsDisplayPanelCinematicSubtitles",
+ "InterfaceOptionsDisplayPanelCinematicSubtitlesText",
+ "InterfaceOptionsDisplayPanelColorblindMode",
+ "InterfaceOptionsDisplayPanelColorblindModeText",
+ "InterfaceOptionsDisplayPanelDetailedLootInfo",
+ "InterfaceOptionsDisplayPanelDetailedLootInfoText",
+ "InterfaceOptionsDisplayPanelPlayAggroSounds",
+ "InterfaceOptionsDisplayPanelPlayAggroSoundsText",
+ "InterfaceOptionsDisplayPanelPreviewTalentChanges_SetFunc",
+ "InterfaceOptionsDisplayPanelRotateMinimap",
+ "InterfaceOptionsDisplayPanelRotateMinimapText",
+ "InterfaceOptionsDisplayPanelScreenEdgeFlash",
+ "InterfaceOptionsDisplayPanelScreenEdgeFlashText",
+ "InterfaceOptionsDisplayPanelShowAggroPercentage",
+ "InterfaceOptionsDisplayPanelShowAggroPercentageText",
+ "InterfaceOptionsDisplayPanelShowAggroPercentage_SetFunc",
+ "InterfaceOptionsDisplayPanelShowCloak",
+ "InterfaceOptionsDisplayPanelShowCloakText",
+ "InterfaceOptionsDisplayPanelShowClock",
+ "InterfaceOptionsDisplayPanelShowClockText",
+ "InterfaceOptionsDisplayPanelShowClock_SetFunc",
+ "InterfaceOptionsDisplayPanelShowFreeBagSpace",
+ "InterfaceOptionsDisplayPanelShowFreeBagSpaceText",
+ "InterfaceOptionsDisplayPanelShowHelm",
+ "InterfaceOptionsDisplayPanelShowHelmText",
+ "InterfaceOptionsDisplayPanelShowItemLevel",
+ "InterfaceOptionsDisplayPanelShowItemLevelText",
+ "InterfaceOptionsDisplayPanelSubText",
+ "InterfaceOptionsDisplayPanelTitle",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplay",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayButton",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayButtonDisabledTexture",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayButtonHighlightTexture",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayButtonNormalTexture",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayButtonPushedTexture",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayLabel",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayLeft",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayMiddle",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayRight",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplayText",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplay_Initialize",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplay_OnClick",
+ "InterfaceOptionsDisplayPanelWorldPVPObjectiveDisplay_OnEvent",
+ "InterfaceOptionsDisplayPanel_OnEvent",
+ "InterfaceOptionsDisplayPanel_OnLoad",
+ "InterfaceOptionsFeaturesPanel",
+ "InterfaceOptionsFeaturesPanelEquipmentManager",
+ "InterfaceOptionsFeaturesPanelEquipmentManagerDescription",
+ "InterfaceOptionsFeaturesPanelEquipmentManagerText",
+ "InterfaceOptionsFeaturesPanelPreviewTalentChanges",
+ "InterfaceOptionsFeaturesPanelPreviewTalentChangesDescription",
+ "InterfaceOptionsFeaturesPanelPreviewTalentChangesText",
+ "InterfaceOptionsFeaturesPanelSubText",
+ "InterfaceOptionsFeaturesPanelTitle",
+ "InterfaceOptionsFrame",
+ "InterfaceOptionsFrameAddOns",
+ "InterfaceOptionsFrameAddOnsBottom",
+ "InterfaceOptionsFrameAddOnsBottomLeft",
+ "InterfaceOptionsFrameAddOnsBottomRight",
+ "InterfaceOptionsFrameAddOnsButton1",
+ "InterfaceOptionsFrameAddOnsButton10",
+ "InterfaceOptionsFrameAddOnsButton10Text",
+ "InterfaceOptionsFrameAddOnsButton10Toggle",
+ "InterfaceOptionsFrameAddOnsButton10ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton10ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton10TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton11",
+ "InterfaceOptionsFrameAddOnsButton11Text",
+ "InterfaceOptionsFrameAddOnsButton11Toggle",
+ "InterfaceOptionsFrameAddOnsButton11ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton11ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton11TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton12",
+ "InterfaceOptionsFrameAddOnsButton12Text",
+ "InterfaceOptionsFrameAddOnsButton12Toggle",
+ "InterfaceOptionsFrameAddOnsButton12ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton12ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton12TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton13",
+ "InterfaceOptionsFrameAddOnsButton13Text",
+ "InterfaceOptionsFrameAddOnsButton13Toggle",
+ "InterfaceOptionsFrameAddOnsButton13ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton13ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton13TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton14",
+ "InterfaceOptionsFrameAddOnsButton14Text",
+ "InterfaceOptionsFrameAddOnsButton14Toggle",
+ "InterfaceOptionsFrameAddOnsButton14ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton14ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton14TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton15",
+ "InterfaceOptionsFrameAddOnsButton15Text",
+ "InterfaceOptionsFrameAddOnsButton15Toggle",
+ "InterfaceOptionsFrameAddOnsButton15ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton15ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton15TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton16",
+ "InterfaceOptionsFrameAddOnsButton16Text",
+ "InterfaceOptionsFrameAddOnsButton16Toggle",
+ "InterfaceOptionsFrameAddOnsButton16ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton16ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton16TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton17",
+ "InterfaceOptionsFrameAddOnsButton17Text",
+ "InterfaceOptionsFrameAddOnsButton17Toggle",
+ "InterfaceOptionsFrameAddOnsButton17ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton17ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton17TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton18",
+ "InterfaceOptionsFrameAddOnsButton18Text",
+ "InterfaceOptionsFrameAddOnsButton18Toggle",
+ "InterfaceOptionsFrameAddOnsButton18ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton18ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton18TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton19",
+ "InterfaceOptionsFrameAddOnsButton19Text",
+ "InterfaceOptionsFrameAddOnsButton19Toggle",
+ "InterfaceOptionsFrameAddOnsButton19ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton19ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton19TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton1Text",
+ "InterfaceOptionsFrameAddOnsButton1Toggle",
+ "InterfaceOptionsFrameAddOnsButton1ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton1ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton1TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton2",
+ "InterfaceOptionsFrameAddOnsButton20",
+ "InterfaceOptionsFrameAddOnsButton20Text",
+ "InterfaceOptionsFrameAddOnsButton20Toggle",
+ "InterfaceOptionsFrameAddOnsButton20ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton20ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton20TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton21",
+ "InterfaceOptionsFrameAddOnsButton21Text",
+ "InterfaceOptionsFrameAddOnsButton21Toggle",
+ "InterfaceOptionsFrameAddOnsButton21ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton21ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton21TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton22",
+ "InterfaceOptionsFrameAddOnsButton22Text",
+ "InterfaceOptionsFrameAddOnsButton22Toggle",
+ "InterfaceOptionsFrameAddOnsButton22ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton22ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton22TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton23",
+ "InterfaceOptionsFrameAddOnsButton23Text",
+ "InterfaceOptionsFrameAddOnsButton23Toggle",
+ "InterfaceOptionsFrameAddOnsButton23ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton23ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton23TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton2Text",
+ "InterfaceOptionsFrameAddOnsButton2Toggle",
+ "InterfaceOptionsFrameAddOnsButton2ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton2ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton2TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton3",
+ "InterfaceOptionsFrameAddOnsButton3Text",
+ "InterfaceOptionsFrameAddOnsButton3Toggle",
+ "InterfaceOptionsFrameAddOnsButton3ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton3ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton3TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton4",
+ "InterfaceOptionsFrameAddOnsButton4Text",
+ "InterfaceOptionsFrameAddOnsButton4Toggle",
+ "InterfaceOptionsFrameAddOnsButton4ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton4ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton4TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton5",
+ "InterfaceOptionsFrameAddOnsButton5Text",
+ "InterfaceOptionsFrameAddOnsButton5Toggle",
+ "InterfaceOptionsFrameAddOnsButton5ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton5ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton5TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton6",
+ "InterfaceOptionsFrameAddOnsButton6Text",
+ "InterfaceOptionsFrameAddOnsButton6Toggle",
+ "InterfaceOptionsFrameAddOnsButton6ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton6ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton6TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton7",
+ "InterfaceOptionsFrameAddOnsButton7Text",
+ "InterfaceOptionsFrameAddOnsButton7Toggle",
+ "InterfaceOptionsFrameAddOnsButton7ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton7ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton7TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton8",
+ "InterfaceOptionsFrameAddOnsButton8Text",
+ "InterfaceOptionsFrameAddOnsButton8Toggle",
+ "InterfaceOptionsFrameAddOnsButton8ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton8ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton8TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsButton9",
+ "InterfaceOptionsFrameAddOnsButton9Text",
+ "InterfaceOptionsFrameAddOnsButton9Toggle",
+ "InterfaceOptionsFrameAddOnsButton9ToggleHighlightTexture",
+ "InterfaceOptionsFrameAddOnsButton9ToggleNormalTexture",
+ "InterfaceOptionsFrameAddOnsButton9TogglePushedTexture",
+ "InterfaceOptionsFrameAddOnsLeft",
+ "InterfaceOptionsFrameAddOnsList",
+ "InterfaceOptionsFrameAddOnsListScrollBar",
+ "InterfaceOptionsFrameAddOnsListScrollBarScrollDownButton",
+ "InterfaceOptionsFrameAddOnsListScrollBarScrollUpButton",
+ "InterfaceOptionsFrameAddOnsListScrollBarThumbTexture",
+ "InterfaceOptionsFrameAddOnsListScrollChildFrame",
+ "InterfaceOptionsFrameAddOnsRight",
+ "InterfaceOptionsFrameAddOnsTop",
+ "InterfaceOptionsFrameAddOnsTopLeft",
+ "InterfaceOptionsFrameAddOnsTopRight",
+ "InterfaceOptionsFrameCancel",
+ "InterfaceOptionsFrameCancelText",
+ "InterfaceOptionsFrameCancel_OnClick",
+ "InterfaceOptionsFrameCategories",
+ "InterfaceOptionsFrameCategoriesBottom",
+ "InterfaceOptionsFrameCategoriesBottomLeft",
+ "InterfaceOptionsFrameCategoriesBottomRight",
+ "InterfaceOptionsFrameCategoriesButton1",
+ "InterfaceOptionsFrameCategoriesButton10",
+ "InterfaceOptionsFrameCategoriesButton10Text",
+ "InterfaceOptionsFrameCategoriesButton10Toggle",
+ "InterfaceOptionsFrameCategoriesButton10ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton10ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton10TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton11",
+ "InterfaceOptionsFrameCategoriesButton11Text",
+ "InterfaceOptionsFrameCategoriesButton11Toggle",
+ "InterfaceOptionsFrameCategoriesButton11ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton11ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton11TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton12",
+ "InterfaceOptionsFrameCategoriesButton12Text",
+ "InterfaceOptionsFrameCategoriesButton12Toggle",
+ "InterfaceOptionsFrameCategoriesButton12ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton12ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton12TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton13",
+ "InterfaceOptionsFrameCategoriesButton13Text",
+ "InterfaceOptionsFrameCategoriesButton13Toggle",
+ "InterfaceOptionsFrameCategoriesButton13ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton13ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton13TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton14",
+ "InterfaceOptionsFrameCategoriesButton14Text",
+ "InterfaceOptionsFrameCategoriesButton14Toggle",
+ "InterfaceOptionsFrameCategoriesButton14ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton14ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton14TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton15",
+ "InterfaceOptionsFrameCategoriesButton15Text",
+ "InterfaceOptionsFrameCategoriesButton15Toggle",
+ "InterfaceOptionsFrameCategoriesButton15ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton15ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton15TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton16",
+ "InterfaceOptionsFrameCategoriesButton16Text",
+ "InterfaceOptionsFrameCategoriesButton16Toggle",
+ "InterfaceOptionsFrameCategoriesButton16ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton16ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton16TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton17",
+ "InterfaceOptionsFrameCategoriesButton17Text",
+ "InterfaceOptionsFrameCategoriesButton17Toggle",
+ "InterfaceOptionsFrameCategoriesButton17ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton17ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton17TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton18",
+ "InterfaceOptionsFrameCategoriesButton18Text",
+ "InterfaceOptionsFrameCategoriesButton18Toggle",
+ "InterfaceOptionsFrameCategoriesButton18ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton18ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton18TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton19",
+ "InterfaceOptionsFrameCategoriesButton19Text",
+ "InterfaceOptionsFrameCategoriesButton19Toggle",
+ "InterfaceOptionsFrameCategoriesButton19ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton19ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton19TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton1Text",
+ "InterfaceOptionsFrameCategoriesButton1Toggle",
+ "InterfaceOptionsFrameCategoriesButton1ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton1ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton1TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton2",
+ "InterfaceOptionsFrameCategoriesButton20",
+ "InterfaceOptionsFrameCategoriesButton20Text",
+ "InterfaceOptionsFrameCategoriesButton20Toggle",
+ "InterfaceOptionsFrameCategoriesButton20ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton20ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton20TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton21",
+ "InterfaceOptionsFrameCategoriesButton21Text",
+ "InterfaceOptionsFrameCategoriesButton21Toggle",
+ "InterfaceOptionsFrameCategoriesButton21ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton21ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton21TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton22",
+ "InterfaceOptionsFrameCategoriesButton22Text",
+ "InterfaceOptionsFrameCategoriesButton22Toggle",
+ "InterfaceOptionsFrameCategoriesButton22ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton22ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton22TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton23",
+ "InterfaceOptionsFrameCategoriesButton23Text",
+ "InterfaceOptionsFrameCategoriesButton23Toggle",
+ "InterfaceOptionsFrameCategoriesButton23ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton23ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton23TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton2Text",
+ "InterfaceOptionsFrameCategoriesButton2Toggle",
+ "InterfaceOptionsFrameCategoriesButton2ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton2ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton2TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton3",
+ "InterfaceOptionsFrameCategoriesButton3Text",
+ "InterfaceOptionsFrameCategoriesButton3Toggle",
+ "InterfaceOptionsFrameCategoriesButton3ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton3ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton3TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton4",
+ "InterfaceOptionsFrameCategoriesButton4Text",
+ "InterfaceOptionsFrameCategoriesButton4Toggle",
+ "InterfaceOptionsFrameCategoriesButton4ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton4ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton4TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton5",
+ "InterfaceOptionsFrameCategoriesButton5Text",
+ "InterfaceOptionsFrameCategoriesButton5Toggle",
+ "InterfaceOptionsFrameCategoriesButton5ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton5ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton5TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton6",
+ "InterfaceOptionsFrameCategoriesButton6Text",
+ "InterfaceOptionsFrameCategoriesButton6Toggle",
+ "InterfaceOptionsFrameCategoriesButton6ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton6ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton6TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton7",
+ "InterfaceOptionsFrameCategoriesButton7Text",
+ "InterfaceOptionsFrameCategoriesButton7Toggle",
+ "InterfaceOptionsFrameCategoriesButton7ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton7ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton7TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton8",
+ "InterfaceOptionsFrameCategoriesButton8Text",
+ "InterfaceOptionsFrameCategoriesButton8Toggle",
+ "InterfaceOptionsFrameCategoriesButton8ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton8ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton8TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesButton9",
+ "InterfaceOptionsFrameCategoriesButton9Text",
+ "InterfaceOptionsFrameCategoriesButton9Toggle",
+ "InterfaceOptionsFrameCategoriesButton9ToggleHighlightTexture",
+ "InterfaceOptionsFrameCategoriesButton9ToggleNormalTexture",
+ "InterfaceOptionsFrameCategoriesButton9TogglePushedTexture",
+ "InterfaceOptionsFrameCategoriesLeft",
+ "InterfaceOptionsFrameCategoriesList",
+ "InterfaceOptionsFrameCategoriesListScrollBar",
+ "InterfaceOptionsFrameCategoriesListScrollBarScrollDownButton",
+ "InterfaceOptionsFrameCategoriesListScrollBarScrollUpButton",
+ "InterfaceOptionsFrameCategoriesListScrollBarThumbTexture",
+ "InterfaceOptionsFrameCategoriesListScrollChildFrame",
+ "InterfaceOptionsFrameCategoriesRight",
+ "InterfaceOptionsFrameCategoriesTop",
+ "InterfaceOptionsFrameCategoriesTopLeft",
+ "InterfaceOptionsFrameCategoriesTopRight",
+ "InterfaceOptionsFrameDefaults",
+ "InterfaceOptionsFrameDefaults_OnClick",
+ "InterfaceOptionsFrameHeader",
+ "InterfaceOptionsFrameHeaderText",
+ "InterfaceOptionsFrameOkay",
+ "InterfaceOptionsFrameOkayText",
+ "InterfaceOptionsFrameOkay_OnClick",
+ "InterfaceOptionsFramePanelContainer",
+ "InterfaceOptionsFrameTab1",
+ "InterfaceOptionsFrameTab1HighlightTexture",
+ "InterfaceOptionsFrameTab1Left",
+ "InterfaceOptionsFrameTab1LeftDisabled",
+ "InterfaceOptionsFrameTab1Middle",
+ "InterfaceOptionsFrameTab1MiddleDisabled",
+ "InterfaceOptionsFrameTab1Right",
+ "InterfaceOptionsFrameTab1RightDisabled",
+ "InterfaceOptionsFrameTab1TabSpacer",
+ "InterfaceOptionsFrameTab1Text",
+ "InterfaceOptionsFrameTab2",
+ "InterfaceOptionsFrameTab2HighlightTexture",
+ "InterfaceOptionsFrameTab2Left",
+ "InterfaceOptionsFrameTab2LeftDisabled",
+ "InterfaceOptionsFrameTab2Middle",
+ "InterfaceOptionsFrameTab2MiddleDisabled",
+ "InterfaceOptionsFrameTab2Right",
+ "InterfaceOptionsFrameTab2RightDisabled",
+ "InterfaceOptionsFrameTab2TabSpacer1",
+ "InterfaceOptionsFrameTab2TabSpacer2",
+ "InterfaceOptionsFrameTab2Text",
+ "InterfaceOptionsFrame_InitializeUVars",
+ "InterfaceOptionsFrame_LoadUVars",
+ "InterfaceOptionsFrame_OnEvent",
+ "InterfaceOptionsFrame_OnHide",
+ "InterfaceOptionsFrame_OnLoad",
+ "InterfaceOptionsFrame_OnShow",
+ "InterfaceOptionsFrame_OpenToCategory",
+ "InterfaceOptionsFrame_SetAllToDefaults",
+ "InterfaceOptionsFrame_SetCurrentToDefaults",
+ "InterfaceOptionsFrame_Show",
+ "InterfaceOptionsFrame_TabOnClick",
+ "InterfaceOptionsHelpPanel",
+ "InterfaceOptionsHelpPanelBeginnerTooltips",
+ "InterfaceOptionsHelpPanelBeginnerTooltipsText",
+ "InterfaceOptionsHelpPanelEnhancedTooltips",
+ "InterfaceOptionsHelpPanelEnhancedTooltipsText",
+ "InterfaceOptionsHelpPanelLoadingScreenTips",
+ "InterfaceOptionsHelpPanelLoadingScreenTipsText",
+ "InterfaceOptionsHelpPanelResetTutorials",
+ "InterfaceOptionsHelpPanelResetTutorialsText",
+ "InterfaceOptionsHelpPanelShowLuaErrors",
+ "InterfaceOptionsHelpPanelShowLuaErrorsText",
+ "InterfaceOptionsHelpPanelShowTutorials",
+ "InterfaceOptionsHelpPanelShowTutorialsText",
+ "InterfaceOptionsHelpPanelSubText",
+ "InterfaceOptionsHelpPanelTitle",
+ "InterfaceOptionsLanguagesPanel",
+ "InterfaceOptionsLanguagesPanelLocaleDropDown",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownButton",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownButtonDisabledTexture",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownButtonHighlightTexture",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownButtonNormalTexture",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownButtonPushedTexture",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownLabel",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownLeft",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownMiddle",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownRight",
+ "InterfaceOptionsLanguagesPanelLocaleDropDownText",
+ "InterfaceOptionsLanguagesPanelLocaleDropDown_Initialize",
+ "InterfaceOptionsLanguagesPanelLocaleDropDown_InitializeHelper",
+ "InterfaceOptionsLanguagesPanelLocaleDropDown_OnClick",
+ "InterfaceOptionsLanguagesPanelLocaleDropDown_OnEvent",
+ "InterfaceOptionsLanguagesPanelSubText",
+ "InterfaceOptionsLanguagesPanelTitle",
+ "InterfaceOptionsLanguagesPanelUseEnglishAudio",
+ "InterfaceOptionsLanguagesPanelUseEnglishAudioText",
+ "InterfaceOptionsLanguagesPanel_OnLoad",
+ "InterfaceOptionsListButton_OnClick",
+ "InterfaceOptionsListButton_ToggleSubCategories",
+ "InterfaceOptionsList_DisplayPanel",
+ "InterfaceOptionsMousePanel",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDown",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownButton",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownButtonDisabledTexture",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownButtonHighlightTexture",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownButtonNormalTexture",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownButtonPushedTexture",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownLabel",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownLeft",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownMiddle",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownRight",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDownText",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDown_Initialize",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDown_OnClick",
+ "InterfaceOptionsMousePanelClickMoveStyleDropDown_OnEvent",
+ "InterfaceOptionsMousePanelClickToMove",
+ "InterfaceOptionsMousePanelClickToMoveText",
+ "InterfaceOptionsMousePanelInvertMouse",
+ "InterfaceOptionsMousePanelInvertMouseText",
+ "InterfaceOptionsMousePanelMouseLookSpeedSlider",
+ "InterfaceOptionsMousePanelMouseLookSpeedSliderHigh",
+ "InterfaceOptionsMousePanelMouseLookSpeedSliderLow",
+ "InterfaceOptionsMousePanelMouseLookSpeedSliderText",
+ "InterfaceOptionsMousePanelMouseLookSpeedSliderThumb",
+ "InterfaceOptionsMousePanelMouseSensitivitySlider",
+ "InterfaceOptionsMousePanelMouseSensitivitySliderHigh",
+ "InterfaceOptionsMousePanelMouseSensitivitySliderLow",
+ "InterfaceOptionsMousePanelMouseSensitivitySliderText",
+ "InterfaceOptionsMousePanelMouseSensitivitySliderThumb",
+ "InterfaceOptionsMousePanelSubText",
+ "InterfaceOptionsMousePanelTitle",
+ "InterfaceOptionsMousePanelWoWMouse",
+ "InterfaceOptionsMousePanelWoWMouseText",
+ "InterfaceOptionsNamesPanel",
+ "InterfaceOptionsNamesPanelEnemy",
+ "InterfaceOptionsNamesPanelEnemyGuardians",
+ "InterfaceOptionsNamesPanelEnemyGuardiansText",
+ "InterfaceOptionsNamesPanelEnemyPets",
+ "InterfaceOptionsNamesPanelEnemyPetsText",
+ "InterfaceOptionsNamesPanelEnemyPlayerNames",
+ "InterfaceOptionsNamesPanelEnemyPlayerNamesText",
+ "InterfaceOptionsNamesPanelEnemyTotems",
+ "InterfaceOptionsNamesPanelEnemyTotemsText",
+ "InterfaceOptionsNamesPanelFriendly",
+ "InterfaceOptionsNamesPanelFriendlyGuardians",
+ "InterfaceOptionsNamesPanelFriendlyGuardiansText",
+ "InterfaceOptionsNamesPanelFriendlyPets",
+ "InterfaceOptionsNamesPanelFriendlyPetsText",
+ "InterfaceOptionsNamesPanelFriendlyPlayerNames",
+ "InterfaceOptionsNamesPanelFriendlyPlayerNamesText",
+ "InterfaceOptionsNamesPanelFriendlyTotems",
+ "InterfaceOptionsNamesPanelFriendlyTotemsText",
+ "InterfaceOptionsNamesPanelGuilds",
+ "InterfaceOptionsNamesPanelGuildsText",
+ "InterfaceOptionsNamesPanelMyName",
+ "InterfaceOptionsNamesPanelMyNameText",
+ "InterfaceOptionsNamesPanelNPCNames",
+ "InterfaceOptionsNamesPanelNPCNamesText",
+ "InterfaceOptionsNamesPanelNonCombatCreature",
+ "InterfaceOptionsNamesPanelNonCombatCreatureText",
+ "InterfaceOptionsNamesPanelSubText",
+ "InterfaceOptionsNamesPanelTitle",
+ "InterfaceOptionsNamesPanelTitles",
+ "InterfaceOptionsNamesPanelTitlesText",
+ "InterfaceOptionsNamesPanelUnitNameplates",
+ "InterfaceOptionsNamesPanelUnitNameplatesAllowOverlap",
+ "InterfaceOptionsNamesPanelUnitNameplatesAllowOverlapText",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemies",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemiesText",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemyGuardians",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemyGuardiansText",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemyPets",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemyPetsText",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemyTotems",
+ "InterfaceOptionsNamesPanelUnitNameplatesEnemyTotemsText",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendlyGuardians",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendlyGuardiansText",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendlyPets",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendlyPetsText",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendlyTotems",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendlyTotemsText",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriends",
+ "InterfaceOptionsNamesPanelUnitNameplatesFriendsText",
+ "InterfaceOptionsNamesPanelUnitNameplatesTitle",
+ "InterfaceOptionsObjectivesPanel",
+ "InterfaceOptionsObjectivesPanelAdvancedWorldMap",
+ "InterfaceOptionsObjectivesPanelAdvancedWorldMapText",
+ "InterfaceOptionsObjectivesPanelAutoQuestProgress",
+ "InterfaceOptionsObjectivesPanelAutoQuestProgressText",
+ "InterfaceOptionsObjectivesPanelAutoQuestTracking",
+ "InterfaceOptionsObjectivesPanelAutoQuestTrackingText",
+ "InterfaceOptionsObjectivesPanelInstantQuestText",
+ "InterfaceOptionsObjectivesPanelInstantQuestTextText",
+ "InterfaceOptionsObjectivesPanelMapQuestDifficulty",
+ "InterfaceOptionsObjectivesPanelMapQuestDifficultyText",
+ "InterfaceOptionsObjectivesPanelSubText",
+ "InterfaceOptionsObjectivesPanelTitle",
+ "InterfaceOptionsObjectivesPanelWatchFrameWidth",
+ "InterfaceOptionsObjectivesPanelWatchFrameWidthText",
+ "InterfaceOptionsObjectivesPanel_OnEvent",
+ "InterfaceOptionsObjectivesPanel_OnLoad",
+ "InterfaceOptionsOptionsFrame_RefreshAddOns",
+ "InterfaceOptionsOptionsFrame_RefreshCategories",
+ "InterfaceOptionsPanel_CheckButton_OnClick",
+ "InterfaceOptionsPanel_CheckButton_Update",
+ "InterfaceOptionsPanel_OnLoad",
+ "InterfaceOptionsSocialPanel",
+ "InterfaceOptionsSocialPanelChatBubbles",
+ "InterfaceOptionsSocialPanelChatBubblesText",
+ "InterfaceOptionsSocialPanelChatHoverDelay",
+ "InterfaceOptionsSocialPanelChatHoverDelayText",
+ "InterfaceOptionsSocialPanelChatMouseScroll",
+ "InterfaceOptionsSocialPanelChatMouseScrollText",
+ "InterfaceOptionsSocialPanelChatMouseScroll_SetScrolling",
+ "InterfaceOptionsSocialPanelChatStyle",
+ "InterfaceOptionsSocialPanelChatStyleButton",
+ "InterfaceOptionsSocialPanelChatStyleButtonDisabledTexture",
+ "InterfaceOptionsSocialPanelChatStyleButtonHighlightTexture",
+ "InterfaceOptionsSocialPanelChatStyleButtonNormalTexture",
+ "InterfaceOptionsSocialPanelChatStyleButtonPushedTexture",
+ "InterfaceOptionsSocialPanelChatStyleLabel",
+ "InterfaceOptionsSocialPanelChatStyleLeft",
+ "InterfaceOptionsSocialPanelChatStyleMiddle",
+ "InterfaceOptionsSocialPanelChatStyleRight",
+ "InterfaceOptionsSocialPanelChatStyleText",
+ "InterfaceOptionsSocialPanelChatStyle_Initialize",
+ "InterfaceOptionsSocialPanelChatStyle_OnClick",
+ "InterfaceOptionsSocialPanelChatStyle_OnEvent",
+ "InterfaceOptionsSocialPanelChatStyle_SetChatStyle",
+ "InterfaceOptionsSocialPanelConversationMode",
+ "InterfaceOptionsSocialPanelConversationModeButton",
+ "InterfaceOptionsSocialPanelConversationModeButtonDisabledTexture",
+ "InterfaceOptionsSocialPanelConversationModeButtonHighlightTexture",
+ "InterfaceOptionsSocialPanelConversationModeButtonNormalTexture",
+ "InterfaceOptionsSocialPanelConversationModeButtonPushedTexture",
+ "InterfaceOptionsSocialPanelConversationModeLabel",
+ "InterfaceOptionsSocialPanelConversationModeLeft",
+ "InterfaceOptionsSocialPanelConversationModeMiddle",
+ "InterfaceOptionsSocialPanelConversationModeRight",
+ "InterfaceOptionsSocialPanelConversationModeText",
+ "InterfaceOptionsSocialPanelConversationMode_Initialize",
+ "InterfaceOptionsSocialPanelConversationMode_OnClick",
+ "InterfaceOptionsSocialPanelConversationMode_OnEvent",
+ "InterfaceOptionsSocialPanelGuildMemberAlert",
+ "InterfaceOptionsSocialPanelGuildMemberAlertText",
+ "InterfaceOptionsSocialPanelGuildRecruitment",
+ "InterfaceOptionsSocialPanelGuildRecruitmentText",
+ "InterfaceOptionsSocialPanelPartyChat",
+ "InterfaceOptionsSocialPanelPartyChatText",
+ "InterfaceOptionsSocialPanelProfanityFilter",
+ "InterfaceOptionsSocialPanelProfanityFilterText",
+ "InterfaceOptionsSocialPanelProfanityFilter_SyncWithBattlenet",
+ "InterfaceOptionsSocialPanelProfanityFilter_UpdateDisplay",
+ "InterfaceOptionsSocialPanelSpamFilter",
+ "InterfaceOptionsSocialPanelSpamFilterText",
+ "InterfaceOptionsSocialPanelSubText",
+ "InterfaceOptionsSocialPanelTimestamps",
+ "InterfaceOptionsSocialPanelTimestampsButton",
+ "InterfaceOptionsSocialPanelTimestampsButtonDisabledTexture",
+ "InterfaceOptionsSocialPanelTimestampsButtonHighlightTexture",
+ "InterfaceOptionsSocialPanelTimestampsButtonNormalTexture",
+ "InterfaceOptionsSocialPanelTimestampsButtonPushedTexture",
+ "InterfaceOptionsSocialPanelTimestampsLabel",
+ "InterfaceOptionsSocialPanelTimestampsLeft",
+ "InterfaceOptionsSocialPanelTimestampsMiddle",
+ "InterfaceOptionsSocialPanelTimestampsRight",
+ "InterfaceOptionsSocialPanelTimestampsText",
+ "InterfaceOptionsSocialPanelTimestamps_AddTimestampFormat",
+ "InterfaceOptionsSocialPanelTimestamps_Initialize",
+ "InterfaceOptionsSocialPanelTimestamps_OnClick",
+ "InterfaceOptionsSocialPanelTimestamps_OnEvent",
+ "InterfaceOptionsSocialPanelTitle",
+ "InterfaceOptionsSocialPanelWholeChatWindowClickable",
+ "InterfaceOptionsSocialPanelWholeChatWindowClickableText",
+ "InterfaceOptionsSocialPanel_OnEvent",
+ "InterfaceOptionsSocialPanel_OnLoad",
+ "InterfaceOptionsStatusTextPanel",
+ "InterfaceOptionsStatusTextPanelParty",
+ "InterfaceOptionsStatusTextPanelPartyText",
+ "InterfaceOptionsStatusTextPanelPercentages",
+ "InterfaceOptionsStatusTextPanelPercentagesText",
+ "InterfaceOptionsStatusTextPanelPet",
+ "InterfaceOptionsStatusTextPanelPetText",
+ "InterfaceOptionsStatusTextPanelPlayer",
+ "InterfaceOptionsStatusTextPanelPlayerText",
+ "InterfaceOptionsStatusTextPanelSubText",
+ "InterfaceOptionsStatusTextPanelTarget",
+ "InterfaceOptionsStatusTextPanelTargetText",
+ "InterfaceOptionsStatusTextPanelTitle",
+ "InterfaceOptionsStatusTextPanelXP",
+ "InterfaceOptionsStatusTextPanelXPText",
+ "InterfaceOptionsUnitFramePanel",
+ "InterfaceOptionsUnitFramePanelArenaEnemyCastBar",
+ "InterfaceOptionsUnitFramePanelArenaEnemyCastBarText",
+ "InterfaceOptionsUnitFramePanelArenaEnemyFrames",
+ "InterfaceOptionsUnitFramePanelArenaEnemyFramesText",
+ "InterfaceOptionsUnitFramePanelArenaEnemyPets",
+ "InterfaceOptionsUnitFramePanelArenaEnemyPetsText",
+ "InterfaceOptionsUnitFramePanelFullSizeFocusFrame",
+ "InterfaceOptionsUnitFramePanelFullSizeFocusFrameText",
+ "InterfaceOptionsUnitFramePanelPartyBackground",
+ "InterfaceOptionsUnitFramePanelPartyBackgroundText",
+ "InterfaceOptionsUnitFramePanelPartyInRaid",
+ "InterfaceOptionsUnitFramePanelPartyInRaidText",
+ "InterfaceOptionsUnitFramePanelPartyPets",
+ "InterfaceOptionsUnitFramePanelPartyPetsText",
+ "InterfaceOptionsUnitFramePanelRaidRange",
+ "InterfaceOptionsUnitFramePanelRaidRangeText",
+ "InterfaceOptionsUnitFramePanelSubText",
+ "InterfaceOptionsUnitFramePanelTitle",
+ "InterfaceOptions_AddCategory",
+ "InterfaceOptions_UpdateMultiActionBars",
+ "InviteUnit",
+ "InvoiceFont_Med",
+ "InvoiceFont_Small",
+ "InvoiceTextFontNormal",
+ "InvoiceTextFontSmall",
+ "IsActionInRange",
+ "IsActiveBattlefieldArena",
+ "IsActiveQuestTrivial",
+ "IsAddOnLoadOnDemand",
+ "IsAddOnLoaded",
+ "IsAlreadyInQueue",
+ "IsAltKeyDown",
+ "IsArenaTeamCaptain",
+ "IsAtStableMaster",
+ "IsAttackAction",
+ "IsAttackSpell",
+ "IsAuctionSortReversed",
+ "IsAutoRepeatAction",
+ "IsAutoRepeatSpell",
+ "IsAvailableQuestTrivial",
+ "IsBNLogin",
+ "IsBagOpen",
+ "IsBattlefieldArena",
+ "IsClassColoringMessageType",
+ "IsCombatLog",
+ "IsConsumableAction",
+ "IsConsumableItem",
+ "IsConsumableSpell",
+ "IsControlKeyDown",
+ "IsCurrentAction",
+ "IsCurrentItem",
+ "IsCurrentQuestFailed",
+ "IsCurrentSpell",
+ "IsDebugBuild",
+ "IsDesaturateSupported",
+ "IsDisplayChannelModerator",
+ "IsDisplayChannelOwner",
+ "IsDressableItem",
+ "IsEquippableItem",
+ "IsEquippedAction",
+ "IsEquippedItem",
+ "IsEquippedItemType",
+ "IsFactionInactive",
+ "IsFalling",
+ "IsFishingLoot",
+ "IsFlyableArea",
+ "IsFlying",
+ "IsFrameHandle",
+ "IsGuildLeader",
+ "IsHarmfulItem",
+ "IsHarmfulSpell",
+ "IsHelpfulItem",
+ "IsHelpfulSpell",
+ "IsIgnored",
+ "IsIgnoredOrMuted",
+ "IsInArenaTeam",
+ "IsInGroup",
+ "IsInGuild",
+ "IsInInstance",
+ "IsInLFGDungeon",
+ "IsInRaid",
+ "IsIndoors",
+ "IsInventoryItemLocked",
+ "IsItemInRange",
+ "IsLFGDungeonJoinable",
+ "IsLeftAltKeyDown",
+ "IsLeftControlKeyDown",
+ "IsLeftShiftKeyDown",
+ "IsLinuxClient",
+ "IsListedInLFR",
+ "IsListeningForMessageType",
+ "IsLoggedIn",
+ "IsMacClient",
+ "IsMessageDoneBy",
+ "IsMessageDoneTo",
+ "IsModifiedClick",
+ "IsModifierKeyDown",
+ "IsMounted",
+ "IsMouseButtonDown",
+ "IsMouselooking",
+ "IsMuted",
+ "IsOptionFrameOpen",
+ "IsOutOfBounds",
+ "IsOutdoors",
+ "IsPVPTimerRunning",
+ "IsPartyLFG",
+ "IsPartyLeader",
+ "IsPassiveSpell",
+ "IsPetAttackAction",
+ "IsPetAttackActive",
+ "IsPlayerResolutionAvailable",
+ "IsPossessBarVisible",
+ "IsQuestCompletable",
+ "IsQuestLogSpecialItemInRange",
+ "IsQuestWatched",
+ "IsRaidLeader",
+ "IsRaidOfficer",
+ "IsRealPartyLeader",
+ "IsRealRaidLeader",
+ "IsReferAFriendLinked",
+ "IsResting",
+ "IsRightAltKeyDown",
+ "IsRightControlKeyDown",
+ "IsRightShiftKeyDown",
+ "IsSecureCmd",
+ "IsSelectedSpell",
+ "IsShiftKeyDown",
+ "IsSilenced",
+ "IsSpellInRange",
+ "IsSpellKnown",
+ "IsStackableAction",
+ "IsStealthed",
+ "IsStereoVideoAvailable",
+ "IsSubZonePVPPOI",
+ "IsSwimming",
+ "IsTabViewable",
+ "IsThreatWarningEnabled",
+ "IsTitleKnown",
+ "IsTrackedAchievement",
+ "IsTradeSkillLinked",
+ "IsTradeskillTrainer",
+ "IsTrainerServiceSkillStep",
+ "IsTutorialFlagged",
+ "IsUnitOnQuest",
+ "IsUsableAction",
+ "IsUsableCheckButton",
+ "IsUsableCheckButtonText",
+ "IsUsableItem",
+ "IsUsableSpell",
+ "IsUsingVehicleControls",
+ "IsVehicleAimAngleAdjustable",
+ "IsVehicleAimPowerAdjustable",
+ "IsVoiceChatAllowed",
+ "IsVoiceChatAllowedByServer",
+ "IsVoiceChatEnabled",
+ "IsWindowsClient",
+ "IsXPUserDisabled",
+ "IsZoomOutAvailable",
+ "ItemAnim_OnAnimFinished",
+ "ItemAnim_OnEvent",
+ "ItemAnim_OnLoad",
+ "ItemHasRange",
+ "ItemRefCloseButton",
+ "ItemRefShoppingTooltip1",
+ "ItemRefShoppingTooltip1TextLeft1",
+ "ItemRefShoppingTooltip1TextLeft2",
+ "ItemRefShoppingTooltip1TextLeft3",
+ "ItemRefShoppingTooltip1TextLeft4",
+ "ItemRefShoppingTooltip1TextRight1",
+ "ItemRefShoppingTooltip1TextRight2",
+ "ItemRefShoppingTooltip1TextRight3",
+ "ItemRefShoppingTooltip1TextRight4",
+ "ItemRefShoppingTooltip1Texture1",
+ "ItemRefShoppingTooltip1Texture2",
+ "ItemRefShoppingTooltip1Texture3",
+ "ItemRefShoppingTooltip2",
+ "ItemRefShoppingTooltip2TextLeft1",
+ "ItemRefShoppingTooltip2TextLeft2",
+ "ItemRefShoppingTooltip2TextLeft3",
+ "ItemRefShoppingTooltip2TextLeft4",
+ "ItemRefShoppingTooltip2TextRight1",
+ "ItemRefShoppingTooltip2TextRight2",
+ "ItemRefShoppingTooltip2TextRight3",
+ "ItemRefShoppingTooltip2TextRight4",
+ "ItemRefShoppingTooltip2Texture1",
+ "ItemRefShoppingTooltip2Texture2",
+ "ItemRefShoppingTooltip2Texture3",
+ "ItemRefShoppingTooltip3",
+ "ItemRefShoppingTooltip3TextLeft1",
+ "ItemRefShoppingTooltip3TextLeft2",
+ "ItemRefShoppingTooltip3TextLeft3",
+ "ItemRefShoppingTooltip3TextLeft4",
+ "ItemRefShoppingTooltip3TextRight1",
+ "ItemRefShoppingTooltip3TextRight2",
+ "ItemRefShoppingTooltip3TextRight3",
+ "ItemRefShoppingTooltip3TextRight4",
+ "ItemRefShoppingTooltip3Texture1",
+ "ItemRefShoppingTooltip3Texture2",
+ "ItemRefShoppingTooltip3Texture3",
+ "ItemRefTooltip",
+ "ItemRefTooltipStatusBar",
+ "ItemRefTooltipStatusBarTexture",
+ "ItemRefTooltipTextLeft1",
+ "ItemRefTooltipTextLeft2",
+ "ItemRefTooltipTextLeft3",
+ "ItemRefTooltipTextLeft4",
+ "ItemRefTooltipTextLeft5",
+ "ItemRefTooltipTextLeft6",
+ "ItemRefTooltipTextLeft7",
+ "ItemRefTooltipTextLeft8",
+ "ItemRefTooltipTextRight1",
+ "ItemRefTooltipTextRight2",
+ "ItemRefTooltipTextRight3",
+ "ItemRefTooltipTextRight4",
+ "ItemRefTooltipTextRight5",
+ "ItemRefTooltipTextRight6",
+ "ItemRefTooltipTextRight7",
+ "ItemRefTooltipTextRight8",
+ "ItemRefTooltipTexture1",
+ "ItemRefTooltipTexture10",
+ "ItemRefTooltipTexture2",
+ "ItemRefTooltipTexture3",
+ "ItemRefTooltipTexture4",
+ "ItemRefTooltipTexture5",
+ "ItemRefTooltipTexture6",
+ "ItemRefTooltipTexture7",
+ "ItemRefTooltipTexture8",
+ "ItemRefTooltipTexture9",
+ "ItemSocketingCloseButton",
+ "ItemSocketingDescription",
+ "ItemSocketingDescriptionStatusBar",
+ "ItemSocketingDescriptionStatusBarTexture",
+ "ItemSocketingDescriptionTextLeft1",
+ "ItemSocketingDescriptionTextLeft2",
+ "ItemSocketingDescriptionTextLeft3",
+ "ItemSocketingDescriptionTextLeft4",
+ "ItemSocketingDescriptionTextLeft5",
+ "ItemSocketingDescriptionTextLeft6",
+ "ItemSocketingDescriptionTextLeft7",
+ "ItemSocketingDescriptionTextLeft8",
+ "ItemSocketingDescriptionTextRight1",
+ "ItemSocketingDescriptionTextRight2",
+ "ItemSocketingDescriptionTextRight3",
+ "ItemSocketingDescriptionTextRight4",
+ "ItemSocketingDescriptionTextRight5",
+ "ItemSocketingDescriptionTextRight6",
+ "ItemSocketingDescriptionTextRight7",
+ "ItemSocketingDescriptionTextRight8",
+ "ItemSocketingDescriptionTexture1",
+ "ItemSocketingDescriptionTexture10",
+ "ItemSocketingDescriptionTexture2",
+ "ItemSocketingDescriptionTexture3",
+ "ItemSocketingDescriptionTexture4",
+ "ItemSocketingDescriptionTexture5",
+ "ItemSocketingDescriptionTexture6",
+ "ItemSocketingDescriptionTexture7",
+ "ItemSocketingDescriptionTexture8",
+ "ItemSocketingDescriptionTexture9",
+ "ItemSocketingFrame",
+ "ItemSocketingFramePortrait",
+ "ItemSocketingFrame_LoadUI",
+ "ItemSocketingFrame_OnEvent",
+ "ItemSocketingFrame_OnLoad",
+ "ItemSocketingFrame_Update",
+ "ItemSocketingScrollChild",
+ "ItemSocketingScrollFrame",
+ "ItemSocketingScrollFrameBottom",
+ "ItemSocketingScrollFrameScrollBar",
+ "ItemSocketingScrollFrameScrollBarScrollDownButton",
+ "ItemSocketingScrollFrameScrollBarScrollUpButton",
+ "ItemSocketingScrollFrameScrollBarThumbTexture",
+ "ItemSocketingScrollFrameTop",
+ "ItemSocketingSocket1",
+ "ItemSocketingSocket1Background",
+ "ItemSocketingSocket1BracketFrame",
+ "ItemSocketingSocket1BracketFrameClosedBracket",
+ "ItemSocketingSocket1BracketFrameOpenBracket",
+ "ItemSocketingSocket1Color",
+ "ItemSocketingSocket1IconTexture",
+ "ItemSocketingSocket1Left",
+ "ItemSocketingSocket1Right",
+ "ItemSocketingSocket1Shine",
+ "ItemSocketingSocket1Shine1",
+ "ItemSocketingSocket1Shine2",
+ "ItemSocketingSocket1Shine3",
+ "ItemSocketingSocket1Shine4",
+ "ItemSocketingSocket2",
+ "ItemSocketingSocket2Background",
+ "ItemSocketingSocket2BracketFrame",
+ "ItemSocketingSocket2BracketFrameClosedBracket",
+ "ItemSocketingSocket2BracketFrameOpenBracket",
+ "ItemSocketingSocket2Color",
+ "ItemSocketingSocket2IconTexture",
+ "ItemSocketingSocket2Left",
+ "ItemSocketingSocket2Right",
+ "ItemSocketingSocket2Shine",
+ "ItemSocketingSocket2Shine1",
+ "ItemSocketingSocket2Shine2",
+ "ItemSocketingSocket2Shine3",
+ "ItemSocketingSocket2Shine4",
+ "ItemSocketingSocket3",
+ "ItemSocketingSocket3Background",
+ "ItemSocketingSocket3BracketFrame",
+ "ItemSocketingSocket3BracketFrameClosedBracket",
+ "ItemSocketingSocket3BracketFrameOpenBracket",
+ "ItemSocketingSocket3Color",
+ "ItemSocketingSocket3IconTexture",
+ "ItemSocketingSocket3Left",
+ "ItemSocketingSocket3Right",
+ "ItemSocketingSocket3Shine",
+ "ItemSocketingSocket3Shine1",
+ "ItemSocketingSocket3Shine2",
+ "ItemSocketingSocket3Shine3",
+ "ItemSocketingSocket3Shine4",
+ "ItemSocketingSocketButton",
+ "ItemSocketingSocketButtonLeft",
+ "ItemSocketingSocketButtonMiddle",
+ "ItemSocketingSocketButtonRight",
+ "ItemSocketingSocketButton_Disable",
+ "ItemSocketingSocketButton_Enable",
+ "ItemSocketingSocketButton_OnEnter",
+ "ItemSocketingSocketButton_OnEvent",
+ "ItemSocketingSocketButton_OnScrollRangeChanged",
+ "ItemTextCloseButton",
+ "ItemTextCurrentPage",
+ "ItemTextFontNormal",
+ "ItemTextFrame",
+ "ItemTextFrame_OnEvent",
+ "ItemTextFrame_OnLoad",
+ "ItemTextFrame_OnUpdate",
+ "ItemTextGetCreator",
+ "ItemTextGetItem",
+ "ItemTextGetMaterial",
+ "ItemTextGetPage",
+ "ItemTextGetText",
+ "ItemTextHasNextPage",
+ "ItemTextMaterialBotLeft",
+ "ItemTextMaterialBotRight",
+ "ItemTextMaterialTopLeft",
+ "ItemTextMaterialTopRight",
+ "ItemTextNextPage",
+ "ItemTextNextPageButton",
+ "ItemTextPageScrollChild",
+ "ItemTextPageText",
+ "ItemTextPrevPage",
+ "ItemTextPrevPageButton",
+ "ItemTextScrollFrame",
+ "ItemTextScrollFrameBottom",
+ "ItemTextScrollFrameMiddle",
+ "ItemTextScrollFrameScrollBar",
+ "ItemTextScrollFrameScrollBarScrollDownButton",
+ "ItemTextScrollFrameScrollBarScrollUpButton",
+ "ItemTextScrollFrameScrollBarThumbTexture",
+ "ItemTextScrollFrameTop",
+ "ItemTextStatusBar",
+ "ItemTextTitleText",
+ "JoinBattlefield",
+ "JoinChannelByName",
+ "JoinLFG",
+ "JoinPermanentChannel",
+ "JoinTemporaryChannel",
+ "JumpOrAscendStart",
+ "KBArticle_BeginLoading",
+ "KBArticle_GetData",
+ "KBArticle_IsLoaded",
+ "KBQuery_BeginLoading",
+ "KBQuery_GetArticleHeaderCount",
+ "KBQuery_GetArticleHeaderData",
+ "KBQuery_GetTotalArticleCount",
+ "KBQuery_IsLoaded",
+ "KBSetup_BeginLoading",
+ "KBSetup_GetArticleHeaderCount",
+ "KBSetup_GetArticleHeaderData",
+ "KBSetup_GetCategoryCount",
+ "KBSetup_GetCategoryData",
+ "KBSetup_GetLanguageCount",
+ "KBSetup_GetLanguageData",
+ "KBSetup_GetSubCategoryCount",
+ "KBSetup_GetSubCategoryData",
+ "KBSetup_GetTotalArticleCount",
+ "KBSetup_IsLoaded",
+ "KBSystem_GetMOTD",
+ "KBSystem_GetServerNotice",
+ "KBSystem_GetServerStatus",
+ "KeyBindingButton_OnClick",
+ "KeyBindingFrame",
+ "KeyBindingFrameBinding1",
+ "KeyBindingFrameBinding10",
+ "KeyBindingFrameBinding10Description",
+ "KeyBindingFrameBinding10Header",
+ "KeyBindingFrameBinding10Key1Button",
+ "KeyBindingFrameBinding10Key1ButtonLeft",
+ "KeyBindingFrameBinding10Key1ButtonMiddle",
+ "KeyBindingFrameBinding10Key1ButtonRight",
+ "KeyBindingFrameBinding10Key1ButtonText",
+ "KeyBindingFrameBinding10Key2Button",
+ "KeyBindingFrameBinding10Key2ButtonLeft",
+ "KeyBindingFrameBinding10Key2ButtonMiddle",
+ "KeyBindingFrameBinding10Key2ButtonRight",
+ "KeyBindingFrameBinding10Key2ButtonText",
+ "KeyBindingFrameBinding11",
+ "KeyBindingFrameBinding11Description",
+ "KeyBindingFrameBinding11Header",
+ "KeyBindingFrameBinding11Key1Button",
+ "KeyBindingFrameBinding11Key1ButtonLeft",
+ "KeyBindingFrameBinding11Key1ButtonMiddle",
+ "KeyBindingFrameBinding11Key1ButtonRight",
+ "KeyBindingFrameBinding11Key1ButtonText",
+ "KeyBindingFrameBinding11Key2Button",
+ "KeyBindingFrameBinding11Key2ButtonLeft",
+ "KeyBindingFrameBinding11Key2ButtonMiddle",
+ "KeyBindingFrameBinding11Key2ButtonRight",
+ "KeyBindingFrameBinding11Key2ButtonText",
+ "KeyBindingFrameBinding12",
+ "KeyBindingFrameBinding12Description",
+ "KeyBindingFrameBinding12Header",
+ "KeyBindingFrameBinding12Key1Button",
+ "KeyBindingFrameBinding12Key1ButtonLeft",
+ "KeyBindingFrameBinding12Key1ButtonMiddle",
+ "KeyBindingFrameBinding12Key1ButtonRight",
+ "KeyBindingFrameBinding12Key1ButtonText",
+ "KeyBindingFrameBinding12Key2Button",
+ "KeyBindingFrameBinding12Key2ButtonLeft",
+ "KeyBindingFrameBinding12Key2ButtonMiddle",
+ "KeyBindingFrameBinding12Key2ButtonRight",
+ "KeyBindingFrameBinding12Key2ButtonText",
+ "KeyBindingFrameBinding13",
+ "KeyBindingFrameBinding13Description",
+ "KeyBindingFrameBinding13Header",
+ "KeyBindingFrameBinding13Key1Button",
+ "KeyBindingFrameBinding13Key1ButtonLeft",
+ "KeyBindingFrameBinding13Key1ButtonMiddle",
+ "KeyBindingFrameBinding13Key1ButtonRight",
+ "KeyBindingFrameBinding13Key1ButtonText",
+ "KeyBindingFrameBinding13Key2Button",
+ "KeyBindingFrameBinding13Key2ButtonLeft",
+ "KeyBindingFrameBinding13Key2ButtonMiddle",
+ "KeyBindingFrameBinding13Key2ButtonRight",
+ "KeyBindingFrameBinding13Key2ButtonText",
+ "KeyBindingFrameBinding14",
+ "KeyBindingFrameBinding14Description",
+ "KeyBindingFrameBinding14Header",
+ "KeyBindingFrameBinding14Key1Button",
+ "KeyBindingFrameBinding14Key1ButtonLeft",
+ "KeyBindingFrameBinding14Key1ButtonMiddle",
+ "KeyBindingFrameBinding14Key1ButtonRight",
+ "KeyBindingFrameBinding14Key1ButtonText",
+ "KeyBindingFrameBinding14Key2Button",
+ "KeyBindingFrameBinding14Key2ButtonLeft",
+ "KeyBindingFrameBinding14Key2ButtonMiddle",
+ "KeyBindingFrameBinding14Key2ButtonRight",
+ "KeyBindingFrameBinding14Key2ButtonText",
+ "KeyBindingFrameBinding15",
+ "KeyBindingFrameBinding15Description",
+ "KeyBindingFrameBinding15Header",
+ "KeyBindingFrameBinding15Key1Button",
+ "KeyBindingFrameBinding15Key1ButtonLeft",
+ "KeyBindingFrameBinding15Key1ButtonMiddle",
+ "KeyBindingFrameBinding15Key1ButtonRight",
+ "KeyBindingFrameBinding15Key1ButtonText",
+ "KeyBindingFrameBinding15Key2Button",
+ "KeyBindingFrameBinding15Key2ButtonLeft",
+ "KeyBindingFrameBinding15Key2ButtonMiddle",
+ "KeyBindingFrameBinding15Key2ButtonRight",
+ "KeyBindingFrameBinding15Key2ButtonText",
+ "KeyBindingFrameBinding16",
+ "KeyBindingFrameBinding16Description",
+ "KeyBindingFrameBinding16Header",
+ "KeyBindingFrameBinding16Key1Button",
+ "KeyBindingFrameBinding16Key1ButtonLeft",
+ "KeyBindingFrameBinding16Key1ButtonMiddle",
+ "KeyBindingFrameBinding16Key1ButtonRight",
+ "KeyBindingFrameBinding16Key1ButtonText",
+ "KeyBindingFrameBinding16Key2Button",
+ "KeyBindingFrameBinding16Key2ButtonLeft",
+ "KeyBindingFrameBinding16Key2ButtonMiddle",
+ "KeyBindingFrameBinding16Key2ButtonRight",
+ "KeyBindingFrameBinding16Key2ButtonText",
+ "KeyBindingFrameBinding17",
+ "KeyBindingFrameBinding17Description",
+ "KeyBindingFrameBinding17Header",
+ "KeyBindingFrameBinding17Key1Button",
+ "KeyBindingFrameBinding17Key1ButtonLeft",
+ "KeyBindingFrameBinding17Key1ButtonMiddle",
+ "KeyBindingFrameBinding17Key1ButtonRight",
+ "KeyBindingFrameBinding17Key1ButtonText",
+ "KeyBindingFrameBinding17Key2Button",
+ "KeyBindingFrameBinding17Key2ButtonLeft",
+ "KeyBindingFrameBinding17Key2ButtonMiddle",
+ "KeyBindingFrameBinding17Key2ButtonRight",
+ "KeyBindingFrameBinding17Key2ButtonText",
+ "KeyBindingFrameBinding1Description",
+ "KeyBindingFrameBinding1Header",
+ "KeyBindingFrameBinding1Key1Button",
+ "KeyBindingFrameBinding1Key1ButtonLeft",
+ "KeyBindingFrameBinding1Key1ButtonMiddle",
+ "KeyBindingFrameBinding1Key1ButtonRight",
+ "KeyBindingFrameBinding1Key1ButtonText",
+ "KeyBindingFrameBinding1Key2Button",
+ "KeyBindingFrameBinding1Key2ButtonLeft",
+ "KeyBindingFrameBinding1Key2ButtonMiddle",
+ "KeyBindingFrameBinding1Key2ButtonRight",
+ "KeyBindingFrameBinding1Key2ButtonText",
+ "KeyBindingFrameBinding2",
+ "KeyBindingFrameBinding2Description",
+ "KeyBindingFrameBinding2Header",
+ "KeyBindingFrameBinding2Key1Button",
+ "KeyBindingFrameBinding2Key1ButtonLeft",
+ "KeyBindingFrameBinding2Key1ButtonMiddle",
+ "KeyBindingFrameBinding2Key1ButtonRight",
+ "KeyBindingFrameBinding2Key1ButtonText",
+ "KeyBindingFrameBinding2Key2Button",
+ "KeyBindingFrameBinding2Key2ButtonLeft",
+ "KeyBindingFrameBinding2Key2ButtonMiddle",
+ "KeyBindingFrameBinding2Key2ButtonRight",
+ "KeyBindingFrameBinding2Key2ButtonText",
+ "KeyBindingFrameBinding3",
+ "KeyBindingFrameBinding3Description",
+ "KeyBindingFrameBinding3Header",
+ "KeyBindingFrameBinding3Key1Button",
+ "KeyBindingFrameBinding3Key1ButtonLeft",
+ "KeyBindingFrameBinding3Key1ButtonMiddle",
+ "KeyBindingFrameBinding3Key1ButtonRight",
+ "KeyBindingFrameBinding3Key1ButtonText",
+ "KeyBindingFrameBinding3Key2Button",
+ "KeyBindingFrameBinding3Key2ButtonLeft",
+ "KeyBindingFrameBinding3Key2ButtonMiddle",
+ "KeyBindingFrameBinding3Key2ButtonRight",
+ "KeyBindingFrameBinding3Key2ButtonText",
+ "KeyBindingFrameBinding4",
+ "KeyBindingFrameBinding4Description",
+ "KeyBindingFrameBinding4Header",
+ "KeyBindingFrameBinding4Key1Button",
+ "KeyBindingFrameBinding4Key1ButtonLeft",
+ "KeyBindingFrameBinding4Key1ButtonMiddle",
+ "KeyBindingFrameBinding4Key1ButtonRight",
+ "KeyBindingFrameBinding4Key1ButtonText",
+ "KeyBindingFrameBinding4Key2Button",
+ "KeyBindingFrameBinding4Key2ButtonLeft",
+ "KeyBindingFrameBinding4Key2ButtonMiddle",
+ "KeyBindingFrameBinding4Key2ButtonRight",
+ "KeyBindingFrameBinding4Key2ButtonText",
+ "KeyBindingFrameBinding5",
+ "KeyBindingFrameBinding5Description",
+ "KeyBindingFrameBinding5Header",
+ "KeyBindingFrameBinding5Key1Button",
+ "KeyBindingFrameBinding5Key1ButtonLeft",
+ "KeyBindingFrameBinding5Key1ButtonMiddle",
+ "KeyBindingFrameBinding5Key1ButtonRight",
+ "KeyBindingFrameBinding5Key1ButtonText",
+ "KeyBindingFrameBinding5Key2Button",
+ "KeyBindingFrameBinding5Key2ButtonLeft",
+ "KeyBindingFrameBinding5Key2ButtonMiddle",
+ "KeyBindingFrameBinding5Key2ButtonRight",
+ "KeyBindingFrameBinding5Key2ButtonText",
+ "KeyBindingFrameBinding6",
+ "KeyBindingFrameBinding6Description",
+ "KeyBindingFrameBinding6Header",
+ "KeyBindingFrameBinding6Key1Button",
+ "KeyBindingFrameBinding6Key1ButtonLeft",
+ "KeyBindingFrameBinding6Key1ButtonMiddle",
+ "KeyBindingFrameBinding6Key1ButtonRight",
+ "KeyBindingFrameBinding6Key1ButtonText",
+ "KeyBindingFrameBinding6Key2Button",
+ "KeyBindingFrameBinding6Key2ButtonLeft",
+ "KeyBindingFrameBinding6Key2ButtonMiddle",
+ "KeyBindingFrameBinding6Key2ButtonRight",
+ "KeyBindingFrameBinding6Key2ButtonText",
+ "KeyBindingFrameBinding7",
+ "KeyBindingFrameBinding7Description",
+ "KeyBindingFrameBinding7Header",
+ "KeyBindingFrameBinding7Key1Button",
+ "KeyBindingFrameBinding7Key1ButtonLeft",
+ "KeyBindingFrameBinding7Key1ButtonMiddle",
+ "KeyBindingFrameBinding7Key1ButtonRight",
+ "KeyBindingFrameBinding7Key1ButtonText",
+ "KeyBindingFrameBinding7Key2Button",
+ "KeyBindingFrameBinding7Key2ButtonLeft",
+ "KeyBindingFrameBinding7Key2ButtonMiddle",
+ "KeyBindingFrameBinding7Key2ButtonRight",
+ "KeyBindingFrameBinding7Key2ButtonText",
+ "KeyBindingFrameBinding8",
+ "KeyBindingFrameBinding8Description",
+ "KeyBindingFrameBinding8Header",
+ "KeyBindingFrameBinding8Key1Button",
+ "KeyBindingFrameBinding8Key1ButtonLeft",
+ "KeyBindingFrameBinding8Key1ButtonMiddle",
+ "KeyBindingFrameBinding8Key1ButtonRight",
+ "KeyBindingFrameBinding8Key1ButtonText",
+ "KeyBindingFrameBinding8Key2Button",
+ "KeyBindingFrameBinding8Key2ButtonLeft",
+ "KeyBindingFrameBinding8Key2ButtonMiddle",
+ "KeyBindingFrameBinding8Key2ButtonRight",
+ "KeyBindingFrameBinding8Key2ButtonText",
+ "KeyBindingFrameBinding9",
+ "KeyBindingFrameBinding9Description",
+ "KeyBindingFrameBinding9Header",
+ "KeyBindingFrameBinding9Key1Button",
+ "KeyBindingFrameBinding9Key1ButtonLeft",
+ "KeyBindingFrameBinding9Key1ButtonMiddle",
+ "KeyBindingFrameBinding9Key1ButtonRight",
+ "KeyBindingFrameBinding9Key1ButtonText",
+ "KeyBindingFrameBinding9Key2Button",
+ "KeyBindingFrameBinding9Key2ButtonLeft",
+ "KeyBindingFrameBinding9Key2ButtonMiddle",
+ "KeyBindingFrameBinding9Key2ButtonRight",
+ "KeyBindingFrameBinding9Key2ButtonText",
+ "KeyBindingFrameCancelButton",
+ "KeyBindingFrameCancelButtonText",
+ "KeyBindingFrameCharacterButton",
+ "KeyBindingFrameCharacterButtonText",
+ "KeyBindingFrameCommandLabel",
+ "KeyBindingFrameDefaultButton",
+ "KeyBindingFrameHeader",
+ "KeyBindingFrameHeaderText",
+ "KeyBindingFrameKey1Label",
+ "KeyBindingFrameKey2Label",
+ "KeyBindingFrameOkayButton",
+ "KeyBindingFrameOkayButtonText",
+ "KeyBindingFrameOutputText",
+ "KeyBindingFrameScrollFrame",
+ "KeyBindingFrameScrollFrameScrollBar",
+ "KeyBindingFrameScrollFrameScrollBarScrollDownButton",
+ "KeyBindingFrameScrollFrameScrollBarScrollUpButton",
+ "KeyBindingFrameScrollFrameScrollBarThumbTexture",
+ "KeyBindingFrameScrollFrameScrollChildFrame",
+ "KeyBindingFrameUnbindButton",
+ "KeyBindingFrameUnbindButtonText",
+ "KeyBindingFrame_ChangeBindingProfile",
+ "KeyBindingFrame_LoadUI",
+ "KeyBindingFrame_OnKeyDown",
+ "KeyBindingFrame_OnLoad",
+ "KeyBindingFrame_OnShow",
+ "KeyBindingFrame_SetBinding",
+ "KeyBindingFrame_SetSelected",
+ "KeyBindingFrame_UnbindKey",
+ "KeyBindingFrame_Update",
+ "KeyBindingFrame_UpdateUnbindKey",
+ "KeyRingButton",
+ "KeyRingButtonIDToInvSlotID",
+ "KeyRingButtonItemAnim",
+ "KnowledgeBaseArticleListFrame",
+ "KnowledgeBaseArticleListFrameCount",
+ "KnowledgeBaseArticleListFrameNextButton",
+ "KnowledgeBaseArticleListFrameNextButtonText",
+ "KnowledgeBaseArticleListFramePreviousButton",
+ "KnowledgeBaseArticleListFramePreviousButtonText",
+ "KnowledgeBaseArticleListFrameTitle",
+ "KnowledgeBaseArticleListFrame_HideArticleList",
+ "KnowledgeBaseArticleListFrame_NextPage",
+ "KnowledgeBaseArticleListFrame_PopulateArticleList",
+ "KnowledgeBaseArticleListFrame_PreviousPage",
+ "KnowledgeBaseArticleListItem1",
+ "KnowledgeBaseArticleListItem10",
+ "KnowledgeBaseArticleListItem10HotIcon",
+ "KnowledgeBaseArticleListItem10Number",
+ "KnowledgeBaseArticleListItem10Title",
+ "KnowledgeBaseArticleListItem10UpdatedIcon",
+ "KnowledgeBaseArticleListItem11",
+ "KnowledgeBaseArticleListItem11HotIcon",
+ "KnowledgeBaseArticleListItem11Number",
+ "KnowledgeBaseArticleListItem11Title",
+ "KnowledgeBaseArticleListItem11UpdatedIcon",
+ "KnowledgeBaseArticleListItem12",
+ "KnowledgeBaseArticleListItem12HotIcon",
+ "KnowledgeBaseArticleListItem12Number",
+ "KnowledgeBaseArticleListItem12Title",
+ "KnowledgeBaseArticleListItem12UpdatedIcon",
+ "KnowledgeBaseArticleListItem13",
+ "KnowledgeBaseArticleListItem13HotIcon",
+ "KnowledgeBaseArticleListItem13Number",
+ "KnowledgeBaseArticleListItem13Title",
+ "KnowledgeBaseArticleListItem13UpdatedIcon",
+ "KnowledgeBaseArticleListItem14",
+ "KnowledgeBaseArticleListItem14HotIcon",
+ "KnowledgeBaseArticleListItem14Number",
+ "KnowledgeBaseArticleListItem14Title",
+ "KnowledgeBaseArticleListItem14UpdatedIcon",
+ "KnowledgeBaseArticleListItem15",
+ "KnowledgeBaseArticleListItem15HotIcon",
+ "KnowledgeBaseArticleListItem15Number",
+ "KnowledgeBaseArticleListItem15Title",
+ "KnowledgeBaseArticleListItem15UpdatedIcon",
+ "KnowledgeBaseArticleListItem16",
+ "KnowledgeBaseArticleListItem16HotIcon",
+ "KnowledgeBaseArticleListItem16Number",
+ "KnowledgeBaseArticleListItem16Title",
+ "KnowledgeBaseArticleListItem16UpdatedIcon",
+ "KnowledgeBaseArticleListItem17",
+ "KnowledgeBaseArticleListItem17HotIcon",
+ "KnowledgeBaseArticleListItem17Number",
+ "KnowledgeBaseArticleListItem17Title",
+ "KnowledgeBaseArticleListItem17UpdatedIcon",
+ "KnowledgeBaseArticleListItem18",
+ "KnowledgeBaseArticleListItem18HotIcon",
+ "KnowledgeBaseArticleListItem18Number",
+ "KnowledgeBaseArticleListItem18Title",
+ "KnowledgeBaseArticleListItem18UpdatedIcon",
+ "KnowledgeBaseArticleListItem19",
+ "KnowledgeBaseArticleListItem19HotIcon",
+ "KnowledgeBaseArticleListItem19Number",
+ "KnowledgeBaseArticleListItem19Title",
+ "KnowledgeBaseArticleListItem19UpdatedIcon",
+ "KnowledgeBaseArticleListItem1HotIcon",
+ "KnowledgeBaseArticleListItem1Number",
+ "KnowledgeBaseArticleListItem1Title",
+ "KnowledgeBaseArticleListItem1UpdatedIcon",
+ "KnowledgeBaseArticleListItem2",
+ "KnowledgeBaseArticleListItem20",
+ "KnowledgeBaseArticleListItem20HotIcon",
+ "KnowledgeBaseArticleListItem20Number",
+ "KnowledgeBaseArticleListItem20Title",
+ "KnowledgeBaseArticleListItem20UpdatedIcon",
+ "KnowledgeBaseArticleListItem2HotIcon",
+ "KnowledgeBaseArticleListItem2Number",
+ "KnowledgeBaseArticleListItem2Title",
+ "KnowledgeBaseArticleListItem2UpdatedIcon",
+ "KnowledgeBaseArticleListItem3",
+ "KnowledgeBaseArticleListItem3HotIcon",
+ "KnowledgeBaseArticleListItem3Number",
+ "KnowledgeBaseArticleListItem3Title",
+ "KnowledgeBaseArticleListItem3UpdatedIcon",
+ "KnowledgeBaseArticleListItem4",
+ "KnowledgeBaseArticleListItem4HotIcon",
+ "KnowledgeBaseArticleListItem4Number",
+ "KnowledgeBaseArticleListItem4Title",
+ "KnowledgeBaseArticleListItem4UpdatedIcon",
+ "KnowledgeBaseArticleListItem5",
+ "KnowledgeBaseArticleListItem5HotIcon",
+ "KnowledgeBaseArticleListItem5Number",
+ "KnowledgeBaseArticleListItem5Title",
+ "KnowledgeBaseArticleListItem5UpdatedIcon",
+ "KnowledgeBaseArticleListItem6",
+ "KnowledgeBaseArticleListItem6HotIcon",
+ "KnowledgeBaseArticleListItem6Number",
+ "KnowledgeBaseArticleListItem6Title",
+ "KnowledgeBaseArticleListItem6UpdatedIcon",
+ "KnowledgeBaseArticleListItem7",
+ "KnowledgeBaseArticleListItem7HotIcon",
+ "KnowledgeBaseArticleListItem7Number",
+ "KnowledgeBaseArticleListItem7Title",
+ "KnowledgeBaseArticleListItem7UpdatedIcon",
+ "KnowledgeBaseArticleListItem8",
+ "KnowledgeBaseArticleListItem8HotIcon",
+ "KnowledgeBaseArticleListItem8Number",
+ "KnowledgeBaseArticleListItem8Title",
+ "KnowledgeBaseArticleListItem8UpdatedIcon",
+ "KnowledgeBaseArticleListItem9",
+ "KnowledgeBaseArticleListItem9HotIcon",
+ "KnowledgeBaseArticleListItem9Number",
+ "KnowledgeBaseArticleListItem9Title",
+ "KnowledgeBaseArticleListItem9UpdatedIcon",
+ "KnowledgeBaseArticleListItem_OnClick",
+ "KnowledgeBaseArticleListItem_OnEnter",
+ "KnowledgeBaseArticleListItem_OnLeave",
+ "KnowledgeBaseArticleListItem_OnUpdate",
+ "KnowledgeBaseArticleListItem_Update",
+ "KnowledgeBaseArticleScrollChildFrame",
+ "KnowledgeBaseArticleScrollChildFrameArticleId",
+ "KnowledgeBaseArticleScrollChildFrameBackButton",
+ "KnowledgeBaseArticleScrollChildFrameBackButtonText",
+ "KnowledgeBaseArticleScrollChildFrameText",
+ "KnowledgeBaseArticleScrollChildFrameTitle",
+ "KnowledgeBaseArticleScrollFrame",
+ "KnowledgeBaseArticleScrollFrameScrollBar",
+ "KnowledgeBaseArticleScrollFrameScrollBarScrollDownButton",
+ "KnowledgeBaseArticleScrollFrameScrollBarScrollUpButton",
+ "KnowledgeBaseArticleScrollFrameScrollBarThumbTexture",
+ "KnowledgeBaseErrorFrame",
+ "KnowledgeBaseErrorFrameText",
+ "KnowledgeBaseErrorFrame_SetErrorMessage",
+ "KnowledgeBaseFrame",
+ "KnowledgeBaseFrameAbandonTicket",
+ "KnowledgeBaseFrameAbandonTicketText",
+ "KnowledgeBaseFrameCancel",
+ "KnowledgeBaseFrameCancelText",
+ "KnowledgeBaseFrameCategoryButton_OnClick",
+ "KnowledgeBaseFrameCategoryDropDown",
+ "KnowledgeBaseFrameCategoryDropDownButton",
+ "KnowledgeBaseFrameCategoryDropDownButtonDisabledTexture",
+ "KnowledgeBaseFrameCategoryDropDownButtonHighlightTexture",
+ "KnowledgeBaseFrameCategoryDropDownButtonNormalTexture",
+ "KnowledgeBaseFrameCategoryDropDownButtonPushedTexture",
+ "KnowledgeBaseFrameCategoryDropDownLeft",
+ "KnowledgeBaseFrameCategoryDropDownMiddle",
+ "KnowledgeBaseFrameCategoryDropDownRight",
+ "KnowledgeBaseFrameCategoryDropDownText",
+ "KnowledgeBaseFrameCategoryDropDown_AddInfo",
+ "KnowledgeBaseFrameCategoryDropDown_Initialize",
+ "KnowledgeBaseFrameCategoryDropDown_OnLoad",
+ "KnowledgeBaseFrameDivider",
+ "KnowledgeBaseFrameDivider2",
+ "KnowledgeBaseFrameDivider2Left",
+ "KnowledgeBaseFrameDivider2Middle",
+ "KnowledgeBaseFrameDivider2Right",
+ "KnowledgeBaseFrameDividerLeft",
+ "KnowledgeBaseFrameDividerMiddle",
+ "KnowledgeBaseFrameDividerRight",
+ "KnowledgeBaseFrameEditBox",
+ "KnowledgeBaseFrameEditBoxLeft",
+ "KnowledgeBaseFrameEditBoxMiddle",
+ "KnowledgeBaseFrameEditBoxRight",
+ "KnowledgeBaseFrameEditTicket",
+ "KnowledgeBaseFrameEditTicketText",
+ "KnowledgeBaseFrameGMTalk",
+ "KnowledgeBaseFrameGMTalkText",
+ "KnowledgeBaseFrameHeader",
+ "KnowledgeBaseFrameLag",
+ "KnowledgeBaseFrameLagText",
+ "KnowledgeBaseFrameReportIssue",
+ "KnowledgeBaseFrameReportIssueText",
+ "KnowledgeBaseFrameSearchButton",
+ "KnowledgeBaseFrameSearchButtonText",
+ "KnowledgeBaseFrameStuck",
+ "KnowledgeBaseFrameStuckText",
+ "KnowledgeBaseFrameSubCategoryButton_OnClick",
+ "KnowledgeBaseFrameSubCategoryDropDown",
+ "KnowledgeBaseFrameSubCategoryDropDownButton",
+ "KnowledgeBaseFrameSubCategoryDropDownButtonDisabledTexture",
+ "KnowledgeBaseFrameSubCategoryDropDownButtonHighlightTexture",
+ "KnowledgeBaseFrameSubCategoryDropDownButtonNormalTexture",
+ "KnowledgeBaseFrameSubCategoryDropDownButtonPushedTexture",
+ "KnowledgeBaseFrameSubCategoryDropDownLeft",
+ "KnowledgeBaseFrameSubCategoryDropDownMiddle",
+ "KnowledgeBaseFrameSubCategoryDropDownRight",
+ "KnowledgeBaseFrameSubCategoryDropDownText",
+ "KnowledgeBaseFrameSubCategoryDropDown_AddInfo",
+ "KnowledgeBaseFrameSubCategoryDropDown_Initialize",
+ "KnowledgeBaseFrameSubCategoryDropDown_OnLoad",
+ "KnowledgeBaseFrameTopIssuesButton",
+ "KnowledgeBaseFrameTopIssuesButtonText",
+ "KnowledgeBaseFrame_DisableButtons",
+ "KnowledgeBaseFrame_EnableButtons",
+ "KnowledgeBaseFrame_LoadTopIssues",
+ "KnowledgeBaseFrame_OnEvent",
+ "KnowledgeBaseFrame_OnLoad",
+ "KnowledgeBaseFrame_OnShow",
+ "KnowledgeBaseFrame_Search",
+ "KnowledgeBaseFrame_ShowArticleFrame",
+ "KnowledgeBaseFrame_ShowErrorFrame",
+ "KnowledgeBaseFrame_ShowSearchFrame",
+ "KnowledgeBaseFrame_UpdateMotd",
+ "KnowledgeBaseFrame_UpdateServerMessage",
+ "KnowledgeBaseMotdLabel",
+ "KnowledgeBaseMotdText",
+ "KnowledgeBaseMotdTextFrame",
+ "KnowledgeBaseMotdTextFrame_OnEnter",
+ "KnowledgeBaseMotdTextFrame_OnLeave",
+ "KnowledgeBaseMotdTextFrame_OnUpdate",
+ "KnowledgeBaseServerMessageLabel",
+ "KnowledgeBaseServerMessageText",
+ "KnowledgeBaseServerMessageTextFrame",
+ "KnowledgeBaseServerMessageTextFrame_OnEnter",
+ "KnowledgeBaseServerMessageTextFrame_OnLeave",
+ "KnowledgeBaseServerMessageTextFrame_OnUpdate",
+ "KnowledgeBaseUpdateTopPanelPositions",
+ "LFDConstructDeclinedMessage",
+ "LFDDungeonReadyDialog",
+ "LFDDungeonReadyDialogBackground",
+ "LFDDungeonReadyDialogBottomArt",
+ "LFDDungeonReadyDialogCloseButton",
+ "LFDDungeonReadyDialogEnterDungeonButton",
+ "LFDDungeonReadyDialogEnterDungeonButtonLeft",
+ "LFDDungeonReadyDialogEnterDungeonButtonMiddle",
+ "LFDDungeonReadyDialogEnterDungeonButtonRight",
+ "LFDDungeonReadyDialogEnterDungeonButtonText",
+ "LFDDungeonReadyDialogFiligree",
+ "LFDDungeonReadyDialogInstanceInfoFrame",
+ "LFDDungeonReadyDialogInstanceInfoFrameName",
+ "LFDDungeonReadyDialogInstanceInfoFrameStatusText",
+ "LFDDungeonReadyDialogInstanceInfo_OnEnter",
+ "LFDDungeonReadyDialogLabel",
+ "LFDDungeonReadyDialogLeaveQueueButton",
+ "LFDDungeonReadyDialogLeaveQueueButtonLeft",
+ "LFDDungeonReadyDialogLeaveQueueButtonMiddle",
+ "LFDDungeonReadyDialogLeaveQueueButtonRight",
+ "LFDDungeonReadyDialogLeaveQueueButtonText",
+ "LFDDungeonReadyDialogRandomInProgressFrame",
+ "LFDDungeonReadyDialogRandomInProgressFrameStatusText",
+ "LFDDungeonReadyDialogReward_OnEnter",
+ "LFDDungeonReadyDialogReward_SetMisc",
+ "LFDDungeonReadyDialogReward_SetReward",
+ "LFDDungeonReadyDialogRewardsFrame",
+ "LFDDungeonReadyDialogRewardsFrameLabel",
+ "LFDDungeonReadyDialogRewardsFrameReward1",
+ "LFDDungeonReadyDialogRewardsFrameReward1Border",
+ "LFDDungeonReadyDialogRewardsFrameReward1Texture",
+ "LFDDungeonReadyDialogRewardsFrameReward2",
+ "LFDDungeonReadyDialogRewardsFrameReward2Border",
+ "LFDDungeonReadyDialogRewardsFrameReward2Texture",
+ "LFDDungeonReadyDialogRoleIcon",
+ "LFDDungeonReadyDialogRoleIconLeaderIcon",
+ "LFDDungeonReadyDialogRoleIconTexture",
+ "LFDDungeonReadyDialogRoleLabel",
+ "LFDDungeonReadyDialogYourRoleDescription",
+ "LFDDungeonReadyDialog_UpdateInstanceInfo",
+ "LFDDungeonReadyDialog_UpdateRewards",
+ "LFDDungeonReadyPopup",
+ "LFDDungeonReadyPopup_OnFail",
+ "LFDDungeonReadyPopup_OnUpdate",
+ "LFDDungeonReadyPopup_Update",
+ "LFDDungeonReadyStatus",
+ "LFDDungeonReadyStatusCloseButton",
+ "LFDDungeonReadyStatusLabel",
+ "LFDDungeonReadyStatusPlayer1",
+ "LFDDungeonReadyStatusPlayer1StatusIcon",
+ "LFDDungeonReadyStatusPlayer1Texture",
+ "LFDDungeonReadyStatusPlayer2",
+ "LFDDungeonReadyStatusPlayer2StatusIcon",
+ "LFDDungeonReadyStatusPlayer2Texture",
+ "LFDDungeonReadyStatusPlayer3",
+ "LFDDungeonReadyStatusPlayer3StatusIcon",
+ "LFDDungeonReadyStatusPlayer3Texture",
+ "LFDDungeonReadyStatusPlayer4",
+ "LFDDungeonReadyStatusPlayer4StatusIcon",
+ "LFDDungeonReadyStatusPlayer4Texture",
+ "LFDDungeonReadyStatusPlayer5",
+ "LFDDungeonReadyStatusPlayer5StatusIcon",
+ "LFDDungeonReadyStatusPlayer5Texture",
+ "LFDDungeonReadyStatus_ResetReadyStates",
+ "LFDDungeonReadyStatus_UpdateIcon",
+ "LFDFrameRoleCheckButton_OnClick",
+ "LFDFrameRoleCheckButton_OnEnter",
+ "LFDFrame_OnEvent",
+ "LFDFrame_OnHide",
+ "LFDFrame_OnLoad",
+ "LFDFrame_OnShow",
+ "LFDFrame_UpdateBackfill",
+ "LFDGetNumDungeons",
+ "LFDHiddenByCollapseList",
+ "LFDList_SetDungeonEnabled",
+ "LFDList_SetHeaderCollapsed",
+ "LFDList_SetHeaderEnabled",
+ "LFDMicroButton",
+ "LFDParentFrame",
+ "LFDParentFramePortrait",
+ "LFDParentFramePortraitIcon",
+ "LFDParentFramePortraitTexture",
+ "LFDQueueFrame",
+ "LFDQueueFrameBackground",
+ "LFDQueueFrameCancelButton",
+ "LFDQueueFrameCancelButtonLeft",
+ "LFDQueueFrameCancelButtonMiddle",
+ "LFDQueueFrameCancelButtonRight",
+ "LFDQueueFrameCancelButtonText",
+ "LFDQueueFrameCooldownFrame",
+ "LFDQueueFrameCooldownFrameBlackFilter",
+ "LFDQueueFrameCooldownFrameDescription",
+ "LFDQueueFrameCooldownFrameName1",
+ "LFDQueueFrameCooldownFrameName2",
+ "LFDQueueFrameCooldownFrameName3",
+ "LFDQueueFrameCooldownFrameName4",
+ "LFDQueueFrameCooldownFrameStatus1",
+ "LFDQueueFrameCooldownFrameStatus2",
+ "LFDQueueFrameCooldownFrameStatus3",
+ "LFDQueueFrameCooldownFrameStatus4",
+ "LFDQueueFrameCooldownFrameTime",
+ "LFDQueueFrameDungeonChoiceEnableButton_OnClick",
+ "LFDQueueFrameDungeonListButton_OnEnter",
+ "LFDQueueFrameExpandOrCollapseButton_OnClick",
+ "LFDQueueFrameFindGroupButton",
+ "LFDQueueFrameFindGroupButtonLeft",
+ "LFDQueueFrameFindGroupButtonMiddle",
+ "LFDQueueFrameFindGroupButtonRight",
+ "LFDQueueFrameFindGroupButtonText",
+ "LFDQueueFrameFindGroupButton_Update",
+ "LFDQueueFrameLayout",
+ "LFDQueueFrameNoLFDWhileLFR",
+ "LFDQueueFrameNoLFDWhileLFRBlackFilter",
+ "LFDQueueFrameNoLFDWhileLFRDescription",
+ "LFDQueueFrameNoLFDWhileLFRLeaveQueueButton",
+ "LFDQueueFrameNoLFDWhileLFRLeaveQueueButtonLeft",
+ "LFDQueueFrameNoLFDWhileLFRLeaveQueueButtonMiddle",
+ "LFDQueueFrameNoLFDWhileLFRLeaveQueueButtonRight",
+ "LFDQueueFrameNoLFDWhileLFRLeaveQueueButtonText",
+ "LFDQueueFramePartyBackfill",
+ "LFDQueueFramePartyBackfillBackfillButton",
+ "LFDQueueFramePartyBackfillBackfillButtonLeft",
+ "LFDQueueFramePartyBackfillBackfillButtonMiddle",
+ "LFDQueueFramePartyBackfillBackfillButtonRight",
+ "LFDQueueFramePartyBackfillBackfillButtonText",
+ "LFDQueueFramePartyBackfillBlackFilter",
+ "LFDQueueFramePartyBackfillDescription",
+ "LFDQueueFramePartyBackfillNoBackfillButton",
+ "LFDQueueFramePartyBackfillNoBackfillButtonLeft",
+ "LFDQueueFramePartyBackfillNoBackfillButtonMiddle",
+ "LFDQueueFramePartyBackfillNoBackfillButtonRight",
+ "LFDQueueFramePartyBackfillNoBackfillButtonText",
+ "LFDQueueFrameRandom",
+ "LFDQueueFrameRandomCooldownFrame_OnEvent",
+ "LFDQueueFrameRandomCooldownFrame_OnLoad",
+ "LFDQueueFrameRandomCooldownFrame_OnUpdate",
+ "LFDQueueFrameRandomCooldownFrame_Update",
+ "LFDQueueFrameRandomScrollFrame",
+ "LFDQueueFrameRandomScrollFrameChildFrame",
+ "LFDQueueFrameRandomScrollFrameChildFrameDescription",
+ "LFDQueueFrameRandomScrollFrameChildFrameItem1",
+ "LFDQueueFrameRandomScrollFrameChildFrameItem1Count",
+ "LFDQueueFrameRandomScrollFrameChildFrameItem1IconTexture",
+ "LFDQueueFrameRandomScrollFrameChildFrameItem1Name",
+ "LFDQueueFrameRandomScrollFrameChildFrameItem1NameFrame",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrame",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrameCopperButton",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrameCopperButtonText",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrameGoldButton",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrameGoldButtonText",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrameSilverButton",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyFrameSilverButtonText",
+ "LFDQueueFrameRandomScrollFrameChildFrameMoneyLabel",
+ "LFDQueueFrameRandomScrollFrameChildFramePUGDescription",
+ "LFDQueueFrameRandomScrollFrameChildFrameRewardsDescription",
+ "LFDQueueFrameRandomScrollFrameChildFrameRewardsLabel",
+ "LFDQueueFrameRandomScrollFrameChildFrameSpacer",
+ "LFDQueueFrameRandomScrollFrameChildFrameTitle",
+ "LFDQueueFrameRandomScrollFrameChildFrameXPAmount",
+ "LFDQueueFrameRandomScrollFrameChildFrameXPLabel",
+ "LFDQueueFrameRandomScrollFrameScrollBackground",
+ "LFDQueueFrameRandomScrollFrameScrollBackgroundBottomRight",
+ "LFDQueueFrameRandomScrollFrameScrollBackgroundTopLeft",
+ "LFDQueueFrameRandomScrollFrameScrollBar",
+ "LFDQueueFrameRandomScrollFrameScrollBarScrollDownButton",
+ "LFDQueueFrameRandomScrollFrameScrollBarScrollUpButton",
+ "LFDQueueFrameRandomScrollFrameScrollBarThumbTexture",
+ "LFDQueueFrameRandom_UpdateFrame",
+ "LFDQueueFrameRoleButtonDPS",
+ "LFDQueueFrameRoleButtonDPSBackground",
+ "LFDQueueFrameRoleButtonHealer",
+ "LFDQueueFrameRoleButtonHealerBackground",
+ "LFDQueueFrameRoleButtonLeader",
+ "LFDQueueFrameRoleButtonTank",
+ "LFDQueueFrameRoleButtonTankBackground",
+ "LFDQueueFrameSpecific",
+ "LFDQueueFrameSpecificListButton1",
+ "LFDQueueFrameSpecificListButton10",
+ "LFDQueueFrameSpecificListButton10EnableButton",
+ "LFDQueueFrameSpecificListButton10ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton10ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton10HeroicIcon",
+ "LFDQueueFrameSpecificListButton10InstanceLevel",
+ "LFDQueueFrameSpecificListButton10InstanceName",
+ "LFDQueueFrameSpecificListButton10LockedIndicator",
+ "LFDQueueFrameSpecificListButton11",
+ "LFDQueueFrameSpecificListButton11EnableButton",
+ "LFDQueueFrameSpecificListButton11ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton11ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton11HeroicIcon",
+ "LFDQueueFrameSpecificListButton11InstanceLevel",
+ "LFDQueueFrameSpecificListButton11InstanceName",
+ "LFDQueueFrameSpecificListButton11LockedIndicator",
+ "LFDQueueFrameSpecificListButton12",
+ "LFDQueueFrameSpecificListButton12EnableButton",
+ "LFDQueueFrameSpecificListButton12ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton12ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton12HeroicIcon",
+ "LFDQueueFrameSpecificListButton12InstanceLevel",
+ "LFDQueueFrameSpecificListButton12InstanceName",
+ "LFDQueueFrameSpecificListButton12LockedIndicator",
+ "LFDQueueFrameSpecificListButton13",
+ "LFDQueueFrameSpecificListButton13EnableButton",
+ "LFDQueueFrameSpecificListButton13ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton13ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton13HeroicIcon",
+ "LFDQueueFrameSpecificListButton13InstanceLevel",
+ "LFDQueueFrameSpecificListButton13InstanceName",
+ "LFDQueueFrameSpecificListButton13LockedIndicator",
+ "LFDQueueFrameSpecificListButton14",
+ "LFDQueueFrameSpecificListButton14EnableButton",
+ "LFDQueueFrameSpecificListButton14ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton14ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton14HeroicIcon",
+ "LFDQueueFrameSpecificListButton14InstanceLevel",
+ "LFDQueueFrameSpecificListButton14InstanceName",
+ "LFDQueueFrameSpecificListButton14LockedIndicator",
+ "LFDQueueFrameSpecificListButton15",
+ "LFDQueueFrameSpecificListButton15EnableButton",
+ "LFDQueueFrameSpecificListButton15ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton15ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton15HeroicIcon",
+ "LFDQueueFrameSpecificListButton15InstanceLevel",
+ "LFDQueueFrameSpecificListButton15InstanceName",
+ "LFDQueueFrameSpecificListButton15LockedIndicator",
+ "LFDQueueFrameSpecificListButton1EnableButton",
+ "LFDQueueFrameSpecificListButton1ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton1ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton1HeroicIcon",
+ "LFDQueueFrameSpecificListButton1InstanceLevel",
+ "LFDQueueFrameSpecificListButton1InstanceName",
+ "LFDQueueFrameSpecificListButton1LockedIndicator",
+ "LFDQueueFrameSpecificListButton2",
+ "LFDQueueFrameSpecificListButton2EnableButton",
+ "LFDQueueFrameSpecificListButton2ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton2ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton2HeroicIcon",
+ "LFDQueueFrameSpecificListButton2InstanceLevel",
+ "LFDQueueFrameSpecificListButton2InstanceName",
+ "LFDQueueFrameSpecificListButton2LockedIndicator",
+ "LFDQueueFrameSpecificListButton3",
+ "LFDQueueFrameSpecificListButton3EnableButton",
+ "LFDQueueFrameSpecificListButton3ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton3ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton3HeroicIcon",
+ "LFDQueueFrameSpecificListButton3InstanceLevel",
+ "LFDQueueFrameSpecificListButton3InstanceName",
+ "LFDQueueFrameSpecificListButton3LockedIndicator",
+ "LFDQueueFrameSpecificListButton4",
+ "LFDQueueFrameSpecificListButton4EnableButton",
+ "LFDQueueFrameSpecificListButton4ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton4ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton4HeroicIcon",
+ "LFDQueueFrameSpecificListButton4InstanceLevel",
+ "LFDQueueFrameSpecificListButton4InstanceName",
+ "LFDQueueFrameSpecificListButton4LockedIndicator",
+ "LFDQueueFrameSpecificListButton5",
+ "LFDQueueFrameSpecificListButton5EnableButton",
+ "LFDQueueFrameSpecificListButton5ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton5ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton5HeroicIcon",
+ "LFDQueueFrameSpecificListButton5InstanceLevel",
+ "LFDQueueFrameSpecificListButton5InstanceName",
+ "LFDQueueFrameSpecificListButton5LockedIndicator",
+ "LFDQueueFrameSpecificListButton6",
+ "LFDQueueFrameSpecificListButton6EnableButton",
+ "LFDQueueFrameSpecificListButton6ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton6ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton6HeroicIcon",
+ "LFDQueueFrameSpecificListButton6InstanceLevel",
+ "LFDQueueFrameSpecificListButton6InstanceName",
+ "LFDQueueFrameSpecificListButton6LockedIndicator",
+ "LFDQueueFrameSpecificListButton7",
+ "LFDQueueFrameSpecificListButton7EnableButton",
+ "LFDQueueFrameSpecificListButton7ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton7ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton7HeroicIcon",
+ "LFDQueueFrameSpecificListButton7InstanceLevel",
+ "LFDQueueFrameSpecificListButton7InstanceName",
+ "LFDQueueFrameSpecificListButton7LockedIndicator",
+ "LFDQueueFrameSpecificListButton8",
+ "LFDQueueFrameSpecificListButton8EnableButton",
+ "LFDQueueFrameSpecificListButton8ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton8ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton8HeroicIcon",
+ "LFDQueueFrameSpecificListButton8InstanceLevel",
+ "LFDQueueFrameSpecificListButton8InstanceName",
+ "LFDQueueFrameSpecificListButton8LockedIndicator",
+ "LFDQueueFrameSpecificListButton9",
+ "LFDQueueFrameSpecificListButton9EnableButton",
+ "LFDQueueFrameSpecificListButton9ExpandOrCollapseButton",
+ "LFDQueueFrameSpecificListButton9ExpandOrCollapseButtonHighlight",
+ "LFDQueueFrameSpecificListButton9HeroicIcon",
+ "LFDQueueFrameSpecificListButton9InstanceLevel",
+ "LFDQueueFrameSpecificListButton9InstanceName",
+ "LFDQueueFrameSpecificListButton9LockedIndicator",
+ "LFDQueueFrameSpecificListButton_SetDungeon",
+ "LFDQueueFrameSpecificListScrollFrame",
+ "LFDQueueFrameSpecificListScrollFrameScrollBackgroundBottomRight",
+ "LFDQueueFrameSpecificListScrollFrameScrollBackgroundTopLeft",
+ "LFDQueueFrameSpecificListScrollFrameScrollBar",
+ "LFDQueueFrameSpecificListScrollFrameScrollBarScrollDownButton",
+ "LFDQueueFrameSpecificListScrollFrameScrollBarScrollUpButton",
+ "LFDQueueFrameSpecificListScrollFrameScrollBarThumbTexture",
+ "LFDQueueFrameSpecificListScrollFrameScrollChildFrame",
+ "LFDQueueFrameSpecificList_Update",
+ "LFDQueueFrameTitleText",
+ "LFDQueueFrameTypeDropDown",
+ "LFDQueueFrameTypeDropDownButton",
+ "LFDQueueFrameTypeDropDownButtonDisabledTexture",
+ "LFDQueueFrameTypeDropDownButtonHighlightTexture",
+ "LFDQueueFrameTypeDropDownButtonNormalTexture",
+ "LFDQueueFrameTypeDropDownButtonPushedTexture",
+ "LFDQueueFrameTypeDropDownButton_OnClick",
+ "LFDQueueFrameTypeDropDownLeft",
+ "LFDQueueFrameTypeDropDownMiddle",
+ "LFDQueueFrameTypeDropDownName",
+ "LFDQueueFrameTypeDropDownRight",
+ "LFDQueueFrameTypeDropDownText",
+ "LFDQueueFrameTypeDropDown_Initialize",
+ "LFDQueueFrameTypeDropDown_SetUp",
+ "LFDQueueFrame_Join",
+ "LFDQueueFrame_QueueForInstanceIfEnabled",
+ "LFDQueueFrame_SetRoles",
+ "LFDQueueFrame_SetType",
+ "LFDQueueFrame_SetTypeRandomDungeon",
+ "LFDQueueFrame_SetTypeSpecificDungeon",
+ "LFDQueueFrame_Update",
+ "LFDQueueFrame_UpdatePortrait",
+ "LFDRoleCheckPopup",
+ "LFDRoleCheckPopupAcceptButton",
+ "LFDRoleCheckPopupAcceptButtonLeft",
+ "LFDRoleCheckPopupAcceptButtonMiddle",
+ "LFDRoleCheckPopupAcceptButtonRight",
+ "LFDRoleCheckPopupAcceptButtonText",
+ "LFDRoleCheckPopupAccept_OnClick",
+ "LFDRoleCheckPopupDeclineButton",
+ "LFDRoleCheckPopupDeclineButtonLeft",
+ "LFDRoleCheckPopupDeclineButtonMiddle",
+ "LFDRoleCheckPopupDeclineButtonRight",
+ "LFDRoleCheckPopupDeclineButtonText",
+ "LFDRoleCheckPopupDecline_OnClick",
+ "LFDRoleCheckPopupDescription",
+ "LFDRoleCheckPopupDescriptionText",
+ "LFDRoleCheckPopupDescription_OnEnter",
+ "LFDRoleCheckPopupRoleButtonDPS",
+ "LFDRoleCheckPopupRoleButtonHealer",
+ "LFDRoleCheckPopupRoleButtonTank",
+ "LFDRoleCheckPopup_Update",
+ "LFDSearchStatus",
+ "LFDSearchStatusDamage1",
+ "LFDSearchStatusDamage1Texture",
+ "LFDSearchStatusDamage2",
+ "LFDSearchStatusDamage2Texture",
+ "LFDSearchStatusDamage3",
+ "LFDSearchStatusDamage3Texture",
+ "LFDSearchStatusElapsedWaitTime",
+ "LFDSearchStatusHealer1",
+ "LFDSearchStatusHealer1Texture",
+ "LFDSearchStatusLookingFor",
+ "LFDSearchStatusPlayer_SetFound",
+ "LFDSearchStatusRoleIcon1",
+ "LFDSearchStatusRoleIcon2",
+ "LFDSearchStatusRoleIcon3",
+ "LFDSearchStatusStatistic",
+ "LFDSearchStatusTank1",
+ "LFDSearchStatusTank1Texture",
+ "LFDSearchStatusTitle",
+ "LFDSearchStatus_OnEvent",
+ "LFDSearchStatus_OnUpdate",
+ "LFDSearchStatus_Update",
+ "LFDSearchStatus_UpdateRoles",
+ "LFD_CURRENT_FILTER",
+ "LFD_IsEmpowered",
+ "LFGDebug",
+ "LFGDungeonList_Setup",
+ "LFGEventFrame",
+ "LFGEventFrame_OnEvent",
+ "LFGEventFrame_OnLoad",
+ "LFGGetDungeonInfoByID",
+ "LFGIsIDHeader",
+ "LFGListFilterChoices",
+ "LFGListRemoveCollapsedChildren",
+ "LFGListRemoveHeadersWithoutChildren",
+ "LFGListUpdateHeaderEnabledAndLockedStates",
+ "LFGLockList",
+ "LFGQueueFrame_UpdateLFGDungeonList",
+ "LFGQueuedForList",
+ "LFGSpecificChoiceEnableButton_SetIsRadio",
+ "LFGTeleport",
+ "LFG_DisableRoleButton",
+ "LFG_EnableRoleButton",
+ "LFG_INSTANCE_INVALID_CODES",
+ "LFG_PermanentlyDisableRoleButton",
+ "LFG_RETURN_VALUES",
+ "LFG_UpdateAvailableRoles",
+ "LFG_UpdateFindGroupButtons",
+ "LFG_UpdateFramesIfShown",
+ "LFG_UpdateLockedOutPanels",
+ "LFG_UpdateQueuedList",
+ "LFG_UpdateRoleCheckboxes",
+ "LFG_UpdateRolesChangeable",
+ "LFRBrowseButton_OnClick",
+ "LFRBrowseButton_OnEnter",
+ "LFRBrowseFrame",
+ "LFRBrowseFrameColumnHeader1",
+ "LFRBrowseFrameColumnHeader1HighlightTexture",
+ "LFRBrowseFrameColumnHeader1Left",
+ "LFRBrowseFrameColumnHeader1Middle",
+ "LFRBrowseFrameColumnHeader1Right",
+ "LFRBrowseFrameColumnHeader2",
+ "LFRBrowseFrameColumnHeader2HighlightTexture",
+ "LFRBrowseFrameColumnHeader2Left",
+ "LFRBrowseFrameColumnHeader2Middle",
+ "LFRBrowseFrameColumnHeader2Right",
+ "LFRBrowseFrameColumnHeader3",
+ "LFRBrowseFrameColumnHeader3HighlightTexture",
+ "LFRBrowseFrameColumnHeader3Left",
+ "LFRBrowseFrameColumnHeader3Middle",
+ "LFRBrowseFrameColumnHeader3Right",
+ "LFRBrowseFrameColumnHeader4",
+ "LFRBrowseFrameColumnHeader4HighlightTexture",
+ "LFRBrowseFrameColumnHeader4Icon",
+ "LFRBrowseFrameColumnHeader4Left",
+ "LFRBrowseFrameColumnHeader4Middle",
+ "LFRBrowseFrameColumnHeader4Right",
+ "LFRBrowseFrameColumnHeader5",
+ "LFRBrowseFrameColumnHeader5HighlightTexture",
+ "LFRBrowseFrameColumnHeader5Icon",
+ "LFRBrowseFrameColumnHeader5Left",
+ "LFRBrowseFrameColumnHeader5Middle",
+ "LFRBrowseFrameColumnHeader5Right",
+ "LFRBrowseFrameColumnHeader6",
+ "LFRBrowseFrameColumnHeader6HighlightTexture",
+ "LFRBrowseFrameColumnHeader6Icon",
+ "LFRBrowseFrameColumnHeader6Left",
+ "LFRBrowseFrameColumnHeader6Middle",
+ "LFRBrowseFrameColumnHeader6Right",
+ "LFRBrowseFrameColumnHeader7",
+ "LFRBrowseFrameColumnHeader7HighlightTexture",
+ "LFRBrowseFrameColumnHeader7Icon",
+ "LFRBrowseFrameColumnHeader7Left",
+ "LFRBrowseFrameColumnHeader7Middle",
+ "LFRBrowseFrameColumnHeader7Right",
+ "LFRBrowseFrameInviteButton",
+ "LFRBrowseFrameInviteButtonLeft",
+ "LFRBrowseFrameInviteButtonMiddle",
+ "LFRBrowseFrameInviteButtonRight",
+ "LFRBrowseFrameInviteButtonText",
+ "LFRBrowseFrameLayout",
+ "LFRBrowseFrameListButton1",
+ "LFRBrowseFrameListButton10",
+ "LFRBrowseFrameListButton10Class",
+ "LFRBrowseFrameListButton10Level",
+ "LFRBrowseFrameListButton10Name",
+ "LFRBrowseFrameListButton10PartyIcon",
+ "LFRBrowseFrameListButton10RoleDamageIcon",
+ "LFRBrowseFrameListButton10RoleHealerIcon",
+ "LFRBrowseFrameListButton10RoleTankIcon",
+ "LFRBrowseFrameListButton11",
+ "LFRBrowseFrameListButton11Class",
+ "LFRBrowseFrameListButton11Level",
+ "LFRBrowseFrameListButton11Name",
+ "LFRBrowseFrameListButton11PartyIcon",
+ "LFRBrowseFrameListButton11RoleDamageIcon",
+ "LFRBrowseFrameListButton11RoleHealerIcon",
+ "LFRBrowseFrameListButton11RoleTankIcon",
+ "LFRBrowseFrameListButton12",
+ "LFRBrowseFrameListButton12Class",
+ "LFRBrowseFrameListButton12Level",
+ "LFRBrowseFrameListButton12Name",
+ "LFRBrowseFrameListButton12PartyIcon",
+ "LFRBrowseFrameListButton12RoleDamageIcon",
+ "LFRBrowseFrameListButton12RoleHealerIcon",
+ "LFRBrowseFrameListButton12RoleTankIcon",
+ "LFRBrowseFrameListButton13",
+ "LFRBrowseFrameListButton13Class",
+ "LFRBrowseFrameListButton13Level",
+ "LFRBrowseFrameListButton13Name",
+ "LFRBrowseFrameListButton13PartyIcon",
+ "LFRBrowseFrameListButton13RoleDamageIcon",
+ "LFRBrowseFrameListButton13RoleHealerIcon",
+ "LFRBrowseFrameListButton13RoleTankIcon",
+ "LFRBrowseFrameListButton14",
+ "LFRBrowseFrameListButton14Class",
+ "LFRBrowseFrameListButton14Level",
+ "LFRBrowseFrameListButton14Name",
+ "LFRBrowseFrameListButton14PartyIcon",
+ "LFRBrowseFrameListButton14RoleDamageIcon",
+ "LFRBrowseFrameListButton14RoleHealerIcon",
+ "LFRBrowseFrameListButton14RoleTankIcon",
+ "LFRBrowseFrameListButton15",
+ "LFRBrowseFrameListButton15Class",
+ "LFRBrowseFrameListButton15Level",
+ "LFRBrowseFrameListButton15Name",
+ "LFRBrowseFrameListButton15PartyIcon",
+ "LFRBrowseFrameListButton15RoleDamageIcon",
+ "LFRBrowseFrameListButton15RoleHealerIcon",
+ "LFRBrowseFrameListButton15RoleTankIcon",
+ "LFRBrowseFrameListButton16",
+ "LFRBrowseFrameListButton16Class",
+ "LFRBrowseFrameListButton16Level",
+ "LFRBrowseFrameListButton16Name",
+ "LFRBrowseFrameListButton16PartyIcon",
+ "LFRBrowseFrameListButton16RoleDamageIcon",
+ "LFRBrowseFrameListButton16RoleHealerIcon",
+ "LFRBrowseFrameListButton16RoleTankIcon",
+ "LFRBrowseFrameListButton17",
+ "LFRBrowseFrameListButton17Class",
+ "LFRBrowseFrameListButton17Level",
+ "LFRBrowseFrameListButton17Name",
+ "LFRBrowseFrameListButton17PartyIcon",
+ "LFRBrowseFrameListButton17RoleDamageIcon",
+ "LFRBrowseFrameListButton17RoleHealerIcon",
+ "LFRBrowseFrameListButton17RoleTankIcon",
+ "LFRBrowseFrameListButton18",
+ "LFRBrowseFrameListButton18Class",
+ "LFRBrowseFrameListButton18Level",
+ "LFRBrowseFrameListButton18Name",
+ "LFRBrowseFrameListButton18PartyIcon",
+ "LFRBrowseFrameListButton18RoleDamageIcon",
+ "LFRBrowseFrameListButton18RoleHealerIcon",
+ "LFRBrowseFrameListButton18RoleTankIcon",
+ "LFRBrowseFrameListButton19",
+ "LFRBrowseFrameListButton19Class",
+ "LFRBrowseFrameListButton19Level",
+ "LFRBrowseFrameListButton19Name",
+ "LFRBrowseFrameListButton19PartyIcon",
+ "LFRBrowseFrameListButton19RoleDamageIcon",
+ "LFRBrowseFrameListButton19RoleHealerIcon",
+ "LFRBrowseFrameListButton19RoleTankIcon",
+ "LFRBrowseFrameListButton1Class",
+ "LFRBrowseFrameListButton1Level",
+ "LFRBrowseFrameListButton1Name",
+ "LFRBrowseFrameListButton1PartyIcon",
+ "LFRBrowseFrameListButton1RoleDamageIcon",
+ "LFRBrowseFrameListButton1RoleHealerIcon",
+ "LFRBrowseFrameListButton1RoleTankIcon",
+ "LFRBrowseFrameListButton2",
+ "LFRBrowseFrameListButton2Class",
+ "LFRBrowseFrameListButton2Level",
+ "LFRBrowseFrameListButton2Name",
+ "LFRBrowseFrameListButton2PartyIcon",
+ "LFRBrowseFrameListButton2RoleDamageIcon",
+ "LFRBrowseFrameListButton2RoleHealerIcon",
+ "LFRBrowseFrameListButton2RoleTankIcon",
+ "LFRBrowseFrameListButton3",
+ "LFRBrowseFrameListButton3Class",
+ "LFRBrowseFrameListButton3Level",
+ "LFRBrowseFrameListButton3Name",
+ "LFRBrowseFrameListButton3PartyIcon",
+ "LFRBrowseFrameListButton3RoleDamageIcon",
+ "LFRBrowseFrameListButton3RoleHealerIcon",
+ "LFRBrowseFrameListButton3RoleTankIcon",
+ "LFRBrowseFrameListButton4",
+ "LFRBrowseFrameListButton4Class",
+ "LFRBrowseFrameListButton4Level",
+ "LFRBrowseFrameListButton4Name",
+ "LFRBrowseFrameListButton4PartyIcon",
+ "LFRBrowseFrameListButton4RoleDamageIcon",
+ "LFRBrowseFrameListButton4RoleHealerIcon",
+ "LFRBrowseFrameListButton4RoleTankIcon",
+ "LFRBrowseFrameListButton5",
+ "LFRBrowseFrameListButton5Class",
+ "LFRBrowseFrameListButton5Level",
+ "LFRBrowseFrameListButton5Name",
+ "LFRBrowseFrameListButton5PartyIcon",
+ "LFRBrowseFrameListButton5RoleDamageIcon",
+ "LFRBrowseFrameListButton5RoleHealerIcon",
+ "LFRBrowseFrameListButton5RoleTankIcon",
+ "LFRBrowseFrameListButton6",
+ "LFRBrowseFrameListButton6Class",
+ "LFRBrowseFrameListButton6Level",
+ "LFRBrowseFrameListButton6Name",
+ "LFRBrowseFrameListButton6PartyIcon",
+ "LFRBrowseFrameListButton6RoleDamageIcon",
+ "LFRBrowseFrameListButton6RoleHealerIcon",
+ "LFRBrowseFrameListButton6RoleTankIcon",
+ "LFRBrowseFrameListButton7",
+ "LFRBrowseFrameListButton7Class",
+ "LFRBrowseFrameListButton7Level",
+ "LFRBrowseFrameListButton7Name",
+ "LFRBrowseFrameListButton7PartyIcon",
+ "LFRBrowseFrameListButton7RoleDamageIcon",
+ "LFRBrowseFrameListButton7RoleHealerIcon",
+ "LFRBrowseFrameListButton7RoleTankIcon",
+ "LFRBrowseFrameListButton8",
+ "LFRBrowseFrameListButton8Class",
+ "LFRBrowseFrameListButton8Level",
+ "LFRBrowseFrameListButton8Name",
+ "LFRBrowseFrameListButton8PartyIcon",
+ "LFRBrowseFrameListButton8RoleDamageIcon",
+ "LFRBrowseFrameListButton8RoleHealerIcon",
+ "LFRBrowseFrameListButton8RoleTankIcon",
+ "LFRBrowseFrameListButton9",
+ "LFRBrowseFrameListButton9Class",
+ "LFRBrowseFrameListButton9Level",
+ "LFRBrowseFrameListButton9Name",
+ "LFRBrowseFrameListButton9PartyIcon",
+ "LFRBrowseFrameListButton9RoleDamageIcon",
+ "LFRBrowseFrameListButton9RoleHealerIcon",
+ "LFRBrowseFrameListButton9RoleTankIcon",
+ "LFRBrowseFrameListButton_SetData",
+ "LFRBrowseFrameListScrollFrame",
+ "LFRBrowseFrameListScrollFrameScrollBar",
+ "LFRBrowseFrameListScrollFrameScrollBarScrollDownButton",
+ "LFRBrowseFrameListScrollFrameScrollBarScrollUpButton",
+ "LFRBrowseFrameListScrollFrameScrollBarThumbTexture",
+ "LFRBrowseFrameListScrollFrameScrollChildFrame",
+ "LFRBrowseFrameList_Update",
+ "LFRBrowseFrameRaidDropDown",
+ "LFRBrowseFrameRaidDropDownButton",
+ "LFRBrowseFrameRaidDropDownButtonDisabledTexture",
+ "LFRBrowseFrameRaidDropDownButtonHighlightTexture",
+ "LFRBrowseFrameRaidDropDownButtonNormalTexture",
+ "LFRBrowseFrameRaidDropDownButtonPushedTexture",
+ "LFRBrowseFrameRaidDropDownButton_OnClick",
+ "LFRBrowseFrameRaidDropDownLeft",
+ "LFRBrowseFrameRaidDropDownMiddle",
+ "LFRBrowseFrameRaidDropDownName",
+ "LFRBrowseFrameRaidDropDownRight",
+ "LFRBrowseFrameRaidDropDownText",
+ "LFRBrowseFrameRaidDropDown_Initialize",
+ "LFRBrowseFrameRaidDropDown_SetUp",
+ "LFRBrowseFrameRefreshButton",
+ "LFRBrowseFrameRefreshButtonLeft",
+ "LFRBrowseFrameRefreshButtonMiddle",
+ "LFRBrowseFrameRefreshButtonRight",
+ "LFRBrowseFrameRefreshButtonText",
+ "LFRBrowseFrameRefreshButton_OnUpdate",
+ "LFRBrowseFrameSendMessageButton",
+ "LFRBrowseFrameSendMessageButtonLeft",
+ "LFRBrowseFrameSendMessageButtonMiddle",
+ "LFRBrowseFrameSendMessageButtonRight",
+ "LFRBrowseFrameSendMessageButtonText",
+ "LFRBrowseFrameTitleText",
+ "LFRBrowseFrame_OnLoad",
+ "LFRBrowseFrame_OnUpdateAlways",
+ "LFRBrowse_UpdateButtonStates",
+ "LFRFrameRoleCheckButton_OnClick",
+ "LFRFrame_OnEvent",
+ "LFRFrame_OnLoad",
+ "LFRFrame_SetActiveTab",
+ "LFRGetNumDungeons",
+ "LFRHiddenByCollapseList",
+ "LFRList_DefaultFilterFunction",
+ "LFRList_SetHeaderCollapsed",
+ "LFRList_SetHeaderEnabled",
+ "LFRList_SetRaidEnabled",
+ "LFRParentFrame",
+ "LFRParentFrameIcon",
+ "LFRParentFrameTab1",
+ "LFRParentFrameTab1HighlightTexture",
+ "LFRParentFrameTab1Left",
+ "LFRParentFrameTab1LeftDisabled",
+ "LFRParentFrameTab1Middle",
+ "LFRParentFrameTab1MiddleDisabled",
+ "LFRParentFrameTab1Right",
+ "LFRParentFrameTab1RightDisabled",
+ "LFRParentFrameTab1Text",
+ "LFRParentFrameTab2",
+ "LFRParentFrameTab2HighlightTexture",
+ "LFRParentFrameTab2Left",
+ "LFRParentFrameTab2LeftDisabled",
+ "LFRParentFrameTab2Middle",
+ "LFRParentFrameTab2MiddleDisabled",
+ "LFRParentFrameTab2Right",
+ "LFRParentFrameTab2RightDisabled",
+ "LFRParentFrameTab2Text",
+ "LFRQueueFrame",
+ "LFRQueueFrameAcceptCommentButton",
+ "LFRQueueFrameAcceptCommentButtonLeft",
+ "LFRQueueFrameAcceptCommentButtonMiddle",
+ "LFRQueueFrameAcceptCommentButtonRight",
+ "LFRQueueFrameAcceptCommentButtonText",
+ "LFRQueueFrameComment",
+ "LFRQueueFrameCommentExplanation",
+ "LFRQueueFrameCommentTextButton",
+ "LFRQueueFrameDungeonChoiceEnableButton_OnClick",
+ "LFRQueueFrameExpandOrCollapseButton_OnClick",
+ "LFRQueueFrameFindGroupButton",
+ "LFRQueueFrameFindGroupButtonLeft",
+ "LFRQueueFrameFindGroupButtonMiddle",
+ "LFRQueueFrameFindGroupButtonRight",
+ "LFRQueueFrameFindGroupButtonText",
+ "LFRQueueFrameFindGroupButton_Update",
+ "LFRQueueFrameLayout",
+ "LFRQueueFrameNoLFRWhileLFD",
+ "LFRQueueFrameNoLFRWhileLFDBlackFilter",
+ "LFRQueueFrameNoLFRWhileLFDDescription",
+ "LFRQueueFrameNoLFRWhileLFDLeaveQueueButton",
+ "LFRQueueFrameNoLFRWhileLFDLeaveQueueButtonLeft",
+ "LFRQueueFrameNoLFRWhileLFDLeaveQueueButtonMiddle",
+ "LFRQueueFrameNoLFRWhileLFDLeaveQueueButtonRight",
+ "LFRQueueFrameNoLFRWhileLFDLeaveQueueButtonText",
+ "LFRQueueFrameRoleButtonDPS",
+ "LFRQueueFrameRoleButtonDPSBackground",
+ "LFRQueueFrameRoleButtonHealer",
+ "LFRQueueFrameRoleButtonHealerBackground",
+ "LFRQueueFrameRoleButtonTank",
+ "LFRQueueFrameRoleButtonTankBackground",
+ "LFRQueueFrameSpecific",
+ "LFRQueueFrameSpecificListButton1",
+ "LFRQueueFrameSpecificListButton10",
+ "LFRQueueFrameSpecificListButton10EnableButton",
+ "LFRQueueFrameSpecificListButton10ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton10ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton10HeroicIcon",
+ "LFRQueueFrameSpecificListButton10InstanceLevel",
+ "LFRQueueFrameSpecificListButton10InstanceName",
+ "LFRQueueFrameSpecificListButton10LockedIndicator",
+ "LFRQueueFrameSpecificListButton11",
+ "LFRQueueFrameSpecificListButton11EnableButton",
+ "LFRQueueFrameSpecificListButton11ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton11ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton11HeroicIcon",
+ "LFRQueueFrameSpecificListButton11InstanceLevel",
+ "LFRQueueFrameSpecificListButton11InstanceName",
+ "LFRQueueFrameSpecificListButton11LockedIndicator",
+ "LFRQueueFrameSpecificListButton12",
+ "LFRQueueFrameSpecificListButton12EnableButton",
+ "LFRQueueFrameSpecificListButton12ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton12ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton12HeroicIcon",
+ "LFRQueueFrameSpecificListButton12InstanceLevel",
+ "LFRQueueFrameSpecificListButton12InstanceName",
+ "LFRQueueFrameSpecificListButton12LockedIndicator",
+ "LFRQueueFrameSpecificListButton13",
+ "LFRQueueFrameSpecificListButton13EnableButton",
+ "LFRQueueFrameSpecificListButton13ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton13ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton13HeroicIcon",
+ "LFRQueueFrameSpecificListButton13InstanceLevel",
+ "LFRQueueFrameSpecificListButton13InstanceName",
+ "LFRQueueFrameSpecificListButton13LockedIndicator",
+ "LFRQueueFrameSpecificListButton14",
+ "LFRQueueFrameSpecificListButton14EnableButton",
+ "LFRQueueFrameSpecificListButton14ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton14ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton14HeroicIcon",
+ "LFRQueueFrameSpecificListButton14InstanceLevel",
+ "LFRQueueFrameSpecificListButton14InstanceName",
+ "LFRQueueFrameSpecificListButton14LockedIndicator",
+ "LFRQueueFrameSpecificListButton1EnableButton",
+ "LFRQueueFrameSpecificListButton1ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton1ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton1HeroicIcon",
+ "LFRQueueFrameSpecificListButton1InstanceLevel",
+ "LFRQueueFrameSpecificListButton1InstanceName",
+ "LFRQueueFrameSpecificListButton1LockedIndicator",
+ "LFRQueueFrameSpecificListButton2",
+ "LFRQueueFrameSpecificListButton2EnableButton",
+ "LFRQueueFrameSpecificListButton2ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton2ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton2HeroicIcon",
+ "LFRQueueFrameSpecificListButton2InstanceLevel",
+ "LFRQueueFrameSpecificListButton2InstanceName",
+ "LFRQueueFrameSpecificListButton2LockedIndicator",
+ "LFRQueueFrameSpecificListButton3",
+ "LFRQueueFrameSpecificListButton3EnableButton",
+ "LFRQueueFrameSpecificListButton3ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton3ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton3HeroicIcon",
+ "LFRQueueFrameSpecificListButton3InstanceLevel",
+ "LFRQueueFrameSpecificListButton3InstanceName",
+ "LFRQueueFrameSpecificListButton3LockedIndicator",
+ "LFRQueueFrameSpecificListButton4",
+ "LFRQueueFrameSpecificListButton4EnableButton",
+ "LFRQueueFrameSpecificListButton4ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton4ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton4HeroicIcon",
+ "LFRQueueFrameSpecificListButton4InstanceLevel",
+ "LFRQueueFrameSpecificListButton4InstanceName",
+ "LFRQueueFrameSpecificListButton4LockedIndicator",
+ "LFRQueueFrameSpecificListButton5",
+ "LFRQueueFrameSpecificListButton5EnableButton",
+ "LFRQueueFrameSpecificListButton5ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton5ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton5HeroicIcon",
+ "LFRQueueFrameSpecificListButton5InstanceLevel",
+ "LFRQueueFrameSpecificListButton5InstanceName",
+ "LFRQueueFrameSpecificListButton5LockedIndicator",
+ "LFRQueueFrameSpecificListButton6",
+ "LFRQueueFrameSpecificListButton6EnableButton",
+ "LFRQueueFrameSpecificListButton6ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton6ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton6HeroicIcon",
+ "LFRQueueFrameSpecificListButton6InstanceLevel",
+ "LFRQueueFrameSpecificListButton6InstanceName",
+ "LFRQueueFrameSpecificListButton6LockedIndicator",
+ "LFRQueueFrameSpecificListButton7",
+ "LFRQueueFrameSpecificListButton7EnableButton",
+ "LFRQueueFrameSpecificListButton7ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton7ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton7HeroicIcon",
+ "LFRQueueFrameSpecificListButton7InstanceLevel",
+ "LFRQueueFrameSpecificListButton7InstanceName",
+ "LFRQueueFrameSpecificListButton7LockedIndicator",
+ "LFRQueueFrameSpecificListButton8",
+ "LFRQueueFrameSpecificListButton8EnableButton",
+ "LFRQueueFrameSpecificListButton8ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton8ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton8HeroicIcon",
+ "LFRQueueFrameSpecificListButton8InstanceLevel",
+ "LFRQueueFrameSpecificListButton8InstanceName",
+ "LFRQueueFrameSpecificListButton8LockedIndicator",
+ "LFRQueueFrameSpecificListButton9",
+ "LFRQueueFrameSpecificListButton9EnableButton",
+ "LFRQueueFrameSpecificListButton9ExpandOrCollapseButton",
+ "LFRQueueFrameSpecificListButton9ExpandOrCollapseButtonHighlight",
+ "LFRQueueFrameSpecificListButton9HeroicIcon",
+ "LFRQueueFrameSpecificListButton9InstanceLevel",
+ "LFRQueueFrameSpecificListButton9InstanceName",
+ "LFRQueueFrameSpecificListButton9LockedIndicator",
+ "LFRQueueFrameSpecificListButton_SetDungeon",
+ "LFRQueueFrameSpecificListScrollFrame",
+ "LFRQueueFrameSpecificListScrollFrameScrollBackgroundBottomRight",
+ "LFRQueueFrameSpecificListScrollFrameScrollBackgroundTopLeft",
+ "LFRQueueFrameSpecificListScrollFrameScrollBar",
+ "LFRQueueFrameSpecificListScrollFrameScrollBarScrollDownButton",
+ "LFRQueueFrameSpecificListScrollFrameScrollBarScrollUpButton",
+ "LFRQueueFrameSpecificListScrollFrameScrollBarThumbTexture",
+ "LFRQueueFrameSpecificListScrollFrameScrollChildFrame",
+ "LFRQueueFrameSpecificList_Update",
+ "LFRQueueFrameSpecificNoRaidsAvailable",
+ "LFRQueueFrameTitleText",
+ "LFRQueueFrame_Join",
+ "LFRQueueFrame_QueueForInstanceIfEnabled",
+ "LFRQueueFrame_SetRoles",
+ "LFRQueueFrame_Update",
+ "LFR_CanQueueForLockedInstances",
+ "LFR_CanQueueForMultiple",
+ "LFR_IsEmpowered",
+ "LIGHTYELLOW_FONT_COLOR",
+ "LOCALE_deDE",
+ "LOCALE_enCN",
+ "LOCALE_enGB",
+ "LOCALE_enTW",
+ "LOCALE_enUS",
+ "LOCALE_esES",
+ "LOCALE_esMX",
+ "LOCALE_frFR",
+ "LOCALE_itIT",
+ "LOCALE_koKR",
+ "LOCALE_ptBR",
+ "LOCALE_ptPT",
+ "LOCALE_ruRU",
+ "LOCALE_zhCN",
+ "LOCALE_zhTW",
+ "LOCALIZED_CLASS_NAMES_FEMALE",
+ "LOCALIZED_CLASS_NAMES_MALE",
+ "LOCAL_MAP_QUESTS",
+ "LanguageMenu",
+ "LanguageMenuButton1",
+ "LanguageMenuButton10",
+ "LanguageMenuButton10ShortcutText",
+ "LanguageMenuButton11",
+ "LanguageMenuButton11ShortcutText",
+ "LanguageMenuButton12",
+ "LanguageMenuButton12ShortcutText",
+ "LanguageMenuButton13",
+ "LanguageMenuButton13ShortcutText",
+ "LanguageMenuButton14",
+ "LanguageMenuButton14ShortcutText",
+ "LanguageMenuButton15",
+ "LanguageMenuButton15ShortcutText",
+ "LanguageMenuButton16",
+ "LanguageMenuButton16ShortcutText",
+ "LanguageMenuButton17",
+ "LanguageMenuButton17ShortcutText",
+ "LanguageMenuButton18",
+ "LanguageMenuButton18ShortcutText",
+ "LanguageMenuButton19",
+ "LanguageMenuButton19ShortcutText",
+ "LanguageMenuButton1ShortcutText",
+ "LanguageMenuButton2",
+ "LanguageMenuButton20",
+ "LanguageMenuButton20ShortcutText",
+ "LanguageMenuButton21",
+ "LanguageMenuButton21ShortcutText",
+ "LanguageMenuButton22",
+ "LanguageMenuButton22ShortcutText",
+ "LanguageMenuButton23",
+ "LanguageMenuButton23ShortcutText",
+ "LanguageMenuButton24",
+ "LanguageMenuButton24ShortcutText",
+ "LanguageMenuButton25",
+ "LanguageMenuButton25ShortcutText",
+ "LanguageMenuButton26",
+ "LanguageMenuButton26ShortcutText",
+ "LanguageMenuButton27",
+ "LanguageMenuButton27ShortcutText",
+ "LanguageMenuButton28",
+ "LanguageMenuButton28ShortcutText",
+ "LanguageMenuButton29",
+ "LanguageMenuButton29ShortcutText",
+ "LanguageMenuButton2ShortcutText",
+ "LanguageMenuButton3",
+ "LanguageMenuButton30",
+ "LanguageMenuButton30ShortcutText",
+ "LanguageMenuButton31",
+ "LanguageMenuButton31ShortcutText",
+ "LanguageMenuButton32",
+ "LanguageMenuButton32ShortcutText",
+ "LanguageMenuButton3ShortcutText",
+ "LanguageMenuButton4",
+ "LanguageMenuButton4ShortcutText",
+ "LanguageMenuButton5",
+ "LanguageMenuButton5ShortcutText",
+ "LanguageMenuButton6",
+ "LanguageMenuButton6ShortcutText",
+ "LanguageMenuButton7",
+ "LanguageMenuButton7ShortcutText",
+ "LanguageMenuButton8",
+ "LanguageMenuButton8ShortcutText",
+ "LanguageMenuButton9",
+ "LanguageMenuButton9ShortcutText",
+ "LanguageMenu_Click",
+ "LanguageMenu_LoadLanguages",
+ "LanguageMenu_OnEvent",
+ "LanguageMenu_OnLoad",
+ "LanguagesPanelOptions",
+ "LearnPreviewTalents",
+ "LearnTalent",
+ "LeaveBattlefield",
+ "LeaveChannelByName",
+ "LeaveLFG",
+ "LeaveParty",
+ "LibCompat_TimerFrame",
+ "LibStub",
+ "ListChannelByName",
+ "ListChannels",
+ "LoadAddOn",
+ "LoadBindings",
+ "LoadMicroButtonTextures",
+ "Localize",
+ "LocalizeFrames",
+ "LocalizePost",
+ "LockMultiCastActionBar",
+ "LockPetActionBar",
+ "LoggingChat",
+ "LoggingCombat",
+ "Logout",
+ "LoopbackVUMeter",
+ "LoopbackVUMeter_OnLoad",
+ "LoopbackVUMeter_OnUpdate",
+ "LootButton1",
+ "LootButton1Count",
+ "LootButton1IconTexture",
+ "LootButton1NameFrame",
+ "LootButton1NormalTexture",
+ "LootButton1Stock",
+ "LootButton1Text",
+ "LootButton2",
+ "LootButton2Count",
+ "LootButton2IconTexture",
+ "LootButton2NameFrame",
+ "LootButton2NormalTexture",
+ "LootButton2Stock",
+ "LootButton2Text",
+ "LootButton3",
+ "LootButton3Count",
+ "LootButton3IconTexture",
+ "LootButton3NameFrame",
+ "LootButton3NormalTexture",
+ "LootButton3Stock",
+ "LootButton3Text",
+ "LootButton4",
+ "LootButton4Count",
+ "LootButton4IconTexture",
+ "LootButton4NameFrame",
+ "LootButton4NormalTexture",
+ "LootButton4Stock",
+ "LootButton4Text",
+ "LootButton_OnClick",
+ "LootCloseButton",
+ "LootFrame",
+ "LootFrameDownButton",
+ "LootFrameNext",
+ "LootFramePortraitOverlay",
+ "LootFramePrev",
+ "LootFrameUpButton",
+ "LootFrame_OnEvent",
+ "LootFrame_OnHide",
+ "LootFrame_OnLoad",
+ "LootFrame_OnShow",
+ "LootFrame_PageDown",
+ "LootFrame_PageUp",
+ "LootFrame_Show",
+ "LootFrame_Update",
+ "LootFrame_UpdateButton",
+ "LootItem_OnEnter",
+ "LootSlot",
+ "LootSlotIsCoin",
+ "LootSlotIsItem",
+ "LowHealthFrame",
+ "LowHealthFrame_OnUpdate",
+ "LowHealthFrame_StartFlashing",
+ "LowHealthFrame_StopFlashing",
+ "LowerBlackBar",
+ "LowerFrameLevel",
+ "MAP_VEHICLES",
+ "MATERIAL_TEXT_COLOR_TABLE",
+ "MATERIAL_TITLETEXT_COLOR_TABLE",
+ "MAX_BOSS_FRAMES",
+ "MAX_PLAYER_LEVEL_TABLE",
+ "MacOptionsButtonCompress",
+ "MacOptionsButtonCompressText",
+ "MacOptionsButtonKeybindings",
+ "MacOptionsButtonKeybindingsText",
+ "MacOptionsCancelFrame",
+ "MacOptionsCancelFrameFileName",
+ "MacOptionsCancelFrameHeader",
+ "MacOptionsCancelFrameNo",
+ "MacOptionsCancelFrameNoText",
+ "MacOptionsCancelFrameQuestion",
+ "MacOptionsCancelFrameYes",
+ "MacOptionsCancelFrameYesText",
+ "MacOptionsCancelFrame_OnShow",
+ "MacOptionsCompressFrame",
+ "MacOptionsCompressFrameCompress",
+ "MacOptionsCompressFrameCompressText",
+ "MacOptionsCompressFrameDelete",
+ "MacOptionsCompressFrameDeleteText",
+ "MacOptionsCompressFrameFileName",
+ "MacOptionsCompressFrameHeader",
+ "MacOptionsCompressFrameSkip",
+ "MacOptionsCompressFrameSkipText",
+ "MacOptionsCompressFrame_OnShow",
+ "MacOptionsFrame",
+ "MacOptionsFrameCancel",
+ "MacOptionsFrameCancelText",
+ "MacOptionsFrameCheckButton1",
+ "MacOptionsFrameCheckButton1Text",
+ "MacOptionsFrameCheckButton2",
+ "MacOptionsFrameCheckButton2Text",
+ "MacOptionsFrameCheckButton3",
+ "MacOptionsFrameCheckButton3Text",
+ "MacOptionsFrameCheckButton4",
+ "MacOptionsFrameCheckButton4Text",
+ "MacOptionsFrameCheckButton5",
+ "MacOptionsFrameCheckButton5Text",
+ "MacOptionsFrameCheckButton6",
+ "MacOptionsFrameCheckButton6Text",
+ "MacOptionsFrameCheckButton7",
+ "MacOptionsFrameCheckButton7Text",
+ "MacOptionsFrameCheckButton8",
+ "MacOptionsFrameCheckButton8Text",
+ "MacOptionsFrameCheckButtons",
+ "MacOptionsFrameCodecDropDown",
+ "MacOptionsFrameCodecDropDownButton",
+ "MacOptionsFrameCodecDropDownButtonDisabledTexture",
+ "MacOptionsFrameCodecDropDownButtonHighlightTexture",
+ "MacOptionsFrameCodecDropDownButtonNormalTexture",
+ "MacOptionsFrameCodecDropDownButtonPushedTexture",
+ "MacOptionsFrameCodecDropDownLabel",
+ "MacOptionsFrameCodecDropDownLeft",
+ "MacOptionsFrameCodecDropDownMiddle",
+ "MacOptionsFrameCodecDropDownRight",
+ "MacOptionsFrameCodecDropDownText",
+ "MacOptionsFrameCodecDropDown_Initialize",
+ "MacOptionsFrameCodecDropDown_OnClick",
+ "MacOptionsFrameCodecDropDown_OnLoad",
+ "MacOptionsFrameDefaults",
+ "MacOptionsFrameFramerateDropDown",
+ "MacOptionsFrameFramerateDropDownButton",
+ "MacOptionsFrameFramerateDropDownButtonDisabledTexture",
+ "MacOptionsFrameFramerateDropDownButtonHighlightTexture",
+ "MacOptionsFrameFramerateDropDownButtonNormalTexture",
+ "MacOptionsFrameFramerateDropDownButtonPushedTexture",
+ "MacOptionsFrameFramerateDropDownLabel",
+ "MacOptionsFrameFramerateDropDownLeft",
+ "MacOptionsFrameFramerateDropDownMiddle",
+ "MacOptionsFrameFramerateDropDownRight",
+ "MacOptionsFrameFramerateDropDownText",
+ "MacOptionsFrameFramerateDropDown_Initialize",
+ "MacOptionsFrameFramerateDropDown_OnClick",
+ "MacOptionsFrameFramerateDropDown_OnLoad",
+ "MacOptionsFrameHeader",
+ "MacOptionsFrameMovieRecording",
+ "MacOptionsFrameMovieRecordingTitle",
+ "MacOptionsFrameOkay",
+ "MacOptionsFrameOkayText",
+ "MacOptionsFrameQualitySlider",
+ "MacOptionsFrameQualitySliderHigh",
+ "MacOptionsFrameQualitySliderLow",
+ "MacOptionsFrameQualitySliderText",
+ "MacOptionsFrameQualitySliderThumb",
+ "MacOptionsFrameResolutionButton_OnClick",
+ "MacOptionsFrameResolutionDropDown",
+ "MacOptionsFrameResolutionDropDownButton",
+ "MacOptionsFrameResolutionDropDownButtonDisabledTexture",
+ "MacOptionsFrameResolutionDropDownButtonHighlightTexture",
+ "MacOptionsFrameResolutionDropDownButtonNormalTexture",
+ "MacOptionsFrameResolutionDropDownButtonPushedTexture",
+ "MacOptionsFrameResolutionDropDownLabel",
+ "MacOptionsFrameResolutionDropDownLeft",
+ "MacOptionsFrameResolutionDropDownMiddle",
+ "MacOptionsFrameResolutionDropDownRight",
+ "MacOptionsFrameResolutionDropDownText",
+ "MacOptionsFrameResolutionDropDown_Initialize",
+ "MacOptionsFrameResolutionDropDown_OnLoad",
+ "MacOptionsFrameText1",
+ "MacOptionsFrameText2",
+ "MacOptionsFrameText3",
+ "MacOptionsFrameText4",
+ "MacOptionsFrame_Cancel",
+ "MacOptionsFrame_DisableCheckBox",
+ "MacOptionsFrame_DisableSlider",
+ "MacOptionsFrame_DisableText",
+ "MacOptionsFrame_EnableCheckBox",
+ "MacOptionsFrame_Load",
+ "MacOptionsFrame_OnEvent",
+ "MacOptionsFrame_OnLoad",
+ "MacOptionsFrame_Save",
+ "MacOptionsFrame_SetDefaults",
+ "MacOptionsFrame_UpdateTime",
+ "MacOptionsITunesRemote",
+ "MacOptionsITunesRemoteTitle",
+ "MacroButton1",
+ "MacroButton10",
+ "MacroButton10Icon",
+ "MacroButton10Name",
+ "MacroButton11",
+ "MacroButton11Icon",
+ "MacroButton11Name",
+ "MacroButton12",
+ "MacroButton12Icon",
+ "MacroButton12Name",
+ "MacroButton13",
+ "MacroButton13Icon",
+ "MacroButton13Name",
+ "MacroButton14",
+ "MacroButton14Icon",
+ "MacroButton14Name",
+ "MacroButton15",
+ "MacroButton15Icon",
+ "MacroButton15Name",
+ "MacroButton16",
+ "MacroButton16Icon",
+ "MacroButton16Name",
+ "MacroButton17",
+ "MacroButton17Icon",
+ "MacroButton17Name",
+ "MacroButton18",
+ "MacroButton18Icon",
+ "MacroButton18Name",
+ "MacroButton19",
+ "MacroButton19Icon",
+ "MacroButton19Name",
+ "MacroButton1Icon",
+ "MacroButton1Name",
+ "MacroButton2",
+ "MacroButton20",
+ "MacroButton20Icon",
+ "MacroButton20Name",
+ "MacroButton21",
+ "MacroButton21Icon",
+ "MacroButton21Name",
+ "MacroButton22",
+ "MacroButton22Icon",
+ "MacroButton22Name",
+ "MacroButton23",
+ "MacroButton23Icon",
+ "MacroButton23Name",
+ "MacroButton24",
+ "MacroButton24Icon",
+ "MacroButton24Name",
+ "MacroButton25",
+ "MacroButton25Icon",
+ "MacroButton25Name",
+ "MacroButton26",
+ "MacroButton26Icon",
+ "MacroButton26Name",
+ "MacroButton27",
+ "MacroButton27Icon",
+ "MacroButton27Name",
+ "MacroButton28",
+ "MacroButton28Icon",
+ "MacroButton28Name",
+ "MacroButton29",
+ "MacroButton29Icon",
+ "MacroButton29Name",
+ "MacroButton2Icon",
+ "MacroButton2Name",
+ "MacroButton3",
+ "MacroButton30",
+ "MacroButton30Icon",
+ "MacroButton30Name",
+ "MacroButton31",
+ "MacroButton31Icon",
+ "MacroButton31Name",
+ "MacroButton32",
+ "MacroButton32Icon",
+ "MacroButton32Name",
+ "MacroButton33",
+ "MacroButton33Icon",
+ "MacroButton33Name",
+ "MacroButton34",
+ "MacroButton34Icon",
+ "MacroButton34Name",
+ "MacroButton35",
+ "MacroButton35Icon",
+ "MacroButton35Name",
+ "MacroButton36",
+ "MacroButton36Icon",
+ "MacroButton36Name",
+ "MacroButton3Icon",
+ "MacroButton3Name",
+ "MacroButton4",
+ "MacroButton4Icon",
+ "MacroButton4Name",
+ "MacroButton5",
+ "MacroButton5Icon",
+ "MacroButton5Name",
+ "MacroButton6",
+ "MacroButton6Icon",
+ "MacroButton6Name",
+ "MacroButton7",
+ "MacroButton7Icon",
+ "MacroButton7Name",
+ "MacroButton8",
+ "MacroButton8Icon",
+ "MacroButton8Name",
+ "MacroButton9",
+ "MacroButton9Icon",
+ "MacroButton9Name",
+ "MacroButtonContainer",
+ "MacroButtonContainer_OnLoad",
+ "MacroButtonScrollFrame",
+ "MacroButtonScrollFrameBottom",
+ "MacroButtonScrollFrameMiddle",
+ "MacroButtonScrollFrameScrollBar",
+ "MacroButtonScrollFrameScrollBarScrollDownButton",
+ "MacroButtonScrollFrameScrollBarScrollUpButton",
+ "MacroButtonScrollFrameScrollBarThumbTexture",
+ "MacroButtonScrollFrameTop",
+ "MacroButton_OnClick",
+ "MacroDeleteButton",
+ "MacroEditBox",
+ "MacroEditButton",
+ "MacroEditButtonText",
+ "MacroEditButton_OnClick",
+ "MacroExitButton",
+ "MacroExitButtonText",
+ "MacroFrame",
+ "MacroFrameCharLimitText",
+ "MacroFrameCloseButton",
+ "MacroFrameEnterMacroText",
+ "MacroFramePortrait",
+ "MacroFrameScrollFrame",
+ "MacroFrameScrollFrameScrollBar",
+ "MacroFrameScrollFrameScrollBarScrollDownButton",
+ "MacroFrameScrollFrameScrollBarScrollUpButton",
+ "MacroFrameScrollFrameScrollBarThumbTexture",
+ "MacroFrameSelectedMacroBackground",
+ "MacroFrameSelectedMacroButton",
+ "MacroFrameSelectedMacroButtonIcon",
+ "MacroFrameSelectedMacroButtonName",
+ "MacroFrameSelectedMacroName",
+ "MacroFrameTab1",
+ "MacroFrameTab1HighlightTexture",
+ "MacroFrameTab1Left",
+ "MacroFrameTab1LeftDisabled",
+ "MacroFrameTab1Middle",
+ "MacroFrameTab1MiddleDisabled",
+ "MacroFrameTab1Right",
+ "MacroFrameTab1RightDisabled",
+ "MacroFrameTab1Text",
+ "MacroFrameTab2",
+ "MacroFrameTab2HighlightTexture",
+ "MacroFrameTab2Left",
+ "MacroFrameTab2LeftDisabled",
+ "MacroFrameTab2Middle",
+ "MacroFrameTab2MiddleDisabled",
+ "MacroFrameTab2Right",
+ "MacroFrameTab2RightDisabled",
+ "MacroFrameTab2Text",
+ "MacroFrameText",
+ "MacroFrameTextBackground",
+ "MacroFrameTextButton",
+ "MacroFrame_AddMacroLine",
+ "MacroFrame_DeleteMacro",
+ "MacroFrame_HideDetails",
+ "MacroFrame_LoadUI",
+ "MacroFrame_OnHide",
+ "MacroFrame_OnLoad",
+ "MacroFrame_OnShow",
+ "MacroFrame_SaveMacro",
+ "MacroFrame_SelectMacro",
+ "MacroFrame_SetAccountMacros",
+ "MacroFrame_SetCharacterMacros",
+ "MacroFrame_Show",
+ "MacroFrame_ShowDetails",
+ "MacroFrame_Update",
+ "MacroHorizontalBarLeft",
+ "MacroNewButton",
+ "MacroNewButtonText",
+ "MacroNewButton_OnClick",
+ "MacroPopupButton1",
+ "MacroPopupButton10",
+ "MacroPopupButton10Icon",
+ "MacroPopupButton10Name",
+ "MacroPopupButton11",
+ "MacroPopupButton11Icon",
+ "MacroPopupButton11Name",
+ "MacroPopupButton12",
+ "MacroPopupButton12Icon",
+ "MacroPopupButton12Name",
+ "MacroPopupButton13",
+ "MacroPopupButton13Icon",
+ "MacroPopupButton13Name",
+ "MacroPopupButton14",
+ "MacroPopupButton14Icon",
+ "MacroPopupButton14Name",
+ "MacroPopupButton15",
+ "MacroPopupButton15Icon",
+ "MacroPopupButton15Name",
+ "MacroPopupButton16",
+ "MacroPopupButton16Icon",
+ "MacroPopupButton16Name",
+ "MacroPopupButton17",
+ "MacroPopupButton17Icon",
+ "MacroPopupButton17Name",
+ "MacroPopupButton18",
+ "MacroPopupButton18Icon",
+ "MacroPopupButton18Name",
+ "MacroPopupButton19",
+ "MacroPopupButton19Icon",
+ "MacroPopupButton19Name",
+ "MacroPopupButton1Icon",
+ "MacroPopupButton1Name",
+ "MacroPopupButton2",
+ "MacroPopupButton20",
+ "MacroPopupButton20Icon",
+ "MacroPopupButton20Name",
+ "MacroPopupButton2Icon",
+ "MacroPopupButton2Name",
+ "MacroPopupButton3",
+ "MacroPopupButton3Icon",
+ "MacroPopupButton3Name",
+ "MacroPopupButton4",
+ "MacroPopupButton4Icon",
+ "MacroPopupButton4Name",
+ "MacroPopupButton5",
+ "MacroPopupButton5Icon",
+ "MacroPopupButton5Name",
+ "MacroPopupButton6",
+ "MacroPopupButton6Icon",
+ "MacroPopupButton6Name",
+ "MacroPopupButton7",
+ "MacroPopupButton7Icon",
+ "MacroPopupButton7Name",
+ "MacroPopupButton8",
+ "MacroPopupButton8Icon",
+ "MacroPopupButton8Name",
+ "MacroPopupButton9",
+ "MacroPopupButton9Icon",
+ "MacroPopupButton9Name",
+ "MacroPopupButton_OnClick",
+ "MacroPopupButton_SelectTexture",
+ "MacroPopupCancelButton",
+ "MacroPopupCancelButtonText",
+ "MacroPopupEditBox",
+ "MacroPopupFrame",
+ "MacroPopupFrame_CancelEdit",
+ "MacroPopupFrame_OnHide",
+ "MacroPopupFrame_OnShow",
+ "MacroPopupFrame_Update",
+ "MacroPopupNameLeft",
+ "MacroPopupNameMiddle",
+ "MacroPopupNameRight",
+ "MacroPopupOkayButton",
+ "MacroPopupOkayButtonText",
+ "MacroPopupOkayButton_OnClick",
+ "MacroPopupOkayButton_Update",
+ "MacroPopupScrollFrame",
+ "MacroPopupScrollFrameScrollBar",
+ "MacroPopupScrollFrameScrollBarScrollDownButton",
+ "MacroPopupScrollFrameScrollBarScrollUpButton",
+ "MacroPopupScrollFrameScrollBarThumbTexture",
+ "MacroPopupScrollFrameScrollChildFrame",
+ "MagicResFrame1",
+ "MagicResFrame2",
+ "MagicResFrame3",
+ "MagicResFrame4",
+ "MagicResFrame5",
+ "MagicResText1",
+ "MagicResText2",
+ "MagicResText3",
+ "MagicResText4",
+ "MagicResText5",
+ "MailFont_Large",
+ "MailFrame",
+ "MailFrameBotLeft",
+ "MailFrameBotRight",
+ "MailFrameTab1",
+ "MailFrameTab1HighlightTexture",
+ "MailFrameTab1Left",
+ "MailFrameTab1LeftDisabled",
+ "MailFrameTab1Middle",
+ "MailFrameTab1MiddleDisabled",
+ "MailFrameTab1Right",
+ "MailFrameTab1RightDisabled",
+ "MailFrameTab1Text",
+ "MailFrameTab2",
+ "MailFrameTab2HighlightTexture",
+ "MailFrameTab2Left",
+ "MailFrameTab2LeftDisabled",
+ "MailFrameTab2Middle",
+ "MailFrameTab2MiddleDisabled",
+ "MailFrameTab2Right",
+ "MailFrameTab2RightDisabled",
+ "MailFrameTab2Text",
+ "MailFrameTab_OnClick",
+ "MailFrameTopLeft",
+ "MailFrameTopRight",
+ "MailFrame_OnEvent",
+ "MailFrame_OnLoad",
+ "MailItem1",
+ "MailItem1Button",
+ "MailItem1ButtonCOD",
+ "MailItem1ButtonCODBackground",
+ "MailItem1ButtonCount",
+ "MailItem1ButtonIcon",
+ "MailItem1ButtonSlot",
+ "MailItem1ExpireTime",
+ "MailItem1Sender",
+ "MailItem1Subject",
+ "MailItem2",
+ "MailItem2Button",
+ "MailItem2ButtonCOD",
+ "MailItem2ButtonCODBackground",
+ "MailItem2ButtonCount",
+ "MailItem2ButtonIcon",
+ "MailItem2ButtonSlot",
+ "MailItem2ExpireTime",
+ "MailItem2Sender",
+ "MailItem2Subject",
+ "MailItem3",
+ "MailItem3Button",
+ "MailItem3ButtonCOD",
+ "MailItem3ButtonCODBackground",
+ "MailItem3ButtonCount",
+ "MailItem3ButtonIcon",
+ "MailItem3ButtonSlot",
+ "MailItem3ExpireTime",
+ "MailItem3Sender",
+ "MailItem3Subject",
+ "MailItem4",
+ "MailItem4Button",
+ "MailItem4ButtonCOD",
+ "MailItem4ButtonCODBackground",
+ "MailItem4ButtonCount",
+ "MailItem4ButtonIcon",
+ "MailItem4ButtonSlot",
+ "MailItem4ExpireTime",
+ "MailItem4Sender",
+ "MailItem4Subject",
+ "MailItem5",
+ "MailItem5Button",
+ "MailItem5ButtonCOD",
+ "MailItem5ButtonCODBackground",
+ "MailItem5ButtonCount",
+ "MailItem5ButtonIcon",
+ "MailItem5ButtonSlot",
+ "MailItem5ExpireTime",
+ "MailItem5Sender",
+ "MailItem5Subject",
+ "MailItem6",
+ "MailItem6Button",
+ "MailItem6ButtonCOD",
+ "MailItem6ButtonCODBackground",
+ "MailItem6ButtonCount",
+ "MailItem6ButtonIcon",
+ "MailItem6ButtonSlot",
+ "MailItem6ExpireTime",
+ "MailItem6Sender",
+ "MailItem6Subject",
+ "MailItem7",
+ "MailItem7Button",
+ "MailItem7ButtonCOD",
+ "MailItem7ButtonCODBackground",
+ "MailItem7ButtonCount",
+ "MailItem7ButtonIcon",
+ "MailItem7ButtonSlot",
+ "MailItem7ExpireTime",
+ "MailItem7Sender",
+ "MailItem7Subject",
+ "MailTextFontNormal",
+ "MainMenuBar",
+ "MainMenuBarArtFrame",
+ "MainMenuBarBackpackButton",
+ "MainMenuBarBackpackButtonCount",
+ "MainMenuBarBackpackButtonIconTexture",
+ "MainMenuBarBackpackButtonItemAnim",
+ "MainMenuBarBackpackButtonNormalTexture",
+ "MainMenuBarBackpackButtonStock",
+ "MainMenuBarBackpackButton_OnEvent",
+ "MainMenuBarBackpackButton_UpdateFreeSlots",
+ "MainMenuBarExpText",
+ "MainMenuBarLeftEndCap",
+ "MainMenuBarMaxLevelBar",
+ "MainMenuBarOverlayFrame",
+ "MainMenuBarPageNumber",
+ "MainMenuBarPerformanceBar",
+ "MainMenuBarPerformanceBarFrame_OnEnter",
+ "MainMenuBarRightEndCap",
+ "MainMenuBarTexture0",
+ "MainMenuBarTexture1",
+ "MainMenuBarTexture2",
+ "MainMenuBarTexture3",
+ "MainMenuBarVehicleLeaveButton",
+ "MainMenuBarVehicleLeaveButton_OnEvent",
+ "MainMenuBarVehicleLeaveButton_OnLoad",
+ "MainMenuBarVehicleLeaveButton_Update",
+ "MainMenuBar_AnimFinished",
+ "MainMenuBar_OnEvent",
+ "MainMenuBar_OnLoad",
+ "MainMenuBar_ToPlayerArt",
+ "MainMenuBar_ToVehicleArt",
+ "MainMenuBar_UnlockAB",
+ "MainMenuBar_UpdateArt",
+ "MainMenuBar_UpdateKeyRing",
+ "MainMenuExpBar",
+ "MainMenuExpBar_Update",
+ "MainMenuMaxLevelBar0",
+ "MainMenuMaxLevelBar1",
+ "MainMenuMaxLevelBar2",
+ "MainMenuMaxLevelBar3",
+ "MainMenuMicroButton",
+ "MainMenuMicroButton_SetNormal",
+ "MainMenuMicroButton_SetPushed",
+ "MainMenuXPBarTexture0",
+ "MainMenuXPBarTexture1",
+ "MainMenuXPBarTexture2",
+ "MainMenuXPBarTexture3",
+ "MakeMinigameMove",
+ "ManageBackpackTokenFrame",
+ "MapFramerateLabel",
+ "MapFramerateText",
+ "MerchantBuyBackItem",
+ "MerchantBuyBackItemItemButton",
+ "MerchantBuyBackItemItemButtonCount",
+ "MerchantBuyBackItemItemButtonIconTexture",
+ "MerchantBuyBackItemItemButtonNormalTexture",
+ "MerchantBuyBackItemItemButtonStock",
+ "MerchantBuyBackItemMoneyFrame",
+ "MerchantBuyBackItemMoneyFrameCopperButton",
+ "MerchantBuyBackItemMoneyFrameCopperButtonText",
+ "MerchantBuyBackItemMoneyFrameGoldButton",
+ "MerchantBuyBackItemMoneyFrameGoldButtonText",
+ "MerchantBuyBackItemMoneyFrameSilverButton",
+ "MerchantBuyBackItemMoneyFrameSilverButtonText",
+ "MerchantBuyBackItemName",
+ "MerchantBuyBackItemNameFrame",
+ "MerchantBuyBackItemSlotTexture",
+ "MerchantFrame",
+ "MerchantFrameBottomLeftBorder",
+ "MerchantFrameBottomRightBorder",
+ "MerchantFrameCloseButton",
+ "MerchantFramePortrait",
+ "MerchantFrameTab1",
+ "MerchantFrameTab1HighlightTexture",
+ "MerchantFrameTab1Left",
+ "MerchantFrameTab1LeftDisabled",
+ "MerchantFrameTab1Middle",
+ "MerchantFrameTab1MiddleDisabled",
+ "MerchantFrameTab1Right",
+ "MerchantFrameTab1RightDisabled",
+ "MerchantFrameTab1Text",
+ "MerchantFrameTab2",
+ "MerchantFrameTab2HighlightTexture",
+ "MerchantFrameTab2Left",
+ "MerchantFrameTab2LeftDisabled",
+ "MerchantFrameTab2Middle",
+ "MerchantFrameTab2MiddleDisabled",
+ "MerchantFrameTab2Right",
+ "MerchantFrameTab2RightDisabled",
+ "MerchantFrameTab2Text",
+ "MerchantFrame_ConfirmExtendedItemCost",
+ "MerchantFrame_ConfirmHighCostItem",
+ "MerchantFrame_OnEvent",
+ "MerchantFrame_OnHide",
+ "MerchantFrame_OnLoad",
+ "MerchantFrame_OnShow",
+ "MerchantFrame_ResetRefundItem",
+ "MerchantFrame_SetRefundItem",
+ "MerchantFrame_Update",
+ "MerchantFrame_UpdateAltCurrency",
+ "MerchantFrame_UpdateBuybackInfo",
+ "MerchantFrame_UpdateCanRepairAll",
+ "MerchantFrame_UpdateGuildBankRepair",
+ "MerchantFrame_UpdateMerchantInfo",
+ "MerchantFrame_UpdateRepairButtons",
+ "MerchantGuildBankRepairButton",
+ "MerchantGuildBankRepairButtonIcon",
+ "MerchantItem1",
+ "MerchantItem10",
+ "MerchantItem10AltCurrencyFrame",
+ "MerchantItem10AltCurrencyFrameArena",
+ "MerchantItem10AltCurrencyFrameArenaText",
+ "MerchantItem10AltCurrencyFrameArenaTexture",
+ "MerchantItem10AltCurrencyFrameHonor",
+ "MerchantItem10AltCurrencyFrameHonorText",
+ "MerchantItem10AltCurrencyFrameHonorTexture",
+ "MerchantItem10AltCurrencyFrameItem1",
+ "MerchantItem10AltCurrencyFrameItem1Text",
+ "MerchantItem10AltCurrencyFrameItem1Texture",
+ "MerchantItem10AltCurrencyFrameItem2",
+ "MerchantItem10AltCurrencyFrameItem2Text",
+ "MerchantItem10AltCurrencyFrameItem2Texture",
+ "MerchantItem10AltCurrencyFrameItem3",
+ "MerchantItem10AltCurrencyFrameItem3Text",
+ "MerchantItem10AltCurrencyFrameItem3Texture",
+ "MerchantItem10ItemButton",
+ "MerchantItem10ItemButtonCount",
+ "MerchantItem10ItemButtonIconTexture",
+ "MerchantItem10ItemButtonNormalTexture",
+ "MerchantItem10ItemButtonStock",
+ "MerchantItem10MoneyFrame",
+ "MerchantItem10MoneyFrameCopperButton",
+ "MerchantItem10MoneyFrameCopperButtonText",
+ "MerchantItem10MoneyFrameGoldButton",
+ "MerchantItem10MoneyFrameGoldButtonText",
+ "MerchantItem10MoneyFrameSilverButton",
+ "MerchantItem10MoneyFrameSilverButtonText",
+ "MerchantItem10Name",
+ "MerchantItem10NameFrame",
+ "MerchantItem10SlotTexture",
+ "MerchantItem11",
+ "MerchantItem11AltCurrencyFrame",
+ "MerchantItem11AltCurrencyFrameArena",
+ "MerchantItem11AltCurrencyFrameArenaText",
+ "MerchantItem11AltCurrencyFrameArenaTexture",
+ "MerchantItem11AltCurrencyFrameHonor",
+ "MerchantItem11AltCurrencyFrameHonorText",
+ "MerchantItem11AltCurrencyFrameHonorTexture",
+ "MerchantItem11AltCurrencyFrameItem1",
+ "MerchantItem11AltCurrencyFrameItem1Text",
+ "MerchantItem11AltCurrencyFrameItem1Texture",
+ "MerchantItem11AltCurrencyFrameItem2",
+ "MerchantItem11AltCurrencyFrameItem2Text",
+ "MerchantItem11AltCurrencyFrameItem2Texture",
+ "MerchantItem11AltCurrencyFrameItem3",
+ "MerchantItem11AltCurrencyFrameItem3Text",
+ "MerchantItem11AltCurrencyFrameItem3Texture",
+ "MerchantItem11ItemButton",
+ "MerchantItem11ItemButtonCount",
+ "MerchantItem11ItemButtonIconTexture",
+ "MerchantItem11ItemButtonNormalTexture",
+ "MerchantItem11ItemButtonStock",
+ "MerchantItem11MoneyFrame",
+ "MerchantItem11MoneyFrameCopperButton",
+ "MerchantItem11MoneyFrameCopperButtonText",
+ "MerchantItem11MoneyFrameGoldButton",
+ "MerchantItem11MoneyFrameGoldButtonText",
+ "MerchantItem11MoneyFrameSilverButton",
+ "MerchantItem11MoneyFrameSilverButtonText",
+ "MerchantItem11Name",
+ "MerchantItem11NameFrame",
+ "MerchantItem11SlotTexture",
+ "MerchantItem12",
+ "MerchantItem12AltCurrencyFrame",
+ "MerchantItem12AltCurrencyFrameArena",
+ "MerchantItem12AltCurrencyFrameArenaText",
+ "MerchantItem12AltCurrencyFrameArenaTexture",
+ "MerchantItem12AltCurrencyFrameHonor",
+ "MerchantItem12AltCurrencyFrameHonorText",
+ "MerchantItem12AltCurrencyFrameHonorTexture",
+ "MerchantItem12AltCurrencyFrameItem1",
+ "MerchantItem12AltCurrencyFrameItem1Text",
+ "MerchantItem12AltCurrencyFrameItem1Texture",
+ "MerchantItem12AltCurrencyFrameItem2",
+ "MerchantItem12AltCurrencyFrameItem2Text",
+ "MerchantItem12AltCurrencyFrameItem2Texture",
+ "MerchantItem12AltCurrencyFrameItem3",
+ "MerchantItem12AltCurrencyFrameItem3Text",
+ "MerchantItem12AltCurrencyFrameItem3Texture",
+ "MerchantItem12ItemButton",
+ "MerchantItem12ItemButtonCount",
+ "MerchantItem12ItemButtonIconTexture",
+ "MerchantItem12ItemButtonNormalTexture",
+ "MerchantItem12ItemButtonStock",
+ "MerchantItem12MoneyFrame",
+ "MerchantItem12MoneyFrameCopperButton",
+ "MerchantItem12MoneyFrameCopperButtonText",
+ "MerchantItem12MoneyFrameGoldButton",
+ "MerchantItem12MoneyFrameGoldButtonText",
+ "MerchantItem12MoneyFrameSilverButton",
+ "MerchantItem12MoneyFrameSilverButtonText",
+ "MerchantItem12Name",
+ "MerchantItem12NameFrame",
+ "MerchantItem12SlotTexture",
+ "MerchantItem1AltCurrencyFrame",
+ "MerchantItem1AltCurrencyFrameArena",
+ "MerchantItem1AltCurrencyFrameArenaText",
+ "MerchantItem1AltCurrencyFrameArenaTexture",
+ "MerchantItem1AltCurrencyFrameHonor",
+ "MerchantItem1AltCurrencyFrameHonorText",
+ "MerchantItem1AltCurrencyFrameHonorTexture",
+ "MerchantItem1AltCurrencyFrameItem1",
+ "MerchantItem1AltCurrencyFrameItem1Text",
+ "MerchantItem1AltCurrencyFrameItem1Texture",
+ "MerchantItem1AltCurrencyFrameItem2",
+ "MerchantItem1AltCurrencyFrameItem2Text",
+ "MerchantItem1AltCurrencyFrameItem2Texture",
+ "MerchantItem1AltCurrencyFrameItem3",
+ "MerchantItem1AltCurrencyFrameItem3Text",
+ "MerchantItem1AltCurrencyFrameItem3Texture",
+ "MerchantItem1ItemButton",
+ "MerchantItem1ItemButtonCount",
+ "MerchantItem1ItemButtonIconTexture",
+ "MerchantItem1ItemButtonNormalTexture",
+ "MerchantItem1ItemButtonStock",
+ "MerchantItem1MoneyFrame",
+ "MerchantItem1MoneyFrameCopperButton",
+ "MerchantItem1MoneyFrameCopperButtonText",
+ "MerchantItem1MoneyFrameGoldButton",
+ "MerchantItem1MoneyFrameGoldButtonText",
+ "MerchantItem1MoneyFrameSilverButton",
+ "MerchantItem1MoneyFrameSilverButtonText",
+ "MerchantItem1Name",
+ "MerchantItem1NameFrame",
+ "MerchantItem1SlotTexture",
+ "MerchantItem2",
+ "MerchantItem2AltCurrencyFrame",
+ "MerchantItem2AltCurrencyFrameArena",
+ "MerchantItem2AltCurrencyFrameArenaText",
+ "MerchantItem2AltCurrencyFrameArenaTexture",
+ "MerchantItem2AltCurrencyFrameHonor",
+ "MerchantItem2AltCurrencyFrameHonorText",
+ "MerchantItem2AltCurrencyFrameHonorTexture",
+ "MerchantItem2AltCurrencyFrameItem1",
+ "MerchantItem2AltCurrencyFrameItem1Text",
+ "MerchantItem2AltCurrencyFrameItem1Texture",
+ "MerchantItem2AltCurrencyFrameItem2",
+ "MerchantItem2AltCurrencyFrameItem2Text",
+ "MerchantItem2AltCurrencyFrameItem2Texture",
+ "MerchantItem2AltCurrencyFrameItem3",
+ "MerchantItem2AltCurrencyFrameItem3Text",
+ "MerchantItem2AltCurrencyFrameItem3Texture",
+ "MerchantItem2ItemButton",
+ "MerchantItem2ItemButtonCount",
+ "MerchantItem2ItemButtonIconTexture",
+ "MerchantItem2ItemButtonNormalTexture",
+ "MerchantItem2ItemButtonStock",
+ "MerchantItem2MoneyFrame",
+ "MerchantItem2MoneyFrameCopperButton",
+ "MerchantItem2MoneyFrameCopperButtonText",
+ "MerchantItem2MoneyFrameGoldButton",
+ "MerchantItem2MoneyFrameGoldButtonText",
+ "MerchantItem2MoneyFrameSilverButton",
+ "MerchantItem2MoneyFrameSilverButtonText",
+ "MerchantItem2Name",
+ "MerchantItem2NameFrame",
+ "MerchantItem2SlotTexture",
+ "MerchantItem3",
+ "MerchantItem3AltCurrencyFrame",
+ "MerchantItem3AltCurrencyFrameArena",
+ "MerchantItem3AltCurrencyFrameArenaText",
+ "MerchantItem3AltCurrencyFrameArenaTexture",
+ "MerchantItem3AltCurrencyFrameHonor",
+ "MerchantItem3AltCurrencyFrameHonorText",
+ "MerchantItem3AltCurrencyFrameHonorTexture",
+ "MerchantItem3AltCurrencyFrameItem1",
+ "MerchantItem3AltCurrencyFrameItem1Text",
+ "MerchantItem3AltCurrencyFrameItem1Texture",
+ "MerchantItem3AltCurrencyFrameItem2",
+ "MerchantItem3AltCurrencyFrameItem2Text",
+ "MerchantItem3AltCurrencyFrameItem2Texture",
+ "MerchantItem3AltCurrencyFrameItem3",
+ "MerchantItem3AltCurrencyFrameItem3Text",
+ "MerchantItem3AltCurrencyFrameItem3Texture",
+ "MerchantItem3ItemButton",
+ "MerchantItem3ItemButtonCount",
+ "MerchantItem3ItemButtonIconTexture",
+ "MerchantItem3ItemButtonNormalTexture",
+ "MerchantItem3ItemButtonStock",
+ "MerchantItem3MoneyFrame",
+ "MerchantItem3MoneyFrameCopperButton",
+ "MerchantItem3MoneyFrameCopperButtonText",
+ "MerchantItem3MoneyFrameGoldButton",
+ "MerchantItem3MoneyFrameGoldButtonText",
+ "MerchantItem3MoneyFrameSilverButton",
+ "MerchantItem3MoneyFrameSilverButtonText",
+ "MerchantItem3Name",
+ "MerchantItem3NameFrame",
+ "MerchantItem3SlotTexture",
+ "MerchantItem4",
+ "MerchantItem4AltCurrencyFrame",
+ "MerchantItem4AltCurrencyFrameArena",
+ "MerchantItem4AltCurrencyFrameArenaText",
+ "MerchantItem4AltCurrencyFrameArenaTexture",
+ "MerchantItem4AltCurrencyFrameHonor",
+ "MerchantItem4AltCurrencyFrameHonorText",
+ "MerchantItem4AltCurrencyFrameHonorTexture",
+ "MerchantItem4AltCurrencyFrameItem1",
+ "MerchantItem4AltCurrencyFrameItem1Text",
+ "MerchantItem4AltCurrencyFrameItem1Texture",
+ "MerchantItem4AltCurrencyFrameItem2",
+ "MerchantItem4AltCurrencyFrameItem2Text",
+ "MerchantItem4AltCurrencyFrameItem2Texture",
+ "MerchantItem4AltCurrencyFrameItem3",
+ "MerchantItem4AltCurrencyFrameItem3Text",
+ "MerchantItem4AltCurrencyFrameItem3Texture",
+ "MerchantItem4ItemButton",
+ "MerchantItem4ItemButtonCount",
+ "MerchantItem4ItemButtonIconTexture",
+ "MerchantItem4ItemButtonNormalTexture",
+ "MerchantItem4ItemButtonStock",
+ "MerchantItem4MoneyFrame",
+ "MerchantItem4MoneyFrameCopperButton",
+ "MerchantItem4MoneyFrameCopperButtonText",
+ "MerchantItem4MoneyFrameGoldButton",
+ "MerchantItem4MoneyFrameGoldButtonText",
+ "MerchantItem4MoneyFrameSilverButton",
+ "MerchantItem4MoneyFrameSilverButtonText",
+ "MerchantItem4Name",
+ "MerchantItem4NameFrame",
+ "MerchantItem4SlotTexture",
+ "MerchantItem5",
+ "MerchantItem5AltCurrencyFrame",
+ "MerchantItem5AltCurrencyFrameArena",
+ "MerchantItem5AltCurrencyFrameArenaText",
+ "MerchantItem5AltCurrencyFrameArenaTexture",
+ "MerchantItem5AltCurrencyFrameHonor",
+ "MerchantItem5AltCurrencyFrameHonorText",
+ "MerchantItem5AltCurrencyFrameHonorTexture",
+ "MerchantItem5AltCurrencyFrameItem1",
+ "MerchantItem5AltCurrencyFrameItem1Text",
+ "MerchantItem5AltCurrencyFrameItem1Texture",
+ "MerchantItem5AltCurrencyFrameItem2",
+ "MerchantItem5AltCurrencyFrameItem2Text",
+ "MerchantItem5AltCurrencyFrameItem2Texture",
+ "MerchantItem5AltCurrencyFrameItem3",
+ "MerchantItem5AltCurrencyFrameItem3Text",
+ "MerchantItem5AltCurrencyFrameItem3Texture",
+ "MerchantItem5ItemButton",
+ "MerchantItem5ItemButtonCount",
+ "MerchantItem5ItemButtonIconTexture",
+ "MerchantItem5ItemButtonNormalTexture",
+ "MerchantItem5ItemButtonStock",
+ "MerchantItem5MoneyFrame",
+ "MerchantItem5MoneyFrameCopperButton",
+ "MerchantItem5MoneyFrameCopperButtonText",
+ "MerchantItem5MoneyFrameGoldButton",
+ "MerchantItem5MoneyFrameGoldButtonText",
+ "MerchantItem5MoneyFrameSilverButton",
+ "MerchantItem5MoneyFrameSilverButtonText",
+ "MerchantItem5Name",
+ "MerchantItem5NameFrame",
+ "MerchantItem5SlotTexture",
+ "MerchantItem6",
+ "MerchantItem6AltCurrencyFrame",
+ "MerchantItem6AltCurrencyFrameArena",
+ "MerchantItem6AltCurrencyFrameArenaText",
+ "MerchantItem6AltCurrencyFrameArenaTexture",
+ "MerchantItem6AltCurrencyFrameHonor",
+ "MerchantItem6AltCurrencyFrameHonorText",
+ "MerchantItem6AltCurrencyFrameHonorTexture",
+ "MerchantItem6AltCurrencyFrameItem1",
+ "MerchantItem6AltCurrencyFrameItem1Text",
+ "MerchantItem6AltCurrencyFrameItem1Texture",
+ "MerchantItem6AltCurrencyFrameItem2",
+ "MerchantItem6AltCurrencyFrameItem2Text",
+ "MerchantItem6AltCurrencyFrameItem2Texture",
+ "MerchantItem6AltCurrencyFrameItem3",
+ "MerchantItem6AltCurrencyFrameItem3Text",
+ "MerchantItem6AltCurrencyFrameItem3Texture",
+ "MerchantItem6ItemButton",
+ "MerchantItem6ItemButtonCount",
+ "MerchantItem6ItemButtonIconTexture",
+ "MerchantItem6ItemButtonNormalTexture",
+ "MerchantItem6ItemButtonStock",
+ "MerchantItem6MoneyFrame",
+ "MerchantItem6MoneyFrameCopperButton",
+ "MerchantItem6MoneyFrameCopperButtonText",
+ "MerchantItem6MoneyFrameGoldButton",
+ "MerchantItem6MoneyFrameGoldButtonText",
+ "MerchantItem6MoneyFrameSilverButton",
+ "MerchantItem6MoneyFrameSilverButtonText",
+ "MerchantItem6Name",
+ "MerchantItem6NameFrame",
+ "MerchantItem6SlotTexture",
+ "MerchantItem7",
+ "MerchantItem7AltCurrencyFrame",
+ "MerchantItem7AltCurrencyFrameArena",
+ "MerchantItem7AltCurrencyFrameArenaText",
+ "MerchantItem7AltCurrencyFrameArenaTexture",
+ "MerchantItem7AltCurrencyFrameHonor",
+ "MerchantItem7AltCurrencyFrameHonorText",
+ "MerchantItem7AltCurrencyFrameHonorTexture",
+ "MerchantItem7AltCurrencyFrameItem1",
+ "MerchantItem7AltCurrencyFrameItem1Text",
+ "MerchantItem7AltCurrencyFrameItem1Texture",
+ "MerchantItem7AltCurrencyFrameItem2",
+ "MerchantItem7AltCurrencyFrameItem2Text",
+ "MerchantItem7AltCurrencyFrameItem2Texture",
+ "MerchantItem7AltCurrencyFrameItem3",
+ "MerchantItem7AltCurrencyFrameItem3Text",
+ "MerchantItem7AltCurrencyFrameItem3Texture",
+ "MerchantItem7ItemButton",
+ "MerchantItem7ItemButtonCount",
+ "MerchantItem7ItemButtonIconTexture",
+ "MerchantItem7ItemButtonNormalTexture",
+ "MerchantItem7ItemButtonStock",
+ "MerchantItem7MoneyFrame",
+ "MerchantItem7MoneyFrameCopperButton",
+ "MerchantItem7MoneyFrameCopperButtonText",
+ "MerchantItem7MoneyFrameGoldButton",
+ "MerchantItem7MoneyFrameGoldButtonText",
+ "MerchantItem7MoneyFrameSilverButton",
+ "MerchantItem7MoneyFrameSilverButtonText",
+ "MerchantItem7Name",
+ "MerchantItem7NameFrame",
+ "MerchantItem7SlotTexture",
+ "MerchantItem8",
+ "MerchantItem8AltCurrencyFrame",
+ "MerchantItem8AltCurrencyFrameArena",
+ "MerchantItem8AltCurrencyFrameArenaText",
+ "MerchantItem8AltCurrencyFrameArenaTexture",
+ "MerchantItem8AltCurrencyFrameHonor",
+ "MerchantItem8AltCurrencyFrameHonorText",
+ "MerchantItem8AltCurrencyFrameHonorTexture",
+ "MerchantItem8AltCurrencyFrameItem1",
+ "MerchantItem8AltCurrencyFrameItem1Text",
+ "MerchantItem8AltCurrencyFrameItem1Texture",
+ "MerchantItem8AltCurrencyFrameItem2",
+ "MerchantItem8AltCurrencyFrameItem2Text",
+ "MerchantItem8AltCurrencyFrameItem2Texture",
+ "MerchantItem8AltCurrencyFrameItem3",
+ "MerchantItem8AltCurrencyFrameItem3Text",
+ "MerchantItem8AltCurrencyFrameItem3Texture",
+ "MerchantItem8ItemButton",
+ "MerchantItem8ItemButtonCount",
+ "MerchantItem8ItemButtonIconTexture",
+ "MerchantItem8ItemButtonNormalTexture",
+ "MerchantItem8ItemButtonStock",
+ "MerchantItem8MoneyFrame",
+ "MerchantItem8MoneyFrameCopperButton",
+ "MerchantItem8MoneyFrameCopperButtonText",
+ "MerchantItem8MoneyFrameGoldButton",
+ "MerchantItem8MoneyFrameGoldButtonText",
+ "MerchantItem8MoneyFrameSilverButton",
+ "MerchantItem8MoneyFrameSilverButtonText",
+ "MerchantItem8Name",
+ "MerchantItem8NameFrame",
+ "MerchantItem8SlotTexture",
+ "MerchantItem9",
+ "MerchantItem9AltCurrencyFrame",
+ "MerchantItem9AltCurrencyFrameArena",
+ "MerchantItem9AltCurrencyFrameArenaText",
+ "MerchantItem9AltCurrencyFrameArenaTexture",
+ "MerchantItem9AltCurrencyFrameHonor",
+ "MerchantItem9AltCurrencyFrameHonorText",
+ "MerchantItem9AltCurrencyFrameHonorTexture",
+ "MerchantItem9AltCurrencyFrameItem1",
+ "MerchantItem9AltCurrencyFrameItem1Text",
+ "MerchantItem9AltCurrencyFrameItem1Texture",
+ "MerchantItem9AltCurrencyFrameItem2",
+ "MerchantItem9AltCurrencyFrameItem2Text",
+ "MerchantItem9AltCurrencyFrameItem2Texture",
+ "MerchantItem9AltCurrencyFrameItem3",
+ "MerchantItem9AltCurrencyFrameItem3Text",
+ "MerchantItem9AltCurrencyFrameItem3Texture",
+ "MerchantItem9ItemButton",
+ "MerchantItem9ItemButtonCount",
+ "MerchantItem9ItemButtonIconTexture",
+ "MerchantItem9ItemButtonNormalTexture",
+ "MerchantItem9ItemButtonStock",
+ "MerchantItem9MoneyFrame",
+ "MerchantItem9MoneyFrameCopperButton",
+ "MerchantItem9MoneyFrameCopperButtonText",
+ "MerchantItem9MoneyFrameGoldButton",
+ "MerchantItem9MoneyFrameGoldButtonText",
+ "MerchantItem9MoneyFrameSilverButton",
+ "MerchantItem9MoneyFrameSilverButtonText",
+ "MerchantItem9Name",
+ "MerchantItem9NameFrame",
+ "MerchantItem9SlotTexture",
+ "MerchantItemButton_OnClick",
+ "MerchantItemButton_OnEnter",
+ "MerchantItemButton_OnLoad",
+ "MerchantItemButton_OnModifiedClick",
+ "MerchantItemBuybackButton_OnLoad",
+ "MerchantMoneyFrame",
+ "MerchantMoneyFrameCopperButton",
+ "MerchantMoneyFrameCopperButtonText",
+ "MerchantMoneyFrameGoldButton",
+ "MerchantMoneyFrameGoldButtonText",
+ "MerchantMoneyFrameSilverButton",
+ "MerchantMoneyFrameSilverButtonText",
+ "MerchantNameText",
+ "MerchantNextPageButton",
+ "MerchantNextPageButton_OnClick",
+ "MerchantPageText",
+ "MerchantPrevPageButton",
+ "MerchantPrevPageButton_OnClick",
+ "MerchantRepairAllButton",
+ "MerchantRepairAllIcon",
+ "MerchantRepairItemButton",
+ "MerchantRepairText",
+ "MessageFrameScrollButton_OnLoad",
+ "MessageFrameScrollButton_OnUpdate",
+ "MessageTypeColor_OpenColorPicker",
+ "MicroButtonPortrait",
+ "MicroButtonTooltipText",
+ "MiniMapBattlefieldBorder",
+ "MiniMapBattlefieldDropDown",
+ "MiniMapBattlefieldDropDownButton",
+ "MiniMapBattlefieldDropDownButtonDisabledTexture",
+ "MiniMapBattlefieldDropDownButtonHighlightTexture",
+ "MiniMapBattlefieldDropDownButtonNormalTexture",
+ "MiniMapBattlefieldDropDownButtonPushedTexture",
+ "MiniMapBattlefieldDropDownLeft",
+ "MiniMapBattlefieldDropDownMiddle",
+ "MiniMapBattlefieldDropDownRight",
+ "MiniMapBattlefieldDropDownText",
+ "MiniMapBattlefieldDropDown_Initialize",
+ "MiniMapBattlefieldDropDown_OnLoad",
+ "MiniMapBattlefieldFrame",
+ "MiniMapBattlefieldFrame_OnUpdate",
+ "MiniMapBattlefieldFrame_isArena",
+ "MiniMapBattlefieldIcon",
+ "MiniMapInstanceDifficulty",
+ "MiniMapInstanceDifficultyText",
+ "MiniMapInstanceDifficultyTexture",
+ "MiniMapInstanceDifficulty_OnEvent",
+ "MiniMapLFGFrame",
+ "MiniMapLFGFrameBorder",
+ "MiniMapLFGFrameDropDown",
+ "MiniMapLFGFrameDropDownButton",
+ "MiniMapLFGFrameDropDownButtonDisabledTexture",
+ "MiniMapLFGFrameDropDownButtonHighlightTexture",
+ "MiniMapLFGFrameDropDownButtonNormalTexture",
+ "MiniMapLFGFrameDropDownButtonPushedTexture",
+ "MiniMapLFGFrameDropDownLeft",
+ "MiniMapLFGFrameDropDownMiddle",
+ "MiniMapLFGFrameDropDownRight",
+ "MiniMapLFGFrameDropDownText",
+ "MiniMapLFGFrameDropDown_Update",
+ "MiniMapLFGFrameIcon",
+ "MiniMapLFGFrameIconTexture",
+ "MiniMapLFGFrame_OnClick",
+ "MiniMapLFGFrame_OnEnter",
+ "MiniMapLFGFrame_OnLeave",
+ "MiniMapLFGFrame_TeleportIn",
+ "MiniMapLFGFrame_TeleportOut",
+ "MiniMapLFG_UpdateIsShown",
+ "MiniMapMailBorder",
+ "MiniMapMailFrame",
+ "MiniMapMailIcon",
+ "MiniMapRecordingBorder",
+ "MiniMapRecordingButton",
+ "MiniMapTracking",
+ "MiniMapTrackingBackground",
+ "MiniMapTrackingButton",
+ "MiniMapTrackingButtonBorder",
+ "MiniMapTrackingButtonShine",
+ "MiniMapTrackingDropDown",
+ "MiniMapTrackingDropDownButton",
+ "MiniMapTrackingDropDownButtonDisabledTexture",
+ "MiniMapTrackingDropDownButtonHighlightTexture",
+ "MiniMapTrackingDropDownButtonNormalTexture",
+ "MiniMapTrackingDropDownButtonPushedTexture",
+ "MiniMapTrackingDropDownLeft",
+ "MiniMapTrackingDropDownMiddle",
+ "MiniMapTrackingDropDownRight",
+ "MiniMapTrackingDropDownText",
+ "MiniMapTrackingDropDown_Initialize",
+ "MiniMapTrackingDropDown_OnLoad",
+ "MiniMapTrackingIcon",
+ "MiniMapTrackingIconOverlay",
+ "MiniMapTrackingShineFadeIn",
+ "MiniMapTrackingShineFadeOut",
+ "MiniMapTracking_SetTracking",
+ "MiniMapTracking_Update",
+ "MiniMapVoiceChatDropDown",
+ "MiniMapVoiceChatDropDownButton",
+ "MiniMapVoiceChatDropDownButtonDisabledTexture",
+ "MiniMapVoiceChatDropDownButtonHighlightTexture",
+ "MiniMapVoiceChatDropDownButtonNormalTexture",
+ "MiniMapVoiceChatDropDownButtonPushedTexture",
+ "MiniMapVoiceChatDropDownLeft",
+ "MiniMapVoiceChatDropDownMiddle",
+ "MiniMapVoiceChatDropDownRight",
+ "MiniMapVoiceChatDropDownText",
+ "MiniMapVoiceChatDropDown_Initialize",
+ "MiniMapVoiceChatDropDown_OnLoad",
+ "MiniMapVoiceChatFrame",
+ "MiniMapVoiceChatFrameBackground",
+ "MiniMapVoiceChatFrameBorder",
+ "MiniMapVoiceChatFrameIcon",
+ "MiniMapVoiceChatFrameIconMuted",
+ "MiniMapVoiceChat_Update",
+ "MiniMapWorldBorder",
+ "MiniMapWorldIcon",
+ "MiniMapWorldMapButton",
+ "MiniMapWorldMapButtonIcon",
+ "Minimap",
+ "MinimapBackdrop",
+ "MinimapBorder",
+ "MinimapBorderTop",
+ "MinimapButton_OnMouseDown",
+ "MinimapButton_OnMouseUp",
+ "MinimapCluster",
+ "MinimapCompassTexture",
+ "MinimapMailFrameUpdate",
+ "MinimapNorthTag",
+ "MinimapPing",
+ "MinimapPingCenter",
+ "MinimapPingExpander",
+ "MinimapPingSpinner",
+ "MinimapPing_FadeOut",
+ "MinimapPing_OnEvent",
+ "MinimapPing_OnLoad",
+ "MinimapPing_OnUpdate",
+ "MinimapZoneText",
+ "MinimapZoneTextButton",
+ "MinimapZoomIn",
+ "MinimapZoomOut",
+ "Minimap_OnClick",
+ "Minimap_SetPing",
+ "Minimap_SetTooltip",
+ "Minimap_Update",
+ "Minimap_UpdateRotationSetting",
+ "Minimap_ZoomIn",
+ "Minimap_ZoomInClick",
+ "Minimap_ZoomOut",
+ "Minimap_ZoomOutClick",
+ "MirrorTimer1",
+ "MirrorTimer1Border",
+ "MirrorTimer1StatusBar",
+ "MirrorTimer1Text",
+ "MirrorTimer2",
+ "MirrorTimer2Border",
+ "MirrorTimer2StatusBar",
+ "MirrorTimer2Text",
+ "MirrorTimer3",
+ "MirrorTimer3Border",
+ "MirrorTimer3StatusBar",
+ "MirrorTimer3Text",
+ "MirrorTimerColors",
+ "MirrorTimerFrame_OnEvent",
+ "MirrorTimerFrame_OnLoad",
+ "MirrorTimerFrame_OnUpdate",
+ "MirrorTimer_Show",
+ "Model_OnLoad",
+ "Model_OnUpdate",
+ "Model_RotateLeft",
+ "Model_RotateRight",
+ "MoneyFrame_OnEvent",
+ "MoneyFrame_OnLoad",
+ "MoneyFrame_SetType",
+ "MoneyFrame_Update",
+ "MoneyFrame_UpdateMoney",
+ "MoneyInputFrame_ClearFocus",
+ "MoneyInputFrame_GetCopper",
+ "MoneyInputFrame_OnShow",
+ "MoneyInputFrame_OnTextChanged",
+ "MoneyInputFrame_ResetMoney",
+ "MoneyInputFrame_SetCopper",
+ "MoneyInputFrame_SetMode",
+ "MoneyInputFrame_SetNextFocus",
+ "MoneyInputFrame_SetOnValueChangedFunc",
+ "MoneyInputFrame_SetPreviousFocus",
+ "MoneyInputFrame_SetTextColor",
+ "MoneyTypeInfo",
+ "MouseIsOver",
+ "MousePanelOptions",
+ "MouselookStart",
+ "MouselookStop",
+ "MoveAndSteerStart",
+ "MoveAndSteerStop",
+ "MoveBackwardStart",
+ "MoveBackwardStop",
+ "MoveForwardStart",
+ "MoveForwardStop",
+ "MoveViewDownStart",
+ "MoveViewDownStop",
+ "MoveViewInStart",
+ "MoveViewInStop",
+ "MoveViewLeftStart",
+ "MoveViewLeftStop",
+ "MoveViewOutStart",
+ "MoveViewOutStop",
+ "MoveViewRightStart",
+ "MoveViewRightStop",
+ "MoveViewUpStart",
+ "MoveViewUpStop",
+ "MovieFrame",
+ "MovieFrameSubtitleString",
+ "MovieFrame_OnEvent",
+ "MovieFrame_OnHide",
+ "MovieFrame_OnKeyUp",
+ "MovieFrame_OnLoad",
+ "MovieFrame_OnMovieFinished",
+ "MovieFrame_OnMovieHideSubtitle",
+ "MovieFrame_OnMovieShowSubtitle",
+ "MovieFrame_OnShow",
+ "MovieFrame_OnUpdate",
+ "MovieFrame_PlayMovie",
+ "MovieProgressBar",
+ "MovieProgressBarText",
+ "MovieProgressFrame",
+ "MovieRecordingCancelButton",
+ "MovieRecordingFrameTextTooltip1",
+ "MovieRecordingFrameTextTooltip2",
+ "MovieRecordingProgress_OnUpdate",
+ "MovieSubtitleFont",
+ "MultiActionBarFrame_OnLoad",
+ "MultiActionBar_HideAllGrids",
+ "MultiActionBar_ShowAllGrids",
+ "MultiActionBar_Update",
+ "MultiActionBar_UpdateGrid",
+ "MultiActionBar_UpdateGridVisibility",
+ "MultiActionButtonDown",
+ "MultiActionButtonUp",
+ "MultiBar1_IsVisible",
+ "MultiBar2_IsVisible",
+ "MultiBar3_IsVisible",
+ "MultiBar4_IsVisible",
+ "MultiBarBottomLeft",
+ "MultiBarBottomLeftButton1",
+ "MultiBarBottomLeftButton10",
+ "MultiBarBottomLeftButton10Border",
+ "MultiBarBottomLeftButton10Cooldown",
+ "MultiBarBottomLeftButton10Count",
+ "MultiBarBottomLeftButton10Flash",
+ "MultiBarBottomLeftButton10HotKey",
+ "MultiBarBottomLeftButton10Icon",
+ "MultiBarBottomLeftButton10Name",
+ "MultiBarBottomLeftButton10NormalTexture",
+ "MultiBarBottomLeftButton11",
+ "MultiBarBottomLeftButton11Border",
+ "MultiBarBottomLeftButton11Cooldown",
+ "MultiBarBottomLeftButton11Count",
+ "MultiBarBottomLeftButton11Flash",
+ "MultiBarBottomLeftButton11HotKey",
+ "MultiBarBottomLeftButton11Icon",
+ "MultiBarBottomLeftButton11Name",
+ "MultiBarBottomLeftButton11NormalTexture",
+ "MultiBarBottomLeftButton12",
+ "MultiBarBottomLeftButton12Border",
+ "MultiBarBottomLeftButton12Cooldown",
+ "MultiBarBottomLeftButton12Count",
+ "MultiBarBottomLeftButton12Flash",
+ "MultiBarBottomLeftButton12HotKey",
+ "MultiBarBottomLeftButton12Icon",
+ "MultiBarBottomLeftButton12Name",
+ "MultiBarBottomLeftButton12NormalTexture",
+ "MultiBarBottomLeftButton1Border",
+ "MultiBarBottomLeftButton1Cooldown",
+ "MultiBarBottomLeftButton1Count",
+ "MultiBarBottomLeftButton1Flash",
+ "MultiBarBottomLeftButton1HotKey",
+ "MultiBarBottomLeftButton1Icon",
+ "MultiBarBottomLeftButton1Name",
+ "MultiBarBottomLeftButton1NormalTexture",
+ "MultiBarBottomLeftButton2",
+ "MultiBarBottomLeftButton2Border",
+ "MultiBarBottomLeftButton2Cooldown",
+ "MultiBarBottomLeftButton2Count",
+ "MultiBarBottomLeftButton2Flash",
+ "MultiBarBottomLeftButton2HotKey",
+ "MultiBarBottomLeftButton2Icon",
+ "MultiBarBottomLeftButton2Name",
+ "MultiBarBottomLeftButton2NormalTexture",
+ "MultiBarBottomLeftButton3",
+ "MultiBarBottomLeftButton3Border",
+ "MultiBarBottomLeftButton3Cooldown",
+ "MultiBarBottomLeftButton3Count",
+ "MultiBarBottomLeftButton3Flash",
+ "MultiBarBottomLeftButton3HotKey",
+ "MultiBarBottomLeftButton3Icon",
+ "MultiBarBottomLeftButton3Name",
+ "MultiBarBottomLeftButton3NormalTexture",
+ "MultiBarBottomLeftButton4",
+ "MultiBarBottomLeftButton4Border",
+ "MultiBarBottomLeftButton4Cooldown",
+ "MultiBarBottomLeftButton4Count",
+ "MultiBarBottomLeftButton4Flash",
+ "MultiBarBottomLeftButton4HotKey",
+ "MultiBarBottomLeftButton4Icon",
+ "MultiBarBottomLeftButton4Name",
+ "MultiBarBottomLeftButton4NormalTexture",
+ "MultiBarBottomLeftButton5",
+ "MultiBarBottomLeftButton5Border",
+ "MultiBarBottomLeftButton5Cooldown",
+ "MultiBarBottomLeftButton5Count",
+ "MultiBarBottomLeftButton5Flash",
+ "MultiBarBottomLeftButton5HotKey",
+ "MultiBarBottomLeftButton5Icon",
+ "MultiBarBottomLeftButton5Name",
+ "MultiBarBottomLeftButton5NormalTexture",
+ "MultiBarBottomLeftButton6",
+ "MultiBarBottomLeftButton6Border",
+ "MultiBarBottomLeftButton6Cooldown",
+ "MultiBarBottomLeftButton6Count",
+ "MultiBarBottomLeftButton6Flash",
+ "MultiBarBottomLeftButton6HotKey",
+ "MultiBarBottomLeftButton6Icon",
+ "MultiBarBottomLeftButton6Name",
+ "MultiBarBottomLeftButton6NormalTexture",
+ "MultiBarBottomLeftButton7",
+ "MultiBarBottomLeftButton7Border",
+ "MultiBarBottomLeftButton7Cooldown",
+ "MultiBarBottomLeftButton7Count",
+ "MultiBarBottomLeftButton7Flash",
+ "MultiBarBottomLeftButton7HotKey",
+ "MultiBarBottomLeftButton7Icon",
+ "MultiBarBottomLeftButton7Name",
+ "MultiBarBottomLeftButton7NormalTexture",
+ "MultiBarBottomLeftButton8",
+ "MultiBarBottomLeftButton8Border",
+ "MultiBarBottomLeftButton8Cooldown",
+ "MultiBarBottomLeftButton8Count",
+ "MultiBarBottomLeftButton8Flash",
+ "MultiBarBottomLeftButton8HotKey",
+ "MultiBarBottomLeftButton8Icon",
+ "MultiBarBottomLeftButton8Name",
+ "MultiBarBottomLeftButton8NormalTexture",
+ "MultiBarBottomLeftButton9",
+ "MultiBarBottomLeftButton9Border",
+ "MultiBarBottomLeftButton9Cooldown",
+ "MultiBarBottomLeftButton9Count",
+ "MultiBarBottomLeftButton9Flash",
+ "MultiBarBottomLeftButton9HotKey",
+ "MultiBarBottomLeftButton9Icon",
+ "MultiBarBottomLeftButton9Name",
+ "MultiBarBottomLeftButton9NormalTexture",
+ "MultiBarBottomRight",
+ "MultiBarBottomRightButton1",
+ "MultiBarBottomRightButton10",
+ "MultiBarBottomRightButton10Border",
+ "MultiBarBottomRightButton10Cooldown",
+ "MultiBarBottomRightButton10Count",
+ "MultiBarBottomRightButton10Flash",
+ "MultiBarBottomRightButton10HotKey",
+ "MultiBarBottomRightButton10Icon",
+ "MultiBarBottomRightButton10Name",
+ "MultiBarBottomRightButton10NormalTexture",
+ "MultiBarBottomRightButton11",
+ "MultiBarBottomRightButton11Border",
+ "MultiBarBottomRightButton11Cooldown",
+ "MultiBarBottomRightButton11Count",
+ "MultiBarBottomRightButton11Flash",
+ "MultiBarBottomRightButton11HotKey",
+ "MultiBarBottomRightButton11Icon",
+ "MultiBarBottomRightButton11Name",
+ "MultiBarBottomRightButton11NormalTexture",
+ "MultiBarBottomRightButton12",
+ "MultiBarBottomRightButton12Border",
+ "MultiBarBottomRightButton12Cooldown",
+ "MultiBarBottomRightButton12Count",
+ "MultiBarBottomRightButton12Flash",
+ "MultiBarBottomRightButton12HotKey",
+ "MultiBarBottomRightButton12Icon",
+ "MultiBarBottomRightButton12Name",
+ "MultiBarBottomRightButton12NormalTexture",
+ "MultiBarBottomRightButton1Border",
+ "MultiBarBottomRightButton1Cooldown",
+ "MultiBarBottomRightButton1Count",
+ "MultiBarBottomRightButton1Flash",
+ "MultiBarBottomRightButton1HotKey",
+ "MultiBarBottomRightButton1Icon",
+ "MultiBarBottomRightButton1Name",
+ "MultiBarBottomRightButton1NormalTexture",
+ "MultiBarBottomRightButton2",
+ "MultiBarBottomRightButton2Border",
+ "MultiBarBottomRightButton2Cooldown",
+ "MultiBarBottomRightButton2Count",
+ "MultiBarBottomRightButton2Flash",
+ "MultiBarBottomRightButton2HotKey",
+ "MultiBarBottomRightButton2Icon",
+ "MultiBarBottomRightButton2Name",
+ "MultiBarBottomRightButton2NormalTexture",
+ "MultiBarBottomRightButton3",
+ "MultiBarBottomRightButton3Border",
+ "MultiBarBottomRightButton3Cooldown",
+ "MultiBarBottomRightButton3Count",
+ "MultiBarBottomRightButton3Flash",
+ "MultiBarBottomRightButton3HotKey",
+ "MultiBarBottomRightButton3Icon",
+ "MultiBarBottomRightButton3Name",
+ "MultiBarBottomRightButton3NormalTexture",
+ "MultiBarBottomRightButton4",
+ "MultiBarBottomRightButton4Border",
+ "MultiBarBottomRightButton4Cooldown",
+ "MultiBarBottomRightButton4Count",
+ "MultiBarBottomRightButton4Flash",
+ "MultiBarBottomRightButton4HotKey",
+ "MultiBarBottomRightButton4Icon",
+ "MultiBarBottomRightButton4Name",
+ "MultiBarBottomRightButton4NormalTexture",
+ "MultiBarBottomRightButton5",
+ "MultiBarBottomRightButton5Border",
+ "MultiBarBottomRightButton5Cooldown",
+ "MultiBarBottomRightButton5Count",
+ "MultiBarBottomRightButton5Flash",
+ "MultiBarBottomRightButton5HotKey",
+ "MultiBarBottomRightButton5Icon",
+ "MultiBarBottomRightButton5Name",
+ "MultiBarBottomRightButton5NormalTexture",
+ "MultiBarBottomRightButton6",
+ "MultiBarBottomRightButton6Border",
+ "MultiBarBottomRightButton6Cooldown",
+ "MultiBarBottomRightButton6Count",
+ "MultiBarBottomRightButton6Flash",
+ "MultiBarBottomRightButton6HotKey",
+ "MultiBarBottomRightButton6Icon",
+ "MultiBarBottomRightButton6Name",
+ "MultiBarBottomRightButton6NormalTexture",
+ "MultiBarBottomRightButton7",
+ "MultiBarBottomRightButton7Border",
+ "MultiBarBottomRightButton7Cooldown",
+ "MultiBarBottomRightButton7Count",
+ "MultiBarBottomRightButton7Flash",
+ "MultiBarBottomRightButton7HotKey",
+ "MultiBarBottomRightButton7Icon",
+ "MultiBarBottomRightButton7Name",
+ "MultiBarBottomRightButton7NormalTexture",
+ "MultiBarBottomRightButton8",
+ "MultiBarBottomRightButton8Border",
+ "MultiBarBottomRightButton8Cooldown",
+ "MultiBarBottomRightButton8Count",
+ "MultiBarBottomRightButton8Flash",
+ "MultiBarBottomRightButton8HotKey",
+ "MultiBarBottomRightButton8Icon",
+ "MultiBarBottomRightButton8Name",
+ "MultiBarBottomRightButton8NormalTexture",
+ "MultiBarBottomRightButton9",
+ "MultiBarBottomRightButton9Border",
+ "MultiBarBottomRightButton9Cooldown",
+ "MultiBarBottomRightButton9Count",
+ "MultiBarBottomRightButton9Flash",
+ "MultiBarBottomRightButton9HotKey",
+ "MultiBarBottomRightButton9Icon",
+ "MultiBarBottomRightButton9Name",
+ "MultiBarBottomRightButton9NormalTexture",
+ "MultiBarLeft",
+ "MultiBarLeftButton1",
+ "MultiBarLeftButton10",
+ "MultiBarLeftButton10Border",
+ "MultiBarLeftButton10Cooldown",
+ "MultiBarLeftButton10Count",
+ "MultiBarLeftButton10Flash",
+ "MultiBarLeftButton10HotKey",
+ "MultiBarLeftButton10Icon",
+ "MultiBarLeftButton10Name",
+ "MultiBarLeftButton10NormalTexture",
+ "MultiBarLeftButton11",
+ "MultiBarLeftButton11Border",
+ "MultiBarLeftButton11Cooldown",
+ "MultiBarLeftButton11Count",
+ "MultiBarLeftButton11Flash",
+ "MultiBarLeftButton11HotKey",
+ "MultiBarLeftButton11Icon",
+ "MultiBarLeftButton11Name",
+ "MultiBarLeftButton11NormalTexture",
+ "MultiBarLeftButton12",
+ "MultiBarLeftButton12Border",
+ "MultiBarLeftButton12Cooldown",
+ "MultiBarLeftButton12Count",
+ "MultiBarLeftButton12Flash",
+ "MultiBarLeftButton12HotKey",
+ "MultiBarLeftButton12Icon",
+ "MultiBarLeftButton12Name",
+ "MultiBarLeftButton12NormalTexture",
+ "MultiBarLeftButton1Border",
+ "MultiBarLeftButton1Cooldown",
+ "MultiBarLeftButton1Count",
+ "MultiBarLeftButton1Flash",
+ "MultiBarLeftButton1HotKey",
+ "MultiBarLeftButton1Icon",
+ "MultiBarLeftButton1Name",
+ "MultiBarLeftButton1NormalTexture",
+ "MultiBarLeftButton2",
+ "MultiBarLeftButton2Border",
+ "MultiBarLeftButton2Cooldown",
+ "MultiBarLeftButton2Count",
+ "MultiBarLeftButton2Flash",
+ "MultiBarLeftButton2HotKey",
+ "MultiBarLeftButton2Icon",
+ "MultiBarLeftButton2Name",
+ "MultiBarLeftButton2NormalTexture",
+ "MultiBarLeftButton3",
+ "MultiBarLeftButton3Border",
+ "MultiBarLeftButton3Cooldown",
+ "MultiBarLeftButton3Count",
+ "MultiBarLeftButton3Flash",
+ "MultiBarLeftButton3HotKey",
+ "MultiBarLeftButton3Icon",
+ "MultiBarLeftButton3Name",
+ "MultiBarLeftButton3NormalTexture",
+ "MultiBarLeftButton4",
+ "MultiBarLeftButton4Border",
+ "MultiBarLeftButton4Cooldown",
+ "MultiBarLeftButton4Count",
+ "MultiBarLeftButton4Flash",
+ "MultiBarLeftButton4HotKey",
+ "MultiBarLeftButton4Icon",
+ "MultiBarLeftButton4Name",
+ "MultiBarLeftButton4NormalTexture",
+ "MultiBarLeftButton5",
+ "MultiBarLeftButton5Border",
+ "MultiBarLeftButton5Cooldown",
+ "MultiBarLeftButton5Count",
+ "MultiBarLeftButton5Flash",
+ "MultiBarLeftButton5HotKey",
+ "MultiBarLeftButton5Icon",
+ "MultiBarLeftButton5Name",
+ "MultiBarLeftButton5NormalTexture",
+ "MultiBarLeftButton6",
+ "MultiBarLeftButton6Border",
+ "MultiBarLeftButton6Cooldown",
+ "MultiBarLeftButton6Count",
+ "MultiBarLeftButton6Flash",
+ "MultiBarLeftButton6HotKey",
+ "MultiBarLeftButton6Icon",
+ "MultiBarLeftButton6Name",
+ "MultiBarLeftButton6NormalTexture",
+ "MultiBarLeftButton7",
+ "MultiBarLeftButton7Border",
+ "MultiBarLeftButton7Cooldown",
+ "MultiBarLeftButton7Count",
+ "MultiBarLeftButton7Flash",
+ "MultiBarLeftButton7HotKey",
+ "MultiBarLeftButton7Icon",
+ "MultiBarLeftButton7Name",
+ "MultiBarLeftButton7NormalTexture",
+ "MultiBarLeftButton8",
+ "MultiBarLeftButton8Border",
+ "MultiBarLeftButton8Cooldown",
+ "MultiBarLeftButton8Count",
+ "MultiBarLeftButton8Flash",
+ "MultiBarLeftButton8HotKey",
+ "MultiBarLeftButton8Icon",
+ "MultiBarLeftButton8Name",
+ "MultiBarLeftButton8NormalTexture",
+ "MultiBarLeftButton9",
+ "MultiBarLeftButton9Border",
+ "MultiBarLeftButton9Cooldown",
+ "MultiBarLeftButton9Count",
+ "MultiBarLeftButton9Flash",
+ "MultiBarLeftButton9HotKey",
+ "MultiBarLeftButton9Icon",
+ "MultiBarLeftButton9Name",
+ "MultiBarLeftButton9NormalTexture",
+ "MultiBarRight",
+ "MultiBarRightButton1",
+ "MultiBarRightButton10",
+ "MultiBarRightButton10Border",
+ "MultiBarRightButton10Cooldown",
+ "MultiBarRightButton10Count",
+ "MultiBarRightButton10Flash",
+ "MultiBarRightButton10HotKey",
+ "MultiBarRightButton10Icon",
+ "MultiBarRightButton10Name",
+ "MultiBarRightButton10NormalTexture",
+ "MultiBarRightButton11",
+ "MultiBarRightButton11Border",
+ "MultiBarRightButton11Cooldown",
+ "MultiBarRightButton11Count",
+ "MultiBarRightButton11Flash",
+ "MultiBarRightButton11HotKey",
+ "MultiBarRightButton11Icon",
+ "MultiBarRightButton11Name",
+ "MultiBarRightButton11NormalTexture",
+ "MultiBarRightButton12",
+ "MultiBarRightButton12Border",
+ "MultiBarRightButton12Cooldown",
+ "MultiBarRightButton12Count",
+ "MultiBarRightButton12Flash",
+ "MultiBarRightButton12HotKey",
+ "MultiBarRightButton12Icon",
+ "MultiBarRightButton12Name",
+ "MultiBarRightButton12NormalTexture",
+ "MultiBarRightButton1Border",
+ "MultiBarRightButton1Cooldown",
+ "MultiBarRightButton1Count",
+ "MultiBarRightButton1Flash",
+ "MultiBarRightButton1HotKey",
+ "MultiBarRightButton1Icon",
+ "MultiBarRightButton1Name",
+ "MultiBarRightButton1NormalTexture",
+ "MultiBarRightButton2",
+ "MultiBarRightButton2Border",
+ "MultiBarRightButton2Cooldown",
+ "MultiBarRightButton2Count",
+ "MultiBarRightButton2Flash",
+ "MultiBarRightButton2HotKey",
+ "MultiBarRightButton2Icon",
+ "MultiBarRightButton2Name",
+ "MultiBarRightButton2NormalTexture",
+ "MultiBarRightButton3",
+ "MultiBarRightButton3Border",
+ "MultiBarRightButton3Cooldown",
+ "MultiBarRightButton3Count",
+ "MultiBarRightButton3Flash",
+ "MultiBarRightButton3HotKey",
+ "MultiBarRightButton3Icon",
+ "MultiBarRightButton3Name",
+ "MultiBarRightButton3NormalTexture",
+ "MultiBarRightButton4",
+ "MultiBarRightButton4Border",
+ "MultiBarRightButton4Cooldown",
+ "MultiBarRightButton4Count",
+ "MultiBarRightButton4Flash",
+ "MultiBarRightButton4HotKey",
+ "MultiBarRightButton4Icon",
+ "MultiBarRightButton4Name",
+ "MultiBarRightButton4NormalTexture",
+ "MultiBarRightButton5",
+ "MultiBarRightButton5Border",
+ "MultiBarRightButton5Cooldown",
+ "MultiBarRightButton5Count",
+ "MultiBarRightButton5Flash",
+ "MultiBarRightButton5HotKey",
+ "MultiBarRightButton5Icon",
+ "MultiBarRightButton5Name",
+ "MultiBarRightButton5NormalTexture",
+ "MultiBarRightButton6",
+ "MultiBarRightButton6Border",
+ "MultiBarRightButton6Cooldown",
+ "MultiBarRightButton6Count",
+ "MultiBarRightButton6Flash",
+ "MultiBarRightButton6HotKey",
+ "MultiBarRightButton6Icon",
+ "MultiBarRightButton6Name",
+ "MultiBarRightButton6NormalTexture",
+ "MultiBarRightButton7",
+ "MultiBarRightButton7Border",
+ "MultiBarRightButton7Cooldown",
+ "MultiBarRightButton7Count",
+ "MultiBarRightButton7Flash",
+ "MultiBarRightButton7HotKey",
+ "MultiBarRightButton7Icon",
+ "MultiBarRightButton7Name",
+ "MultiBarRightButton7NormalTexture",
+ "MultiBarRightButton8",
+ "MultiBarRightButton8Border",
+ "MultiBarRightButton8Cooldown",
+ "MultiBarRightButton8Count",
+ "MultiBarRightButton8Flash",
+ "MultiBarRightButton8HotKey",
+ "MultiBarRightButton8Icon",
+ "MultiBarRightButton8Name",
+ "MultiBarRightButton8NormalTexture",
+ "MultiBarRightButton9",
+ "MultiBarRightButton9Border",
+ "MultiBarRightButton9Cooldown",
+ "MultiBarRightButton9Count",
+ "MultiBarRightButton9Flash",
+ "MultiBarRightButton9HotKey",
+ "MultiBarRightButton9Icon",
+ "MultiBarRightButton9Name",
+ "MultiBarRightButton9NormalTexture",
+ "MultiCastActionBarFrame",
+ "MultiCastActionBarFrame_OnEvent",
+ "MultiCastActionBarFrame_OnLoad",
+ "MultiCastActionBarFrame_OnUpdate",
+ "MultiCastActionBarFrame_Update",
+ "MultiCastActionButton1",
+ "MultiCastActionButton10",
+ "MultiCastActionButton10Border",
+ "MultiCastActionButton10Cooldown",
+ "MultiCastActionButton10Count",
+ "MultiCastActionButton10Flash",
+ "MultiCastActionButton10HotKey",
+ "MultiCastActionButton10Icon",
+ "MultiCastActionButton10Name",
+ "MultiCastActionButton10NormalTexture",
+ "MultiCastActionButton11",
+ "MultiCastActionButton11Border",
+ "MultiCastActionButton11Cooldown",
+ "MultiCastActionButton11Count",
+ "MultiCastActionButton11Flash",
+ "MultiCastActionButton11HotKey",
+ "MultiCastActionButton11Icon",
+ "MultiCastActionButton11Name",
+ "MultiCastActionButton11NormalTexture",
+ "MultiCastActionButton12",
+ "MultiCastActionButton12Border",
+ "MultiCastActionButton12Cooldown",
+ "MultiCastActionButton12Count",
+ "MultiCastActionButton12Flash",
+ "MultiCastActionButton12HotKey",
+ "MultiCastActionButton12Icon",
+ "MultiCastActionButton12Name",
+ "MultiCastActionButton12NormalTexture",
+ "MultiCastActionButton1Border",
+ "MultiCastActionButton1Cooldown",
+ "MultiCastActionButton1Count",
+ "MultiCastActionButton1Flash",
+ "MultiCastActionButton1HotKey",
+ "MultiCastActionButton1Icon",
+ "MultiCastActionButton1Name",
+ "MultiCastActionButton1NormalTexture",
+ "MultiCastActionButton2",
+ "MultiCastActionButton2Border",
+ "MultiCastActionButton2Cooldown",
+ "MultiCastActionButton2Count",
+ "MultiCastActionButton2Flash",
+ "MultiCastActionButton2HotKey",
+ "MultiCastActionButton2Icon",
+ "MultiCastActionButton2Name",
+ "MultiCastActionButton2NormalTexture",
+ "MultiCastActionButton3",
+ "MultiCastActionButton3Border",
+ "MultiCastActionButton3Cooldown",
+ "MultiCastActionButton3Count",
+ "MultiCastActionButton3Flash",
+ "MultiCastActionButton3HotKey",
+ "MultiCastActionButton3Icon",
+ "MultiCastActionButton3Name",
+ "MultiCastActionButton3NormalTexture",
+ "MultiCastActionButton4",
+ "MultiCastActionButton4Border",
+ "MultiCastActionButton4Cooldown",
+ "MultiCastActionButton4Count",
+ "MultiCastActionButton4Flash",
+ "MultiCastActionButton4HotKey",
+ "MultiCastActionButton4Icon",
+ "MultiCastActionButton4Name",
+ "MultiCastActionButton4NormalTexture",
+ "MultiCastActionButton5",
+ "MultiCastActionButton5Border",
+ "MultiCastActionButton5Cooldown",
+ "MultiCastActionButton5Count",
+ "MultiCastActionButton5Flash",
+ "MultiCastActionButton5HotKey",
+ "MultiCastActionButton5Icon",
+ "MultiCastActionButton5Name",
+ "MultiCastActionButton5NormalTexture",
+ "MultiCastActionButton6",
+ "MultiCastActionButton6Border",
+ "MultiCastActionButton6Cooldown",
+ "MultiCastActionButton6Count",
+ "MultiCastActionButton6Flash",
+ "MultiCastActionButton6HotKey",
+ "MultiCastActionButton6Icon",
+ "MultiCastActionButton6Name",
+ "MultiCastActionButton6NormalTexture",
+ "MultiCastActionButton7",
+ "MultiCastActionButton7Border",
+ "MultiCastActionButton7Cooldown",
+ "MultiCastActionButton7Count",
+ "MultiCastActionButton7Flash",
+ "MultiCastActionButton7HotKey",
+ "MultiCastActionButton7Icon",
+ "MultiCastActionButton7Name",
+ "MultiCastActionButton7NormalTexture",
+ "MultiCastActionButton8",
+ "MultiCastActionButton8Border",
+ "MultiCastActionButton8Cooldown",
+ "MultiCastActionButton8Count",
+ "MultiCastActionButton8Flash",
+ "MultiCastActionButton8HotKey",
+ "MultiCastActionButton8Icon",
+ "MultiCastActionButton8Name",
+ "MultiCastActionButton8NormalTexture",
+ "MultiCastActionButton9",
+ "MultiCastActionButton9Border",
+ "MultiCastActionButton9Cooldown",
+ "MultiCastActionButton9Count",
+ "MultiCastActionButton9Flash",
+ "MultiCastActionButton9HotKey",
+ "MultiCastActionButton9Icon",
+ "MultiCastActionButton9Name",
+ "MultiCastActionButton9NormalTexture",
+ "MultiCastActionButtonDown",
+ "MultiCastActionButtonUp",
+ "MultiCastActionButton_OnEnter",
+ "MultiCastActionButton_OnEvent",
+ "MultiCastActionButton_OnLeave",
+ "MultiCastActionButton_OnLoad",
+ "MultiCastActionButton_OnPostClick",
+ "MultiCastActionButton_OnShow",
+ "MultiCastActionButton_Update",
+ "MultiCastActionPage1",
+ "MultiCastActionPage2",
+ "MultiCastActionPage3",
+ "MultiCastFlyoutButton_OnClick",
+ "MultiCastFlyoutButton_OnEnter",
+ "MultiCastFlyoutButton_OnLeave",
+ "MultiCastFlyoutButton_OnLoad",
+ "MultiCastFlyoutButton_SetTooltip",
+ "MultiCastFlyoutFrame",
+ "MultiCastFlyoutFrameCloseButton",
+ "MultiCastFlyoutFrameCloseButton_OnClick",
+ "MultiCastFlyoutFrameMiddle",
+ "MultiCastFlyoutFrameOpenButton",
+ "MultiCastFlyoutFrameOpenButton_Hide",
+ "MultiCastFlyoutFrameOpenButton_OnClick",
+ "MultiCastFlyoutFrameOpenButton_OnLeave",
+ "MultiCastFlyoutFrameOpenButton_Show",
+ "MultiCastFlyoutFrameTop",
+ "MultiCastFlyoutFrame_Hide",
+ "MultiCastFlyoutFrame_LoadPageSpells",
+ "MultiCastFlyoutFrame_LoadSlotSpells",
+ "MultiCastFlyoutFrame_OnEnter",
+ "MultiCastFlyoutFrame_OnHide",
+ "MultiCastFlyoutFrame_OnLeave",
+ "MultiCastFlyoutFrame_OnShow",
+ "MultiCastFlyoutFrame_OnUpdate",
+ "MultiCastFlyoutFrame_ToggleFlyout",
+ "MultiCastRecallSpellButton",
+ "MultiCastRecallSpellButtonBorder",
+ "MultiCastRecallSpellButtonCooldown",
+ "MultiCastRecallSpellButtonCount",
+ "MultiCastRecallSpellButtonFlash",
+ "MultiCastRecallSpellButtonHighlight",
+ "MultiCastRecallSpellButtonHotKey",
+ "MultiCastRecallSpellButtonIcon",
+ "MultiCastRecallSpellButtonName",
+ "MultiCastRecallSpellButtonNormalTexture",
+ "MultiCastRecallSpellButtonUp",
+ "MultiCastRecallSpellButton_OnClick",
+ "MultiCastRecallSpellButton_OnLoad",
+ "MultiCastRecallSpellButton_Update",
+ "MultiCastSlotButton1",
+ "MultiCastSlotButton2",
+ "MultiCastSlotButton3",
+ "MultiCastSlotButton4",
+ "MultiCastSlotButton_OnEnter",
+ "MultiCastSlotButton_OnEvent",
+ "MultiCastSlotButton_OnLeave",
+ "MultiCastSlotButton_Update",
+ "MultiCastSpellButton_OnEnter",
+ "MultiCastSpellButton_OnEvent",
+ "MultiCastSpellButton_OnLeave",
+ "MultiCastSpellButton_OnLoad",
+ "MultiCastSpellButton_SetTooltip",
+ "MultiCastSpellButton_UpdateCooldown",
+ "MultiCastSpellButton_UpdateState",
+ "MultiCastSummonSpellButton",
+ "MultiCastSummonSpellButtonBorder",
+ "MultiCastSummonSpellButtonCooldown",
+ "MultiCastSummonSpellButtonCount",
+ "MultiCastSummonSpellButtonFlash",
+ "MultiCastSummonSpellButtonFlyoutButton",
+ "MultiCastSummonSpellButtonHighlight",
+ "MultiCastSummonSpellButtonHotKey",
+ "MultiCastSummonSpellButtonIcon",
+ "MultiCastSummonSpellButtonName",
+ "MultiCastSummonSpellButtonNormalTexture",
+ "MultiCastSummonSpellButtonUp",
+ "MultiCastSummonSpellButton_OnClick",
+ "MultiCastSummonSpellButton_OnEnter",
+ "MultiCastSummonSpellButton_OnEvent",
+ "MultiCastSummonSpellButton_OnLeave",
+ "MultiCastSummonSpellButton_OnLoad",
+ "MultiCastSummonSpellButton_Update",
+ "MultibarGrid_IsVisible",
+ "Multibar_EmptyFunc",
+ "NORMAL_FONT_COLOR",
+ "NamePanelOptions",
+ "NewGMTicket",
+ "NextView",
+ "NoPlayTime",
+ "NotWhileDeadError",
+ "NotifyInspect",
+ "NumTaxiNodes",
+ "NumberFontNormal",
+ "NumberFontNormalHuge",
+ "NumberFontNormalLarge",
+ "NumberFontNormalLargeRight",
+ "NumberFontNormalLargeRightRed",
+ "NumberFontNormalLargeRightYellow",
+ "NumberFontNormalLargeYellow",
+ "NumberFontNormalRight",
+ "NumberFontNormalRightRed",
+ "NumberFontNormalRightYellow",
+ "NumberFontNormalSmall",
+ "NumberFontNormalSmallGray",
+ "NumberFontNormalYellow",
+ "NumberFont_OutlineThick_Mono_Small",
+ "NumberFont_Outline_Huge",
+ "NumberFont_Outline_Large",
+ "NumberFont_Outline_Med",
+ "NumberFont_Shadow_Med",
+ "NumberFont_Shadow_Small",
+ "OPEN_DROPDOWNMENUS",
+ "OPEN_FILTER_LIST",
+ "ORANGE_FONT_COLOR",
+ "ObjectPoolMixin",
+ "ObjectivesPanelOptions",
+ "OfferPetition",
+ "OffhandHasWeapon",
+ "OfficerNoteText",
+ "OnMenuLoad",
+ "OpacityFrame",
+ "OpacityFrameCloseButton",
+ "OpacityFrameSlider",
+ "OpacityFrameSliderText",
+ "OpacitySliderFrame",
+ "OpacitySliderFrameText",
+ "OpenAllBags",
+ "OpenBackpack",
+ "OpenBag",
+ "OpenCalendar",
+ "OpenCoinPickupFrame",
+ "OpenColorPicker",
+ "OpenGlyphFrame",
+ "OpenMailArithmeticLine",
+ "OpenMailAttachmentButton1",
+ "OpenMailAttachmentButton10",
+ "OpenMailAttachmentButton10Count",
+ "OpenMailAttachmentButton10IconTexture",
+ "OpenMailAttachmentButton10NormalTexture",
+ "OpenMailAttachmentButton10Stock",
+ "OpenMailAttachmentButton11",
+ "OpenMailAttachmentButton11Count",
+ "OpenMailAttachmentButton11IconTexture",
+ "OpenMailAttachmentButton11NormalTexture",
+ "OpenMailAttachmentButton11Stock",
+ "OpenMailAttachmentButton12",
+ "OpenMailAttachmentButton12Count",
+ "OpenMailAttachmentButton12IconTexture",
+ "OpenMailAttachmentButton12NormalTexture",
+ "OpenMailAttachmentButton12Stock",
+ "OpenMailAttachmentButton13",
+ "OpenMailAttachmentButton13Count",
+ "OpenMailAttachmentButton13IconTexture",
+ "OpenMailAttachmentButton13NormalTexture",
+ "OpenMailAttachmentButton13Stock",
+ "OpenMailAttachmentButton14",
+ "OpenMailAttachmentButton14Count",
+ "OpenMailAttachmentButton14IconTexture",
+ "OpenMailAttachmentButton14NormalTexture",
+ "OpenMailAttachmentButton14Stock",
+ "OpenMailAttachmentButton15",
+ "OpenMailAttachmentButton15Count",
+ "OpenMailAttachmentButton15IconTexture",
+ "OpenMailAttachmentButton15NormalTexture",
+ "OpenMailAttachmentButton15Stock",
+ "OpenMailAttachmentButton16",
+ "OpenMailAttachmentButton16Count",
+ "OpenMailAttachmentButton16IconTexture",
+ "OpenMailAttachmentButton16NormalTexture",
+ "OpenMailAttachmentButton16Stock",
+ "OpenMailAttachmentButton1Count",
+ "OpenMailAttachmentButton1IconTexture",
+ "OpenMailAttachmentButton1NormalTexture",
+ "OpenMailAttachmentButton1Stock",
+ "OpenMailAttachmentButton2",
+ "OpenMailAttachmentButton2Count",
+ "OpenMailAttachmentButton2IconTexture",
+ "OpenMailAttachmentButton2NormalTexture",
+ "OpenMailAttachmentButton2Stock",
+ "OpenMailAttachmentButton3",
+ "OpenMailAttachmentButton3Count",
+ "OpenMailAttachmentButton3IconTexture",
+ "OpenMailAttachmentButton3NormalTexture",
+ "OpenMailAttachmentButton3Stock",
+ "OpenMailAttachmentButton4",
+ "OpenMailAttachmentButton4Count",
+ "OpenMailAttachmentButton4IconTexture",
+ "OpenMailAttachmentButton4NormalTexture",
+ "OpenMailAttachmentButton4Stock",
+ "OpenMailAttachmentButton5",
+ "OpenMailAttachmentButton5Count",
+ "OpenMailAttachmentButton5IconTexture",
+ "OpenMailAttachmentButton5NormalTexture",
+ "OpenMailAttachmentButton5Stock",
+ "OpenMailAttachmentButton6",
+ "OpenMailAttachmentButton6Count",
+ "OpenMailAttachmentButton6IconTexture",
+ "OpenMailAttachmentButton6NormalTexture",
+ "OpenMailAttachmentButton6Stock",
+ "OpenMailAttachmentButton7",
+ "OpenMailAttachmentButton7Count",
+ "OpenMailAttachmentButton7IconTexture",
+ "OpenMailAttachmentButton7NormalTexture",
+ "OpenMailAttachmentButton7Stock",
+ "OpenMailAttachmentButton8",
+ "OpenMailAttachmentButton8Count",
+ "OpenMailAttachmentButton8IconTexture",
+ "OpenMailAttachmentButton8NormalTexture",
+ "OpenMailAttachmentButton8Stock",
+ "OpenMailAttachmentButton9",
+ "OpenMailAttachmentButton9Count",
+ "OpenMailAttachmentButton9IconTexture",
+ "OpenMailAttachmentButton9NormalTexture",
+ "OpenMailAttachmentButton9Stock",
+ "OpenMailAttachmentText",
+ "OpenMailAttachment_OnClick",
+ "OpenMailAttachment_OnEnter",
+ "OpenMailBodyText",
+ "OpenMailCancelButton",
+ "OpenMailCancelButtonText",
+ "OpenMailCloseButton",
+ "OpenMailDeleteButton",
+ "OpenMailDeleteButtonText",
+ "OpenMailDepositMoneyFrame",
+ "OpenMailDepositMoneyFrameCopperButton",
+ "OpenMailDepositMoneyFrameCopperButtonText",
+ "OpenMailDepositMoneyFrameGoldButton",
+ "OpenMailDepositMoneyFrameGoldButtonText",
+ "OpenMailDepositMoneyFrameSilverButton",
+ "OpenMailDepositMoneyFrameSilverButtonText",
+ "OpenMailFrame",
+ "OpenMailFrameBotLeft",
+ "OpenMailFrameBotRight",
+ "OpenMailFrameIcon",
+ "OpenMailFrameTopLeft",
+ "OpenMailFrameTopRight",
+ "OpenMailFrame_OnHide",
+ "OpenMailFrame_UpdateButtonPositions",
+ "OpenMailHorizontalBarLeft",
+ "OpenMailHouseCutMoneyFrame",
+ "OpenMailHouseCutMoneyFrameCopperButton",
+ "OpenMailHouseCutMoneyFrameCopperButtonText",
+ "OpenMailHouseCutMoneyFrameGoldButton",
+ "OpenMailHouseCutMoneyFrameGoldButtonText",
+ "OpenMailHouseCutMoneyFrameSilverButton",
+ "OpenMailHouseCutMoneyFrameSilverButtonText",
+ "OpenMailInvoiceAmountReceived",
+ "OpenMailInvoiceBuyMode",
+ "OpenMailInvoiceDeposit",
+ "OpenMailInvoiceFrame",
+ "OpenMailInvoiceHouseCut",
+ "OpenMailInvoiceItemLabel",
+ "OpenMailInvoiceMoneyDelay",
+ "OpenMailInvoiceNotYetSent",
+ "OpenMailInvoicePurchaser",
+ "OpenMailInvoiceSalePrice",
+ "OpenMailLetterButton",
+ "OpenMailLetterButtonCount",
+ "OpenMailLetterButtonIconTexture",
+ "OpenMailLetterButtonNormalTexture",
+ "OpenMailLetterButtonStock",
+ "OpenMailMoneyButton",
+ "OpenMailMoneyButtonCount",
+ "OpenMailMoneyButtonIconTexture",
+ "OpenMailMoneyButtonNormalTexture",
+ "OpenMailMoneyButtonStock",
+ "OpenMailReplyButton",
+ "OpenMailReplyButtonText",
+ "OpenMailReportSpamButton",
+ "OpenMailReportSpamButtonText",
+ "OpenMailSalePriceMoneyFrame",
+ "OpenMailSalePriceMoneyFrameCopperButton",
+ "OpenMailSalePriceMoneyFrameCopperButtonText",
+ "OpenMailSalePriceMoneyFrameGoldButton",
+ "OpenMailSalePriceMoneyFrameGoldButtonText",
+ "OpenMailSalePriceMoneyFrameSilverButton",
+ "OpenMailSalePriceMoneyFrameSilverButtonText",
+ "OpenMailScrollChildFrame",
+ "OpenMailScrollFrame",
+ "OpenMailScrollFrameScrollBar",
+ "OpenMailScrollFrameScrollBarScrollDownButton",
+ "OpenMailScrollFrameScrollBarScrollUpButton",
+ "OpenMailScrollFrameScrollBarThumbTexture",
+ "OpenMailSender",
+ "OpenMailSenderLabel",
+ "OpenMailSubject",
+ "OpenMailSubjectLabel",
+ "OpenMailTitleText",
+ "OpenMailTransactionAmountMoneyFrame",
+ "OpenMailTransactionAmountMoneyFrameCopperButton",
+ "OpenMailTransactionAmountMoneyFrameCopperButtonText",
+ "OpenMailTransactionAmountMoneyFrameGoldButton",
+ "OpenMailTransactionAmountMoneyFrameGoldButtonText",
+ "OpenMailTransactionAmountMoneyFrameSilverButton",
+ "OpenMailTransactionAmountMoneyFrameSilverButtonText",
+ "OpenMail_Delete",
+ "OpenMail_GetItemCounts",
+ "OpenMail_Reply",
+ "OpenMail_ReportSpam",
+ "OpenMail_Update",
+ "OpenScrollBarBackgroundTop",
+ "OpenStackSplitFrame",
+ "OpenStationeryBackgroundLeft",
+ "OpenStationeryBackgroundRight",
+ "OpenTrainer",
+ "OpeningCinematic",
+ "OptionsCategoryFrame_Update",
+ "OptionsFrameCancel_OnClick",
+ "OptionsFrameDefault_OnClick",
+ "OptionsFrameOkay_OnClick",
+ "OptionsFrame_AddCategory",
+ "OptionsFrame_OnHide",
+ "OptionsFrame_OnLoad",
+ "OptionsFrame_OnShow",
+ "OptionsFrame_OpenToCategory",
+ "OptionsFrame_RefreshCategories",
+ "OptionsFrame_SetAllToDefaults",
+ "OptionsFrame_SetCurrentToDefaults",
+ "OptionsListButtonToggle_OnClick",
+ "OptionsListButton_OnClick",
+ "OptionsListButton_OnLoad",
+ "OptionsListButton_ToggleSubCategories",
+ "OptionsListScroll_Update",
+ "OptionsList_ClearSelection",
+ "OptionsList_DisplayButton",
+ "OptionsList_DisplayPanel",
+ "OptionsList_DisplayScrollBar",
+ "OptionsList_HideButton",
+ "OptionsList_HideScrollBar",
+ "OptionsList_OnLoad",
+ "OptionsList_SelectButton",
+ "OtherMenuChatTypeGroups",
+ "OutlandButton",
+ "OutlandButtonHighlight",
+ "PASSIVE_SPELL_FONT_COLOR",
+ "PDFITEMFLYOUT_MULTIROW_BOTTOM_COORDS",
+ "PDFITEMFLYOUT_MULTIROW_MIDDLE_COORDS",
+ "PDFITEMFLYOUT_MULTIROW_TOP_COORDS",
+ "PDFITEMFLYOUT_ONEROW_CENTER_COORDS",
+ "PDFITEMFLYOUT_ONEROW_LEFT_COORDS",
+ "PDFITEMFLYOUT_ONEROW_RIGHT_COORDS",
+ "PDFITEMFLYOUT_ONESLOT_LEFT_COORDS",
+ "PDFITEMFLYOUT_ONESLOT_RIGHT_COORDS",
+ "PENDING_GUILDBANK_PERMISSIONS",
+ "PLAYERSTAT_DROPDOWN_OPTIONS",
+ "PLAYER_FACTION_GROUP",
+ "PREVIOUS_BATTLEFIELD_QUEUES",
+ "PULSEBUTTONS",
+ "PVPArenaTextString",
+ "PVPBannerCustomization_Left",
+ "PVPBannerCustomization_Right",
+ "PVPBannerFrame",
+ "PVPBannerFrameAcceptButton",
+ "PVPBannerFrameAcceptButtonText",
+ "PVPBannerFrameBackground",
+ "PVPBannerFrameCancelButton",
+ "PVPBannerFrameCancelButtonText",
+ "PVPBannerFrameCloseButton",
+ "PVPBannerFrameCustomization1",
+ "PVPBannerFrameCustomization1Left",
+ "PVPBannerFrameCustomization1LeftButton",
+ "PVPBannerFrameCustomization1Middle",
+ "PVPBannerFrameCustomization1Right",
+ "PVPBannerFrameCustomization1RightButton",
+ "PVPBannerFrameCustomization1Text",
+ "PVPBannerFrameCustomization2",
+ "PVPBannerFrameCustomization2Left",
+ "PVPBannerFrameCustomization2LeftButton",
+ "PVPBannerFrameCustomization2Middle",
+ "PVPBannerFrameCustomization2Right",
+ "PVPBannerFrameCustomization2RightButton",
+ "PVPBannerFrameCustomization2Text",
+ "PVPBannerFrameCustomizationBorder",
+ "PVPBannerFrameCustomizationFrame",
+ "PVPBannerFrameEmblemBottomLeft",
+ "PVPBannerFrameEmblemBottomRight",
+ "PVPBannerFrameEmblemTopLeft",
+ "PVPBannerFrameEmblemTopRight",
+ "PVPBannerFrameGreetingText",
+ "PVPBannerFrameNameText",
+ "PVPBannerFrameOuterFrameBottom",
+ "PVPBannerFrameOuterFrameBottomLeft",
+ "PVPBannerFrameOuterFrameBottomRight",
+ "PVPBannerFrameOuterFrameLeftBottom",
+ "PVPBannerFrameOuterFrameLeftTop",
+ "PVPBannerFrameOuterFrameRightBottom",
+ "PVPBannerFrameOuterFrameRightTop",
+ "PVPBannerFrameOuterFrameTop",
+ "PVPBannerFrameOuterFrameTopLeft",
+ "PVPBannerFrameOuterFrameTopRight",
+ "PVPBannerFramePortrait",
+ "PVPBannerFrameSaveButton",
+ "PVPBannerFrameSaveButtonText",
+ "PVPBannerFrameStandard",
+ "PVPBannerFrameStandardBanner",
+ "PVPBannerFrameStandardBorder",
+ "PVPBannerFrameStandardEmblem",
+ "PVPBannerFrameStandardEmblemWatermark",
+ "PVPBannerFrame_OnShow",
+ "PVPBannerFrame_OpenColorPicker",
+ "PVPBannerFrame_SaveBanner",
+ "PVPBannerFrame_SetBannerColor",
+ "PVPBannerFrame_SetBorderColor",
+ "PVPBannerFrame_SetEmblemColor",
+ "PVPBattlegroundButton_OnClick",
+ "PVPBattlegroundFrame",
+ "PVPBattlegroundFrameBGTex",
+ "PVPBattlegroundFrameCancelButton",
+ "PVPBattlegroundFrameCancelButtonText",
+ "PVPBattlegroundFrameFrameLabel",
+ "PVPBattlegroundFrameGroupJoinButton",
+ "PVPBattlegroundFrameGroupJoinButtonText",
+ "PVPBattlegroundFrameInfoScrollFrame",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrame",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameDescription",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfo",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoDescription",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoLossReward",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoLossRewardArenaAmount",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoLossRewardArenaSymbol",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoLossRewardHonorAmount",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoLossRewardHonorSymbol",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoLossRewardLabel",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoRewardsLabel",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoTitle",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoWinReward",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoWinRewardArenaAmount",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoWinRewardArenaSymbol",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoWinRewardHonorAmount",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoWinRewardHonorSymbol",
+ "PVPBattlegroundFrameInfoScrollFrameChildFrameRewardsInfoWinRewardLabel",
+ "PVPBattlegroundFrameInfoScrollFrameScrollBar",
+ "PVPBattlegroundFrameInfoScrollFrameScrollBarScrollDownButton",
+ "PVPBattlegroundFrameInfoScrollFrameScrollBarScrollUpButton",
+ "PVPBattlegroundFrameInfoScrollFrameScrollBarThumbTexture",
+ "PVPBattlegroundFrameJoinButton",
+ "PVPBattlegroundFrameJoinButtonText",
+ "PVPBattlegroundFrameJoinButton_OnClick",
+ "PVPBattlegroundFrameNameHeader",
+ "PVPBattlegroundFramePortrait",
+ "PVPBattlegroundFrameTypeScrollFrame",
+ "PVPBattlegroundFrameTypeScrollFrameScrollBar",
+ "PVPBattlegroundFrameTypeScrollFrameScrollBarScrollDownButton",
+ "PVPBattlegroundFrameTypeScrollFrameScrollBarScrollUpButton",
+ "PVPBattlegroundFrameTypeScrollFrameScrollBarThumbTexture",
+ "PVPBattlegroundFrameTypeScrollFrameScrollChildFrame",
+ "PVPBattlegroundFrame_OnEvent",
+ "PVPBattlegroundFrame_OnHide",
+ "PVPBattlegroundFrame_OnLoad",
+ "PVPBattlegroundFrame_OnShow",
+ "PVPBattlegroundFrame_UpdateGroupAvailable",
+ "PVPBattlegroundFrame_UpdateVisible",
+ "PVPBattleground_GetSelectedBattlegroundInfo",
+ "PVPBattleground_ResetInfo",
+ "PVPBattleground_UpdateBattlegrounds",
+ "PVPBattleground_UpdateInfo",
+ "PVPBattleground_UpdateJoinButton",
+ "PVPBattleground_UpdateQueueStatus",
+ "PVPBattleground_UpdateRandomInfo",
+ "PVPColorPickerButton1",
+ "PVPColorPickerButton1Text",
+ "PVPColorPickerButton2",
+ "PVPColorPickerButton2Text",
+ "PVPColorPickerButton3",
+ "PVPColorPickerButton3Text",
+ "PVPDropDown",
+ "PVPDropDownButton",
+ "PVPDropDownButtonDisabledTexture",
+ "PVPDropDownButtonHighlightTexture",
+ "PVPDropDownButtonNormalTexture",
+ "PVPDropDownButtonPushedTexture",
+ "PVPDropDownLeft",
+ "PVPDropDownMiddle",
+ "PVPDropDownRight",
+ "PVPDropDownText",
+ "PVPDropDown_Initialize",
+ "PVPFrame",
+ "PVPFrameArena",
+ "PVPFrameArenaIcon",
+ "PVPFrameArenaLabel",
+ "PVPFrameArenaPoints",
+ "PVPFrameBackground",
+ "PVPFrameBlackFilter",
+ "PVPFrameHonor",
+ "PVPFrameHonorIcon",
+ "PVPFrameHonorLabel",
+ "PVPFrameHonorPoints",
+ "PVPFrameLine1",
+ "PVPFrameOffSeason",
+ "PVPFrameOffSeasonText",
+ "PVPFramePortrait",
+ "PVPFrameToggleButton",
+ "PVPFrameToggleButton_OnClick",
+ "PVPFrame_IsJustBG",
+ "PVPFrame_OnEvent",
+ "PVPFrame_OnHide",
+ "PVPFrame_OnLoad",
+ "PVPFrame_OnShow",
+ "PVPFrame_SetFaction",
+ "PVPFrame_SetJustBG",
+ "PVPFrame_SetToInSeason",
+ "PVPFrame_SetToOffSeason",
+ "PVPFrame_ShowDropdown",
+ "PVPFrame_Update",
+ "PVPHonor",
+ "PVPHonorHonorLabel",
+ "PVPHonorKillsLabel",
+ "PVPHonorLifetimeHonor",
+ "PVPHonorLifetimeKills",
+ "PVPHonorLifetimeLabel",
+ "PVPHonorTodayHonor",
+ "PVPHonorTodayKills",
+ "PVPHonorTodayLabel",
+ "PVPHonorYesterdayHonor",
+ "PVPHonorYesterdayKills",
+ "PVPHonorYesterdayLabel",
+ "PVPHonor_Update",
+ "PVPInfoTextFont",
+ "PVPInfoTextString",
+ "PVPMicroButton",
+ "PVPMicroButtonTexture",
+ "PVPMicroButton_SetNormal",
+ "PVPMicroButton_SetPushed",
+ "PVPParentFrame",
+ "PVPParentFrameCloseButton",
+ "PVPParentFrameTab1",
+ "PVPParentFrameTab1HighlightTexture",
+ "PVPParentFrameTab1Left",
+ "PVPParentFrameTab1LeftDisabled",
+ "PVPParentFrameTab1Middle",
+ "PVPParentFrameTab1MiddleDisabled",
+ "PVPParentFrameTab1Right",
+ "PVPParentFrameTab1RightDisabled",
+ "PVPParentFrameTab1Text",
+ "PVPParentFrameTab2",
+ "PVPParentFrameTab2HighlightTexture",
+ "PVPParentFrameTab2Left",
+ "PVPParentFrameTab2LeftDisabled",
+ "PVPParentFrameTab2Middle",
+ "PVPParentFrameTab2MiddleDisabled",
+ "PVPParentFrameTab2Right",
+ "PVPParentFrameTab2RightDisabled",
+ "PVPParentFrameTab2Text",
+ "PVPQueue_UpdateRandomInfo",
+ "PVPStandard_OnLoad",
+ "PVPTeam1",
+ "PVPTeam1Background",
+ "PVPTeam1Bottom",
+ "PVPTeam1Data",
+ "PVPTeam1Data-",
+ "PVPTeam1DataGames",
+ "PVPTeam1DataGamesLabel",
+ "PVPTeam1DataLoss",
+ "PVPTeam1DataName",
+ "PVPTeam1DataPlayed",
+ "PVPTeam1DataPlayedLabel",
+ "PVPTeam1DataRating",
+ "PVPTeam1DataRatingLabel",
+ "PVPTeam1DataTypeLabel",
+ "PVPTeam1DataWinLossLabel",
+ "PVPTeam1DataWins",
+ "PVPTeam1Highlight",
+ "PVPTeam1Left",
+ "PVPTeam1Right",
+ "PVPTeam1Standard",
+ "PVPTeam1StandardBanner",
+ "PVPTeam1StandardBar",
+ "PVPTeam1StandardBorder",
+ "PVPTeam1StandardEmblem",
+ "PVPTeam1TeamType",
+ "PVPTeam1Top",
+ "PVPTeam2",
+ "PVPTeam2Background",
+ "PVPTeam2Bottom",
+ "PVPTeam2Data",
+ "PVPTeam2Data-",
+ "PVPTeam2DataGames",
+ "PVPTeam2DataGamesLabel",
+ "PVPTeam2DataLoss",
+ "PVPTeam2DataName",
+ "PVPTeam2DataPlayed",
+ "PVPTeam2DataPlayedLabel",
+ "PVPTeam2DataRating",
+ "PVPTeam2DataRatingLabel",
+ "PVPTeam2DataTypeLabel",
+ "PVPTeam2DataWinLossLabel",
+ "PVPTeam2DataWins",
+ "PVPTeam2Highlight",
+ "PVPTeam2Left",
+ "PVPTeam2Right",
+ "PVPTeam2Standard",
+ "PVPTeam2StandardBanner",
+ "PVPTeam2StandardBar",
+ "PVPTeam2StandardBorder",
+ "PVPTeam2StandardEmblem",
+ "PVPTeam2TeamType",
+ "PVPTeam2Top",
+ "PVPTeam3",
+ "PVPTeam3Background",
+ "PVPTeam3Bottom",
+ "PVPTeam3Data",
+ "PVPTeam3Data-",
+ "PVPTeam3DataGames",
+ "PVPTeam3DataGamesLabel",
+ "PVPTeam3DataLoss",
+ "PVPTeam3DataName",
+ "PVPTeam3DataPlayed",
+ "PVPTeam3DataPlayedLabel",
+ "PVPTeam3DataRating",
+ "PVPTeam3DataRatingLabel",
+ "PVPTeam3DataTypeLabel",
+ "PVPTeam3DataWinLossLabel",
+ "PVPTeam3DataWins",
+ "PVPTeam3Highlight",
+ "PVPTeam3Left",
+ "PVPTeam3Right",
+ "PVPTeam3Standard",
+ "PVPTeam3StandardBanner",
+ "PVPTeam3StandardBar",
+ "PVPTeam3StandardBorder",
+ "PVPTeam3StandardEmblem",
+ "PVPTeam3TeamType",
+ "PVPTeam3Top",
+ "PVPTeamDetails",
+ "PVPTeamDetails-",
+ "PVPTeamDetailsAddTeamMember",
+ "PVPTeamDetailsAddTeamMemberText",
+ "PVPTeamDetailsButton1",
+ "PVPTeamDetailsButton10",
+ "PVPTeamDetailsButton10Class",
+ "PVPTeamDetailsButton10ClassText",
+ "PVPTeamDetailsButton10Name",
+ "PVPTeamDetailsButton10NameText",
+ "PVPTeamDetailsButton10Played",
+ "PVPTeamDetailsButton10PlayedText",
+ "PVPTeamDetailsButton10Rating",
+ "PVPTeamDetailsButton10RatingText",
+ "PVPTeamDetailsButton10WinLoss",
+ "PVPTeamDetailsButton10WinLoss-",
+ "PVPTeamDetailsButton10WinLossLoss",
+ "PVPTeamDetailsButton10WinLossWin",
+ "PVPTeamDetailsButton1Class",
+ "PVPTeamDetailsButton1ClassText",
+ "PVPTeamDetailsButton1Name",
+ "PVPTeamDetailsButton1NameText",
+ "PVPTeamDetailsButton1Played",
+ "PVPTeamDetailsButton1PlayedText",
+ "PVPTeamDetailsButton1Rating",
+ "PVPTeamDetailsButton1RatingText",
+ "PVPTeamDetailsButton1WinLoss",
+ "PVPTeamDetailsButton1WinLoss-",
+ "PVPTeamDetailsButton1WinLossLoss",
+ "PVPTeamDetailsButton1WinLossWin",
+ "PVPTeamDetailsButton2",
+ "PVPTeamDetailsButton2Class",
+ "PVPTeamDetailsButton2ClassText",
+ "PVPTeamDetailsButton2Name",
+ "PVPTeamDetailsButton2NameText",
+ "PVPTeamDetailsButton2Played",
+ "PVPTeamDetailsButton2PlayedText",
+ "PVPTeamDetailsButton2Rating",
+ "PVPTeamDetailsButton2RatingText",
+ "PVPTeamDetailsButton2WinLoss",
+ "PVPTeamDetailsButton2WinLoss-",
+ "PVPTeamDetailsButton2WinLossLoss",
+ "PVPTeamDetailsButton2WinLossWin",
+ "PVPTeamDetailsButton3",
+ "PVPTeamDetailsButton3Class",
+ "PVPTeamDetailsButton3ClassText",
+ "PVPTeamDetailsButton3Name",
+ "PVPTeamDetailsButton3NameText",
+ "PVPTeamDetailsButton3Played",
+ "PVPTeamDetailsButton3PlayedText",
+ "PVPTeamDetailsButton3Rating",
+ "PVPTeamDetailsButton3RatingText",
+ "PVPTeamDetailsButton3WinLoss",
+ "PVPTeamDetailsButton3WinLoss-",
+ "PVPTeamDetailsButton3WinLossLoss",
+ "PVPTeamDetailsButton3WinLossWin",
+ "PVPTeamDetailsButton4",
+ "PVPTeamDetailsButton4Class",
+ "PVPTeamDetailsButton4ClassText",
+ "PVPTeamDetailsButton4Name",
+ "PVPTeamDetailsButton4NameText",
+ "PVPTeamDetailsButton4Played",
+ "PVPTeamDetailsButton4PlayedText",
+ "PVPTeamDetailsButton4Rating",
+ "PVPTeamDetailsButton4RatingText",
+ "PVPTeamDetailsButton4WinLoss",
+ "PVPTeamDetailsButton4WinLoss-",
+ "PVPTeamDetailsButton4WinLossLoss",
+ "PVPTeamDetailsButton4WinLossWin",
+ "PVPTeamDetailsButton5",
+ "PVPTeamDetailsButton5Class",
+ "PVPTeamDetailsButton5ClassText",
+ "PVPTeamDetailsButton5Name",
+ "PVPTeamDetailsButton5NameText",
+ "PVPTeamDetailsButton5Played",
+ "PVPTeamDetailsButton5PlayedText",
+ "PVPTeamDetailsButton5Rating",
+ "PVPTeamDetailsButton5RatingText",
+ "PVPTeamDetailsButton5WinLoss",
+ "PVPTeamDetailsButton5WinLoss-",
+ "PVPTeamDetailsButton5WinLossLoss",
+ "PVPTeamDetailsButton5WinLossWin",
+ "PVPTeamDetailsButton6",
+ "PVPTeamDetailsButton6Class",
+ "PVPTeamDetailsButton6ClassText",
+ "PVPTeamDetailsButton6Name",
+ "PVPTeamDetailsButton6NameText",
+ "PVPTeamDetailsButton6Played",
+ "PVPTeamDetailsButton6PlayedText",
+ "PVPTeamDetailsButton6Rating",
+ "PVPTeamDetailsButton6RatingText",
+ "PVPTeamDetailsButton6WinLoss",
+ "PVPTeamDetailsButton6WinLoss-",
+ "PVPTeamDetailsButton6WinLossLoss",
+ "PVPTeamDetailsButton6WinLossWin",
+ "PVPTeamDetailsButton7",
+ "PVPTeamDetailsButton7Class",
+ "PVPTeamDetailsButton7ClassText",
+ "PVPTeamDetailsButton7Name",
+ "PVPTeamDetailsButton7NameText",
+ "PVPTeamDetailsButton7Played",
+ "PVPTeamDetailsButton7PlayedText",
+ "PVPTeamDetailsButton7Rating",
+ "PVPTeamDetailsButton7RatingText",
+ "PVPTeamDetailsButton7WinLoss",
+ "PVPTeamDetailsButton7WinLoss-",
+ "PVPTeamDetailsButton7WinLossLoss",
+ "PVPTeamDetailsButton7WinLossWin",
+ "PVPTeamDetailsButton8",
+ "PVPTeamDetailsButton8Class",
+ "PVPTeamDetailsButton8ClassText",
+ "PVPTeamDetailsButton8Name",
+ "PVPTeamDetailsButton8NameText",
+ "PVPTeamDetailsButton8Played",
+ "PVPTeamDetailsButton8PlayedText",
+ "PVPTeamDetailsButton8Rating",
+ "PVPTeamDetailsButton8RatingText",
+ "PVPTeamDetailsButton8WinLoss",
+ "PVPTeamDetailsButton8WinLoss-",
+ "PVPTeamDetailsButton8WinLossLoss",
+ "PVPTeamDetailsButton8WinLossWin",
+ "PVPTeamDetailsButton9",
+ "PVPTeamDetailsButton9Class",
+ "PVPTeamDetailsButton9ClassText",
+ "PVPTeamDetailsButton9Name",
+ "PVPTeamDetailsButton9NameText",
+ "PVPTeamDetailsButton9Played",
+ "PVPTeamDetailsButton9PlayedText",
+ "PVPTeamDetailsButton9Rating",
+ "PVPTeamDetailsButton9RatingText",
+ "PVPTeamDetailsButton9WinLoss",
+ "PVPTeamDetailsButton9WinLoss-",
+ "PVPTeamDetailsButton9WinLossLoss",
+ "PVPTeamDetailsButton9WinLossWin",
+ "PVPTeamDetailsButton_OnClick",
+ "PVPTeamDetailsCloseButton",
+ "PVPTeamDetailsFrameColumnHeader1",
+ "PVPTeamDetailsFrameColumnHeader1HighlightTexture",
+ "PVPTeamDetailsFrameColumnHeader1Left",
+ "PVPTeamDetailsFrameColumnHeader1Middle",
+ "PVPTeamDetailsFrameColumnHeader1Right",
+ "PVPTeamDetailsFrameColumnHeader2",
+ "PVPTeamDetailsFrameColumnHeader2HighlightTexture",
+ "PVPTeamDetailsFrameColumnHeader2Left",
+ "PVPTeamDetailsFrameColumnHeader2Middle",
+ "PVPTeamDetailsFrameColumnHeader2Right",
+ "PVPTeamDetailsFrameColumnHeader3",
+ "PVPTeamDetailsFrameColumnHeader3HighlightTexture",
+ "PVPTeamDetailsFrameColumnHeader3Left",
+ "PVPTeamDetailsFrameColumnHeader3Middle",
+ "PVPTeamDetailsFrameColumnHeader3Right",
+ "PVPTeamDetailsFrameColumnHeader4",
+ "PVPTeamDetailsFrameColumnHeader4HighlightTexture",
+ "PVPTeamDetailsFrameColumnHeader4Left",
+ "PVPTeamDetailsFrameColumnHeader4Middle",
+ "PVPTeamDetailsFrameColumnHeader4Right",
+ "PVPTeamDetailsFrameColumnHeader5",
+ "PVPTeamDetailsFrameColumnHeader5HighlightTexture",
+ "PVPTeamDetailsFrameColumnHeader5Left",
+ "PVPTeamDetailsFrameColumnHeader5Middle",
+ "PVPTeamDetailsFrameColumnHeader5Right",
+ "PVPTeamDetailsGames",
+ "PVPTeamDetailsGamesLabel",
+ "PVPTeamDetailsLoss",
+ "PVPTeamDetailsName",
+ "PVPTeamDetailsRank",
+ "PVPTeamDetailsRankLabel",
+ "PVPTeamDetailsRating",
+ "PVPTeamDetailsRatingLabel",
+ "PVPTeamDetailsSize",
+ "PVPTeamDetailsStatsType",
+ "PVPTeamDetailsToggleButton",
+ "PVPTeamDetailsToggleButton_OnClick",
+ "PVPTeamDetailsWinLossLabel",
+ "PVPTeamDetailsWins",
+ "PVPTeamDetails_OnHide",
+ "PVPTeamDetails_OnShow",
+ "PVPTeamDetails_Update",
+ "PVPTeam_OnClick",
+ "PVPTeam_OnEnter",
+ "PVPTeam_OnLeave",
+ "PVPTeam_OnMouseDown",
+ "PVPTeam_OnMouseUp",
+ "PVPTeam_Update",
+ "PanelTemplates_DeselectTab",
+ "PanelTemplates_DisableTab",
+ "PanelTemplates_EnableTab",
+ "PanelTemplates_GetSelectedTab",
+ "PanelTemplates_GetTabWidth",
+ "PanelTemplates_SelectTab",
+ "PanelTemplates_SetDisabledTabState",
+ "PanelTemplates_SetNumTabs",
+ "PanelTemplates_SetTab",
+ "PanelTemplates_TabResize",
+ "PanelTemplates_Tab_OnClick",
+ "PanelTemplates_UpdateTabs",
+ "PaperDollFormatStat",
+ "PaperDollFrame",
+ "PaperDollFrameItemFlyout",
+ "PaperDollFrameItemFlyoutButton_OnClick",
+ "PaperDollFrameItemFlyoutButton_OnEnter",
+ "PaperDollFrameItemFlyoutButtons",
+ "PaperDollFrameItemFlyoutHighlight",
+ "PaperDollFrameItemFlyout_CreateButton",
+ "PaperDollFrameItemFlyout_DisplayButton",
+ "PaperDollFrameItemFlyout_DisplaySpecialButton",
+ "PaperDollFrameItemFlyout_Hide",
+ "PaperDollFrameItemFlyout_OnEvent",
+ "PaperDollFrameItemFlyout_OnHide",
+ "PaperDollFrameItemFlyout_OnShow",
+ "PaperDollFrameItemFlyout_OnUpdate",
+ "PaperDollFrameItemFlyout_Show",
+ "PaperDollFrameItemPopoutButton_HideAll",
+ "PaperDollFrameItemPopoutButton_OnClick",
+ "PaperDollFrameItemPopoutButton_OnLoad",
+ "PaperDollFrameItemPopoutButton_SetReversed",
+ "PaperDollFrameItemPopoutButton_ShowAll",
+ "PaperDollFrame_ClearIgnoredSlots",
+ "PaperDollFrame_GetArmorReduction",
+ "PaperDollFrame_IgnoreSlotsForSet",
+ "PaperDollFrame_OnEvent",
+ "PaperDollFrame_OnHide",
+ "PaperDollFrame_OnLoad",
+ "PaperDollFrame_OnShow",
+ "PaperDollFrame_SetArmor",
+ "PaperDollFrame_SetAttackBothHands",
+ "PaperDollFrame_SetAttackPower",
+ "PaperDollFrame_SetAttackSpeed",
+ "PaperDollFrame_SetBlock",
+ "PaperDollFrame_SetDamage",
+ "PaperDollFrame_SetDefense",
+ "PaperDollFrame_SetDodge",
+ "PaperDollFrame_SetExpertise",
+ "PaperDollFrame_SetGuild",
+ "PaperDollFrame_SetLabelAndText",
+ "PaperDollFrame_SetLevel",
+ "PaperDollFrame_SetManaRegen",
+ "PaperDollFrame_SetMeleeCritChance",
+ "PaperDollFrame_SetParry",
+ "PaperDollFrame_SetRangedAttack",
+ "PaperDollFrame_SetRangedAttackPower",
+ "PaperDollFrame_SetRangedAttackSpeed",
+ "PaperDollFrame_SetRangedCritChance",
+ "PaperDollFrame_SetRangedDamage",
+ "PaperDollFrame_SetRating",
+ "PaperDollFrame_SetResilience",
+ "PaperDollFrame_SetResistances",
+ "PaperDollFrame_SetSpellBonusDamage",
+ "PaperDollFrame_SetSpellBonusHealing",
+ "PaperDollFrame_SetSpellCritChance",
+ "PaperDollFrame_SetSpellHaste",
+ "PaperDollFrame_SetSpellPenetration",
+ "PaperDollFrame_SetStat",
+ "PaperDollFrame_UpdateStats",
+ "PaperDollItemSlotButton_OnClick",
+ "PaperDollItemSlotButton_OnEnter",
+ "PaperDollItemSlotButton_OnEvent",
+ "PaperDollItemSlotButton_OnHide",
+ "PaperDollItemSlotButton_OnLeave",
+ "PaperDollItemSlotButton_OnLoad",
+ "PaperDollItemSlotButton_OnModifiedClick",
+ "PaperDollItemSlotButton_OnShow",
+ "PaperDollItemSlotButton_Update",
+ "PaperDollItemSlotButton_UpdateFlyout",
+ "PaperDollItemSlotButton_UpdateLock",
+ "PaperDollStatTooltip",
+ "PaperDoll_IsEquippedSlot",
+ "PartialPlayTime",
+ "PartyFrameDropDown_Initialize",
+ "PartyFrameDropDown_OnLoad",
+ "PartyLFGStartBackfill",
+ "PartyMemberBackground",
+ "PartyMemberBackground_SaveOpacity",
+ "PartyMemberBackground_SetOpacity",
+ "PartyMemberBackground_ToggleOpacity",
+ "PartyMemberBuffTooltip",
+ "PartyMemberBuffTooltipBuff1",
+ "PartyMemberBuffTooltipBuff10",
+ "PartyMemberBuffTooltipBuff10Icon",
+ "PartyMemberBuffTooltipBuff11",
+ "PartyMemberBuffTooltipBuff11Icon",
+ "PartyMemberBuffTooltipBuff12",
+ "PartyMemberBuffTooltipBuff12Icon",
+ "PartyMemberBuffTooltipBuff13",
+ "PartyMemberBuffTooltipBuff13Icon",
+ "PartyMemberBuffTooltipBuff14",
+ "PartyMemberBuffTooltipBuff14Icon",
+ "PartyMemberBuffTooltipBuff15",
+ "PartyMemberBuffTooltipBuff15Icon",
+ "PartyMemberBuffTooltipBuff16",
+ "PartyMemberBuffTooltipBuff16Icon",
+ "PartyMemberBuffTooltipBuff1Icon",
+ "PartyMemberBuffTooltipBuff2",
+ "PartyMemberBuffTooltipBuff2Icon",
+ "PartyMemberBuffTooltipBuff3",
+ "PartyMemberBuffTooltipBuff3Icon",
+ "PartyMemberBuffTooltipBuff4",
+ "PartyMemberBuffTooltipBuff4Icon",
+ "PartyMemberBuffTooltipBuff5",
+ "PartyMemberBuffTooltipBuff5Icon",
+ "PartyMemberBuffTooltipBuff6",
+ "PartyMemberBuffTooltipBuff6Icon",
+ "PartyMemberBuffTooltipBuff7",
+ "PartyMemberBuffTooltipBuff7Icon",
+ "PartyMemberBuffTooltipBuff8",
+ "PartyMemberBuffTooltipBuff8Icon",
+ "PartyMemberBuffTooltipBuff9",
+ "PartyMemberBuffTooltipBuff9Icon",
+ "PartyMemberBuffTooltipDebuff1",
+ "PartyMemberBuffTooltipDebuff1Border",
+ "PartyMemberBuffTooltipDebuff1Icon",
+ "PartyMemberBuffTooltipDebuff2",
+ "PartyMemberBuffTooltipDebuff2Border",
+ "PartyMemberBuffTooltipDebuff2Icon",
+ "PartyMemberBuffTooltipDebuff3",
+ "PartyMemberBuffTooltipDebuff3Border",
+ "PartyMemberBuffTooltipDebuff3Icon",
+ "PartyMemberBuffTooltipDebuff4",
+ "PartyMemberBuffTooltipDebuff4Border",
+ "PartyMemberBuffTooltipDebuff4Icon",
+ "PartyMemberBuffTooltipDebuff5",
+ "PartyMemberBuffTooltipDebuff5Border",
+ "PartyMemberBuffTooltipDebuff5Icon",
+ "PartyMemberBuffTooltipDebuff6",
+ "PartyMemberBuffTooltipDebuff6Border",
+ "PartyMemberBuffTooltipDebuff6Icon",
+ "PartyMemberBuffTooltipDebuff7",
+ "PartyMemberBuffTooltipDebuff7Border",
+ "PartyMemberBuffTooltipDebuff7Icon",
+ "PartyMemberBuffTooltipDebuff8",
+ "PartyMemberBuffTooltipDebuff8Border",
+ "PartyMemberBuffTooltipDebuff8Icon",
+ "PartyMemberBuffTooltip_Update",
+ "PartyMemberFrame1",
+ "PartyMemberFrame1Background",
+ "PartyMemberFrame1Debuff1",
+ "PartyMemberFrame1Debuff1Border",
+ "PartyMemberFrame1Debuff1Icon",
+ "PartyMemberFrame1Debuff2",
+ "PartyMemberFrame1Debuff2Border",
+ "PartyMemberFrame1Debuff2Icon",
+ "PartyMemberFrame1Debuff3",
+ "PartyMemberFrame1Debuff3Border",
+ "PartyMemberFrame1Debuff3Icon",
+ "PartyMemberFrame1Debuff4",
+ "PartyMemberFrame1Debuff4Border",
+ "PartyMemberFrame1Debuff4Icon",
+ "PartyMemberFrame1Disconnect",
+ "PartyMemberFrame1DropDown",
+ "PartyMemberFrame1DropDownButton",
+ "PartyMemberFrame1DropDownButtonDisabledTexture",
+ "PartyMemberFrame1DropDownButtonHighlightTexture",
+ "PartyMemberFrame1DropDownButtonNormalTexture",
+ "PartyMemberFrame1DropDownButtonPushedTexture",
+ "PartyMemberFrame1DropDownLeft",
+ "PartyMemberFrame1DropDownMiddle",
+ "PartyMemberFrame1DropDownRight",
+ "PartyMemberFrame1DropDownText",
+ "PartyMemberFrame1Flash",
+ "PartyMemberFrame1GuideIcon",
+ "PartyMemberFrame1HealthBar",
+ "PartyMemberFrame1HealthBarText",
+ "PartyMemberFrame1LeaderIcon",
+ "PartyMemberFrame1ManaBar",
+ "PartyMemberFrame1ManaBarText",
+ "PartyMemberFrame1MasterIcon",
+ "PartyMemberFrame1Name",
+ "PartyMemberFrame1PVPIcon",
+ "PartyMemberFrame1PetFrame",
+ "PartyMemberFrame1PetFrameDebuff1",
+ "PartyMemberFrame1PetFrameDebuff1Border",
+ "PartyMemberFrame1PetFrameDebuff1Icon",
+ "PartyMemberFrame1PetFrameDebuff2",
+ "PartyMemberFrame1PetFrameDebuff2Border",
+ "PartyMemberFrame1PetFrameDebuff2Icon",
+ "PartyMemberFrame1PetFrameDebuff3",
+ "PartyMemberFrame1PetFrameDebuff3Border",
+ "PartyMemberFrame1PetFrameDebuff3Icon",
+ "PartyMemberFrame1PetFrameDebuff4",
+ "PartyMemberFrame1PetFrameDebuff4Border",
+ "PartyMemberFrame1PetFrameDebuff4Icon",
+ "PartyMemberFrame1PetFrameFlash",
+ "PartyMemberFrame1PetFrameHealthBar",
+ "PartyMemberFrame1PetFrameName",
+ "PartyMemberFrame1PetFramePortrait",
+ "PartyMemberFrame1PetFrameTexture",
+ "PartyMemberFrame1Portrait",
+ "PartyMemberFrame1ReadyCheck",
+ "PartyMemberFrame1ReadyCheckTexture",
+ "PartyMemberFrame1RoleIcon",
+ "PartyMemberFrame1Speaker",
+ "PartyMemberFrame1SpeakerFlash",
+ "PartyMemberFrame1SpeakerFrame",
+ "PartyMemberFrame1SpeakerFrameFlash",
+ "PartyMemberFrame1SpeakerFrameMuted",
+ "PartyMemberFrame1SpeakerFrameOn",
+ "PartyMemberFrame1SpeakerMuted",
+ "PartyMemberFrame1SpeakerOn",
+ "PartyMemberFrame1Status",
+ "PartyMemberFrame1Texture",
+ "PartyMemberFrame1VehicleTexture",
+ "PartyMemberFrame2",
+ "PartyMemberFrame2Background",
+ "PartyMemberFrame2Debuff1",
+ "PartyMemberFrame2Debuff1Border",
+ "PartyMemberFrame2Debuff1Icon",
+ "PartyMemberFrame2Debuff2",
+ "PartyMemberFrame2Debuff2Border",
+ "PartyMemberFrame2Debuff2Icon",
+ "PartyMemberFrame2Debuff3",
+ "PartyMemberFrame2Debuff3Border",
+ "PartyMemberFrame2Debuff3Icon",
+ "PartyMemberFrame2Debuff4",
+ "PartyMemberFrame2Debuff4Border",
+ "PartyMemberFrame2Debuff4Icon",
+ "PartyMemberFrame2Disconnect",
+ "PartyMemberFrame2DropDown",
+ "PartyMemberFrame2DropDownButton",
+ "PartyMemberFrame2DropDownButtonDisabledTexture",
+ "PartyMemberFrame2DropDownButtonHighlightTexture",
+ "PartyMemberFrame2DropDownButtonNormalTexture",
+ "PartyMemberFrame2DropDownButtonPushedTexture",
+ "PartyMemberFrame2DropDownLeft",
+ "PartyMemberFrame2DropDownMiddle",
+ "PartyMemberFrame2DropDownRight",
+ "PartyMemberFrame2DropDownText",
+ "PartyMemberFrame2Flash",
+ "PartyMemberFrame2GuideIcon",
+ "PartyMemberFrame2HealthBar",
+ "PartyMemberFrame2HealthBarText",
+ "PartyMemberFrame2LeaderIcon",
+ "PartyMemberFrame2ManaBar",
+ "PartyMemberFrame2ManaBarText",
+ "PartyMemberFrame2MasterIcon",
+ "PartyMemberFrame2Name",
+ "PartyMemberFrame2PVPIcon",
+ "PartyMemberFrame2PetFrame",
+ "PartyMemberFrame2PetFrameDebuff1",
+ "PartyMemberFrame2PetFrameDebuff1Border",
+ "PartyMemberFrame2PetFrameDebuff1Icon",
+ "PartyMemberFrame2PetFrameDebuff2",
+ "PartyMemberFrame2PetFrameDebuff2Border",
+ "PartyMemberFrame2PetFrameDebuff2Icon",
+ "PartyMemberFrame2PetFrameDebuff3",
+ "PartyMemberFrame2PetFrameDebuff3Border",
+ "PartyMemberFrame2PetFrameDebuff3Icon",
+ "PartyMemberFrame2PetFrameDebuff4",
+ "PartyMemberFrame2PetFrameDebuff4Border",
+ "PartyMemberFrame2PetFrameDebuff4Icon",
+ "PartyMemberFrame2PetFrameFlash",
+ "PartyMemberFrame2PetFrameHealthBar",
+ "PartyMemberFrame2PetFrameName",
+ "PartyMemberFrame2PetFramePortrait",
+ "PartyMemberFrame2PetFrameTexture",
+ "PartyMemberFrame2Portrait",
+ "PartyMemberFrame2ReadyCheck",
+ "PartyMemberFrame2ReadyCheckTexture",
+ "PartyMemberFrame2RoleIcon",
+ "PartyMemberFrame2Speaker",
+ "PartyMemberFrame2SpeakerFlash",
+ "PartyMemberFrame2SpeakerFrame",
+ "PartyMemberFrame2SpeakerFrameFlash",
+ "PartyMemberFrame2SpeakerFrameMuted",
+ "PartyMemberFrame2SpeakerFrameOn",
+ "PartyMemberFrame2SpeakerMuted",
+ "PartyMemberFrame2SpeakerOn",
+ "PartyMemberFrame2Status",
+ "PartyMemberFrame2Texture",
+ "PartyMemberFrame2VehicleTexture",
+ "PartyMemberFrame3",
+ "PartyMemberFrame3Background",
+ "PartyMemberFrame3Debuff1",
+ "PartyMemberFrame3Debuff1Border",
+ "PartyMemberFrame3Debuff1Icon",
+ "PartyMemberFrame3Debuff2",
+ "PartyMemberFrame3Debuff2Border",
+ "PartyMemberFrame3Debuff2Icon",
+ "PartyMemberFrame3Debuff3",
+ "PartyMemberFrame3Debuff3Border",
+ "PartyMemberFrame3Debuff3Icon",
+ "PartyMemberFrame3Debuff4",
+ "PartyMemberFrame3Debuff4Border",
+ "PartyMemberFrame3Debuff4Icon",
+ "PartyMemberFrame3Disconnect",
+ "PartyMemberFrame3DropDown",
+ "PartyMemberFrame3DropDownButton",
+ "PartyMemberFrame3DropDownButtonDisabledTexture",
+ "PartyMemberFrame3DropDownButtonHighlightTexture",
+ "PartyMemberFrame3DropDownButtonNormalTexture",
+ "PartyMemberFrame3DropDownButtonPushedTexture",
+ "PartyMemberFrame3DropDownLeft",
+ "PartyMemberFrame3DropDownMiddle",
+ "PartyMemberFrame3DropDownRight",
+ "PartyMemberFrame3DropDownText",
+ "PartyMemberFrame3Flash",
+ "PartyMemberFrame3GuideIcon",
+ "PartyMemberFrame3HealthBar",
+ "PartyMemberFrame3HealthBarText",
+ "PartyMemberFrame3LeaderIcon",
+ "PartyMemberFrame3ManaBar",
+ "PartyMemberFrame3ManaBarText",
+ "PartyMemberFrame3MasterIcon",
+ "PartyMemberFrame3Name",
+ "PartyMemberFrame3PVPIcon",
+ "PartyMemberFrame3PetFrame",
+ "PartyMemberFrame3PetFrameDebuff1",
+ "PartyMemberFrame3PetFrameDebuff1Border",
+ "PartyMemberFrame3PetFrameDebuff1Icon",
+ "PartyMemberFrame3PetFrameDebuff2",
+ "PartyMemberFrame3PetFrameDebuff2Border",
+ "PartyMemberFrame3PetFrameDebuff2Icon",
+ "PartyMemberFrame3PetFrameDebuff3",
+ "PartyMemberFrame3PetFrameDebuff3Border",
+ "PartyMemberFrame3PetFrameDebuff3Icon",
+ "PartyMemberFrame3PetFrameDebuff4",
+ "PartyMemberFrame3PetFrameDebuff4Border",
+ "PartyMemberFrame3PetFrameDebuff4Icon",
+ "PartyMemberFrame3PetFrameFlash",
+ "PartyMemberFrame3PetFrameHealthBar",
+ "PartyMemberFrame3PetFrameName",
+ "PartyMemberFrame3PetFramePortrait",
+ "PartyMemberFrame3PetFrameTexture",
+ "PartyMemberFrame3Portrait",
+ "PartyMemberFrame3ReadyCheck",
+ "PartyMemberFrame3ReadyCheckTexture",
+ "PartyMemberFrame3RoleIcon",
+ "PartyMemberFrame3Speaker",
+ "PartyMemberFrame3SpeakerFlash",
+ "PartyMemberFrame3SpeakerFrame",
+ "PartyMemberFrame3SpeakerFrameFlash",
+ "PartyMemberFrame3SpeakerFrameMuted",
+ "PartyMemberFrame3SpeakerFrameOn",
+ "PartyMemberFrame3SpeakerMuted",
+ "PartyMemberFrame3SpeakerOn",
+ "PartyMemberFrame3Status",
+ "PartyMemberFrame3Texture",
+ "PartyMemberFrame3VehicleTexture",
+ "PartyMemberFrame4",
+ "PartyMemberFrame4Background",
+ "PartyMemberFrame4Debuff1",
+ "PartyMemberFrame4Debuff1Border",
+ "PartyMemberFrame4Debuff1Icon",
+ "PartyMemberFrame4Debuff2",
+ "PartyMemberFrame4Debuff2Border",
+ "PartyMemberFrame4Debuff2Icon",
+ "PartyMemberFrame4Debuff3",
+ "PartyMemberFrame4Debuff3Border",
+ "PartyMemberFrame4Debuff3Icon",
+ "PartyMemberFrame4Debuff4",
+ "PartyMemberFrame4Debuff4Border",
+ "PartyMemberFrame4Debuff4Icon",
+ "PartyMemberFrame4Disconnect",
+ "PartyMemberFrame4DropDown",
+ "PartyMemberFrame4DropDownButton",
+ "PartyMemberFrame4DropDownButtonDisabledTexture",
+ "PartyMemberFrame4DropDownButtonHighlightTexture",
+ "PartyMemberFrame4DropDownButtonNormalTexture",
+ "PartyMemberFrame4DropDownButtonPushedTexture",
+ "PartyMemberFrame4DropDownLeft",
+ "PartyMemberFrame4DropDownMiddle",
+ "PartyMemberFrame4DropDownRight",
+ "PartyMemberFrame4DropDownText",
+ "PartyMemberFrame4Flash",
+ "PartyMemberFrame4GuideIcon",
+ "PartyMemberFrame4HealthBar",
+ "PartyMemberFrame4HealthBarText",
+ "PartyMemberFrame4LeaderIcon",
+ "PartyMemberFrame4ManaBar",
+ "PartyMemberFrame4ManaBarText",
+ "PartyMemberFrame4MasterIcon",
+ "PartyMemberFrame4Name",
+ "PartyMemberFrame4PVPIcon",
+ "PartyMemberFrame4PetFrame",
+ "PartyMemberFrame4PetFrameDebuff1",
+ "PartyMemberFrame4PetFrameDebuff1Border",
+ "PartyMemberFrame4PetFrameDebuff1Icon",
+ "PartyMemberFrame4PetFrameDebuff2",
+ "PartyMemberFrame4PetFrameDebuff2Border",
+ "PartyMemberFrame4PetFrameDebuff2Icon",
+ "PartyMemberFrame4PetFrameDebuff3",
+ "PartyMemberFrame4PetFrameDebuff3Border",
+ "PartyMemberFrame4PetFrameDebuff3Icon",
+ "PartyMemberFrame4PetFrameDebuff4",
+ "PartyMemberFrame4PetFrameDebuff4Border",
+ "PartyMemberFrame4PetFrameDebuff4Icon",
+ "PartyMemberFrame4PetFrameFlash",
+ "PartyMemberFrame4PetFrameHealthBar",
+ "PartyMemberFrame4PetFrameName",
+ "PartyMemberFrame4PetFramePortrait",
+ "PartyMemberFrame4PetFrameTexture",
+ "PartyMemberFrame4Portrait",
+ "PartyMemberFrame4ReadyCheck",
+ "PartyMemberFrame4ReadyCheckTexture",
+ "PartyMemberFrame4RoleIcon",
+ "PartyMemberFrame4Speaker",
+ "PartyMemberFrame4SpeakerFlash",
+ "PartyMemberFrame4SpeakerFrame",
+ "PartyMemberFrame4SpeakerFrameFlash",
+ "PartyMemberFrame4SpeakerFrameMuted",
+ "PartyMemberFrame4SpeakerFrameOn",
+ "PartyMemberFrame4SpeakerMuted",
+ "PartyMemberFrame4SpeakerOn",
+ "PartyMemberFrame4Status",
+ "PartyMemberFrame4Texture",
+ "PartyMemberFrame4VehicleTexture",
+ "PartyMemberFrame_OnEvent",
+ "PartyMemberFrame_OnLoad",
+ "PartyMemberFrame_OnUpdate",
+ "PartyMemberFrame_RefreshPetDebuffs",
+ "PartyMemberFrame_ToPlayerArt",
+ "PartyMemberFrame_ToVehicleArt",
+ "PartyMemberFrame_UpdateArt",
+ "PartyMemberFrame_UpdateAssignedRoles",
+ "PartyMemberFrame_UpdateLeader",
+ "PartyMemberFrame_UpdateMember",
+ "PartyMemberFrame_UpdateMemberHealth",
+ "PartyMemberFrame_UpdateOnlineStatus",
+ "PartyMemberFrame_UpdatePet",
+ "PartyMemberFrame_UpdatePvPStatus",
+ "PartyMemberFrame_UpdateReadyCheck",
+ "PartyMemberFrame_UpdateStatusBarText",
+ "PartyMemberFrame_UpdateVoiceStatus",
+ "PartyMemberHealthCheck",
+ "PendingListFrame",
+ "PendingListFrameDropDown",
+ "PendingListFrameDropDownButton",
+ "PendingListFrameDropDownButtonDisabledTexture",
+ "PendingListFrameDropDownButtonHighlightTexture",
+ "PendingListFrameDropDownButtonNormalTexture",
+ "PendingListFrameDropDownButtonPushedTexture",
+ "PendingListFrameDropDownLeft",
+ "PendingListFrameDropDownMiddle",
+ "PendingListFrameDropDownRight",
+ "PendingListFrameDropDownText",
+ "PendingListFrameDropDown_Initialize",
+ "PendingListFrameDropDown_OnLoad",
+ "PendingListFrame_BlockCommunication",
+ "PendingListFrame_OnHide",
+ "PendingListFrame_OnShow",
+ "PendingListFrame_ReportPlayer",
+ "PendingListFrame_ReportSpam",
+ "PendingListInfoFrame",
+ "PendingListInfoFrameBattlenetIcon",
+ "PendingListInfoFrameContinueButton",
+ "PendingListInfoFrameContinueButtonLeft",
+ "PendingListInfoFrameContinueButtonMiddle",
+ "PendingListInfoFrameContinueButtonRight",
+ "PendingListInfoFrameContinueButtonText",
+ "PendingListInfoFrameLeft",
+ "PendingListInfoFramePlayerIcon",
+ "PendingListInfoFrameTitle",
+ "PendingList_Scroll",
+ "PendingList_Update",
+ "PendingList_UpdateTab",
+ "PersonalNoteText",
+ "PetAbandon",
+ "PetActionBarFrame",
+ "PetActionBarFrame_IsAboveShapeshift",
+ "PetActionBarFrame_OnUpdate",
+ "PetActionBar_HideGrid",
+ "PetActionBar_OnEvent",
+ "PetActionBar_OnLoad",
+ "PetActionBar_ShowGrid",
+ "PetActionBar_Update",
+ "PetActionBar_UpdateCooldowns",
+ "PetActionBar_UpdatePositionValues",
+ "PetActionButton1",
+ "PetActionButton10",
+ "PetActionButton10AutoCastable",
+ "PetActionButton10Border",
+ "PetActionButton10Cooldown",
+ "PetActionButton10Count",
+ "PetActionButton10Flash",
+ "PetActionButton10HotKey",
+ "PetActionButton10Icon",
+ "PetActionButton10Name",
+ "PetActionButton10NormalTexture2",
+ "PetActionButton10Shine",
+ "PetActionButton10Shine1",
+ "PetActionButton10Shine10",
+ "PetActionButton10Shine11",
+ "PetActionButton10Shine12",
+ "PetActionButton10Shine13",
+ "PetActionButton10Shine14",
+ "PetActionButton10Shine15",
+ "PetActionButton10Shine16",
+ "PetActionButton10Shine2",
+ "PetActionButton10Shine3",
+ "PetActionButton10Shine4",
+ "PetActionButton10Shine5",
+ "PetActionButton10Shine6",
+ "PetActionButton10Shine7",
+ "PetActionButton10Shine8",
+ "PetActionButton10Shine9",
+ "PetActionButton1AutoCastable",
+ "PetActionButton1Border",
+ "PetActionButton1Cooldown",
+ "PetActionButton1Count",
+ "PetActionButton1Flash",
+ "PetActionButton1HotKey",
+ "PetActionButton1Icon",
+ "PetActionButton1Name",
+ "PetActionButton1NormalTexture2",
+ "PetActionButton1Shine",
+ "PetActionButton1Shine1",
+ "PetActionButton1Shine10",
+ "PetActionButton1Shine11",
+ "PetActionButton1Shine12",
+ "PetActionButton1Shine13",
+ "PetActionButton1Shine14",
+ "PetActionButton1Shine15",
+ "PetActionButton1Shine16",
+ "PetActionButton1Shine2",
+ "PetActionButton1Shine3",
+ "PetActionButton1Shine4",
+ "PetActionButton1Shine5",
+ "PetActionButton1Shine6",
+ "PetActionButton1Shine7",
+ "PetActionButton1Shine8",
+ "PetActionButton1Shine9",
+ "PetActionButton2",
+ "PetActionButton2AutoCastable",
+ "PetActionButton2Border",
+ "PetActionButton2Cooldown",
+ "PetActionButton2Count",
+ "PetActionButton2Flash",
+ "PetActionButton2HotKey",
+ "PetActionButton2Icon",
+ "PetActionButton2Name",
+ "PetActionButton2NormalTexture2",
+ "PetActionButton2Shine",
+ "PetActionButton2Shine1",
+ "PetActionButton2Shine10",
+ "PetActionButton2Shine11",
+ "PetActionButton2Shine12",
+ "PetActionButton2Shine13",
+ "PetActionButton2Shine14",
+ "PetActionButton2Shine15",
+ "PetActionButton2Shine16",
+ "PetActionButton2Shine2",
+ "PetActionButton2Shine3",
+ "PetActionButton2Shine4",
+ "PetActionButton2Shine5",
+ "PetActionButton2Shine6",
+ "PetActionButton2Shine7",
+ "PetActionButton2Shine8",
+ "PetActionButton2Shine9",
+ "PetActionButton3",
+ "PetActionButton3AutoCastable",
+ "PetActionButton3Border",
+ "PetActionButton3Cooldown",
+ "PetActionButton3Count",
+ "PetActionButton3Flash",
+ "PetActionButton3HotKey",
+ "PetActionButton3Icon",
+ "PetActionButton3Name",
+ "PetActionButton3NormalTexture2",
+ "PetActionButton3Shine",
+ "PetActionButton3Shine1",
+ "PetActionButton3Shine10",
+ "PetActionButton3Shine11",
+ "PetActionButton3Shine12",
+ "PetActionButton3Shine13",
+ "PetActionButton3Shine14",
+ "PetActionButton3Shine15",
+ "PetActionButton3Shine16",
+ "PetActionButton3Shine2",
+ "PetActionButton3Shine3",
+ "PetActionButton3Shine4",
+ "PetActionButton3Shine5",
+ "PetActionButton3Shine6",
+ "PetActionButton3Shine7",
+ "PetActionButton3Shine8",
+ "PetActionButton3Shine9",
+ "PetActionButton4",
+ "PetActionButton4AutoCastable",
+ "PetActionButton4Border",
+ "PetActionButton4Cooldown",
+ "PetActionButton4Count",
+ "PetActionButton4Flash",
+ "PetActionButton4HotKey",
+ "PetActionButton4Icon",
+ "PetActionButton4Name",
+ "PetActionButton4NormalTexture2",
+ "PetActionButton4Shine",
+ "PetActionButton4Shine1",
+ "PetActionButton4Shine10",
+ "PetActionButton4Shine11",
+ "PetActionButton4Shine12",
+ "PetActionButton4Shine13",
+ "PetActionButton4Shine14",
+ "PetActionButton4Shine15",
+ "PetActionButton4Shine16",
+ "PetActionButton4Shine2",
+ "PetActionButton4Shine3",
+ "PetActionButton4Shine4",
+ "PetActionButton4Shine5",
+ "PetActionButton4Shine6",
+ "PetActionButton4Shine7",
+ "PetActionButton4Shine8",
+ "PetActionButton4Shine9",
+ "PetActionButton5",
+ "PetActionButton5AutoCastable",
+ "PetActionButton5Border",
+ "PetActionButton5Cooldown",
+ "PetActionButton5Count",
+ "PetActionButton5Flash",
+ "PetActionButton5HotKey",
+ "PetActionButton5Icon",
+ "PetActionButton5Name",
+ "PetActionButton5NormalTexture2",
+ "PetActionButton5Shine",
+ "PetActionButton5Shine1",
+ "PetActionButton5Shine10",
+ "PetActionButton5Shine11",
+ "PetActionButton5Shine12",
+ "PetActionButton5Shine13",
+ "PetActionButton5Shine14",
+ "PetActionButton5Shine15",
+ "PetActionButton5Shine16",
+ "PetActionButton5Shine2",
+ "PetActionButton5Shine3",
+ "PetActionButton5Shine4",
+ "PetActionButton5Shine5",
+ "PetActionButton5Shine6",
+ "PetActionButton5Shine7",
+ "PetActionButton5Shine8",
+ "PetActionButton5Shine9",
+ "PetActionButton6",
+ "PetActionButton6AutoCastable",
+ "PetActionButton6Border",
+ "PetActionButton6Cooldown",
+ "PetActionButton6Count",
+ "PetActionButton6Flash",
+ "PetActionButton6HotKey",
+ "PetActionButton6Icon",
+ "PetActionButton6Name",
+ "PetActionButton6NormalTexture2",
+ "PetActionButton6Shine",
+ "PetActionButton6Shine1",
+ "PetActionButton6Shine10",
+ "PetActionButton6Shine11",
+ "PetActionButton6Shine12",
+ "PetActionButton6Shine13",
+ "PetActionButton6Shine14",
+ "PetActionButton6Shine15",
+ "PetActionButton6Shine16",
+ "PetActionButton6Shine2",
+ "PetActionButton6Shine3",
+ "PetActionButton6Shine4",
+ "PetActionButton6Shine5",
+ "PetActionButton6Shine6",
+ "PetActionButton6Shine7",
+ "PetActionButton6Shine8",
+ "PetActionButton6Shine9",
+ "PetActionButton7",
+ "PetActionButton7AutoCastable",
+ "PetActionButton7Border",
+ "PetActionButton7Cooldown",
+ "PetActionButton7Count",
+ "PetActionButton7Flash",
+ "PetActionButton7HotKey",
+ "PetActionButton7Icon",
+ "PetActionButton7Name",
+ "PetActionButton7NormalTexture2",
+ "PetActionButton7Shine",
+ "PetActionButton7Shine1",
+ "PetActionButton7Shine10",
+ "PetActionButton7Shine11",
+ "PetActionButton7Shine12",
+ "PetActionButton7Shine13",
+ "PetActionButton7Shine14",
+ "PetActionButton7Shine15",
+ "PetActionButton7Shine16",
+ "PetActionButton7Shine2",
+ "PetActionButton7Shine3",
+ "PetActionButton7Shine4",
+ "PetActionButton7Shine5",
+ "PetActionButton7Shine6",
+ "PetActionButton7Shine7",
+ "PetActionButton7Shine8",
+ "PetActionButton7Shine9",
+ "PetActionButton8",
+ "PetActionButton8AutoCastable",
+ "PetActionButton8Border",
+ "PetActionButton8Cooldown",
+ "PetActionButton8Count",
+ "PetActionButton8Flash",
+ "PetActionButton8HotKey",
+ "PetActionButton8Icon",
+ "PetActionButton8Name",
+ "PetActionButton8NormalTexture2",
+ "PetActionButton8Shine",
+ "PetActionButton8Shine1",
+ "PetActionButton8Shine10",
+ "PetActionButton8Shine11",
+ "PetActionButton8Shine12",
+ "PetActionButton8Shine13",
+ "PetActionButton8Shine14",
+ "PetActionButton8Shine15",
+ "PetActionButton8Shine16",
+ "PetActionButton8Shine2",
+ "PetActionButton8Shine3",
+ "PetActionButton8Shine4",
+ "PetActionButton8Shine5",
+ "PetActionButton8Shine6",
+ "PetActionButton8Shine7",
+ "PetActionButton8Shine8",
+ "PetActionButton8Shine9",
+ "PetActionButton9",
+ "PetActionButton9AutoCastable",
+ "PetActionButton9Border",
+ "PetActionButton9Cooldown",
+ "PetActionButton9Count",
+ "PetActionButton9Flash",
+ "PetActionButton9HotKey",
+ "PetActionButton9Icon",
+ "PetActionButton9Name",
+ "PetActionButton9NormalTexture2",
+ "PetActionButton9Shine",
+ "PetActionButton9Shine1",
+ "PetActionButton9Shine10",
+ "PetActionButton9Shine11",
+ "PetActionButton9Shine12",
+ "PetActionButton9Shine13",
+ "PetActionButton9Shine14",
+ "PetActionButton9Shine15",
+ "PetActionButton9Shine16",
+ "PetActionButton9Shine2",
+ "PetActionButton9Shine3",
+ "PetActionButton9Shine4",
+ "PetActionButton9Shine5",
+ "PetActionButton9Shine6",
+ "PetActionButton9Shine7",
+ "PetActionButton9Shine8",
+ "PetActionButton9Shine9",
+ "PetActionButtonDown",
+ "PetActionButtonUp",
+ "PetActionButton_IsFlashing",
+ "PetActionButton_OnClick",
+ "PetActionButton_OnDragStart",
+ "PetActionButton_OnEnter",
+ "PetActionButton_OnEvent",
+ "PetActionButton_OnLeave",
+ "PetActionButton_OnLoad",
+ "PetActionButton_OnModifiedClick",
+ "PetActionButton_OnReceiveDrag",
+ "PetActionButton_OnUpdate",
+ "PetActionButton_SetHotkeys",
+ "PetActionButton_StartFlash",
+ "PetActionButton_StopFlash",
+ "PetAggressiveMode",
+ "PetArmorFrame",
+ "PetArmorFrameLabel",
+ "PetArmorFrameStat",
+ "PetArmorFrameStatText",
+ "PetAttack",
+ "PetAttackModeTexture",
+ "PetAttackPowerFrame",
+ "PetAttackPowerFrameLabel",
+ "PetAttackPowerFrameStat",
+ "PetAttackPowerFrameStatText",
+ "PetAttributesFrame",
+ "PetCanBeAbandoned",
+ "PetCanBeDismissed",
+ "PetCanBeRenamed",
+ "PetCastingBarFrame",
+ "PetCastingBarFrameBorder",
+ "PetCastingBarFrameBorderShield",
+ "PetCastingBarFrameFlash",
+ "PetCastingBarFrameIcon",
+ "PetCastingBarFrameSpark",
+ "PetCastingBarFrameText",
+ "PetCastingBarFrame_OnEvent",
+ "PetCastingBarFrame_OnLoad",
+ "PetDamageFrame",
+ "PetDamageFrameLabel",
+ "PetDamageFrameStat",
+ "PetDamageFrameStatText",
+ "PetDefensiveMode",
+ "PetDismiss",
+ "PetExpBar_Update",
+ "PetFollow",
+ "PetFrame",
+ "PetFrameDebuff1",
+ "PetFrameDebuff1Border",
+ "PetFrameDebuff1Icon",
+ "PetFrameDebuff2",
+ "PetFrameDebuff2Border",
+ "PetFrameDebuff2Icon",
+ "PetFrameDebuff3",
+ "PetFrameDebuff3Border",
+ "PetFrameDebuff3Icon",
+ "PetFrameDebuff4",
+ "PetFrameDebuff4Border",
+ "PetFrameDebuff4Icon",
+ "PetFrameDropDown",
+ "PetFrameDropDownButton",
+ "PetFrameDropDownButtonDisabledTexture",
+ "PetFrameDropDownButtonHighlightTexture",
+ "PetFrameDropDownButtonNormalTexture",
+ "PetFrameDropDownButtonPushedTexture",
+ "PetFrameDropDownLeft",
+ "PetFrameDropDownMiddle",
+ "PetFrameDropDownRight",
+ "PetFrameDropDownText",
+ "PetFrameDropDown_Initialize",
+ "PetFrameDropDown_OnLoad",
+ "PetFrameFlash",
+ "PetFrameHappiness",
+ "PetFrameHappinessTexture",
+ "PetFrameHealthBar",
+ "PetFrameHealthBarText",
+ "PetFrameManaBar",
+ "PetFrameManaBarText",
+ "PetFrameTexture",
+ "PetFrame_OnEvent",
+ "PetFrame_OnLoad",
+ "PetFrame_OnUpdate",
+ "PetFrame_SetHappiness",
+ "PetFrame_Update",
+ "PetHasActionBar",
+ "PetHitIndicator",
+ "PetLevelText",
+ "PetMagicResFrame1",
+ "PetMagicResFrame2",
+ "PetMagicResFrame3",
+ "PetMagicResFrame4",
+ "PetMagicResFrame5",
+ "PetMagicResText1",
+ "PetMagicResText2",
+ "PetMagicResText3",
+ "PetMagicResText4",
+ "PetMagicResText5",
+ "PetModelFrame",
+ "PetModelFrameRotateLeftButton",
+ "PetModelFrameRotateRightButton",
+ "PetName",
+ "PetNameText",
+ "PetPaperDollCloseButton",
+ "PetPaperDollCloseButtonText",
+ "PetPaperDollFrame",
+ "PetPaperDollFrameCompanionFrame",
+ "PetPaperDollFrameExpBar",
+ "PetPaperDollFrameExpBarText",
+ "PetPaperDollFramePetFrame",
+ "PetPaperDollFrameTab1",
+ "PetPaperDollFrameTab1HighlightTexture",
+ "PetPaperDollFrameTab1Left",
+ "PetPaperDollFrameTab1LeftDisabled",
+ "PetPaperDollFrameTab1Middle",
+ "PetPaperDollFrameTab1MiddleDisabled",
+ "PetPaperDollFrameTab1Right",
+ "PetPaperDollFrameTab1RightDisabled",
+ "PetPaperDollFrameTab1Text",
+ "PetPaperDollFrameTab2",
+ "PetPaperDollFrameTab2HighlightTexture",
+ "PetPaperDollFrameTab2Left",
+ "PetPaperDollFrameTab2LeftDisabled",
+ "PetPaperDollFrameTab2Middle",
+ "PetPaperDollFrameTab2MiddleDisabled",
+ "PetPaperDollFrameTab2Right",
+ "PetPaperDollFrameTab2RightDisabled",
+ "PetPaperDollFrameTab2Text",
+ "PetPaperDollFrameTab3",
+ "PetPaperDollFrameTab3HighlightTexture",
+ "PetPaperDollFrameTab3Left",
+ "PetPaperDollFrameTab3LeftDisabled",
+ "PetPaperDollFrameTab3Middle",
+ "PetPaperDollFrameTab3MiddleDisabled",
+ "PetPaperDollFrameTab3Right",
+ "PetPaperDollFrameTab3RightDisabled",
+ "PetPaperDollFrameTab3Text",
+ "PetPaperDollFrame_FindCompanionIndex",
+ "PetPaperDollFrame_OnEvent",
+ "PetPaperDollFrame_OnHide",
+ "PetPaperDollFrame_OnLoad",
+ "PetPaperDollFrame_OnShow",
+ "PetPaperDollFrame_SetCompanionPage",
+ "PetPaperDollFrame_SetResistances",
+ "PetPaperDollFrame_SetSpellBonusDamage",
+ "PetPaperDollFrame_SetStats",
+ "PetPaperDollFrame_SetTab",
+ "PetPaperDollFrame_Update",
+ "PetPaperDollFrame_UpdateCompanionCooldowns",
+ "PetPaperDollFrame_UpdateCompanionPreview",
+ "PetPaperDollFrame_UpdateCompanions",
+ "PetPaperDollFrame_UpdateIsAvailable",
+ "PetPaperDollFrame_UpdateTabs",
+ "PetPaperDollPetInfo",
+ "PetPaperDollXPBar1",
+ "PetPassiveMode",
+ "PetPortrait",
+ "PetRename",
+ "PetResistanceFrame",
+ "PetSpellDamageFrame",
+ "PetSpellDamageFrameLabel",
+ "PetSpellDamageFrameStat",
+ "PetSpellDamageFrameStatText",
+ "PetStableCostLabel",
+ "PetStableCostMoneyFrame",
+ "PetStableCostMoneyFrameCopperButton",
+ "PetStableCostMoneyFrameCopperButtonText",
+ "PetStableCostMoneyFrameGoldButton",
+ "PetStableCostMoneyFrameGoldButtonText",
+ "PetStableCostMoneyFrameSilverButton",
+ "PetStableCostMoneyFrameSilverButtonText",
+ "PetStableCurrentPet",
+ "PetStableCurrentPetBackground",
+ "PetStableCurrentPetIconTexture",
+ "PetStableCurrentPetNormalTexture",
+ "PetStableFrame",
+ "PetStableFrameBottomLeft",
+ "PetStableFrameBottomRight",
+ "PetStableFrameCloseButton",
+ "PetStableFramePortrait",
+ "PetStableLevelText",
+ "PetStableModel",
+ "PetStableModelRotateLeftButton",
+ "PetStableModelRotateRightButton",
+ "PetStableMoneyFrame",
+ "PetStableMoneyFrameCopperButton",
+ "PetStableMoneyFrameCopperButtonText",
+ "PetStableMoneyFrameGoldButton",
+ "PetStableMoneyFrameGoldButtonText",
+ "PetStableMoneyFrameSilverButton",
+ "PetStableMoneyFrameSilverButtonText",
+ "PetStablePetInfo",
+ "PetStablePurchaseButton",
+ "PetStablePurchaseButtonText",
+ "PetStableSlotText",
+ "PetStableStabledPet1",
+ "PetStableStabledPet1Background",
+ "PetStableStabledPet1IconTexture",
+ "PetStableStabledPet1NormalTexture",
+ "PetStableStabledPet2",
+ "PetStableStabledPet2Background",
+ "PetStableStabledPet2IconTexture",
+ "PetStableStabledPet2NormalTexture",
+ "PetStableStabledPet3",
+ "PetStableStabledPet3Background",
+ "PetStableStabledPet3IconTexture",
+ "PetStableStabledPet3NormalTexture",
+ "PetStableStabledPet4",
+ "PetStableStabledPet4Background",
+ "PetStableStabledPet4IconTexture",
+ "PetStableStabledPet4NormalTexture",
+ "PetStableTitleLabel",
+ "PetStable_NoPetsAllowed",
+ "PetStable_OnEvent",
+ "PetStable_OnLoad",
+ "PetStable_Update",
+ "PetStatFrame1",
+ "PetStatFrame1Label",
+ "PetStatFrame1Stat",
+ "PetStatFrame1StatText",
+ "PetStatFrame2",
+ "PetStatFrame2Label",
+ "PetStatFrame2Stat",
+ "PetStatFrame2StatText",
+ "PetStatFrame3",
+ "PetStatFrame3Label",
+ "PetStatFrame3Stat",
+ "PetStatFrame3StatText",
+ "PetStatFrame4",
+ "PetStatFrame4Label",
+ "PetStatFrame4Stat",
+ "PetStatFrame4StatText",
+ "PetStatFrame5",
+ "PetStatFrame5Label",
+ "PetStatFrame5Stat",
+ "PetStatFrame5StatText",
+ "PetStopAttack",
+ "PetWait",
+ "PetitionFrame",
+ "PetitionFrameCancelButton",
+ "PetitionFrameCancelButtonText",
+ "PetitionFrameCharterName",
+ "PetitionFrameCharterTitle",
+ "PetitionFrameCloseButton",
+ "PetitionFrameInstructions",
+ "PetitionFrameMasterName",
+ "PetitionFrameMasterTitle",
+ "PetitionFrameMemberName1",
+ "PetitionFrameMemberName2",
+ "PetitionFrameMemberName3",
+ "PetitionFrameMemberName4",
+ "PetitionFrameMemberName5",
+ "PetitionFrameMemberName6",
+ "PetitionFrameMemberName7",
+ "PetitionFrameMemberName8",
+ "PetitionFrameMemberName9",
+ "PetitionFrameMemberTitle",
+ "PetitionFrameNpcNameText",
+ "PetitionFramePortrait",
+ "PetitionFrameRenameButton",
+ "PetitionFrameRenameButtonText",
+ "PetitionFrameRequestButton",
+ "PetitionFrameRequestButtonText",
+ "PetitionFrameSignButton",
+ "PetitionFrameSignButtonText",
+ "PetitionFrame_Update",
+ "PetitionNpcNameFrame",
+ "PetitionText",
+ "PickupAction",
+ "PickupBagFromSlot",
+ "PickupCompanion",
+ "PickupContainerItem",
+ "PickupEquipmentSet",
+ "PickupEquipmentSetByName",
+ "PickupGuildBankItem",
+ "PickupGuildBankMoney",
+ "PickupInventoryItem",
+ "PickupItem",
+ "PickupMacro",
+ "PickupMerchantItem",
+ "PickupPetAction",
+ "PickupPlayerMoney",
+ "PickupSpell",
+ "PickupStablePet",
+ "PickupTradeMoney",
+ "PitchDownStart",
+ "PitchDownStop",
+ "PitchUpStart",
+ "PitchUpStop",
+ "PlaceAction",
+ "PlaceAuctionBid",
+ "PlaceGlyphInSocket",
+ "PlayDance",
+ "PlayLoopbackSoundButton",
+ "PlayLoopbackSoundButtonText",
+ "PlayLoopbackSoundButtonTexture",
+ "PlayMusic",
+ "PlaySound",
+ "PlaySoundFile",
+ "PlayerArrowEffectFrame",
+ "PlayerArrowFrame",
+ "PlayerAttackBackground",
+ "PlayerAttackGlow",
+ "PlayerAttackIcon",
+ "PlayerCanTeleport",
+ "PlayerFrame",
+ "PlayerFrameAlternateManaBar",
+ "PlayerFrameAlternateManaBarBackground",
+ "PlayerFrameAlternateManaBarBorder",
+ "PlayerFrameAlternateManaBarText",
+ "PlayerFrameBackground",
+ "PlayerFrameDropDown",
+ "PlayerFrameDropDownButton",
+ "PlayerFrameDropDownButtonDisabledTexture",
+ "PlayerFrameDropDownButtonHighlightTexture",
+ "PlayerFrameDropDownButtonNormalTexture",
+ "PlayerFrameDropDownButtonPushedTexture",
+ "PlayerFrameDropDownLeft",
+ "PlayerFrameDropDownMiddle",
+ "PlayerFrameDropDownRight",
+ "PlayerFrameDropDownText",
+ "PlayerFrameDropDown_Initialize",
+ "PlayerFrameDropDown_OnLoad",
+ "PlayerFrameFlash",
+ "PlayerFrameGroupIndicator",
+ "PlayerFrameGroupIndicatorLeft",
+ "PlayerFrameGroupIndicatorMiddle",
+ "PlayerFrameGroupIndicatorRight",
+ "PlayerFrameGroupIndicatorText",
+ "PlayerFrameHealthBar",
+ "PlayerFrameHealthBarText",
+ "PlayerFrameManaBar",
+ "PlayerFrameManaBarText",
+ "PlayerFrameReadyCheck",
+ "PlayerFrameReadyCheckTexture",
+ "PlayerFrameRoleIcon",
+ "PlayerFrameTexture",
+ "PlayerFrameVehicleTexture",
+ "PlayerFrame_AnimFinished",
+ "PlayerFrame_AnimateOut",
+ "PlayerFrame_OnEvent",
+ "PlayerFrame_OnLoad",
+ "PlayerFrame_OnReceiveDrag",
+ "PlayerFrame_OnUpdate",
+ "PlayerFrame_SequenceFinished",
+ "PlayerFrame_SetRunicPower",
+ "PlayerFrame_SetupDeathKnniggetLayout",
+ "PlayerFrame_ToPlayerArt",
+ "PlayerFrame_ToVehicleArt",
+ "PlayerFrame_Update",
+ "PlayerFrame_UpdateArt",
+ "PlayerFrame_UpdateGroupIndicator",
+ "PlayerFrame_UpdateLayout",
+ "PlayerFrame_UpdatePartyLeader",
+ "PlayerFrame_UpdatePlaytime",
+ "PlayerFrame_UpdatePvPStatus",
+ "PlayerFrame_UpdateReadyCheck",
+ "PlayerFrame_UpdateRolesAssigned",
+ "PlayerFrame_UpdateStatus",
+ "PlayerFrame_UpdateVoiceStatus",
+ "PlayerGlyphTab_OnClick",
+ "PlayerGlyphTab_OnEvent",
+ "PlayerGlyphTab_OnLoad",
+ "PlayerGuideIcon",
+ "PlayerHitIndicator",
+ "PlayerIsPVPInactive",
+ "PlayerLeaderIcon",
+ "PlayerLevelText",
+ "PlayerMasterIcon",
+ "PlayerMiniArrowEffectFrame",
+ "PlayerMiniArrowFrame",
+ "PlayerName",
+ "PlayerPVPIcon",
+ "PlayerPVPIconHitArea",
+ "PlayerPVPTimerText",
+ "PlayerPlayTime",
+ "PlayerPlayTimeIcon",
+ "PlayerPortrait",
+ "PlayerRestGlow",
+ "PlayerRestIcon",
+ "PlayerSpeakerFrame",
+ "PlayerSpeakerFrameFlash",
+ "PlayerSpeakerFrameMuted",
+ "PlayerSpeakerFrameOn",
+ "PlayerSpecTab1",
+ "PlayerSpecTab1Background",
+ "PlayerSpecTab2",
+ "PlayerSpecTab2Background",
+ "PlayerSpecTab3",
+ "PlayerSpecTab3Background",
+ "PlayerSpecTab_Load",
+ "PlayerSpecTab_OnClick",
+ "PlayerSpecTab_OnEnter",
+ "PlayerSpecTab_Update",
+ "PlayerStatFrameLeft1",
+ "PlayerStatFrameLeft1Label",
+ "PlayerStatFrameLeft1Stat",
+ "PlayerStatFrameLeft1StatText",
+ "PlayerStatFrameLeft2",
+ "PlayerStatFrameLeft2Label",
+ "PlayerStatFrameLeft2Stat",
+ "PlayerStatFrameLeft2StatText",
+ "PlayerStatFrameLeft3",
+ "PlayerStatFrameLeft3Label",
+ "PlayerStatFrameLeft3Stat",
+ "PlayerStatFrameLeft3StatText",
+ "PlayerStatFrameLeft4",
+ "PlayerStatFrameLeft4Label",
+ "PlayerStatFrameLeft4Stat",
+ "PlayerStatFrameLeft4StatText",
+ "PlayerStatFrameLeft5",
+ "PlayerStatFrameLeft5Label",
+ "PlayerStatFrameLeft5Stat",
+ "PlayerStatFrameLeft5StatText",
+ "PlayerStatFrameLeft6",
+ "PlayerStatFrameLeft6Label",
+ "PlayerStatFrameLeft6Stat",
+ "PlayerStatFrameLeft6StatText",
+ "PlayerStatFrameLeftDropDown",
+ "PlayerStatFrameLeftDropDownButton",
+ "PlayerStatFrameLeftDropDownButtonDisabledTexture",
+ "PlayerStatFrameLeftDropDownButtonHighlightTexture",
+ "PlayerStatFrameLeftDropDownButtonNormalTexture",
+ "PlayerStatFrameLeftDropDownButtonPushedTexture",
+ "PlayerStatFrameLeftDropDownLeft",
+ "PlayerStatFrameLeftDropDownMiddle",
+ "PlayerStatFrameLeftDropDownRight",
+ "PlayerStatFrameLeftDropDownText",
+ "PlayerStatFrameLeftDropDown_Initialize",
+ "PlayerStatFrameLeftDropDown_OnClick",
+ "PlayerStatFrameLeftDropDown_OnLoad",
+ "PlayerStatFrameLeftDropDown_OnShow",
+ "PlayerStatFrameRight1",
+ "PlayerStatFrameRight1Label",
+ "PlayerStatFrameRight1Stat",
+ "PlayerStatFrameRight1StatText",
+ "PlayerStatFrameRight2",
+ "PlayerStatFrameRight2Label",
+ "PlayerStatFrameRight2Stat",
+ "PlayerStatFrameRight2StatText",
+ "PlayerStatFrameRight3",
+ "PlayerStatFrameRight3Label",
+ "PlayerStatFrameRight3Stat",
+ "PlayerStatFrameRight3StatText",
+ "PlayerStatFrameRight4",
+ "PlayerStatFrameRight4Label",
+ "PlayerStatFrameRight4Stat",
+ "PlayerStatFrameRight4StatText",
+ "PlayerStatFrameRight5",
+ "PlayerStatFrameRight5Label",
+ "PlayerStatFrameRight5Stat",
+ "PlayerStatFrameRight5StatText",
+ "PlayerStatFrameRight6",
+ "PlayerStatFrameRight6Label",
+ "PlayerStatFrameRight6Stat",
+ "PlayerStatFrameRight6StatText",
+ "PlayerStatFrameRightDropDown",
+ "PlayerStatFrameRightDropDownButton",
+ "PlayerStatFrameRightDropDownButtonDisabledTexture",
+ "PlayerStatFrameRightDropDownButtonHighlightTexture",
+ "PlayerStatFrameRightDropDownButtonNormalTexture",
+ "PlayerStatFrameRightDropDownButtonPushedTexture",
+ "PlayerStatFrameRightDropDownLeft",
+ "PlayerStatFrameRightDropDownMiddle",
+ "PlayerStatFrameRightDropDownRight",
+ "PlayerStatFrameRightDropDownText",
+ "PlayerStatFrameRightDropDown_Initialize",
+ "PlayerStatFrameRightDropDown_OnClick",
+ "PlayerStatFrameRightDropDown_OnLoad",
+ "PlayerStatFrameRightDropDown_OnShow",
+ "PlayerStatLeftBottom",
+ "PlayerStatLeftMiddle",
+ "PlayerStatLeftTop",
+ "PlayerStatRightBottom",
+ "PlayerStatRightMiddle",
+ "PlayerStatRightTop",
+ "PlayerStatusGlow",
+ "PlayerStatusTexture",
+ "PlayerTalentFrame",
+ "PlayerTalentFrameActivateButton",
+ "PlayerTalentFrameActivateButtonLeft",
+ "PlayerTalentFrameActivateButtonMiddle",
+ "PlayerTalentFrameActivateButtonRight",
+ "PlayerTalentFrameActivateButtonText",
+ "PlayerTalentFrameActivateButton_OnClick",
+ "PlayerTalentFrameActivateButton_OnEvent",
+ "PlayerTalentFrameActivateButton_OnHide",
+ "PlayerTalentFrameActivateButton_OnLoad",
+ "PlayerTalentFrameActivateButton_OnShow",
+ "PlayerTalentFrameActivateButton_Update",
+ "PlayerTalentFrameActiveSpecTabHighlight",
+ "PlayerTalentFrameActiveTalentGroupFrame",
+ "PlayerTalentFrameArrow1",
+ "PlayerTalentFrameArrow10",
+ "PlayerTalentFrameArrow11",
+ "PlayerTalentFrameArrow12",
+ "PlayerTalentFrameArrow13",
+ "PlayerTalentFrameArrow14",
+ "PlayerTalentFrameArrow15",
+ "PlayerTalentFrameArrow16",
+ "PlayerTalentFrameArrow17",
+ "PlayerTalentFrameArrow18",
+ "PlayerTalentFrameArrow19",
+ "PlayerTalentFrameArrow2",
+ "PlayerTalentFrameArrow20",
+ "PlayerTalentFrameArrow21",
+ "PlayerTalentFrameArrow22",
+ "PlayerTalentFrameArrow23",
+ "PlayerTalentFrameArrow24",
+ "PlayerTalentFrameArrow25",
+ "PlayerTalentFrameArrow26",
+ "PlayerTalentFrameArrow27",
+ "PlayerTalentFrameArrow28",
+ "PlayerTalentFrameArrow29",
+ "PlayerTalentFrameArrow3",
+ "PlayerTalentFrameArrow30",
+ "PlayerTalentFrameArrow4",
+ "PlayerTalentFrameArrow5",
+ "PlayerTalentFrameArrow6",
+ "PlayerTalentFrameArrow7",
+ "PlayerTalentFrameArrow8",
+ "PlayerTalentFrameArrow9",
+ "PlayerTalentFrameArrowFrame",
+ "PlayerTalentFrameBackgroundBottomLeft",
+ "PlayerTalentFrameBackgroundBottomRight",
+ "PlayerTalentFrameBackgroundTopLeft",
+ "PlayerTalentFrameBackgroundTopRight",
+ "PlayerTalentFrameBottomLeft",
+ "PlayerTalentFrameBottomRight",
+ "PlayerTalentFrameBranch1",
+ "PlayerTalentFrameBranch10",
+ "PlayerTalentFrameBranch11",
+ "PlayerTalentFrameBranch12",
+ "PlayerTalentFrameBranch13",
+ "PlayerTalentFrameBranch14",
+ "PlayerTalentFrameBranch15",
+ "PlayerTalentFrameBranch16",
+ "PlayerTalentFrameBranch17",
+ "PlayerTalentFrameBranch18",
+ "PlayerTalentFrameBranch19",
+ "PlayerTalentFrameBranch2",
+ "PlayerTalentFrameBranch20",
+ "PlayerTalentFrameBranch21",
+ "PlayerTalentFrameBranch22",
+ "PlayerTalentFrameBranch23",
+ "PlayerTalentFrameBranch24",
+ "PlayerTalentFrameBranch25",
+ "PlayerTalentFrameBranch26",
+ "PlayerTalentFrameBranch27",
+ "PlayerTalentFrameBranch28",
+ "PlayerTalentFrameBranch29",
+ "PlayerTalentFrameBranch3",
+ "PlayerTalentFrameBranch30",
+ "PlayerTalentFrameBranch4",
+ "PlayerTalentFrameBranch5",
+ "PlayerTalentFrameBranch6",
+ "PlayerTalentFrameBranch7",
+ "PlayerTalentFrameBranch8",
+ "PlayerTalentFrameBranch9",
+ "PlayerTalentFrameCloseButton",
+ "PlayerTalentFrameDownArrow_OnClick",
+ "PlayerTalentFrameLearnButton",
+ "PlayerTalentFrameLearnButtonText",
+ "PlayerTalentFrameLearnButton_OnClick",
+ "PlayerTalentFrameLearnButton_OnEnter",
+ "PlayerTalentFramePointsBar",
+ "PlayerTalentFramePointsBarBackground",
+ "PlayerTalentFramePointsBarBorderLeft",
+ "PlayerTalentFramePointsBarBorderMiddle",
+ "PlayerTalentFramePointsBarBorderRight",
+ "PlayerTalentFramePointsLeft",
+ "PlayerTalentFramePointsMiddle",
+ "PlayerTalentFramePointsRight",
+ "PlayerTalentFramePortrait",
+ "PlayerTalentFramePreviewBar",
+ "PlayerTalentFramePreviewBarButtonBorder",
+ "PlayerTalentFramePreviewBarFiller",
+ "PlayerTalentFramePreviewBarFillerButtonBackgroundLeft",
+ "PlayerTalentFramePreviewBarFillerButtonBackgroundMiddle",
+ "PlayerTalentFramePreviewBarFillerButtonBackgroundRight",
+ "PlayerTalentFrameResetButton",
+ "PlayerTalentFrameResetButtonText",
+ "PlayerTalentFrameResetButton_OnClick",
+ "PlayerTalentFrameResetButton_OnEnter",
+ "PlayerTalentFrameScrollButtonOverlay",
+ "PlayerTalentFrameScrollChildFrame",
+ "PlayerTalentFrameScrollFrame",
+ "PlayerTalentFrameScrollFrameBackgroundBottom",
+ "PlayerTalentFrameScrollFrameBackgroundTop",
+ "PlayerTalentFrameScrollFrameScrollBar",
+ "PlayerTalentFrameScrollFrameScrollBarScrollDownButton",
+ "PlayerTalentFrameScrollFrameScrollBarScrollUpButton",
+ "PlayerTalentFrameScrollFrameScrollBarThumbTexture",
+ "PlayerTalentFrameSpentPointsText",
+ "PlayerTalentFrameStatusFrame",
+ "PlayerTalentFrameStatusText",
+ "PlayerTalentFrameTab1",
+ "PlayerTalentFrameTab1HighlightTexture",
+ "PlayerTalentFrameTab1Left",
+ "PlayerTalentFrameTab1LeftDisabled",
+ "PlayerTalentFrameTab1Middle",
+ "PlayerTalentFrameTab1MiddleDisabled",
+ "PlayerTalentFrameTab1Right",
+ "PlayerTalentFrameTab1RightDisabled",
+ "PlayerTalentFrameTab1Text",
+ "PlayerTalentFrameTab2",
+ "PlayerTalentFrameTab2HighlightTexture",
+ "PlayerTalentFrameTab2Left",
+ "PlayerTalentFrameTab2LeftDisabled",
+ "PlayerTalentFrameTab2Middle",
+ "PlayerTalentFrameTab2MiddleDisabled",
+ "PlayerTalentFrameTab2Right",
+ "PlayerTalentFrameTab2RightDisabled",
+ "PlayerTalentFrameTab2Text",
+ "PlayerTalentFrameTab3",
+ "PlayerTalentFrameTab3HighlightTexture",
+ "PlayerTalentFrameTab3Left",
+ "PlayerTalentFrameTab3LeftDisabled",
+ "PlayerTalentFrameTab3Middle",
+ "PlayerTalentFrameTab3MiddleDisabled",
+ "PlayerTalentFrameTab3Right",
+ "PlayerTalentFrameTab3RightDisabled",
+ "PlayerTalentFrameTab3Text",
+ "PlayerTalentFrameTab4",
+ "PlayerTalentFrameTab4HighlightTexture",
+ "PlayerTalentFrameTab4Left",
+ "PlayerTalentFrameTab4LeftDisabled",
+ "PlayerTalentFrameTab4Middle",
+ "PlayerTalentFrameTab4MiddleDisabled",
+ "PlayerTalentFrameTab4Right",
+ "PlayerTalentFrameTab4RightDisabled",
+ "PlayerTalentFrameTab4Text",
+ "PlayerTalentFrameTab_OnClick",
+ "PlayerTalentFrameTab_OnEnter",
+ "PlayerTalentFrameTab_OnLoad",
+ "PlayerTalentFrameTalent1",
+ "PlayerTalentFrameTalent10",
+ "PlayerTalentFrameTalent10Count",
+ "PlayerTalentFrameTalent10IconTexture",
+ "PlayerTalentFrameTalent10NormalTexture",
+ "PlayerTalentFrameTalent10Rank",
+ "PlayerTalentFrameTalent10RankBorder",
+ "PlayerTalentFrameTalent10Slot",
+ "PlayerTalentFrameTalent10Stock",
+ "PlayerTalentFrameTalent11",
+ "PlayerTalentFrameTalent11Count",
+ "PlayerTalentFrameTalent11IconTexture",
+ "PlayerTalentFrameTalent11NormalTexture",
+ "PlayerTalentFrameTalent11Rank",
+ "PlayerTalentFrameTalent11RankBorder",
+ "PlayerTalentFrameTalent11Slot",
+ "PlayerTalentFrameTalent11Stock",
+ "PlayerTalentFrameTalent12",
+ "PlayerTalentFrameTalent12Count",
+ "PlayerTalentFrameTalent12IconTexture",
+ "PlayerTalentFrameTalent12NormalTexture",
+ "PlayerTalentFrameTalent12Rank",
+ "PlayerTalentFrameTalent12RankBorder",
+ "PlayerTalentFrameTalent12Slot",
+ "PlayerTalentFrameTalent12Stock",
+ "PlayerTalentFrameTalent13",
+ "PlayerTalentFrameTalent13Count",
+ "PlayerTalentFrameTalent13IconTexture",
+ "PlayerTalentFrameTalent13NormalTexture",
+ "PlayerTalentFrameTalent13Rank",
+ "PlayerTalentFrameTalent13RankBorder",
+ "PlayerTalentFrameTalent13Slot",
+ "PlayerTalentFrameTalent13Stock",
+ "PlayerTalentFrameTalent14",
+ "PlayerTalentFrameTalent14Count",
+ "PlayerTalentFrameTalent14IconTexture",
+ "PlayerTalentFrameTalent14NormalTexture",
+ "PlayerTalentFrameTalent14Rank",
+ "PlayerTalentFrameTalent14RankBorder",
+ "PlayerTalentFrameTalent14Slot",
+ "PlayerTalentFrameTalent14Stock",
+ "PlayerTalentFrameTalent15",
+ "PlayerTalentFrameTalent15Count",
+ "PlayerTalentFrameTalent15IconTexture",
+ "PlayerTalentFrameTalent15NormalTexture",
+ "PlayerTalentFrameTalent15Rank",
+ "PlayerTalentFrameTalent15RankBorder",
+ "PlayerTalentFrameTalent15Slot",
+ "PlayerTalentFrameTalent15Stock",
+ "PlayerTalentFrameTalent16",
+ "PlayerTalentFrameTalent16Count",
+ "PlayerTalentFrameTalent16IconTexture",
+ "PlayerTalentFrameTalent16NormalTexture",
+ "PlayerTalentFrameTalent16Rank",
+ "PlayerTalentFrameTalent16RankBorder",
+ "PlayerTalentFrameTalent16Slot",
+ "PlayerTalentFrameTalent16Stock",
+ "PlayerTalentFrameTalent17",
+ "PlayerTalentFrameTalent17Count",
+ "PlayerTalentFrameTalent17IconTexture",
+ "PlayerTalentFrameTalent17NormalTexture",
+ "PlayerTalentFrameTalent17Rank",
+ "PlayerTalentFrameTalent17RankBorder",
+ "PlayerTalentFrameTalent17Slot",
+ "PlayerTalentFrameTalent17Stock",
+ "PlayerTalentFrameTalent18",
+ "PlayerTalentFrameTalent18Count",
+ "PlayerTalentFrameTalent18IconTexture",
+ "PlayerTalentFrameTalent18NormalTexture",
+ "PlayerTalentFrameTalent18Rank",
+ "PlayerTalentFrameTalent18RankBorder",
+ "PlayerTalentFrameTalent18Slot",
+ "PlayerTalentFrameTalent18Stock",
+ "PlayerTalentFrameTalent19",
+ "PlayerTalentFrameTalent19Count",
+ "PlayerTalentFrameTalent19IconTexture",
+ "PlayerTalentFrameTalent19NormalTexture",
+ "PlayerTalentFrameTalent19Rank",
+ "PlayerTalentFrameTalent19RankBorder",
+ "PlayerTalentFrameTalent19Slot",
+ "PlayerTalentFrameTalent19Stock",
+ "PlayerTalentFrameTalent1Count",
+ "PlayerTalentFrameTalent1IconTexture",
+ "PlayerTalentFrameTalent1NormalTexture",
+ "PlayerTalentFrameTalent1Rank",
+ "PlayerTalentFrameTalent1RankBorder",
+ "PlayerTalentFrameTalent1Slot",
+ "PlayerTalentFrameTalent1Stock",
+ "PlayerTalentFrameTalent2",
+ "PlayerTalentFrameTalent20",
+ "PlayerTalentFrameTalent20Count",
+ "PlayerTalentFrameTalent20IconTexture",
+ "PlayerTalentFrameTalent20NormalTexture",
+ "PlayerTalentFrameTalent20Rank",
+ "PlayerTalentFrameTalent20RankBorder",
+ "PlayerTalentFrameTalent20Slot",
+ "PlayerTalentFrameTalent20Stock",
+ "PlayerTalentFrameTalent21",
+ "PlayerTalentFrameTalent21Count",
+ "PlayerTalentFrameTalent21IconTexture",
+ "PlayerTalentFrameTalent21NormalTexture",
+ "PlayerTalentFrameTalent21Rank",
+ "PlayerTalentFrameTalent21RankBorder",
+ "PlayerTalentFrameTalent21Slot",
+ "PlayerTalentFrameTalent21Stock",
+ "PlayerTalentFrameTalent22",
+ "PlayerTalentFrameTalent22Count",
+ "PlayerTalentFrameTalent22IconTexture",
+ "PlayerTalentFrameTalent22NormalTexture",
+ "PlayerTalentFrameTalent22Rank",
+ "PlayerTalentFrameTalent22RankBorder",
+ "PlayerTalentFrameTalent22Slot",
+ "PlayerTalentFrameTalent22Stock",
+ "PlayerTalentFrameTalent23",
+ "PlayerTalentFrameTalent23Count",
+ "PlayerTalentFrameTalent23IconTexture",
+ "PlayerTalentFrameTalent23NormalTexture",
+ "PlayerTalentFrameTalent23Rank",
+ "PlayerTalentFrameTalent23RankBorder",
+ "PlayerTalentFrameTalent23Slot",
+ "PlayerTalentFrameTalent23Stock",
+ "PlayerTalentFrameTalent24",
+ "PlayerTalentFrameTalent24Count",
+ "PlayerTalentFrameTalent24IconTexture",
+ "PlayerTalentFrameTalent24NormalTexture",
+ "PlayerTalentFrameTalent24Rank",
+ "PlayerTalentFrameTalent24RankBorder",
+ "PlayerTalentFrameTalent24Slot",
+ "PlayerTalentFrameTalent24Stock",
+ "PlayerTalentFrameTalent25",
+ "PlayerTalentFrameTalent25Count",
+ "PlayerTalentFrameTalent25IconTexture",
+ "PlayerTalentFrameTalent25NormalTexture",
+ "PlayerTalentFrameTalent25Rank",
+ "PlayerTalentFrameTalent25RankBorder",
+ "PlayerTalentFrameTalent25Slot",
+ "PlayerTalentFrameTalent25Stock",
+ "PlayerTalentFrameTalent26",
+ "PlayerTalentFrameTalent26Count",
+ "PlayerTalentFrameTalent26IconTexture",
+ "PlayerTalentFrameTalent26NormalTexture",
+ "PlayerTalentFrameTalent26Rank",
+ "PlayerTalentFrameTalent26RankBorder",
+ "PlayerTalentFrameTalent26Slot",
+ "PlayerTalentFrameTalent26Stock",
+ "PlayerTalentFrameTalent27",
+ "PlayerTalentFrameTalent27Count",
+ "PlayerTalentFrameTalent27IconTexture",
+ "PlayerTalentFrameTalent27NormalTexture",
+ "PlayerTalentFrameTalent27Rank",
+ "PlayerTalentFrameTalent27RankBorder",
+ "PlayerTalentFrameTalent27Slot",
+ "PlayerTalentFrameTalent27Stock",
+ "PlayerTalentFrameTalent28",
+ "PlayerTalentFrameTalent28Count",
+ "PlayerTalentFrameTalent28IconTexture",
+ "PlayerTalentFrameTalent28NormalTexture",
+ "PlayerTalentFrameTalent28Rank",
+ "PlayerTalentFrameTalent28RankBorder",
+ "PlayerTalentFrameTalent28Slot",
+ "PlayerTalentFrameTalent28Stock",
+ "PlayerTalentFrameTalent29",
+ "PlayerTalentFrameTalent29Count",
+ "PlayerTalentFrameTalent29IconTexture",
+ "PlayerTalentFrameTalent29NormalTexture",
+ "PlayerTalentFrameTalent29Rank",
+ "PlayerTalentFrameTalent29RankBorder",
+ "PlayerTalentFrameTalent29Slot",
+ "PlayerTalentFrameTalent29Stock",
+ "PlayerTalentFrameTalent2Count",
+ "PlayerTalentFrameTalent2IconTexture",
+ "PlayerTalentFrameTalent2NormalTexture",
+ "PlayerTalentFrameTalent2Rank",
+ "PlayerTalentFrameTalent2RankBorder",
+ "PlayerTalentFrameTalent2Slot",
+ "PlayerTalentFrameTalent2Stock",
+ "PlayerTalentFrameTalent3",
+ "PlayerTalentFrameTalent30",
+ "PlayerTalentFrameTalent30Count",
+ "PlayerTalentFrameTalent30IconTexture",
+ "PlayerTalentFrameTalent30NormalTexture",
+ "PlayerTalentFrameTalent30Rank",
+ "PlayerTalentFrameTalent30RankBorder",
+ "PlayerTalentFrameTalent30Slot",
+ "PlayerTalentFrameTalent30Stock",
+ "PlayerTalentFrameTalent31",
+ "PlayerTalentFrameTalent31Count",
+ "PlayerTalentFrameTalent31IconTexture",
+ "PlayerTalentFrameTalent31NormalTexture",
+ "PlayerTalentFrameTalent31Rank",
+ "PlayerTalentFrameTalent31RankBorder",
+ "PlayerTalentFrameTalent31Slot",
+ "PlayerTalentFrameTalent31Stock",
+ "PlayerTalentFrameTalent32",
+ "PlayerTalentFrameTalent32Count",
+ "PlayerTalentFrameTalent32IconTexture",
+ "PlayerTalentFrameTalent32NormalTexture",
+ "PlayerTalentFrameTalent32Rank",
+ "PlayerTalentFrameTalent32RankBorder",
+ "PlayerTalentFrameTalent32Slot",
+ "PlayerTalentFrameTalent32Stock",
+ "PlayerTalentFrameTalent33",
+ "PlayerTalentFrameTalent33Count",
+ "PlayerTalentFrameTalent33IconTexture",
+ "PlayerTalentFrameTalent33NormalTexture",
+ "PlayerTalentFrameTalent33Rank",
+ "PlayerTalentFrameTalent33RankBorder",
+ "PlayerTalentFrameTalent33Slot",
+ "PlayerTalentFrameTalent33Stock",
+ "PlayerTalentFrameTalent34",
+ "PlayerTalentFrameTalent34Count",
+ "PlayerTalentFrameTalent34IconTexture",
+ "PlayerTalentFrameTalent34NormalTexture",
+ "PlayerTalentFrameTalent34Rank",
+ "PlayerTalentFrameTalent34RankBorder",
+ "PlayerTalentFrameTalent34Slot",
+ "PlayerTalentFrameTalent34Stock",
+ "PlayerTalentFrameTalent35",
+ "PlayerTalentFrameTalent35Count",
+ "PlayerTalentFrameTalent35IconTexture",
+ "PlayerTalentFrameTalent35NormalTexture",
+ "PlayerTalentFrameTalent35Rank",
+ "PlayerTalentFrameTalent35RankBorder",
+ "PlayerTalentFrameTalent35Slot",
+ "PlayerTalentFrameTalent35Stock",
+ "PlayerTalentFrameTalent36",
+ "PlayerTalentFrameTalent36Count",
+ "PlayerTalentFrameTalent36IconTexture",
+ "PlayerTalentFrameTalent36NormalTexture",
+ "PlayerTalentFrameTalent36Rank",
+ "PlayerTalentFrameTalent36RankBorder",
+ "PlayerTalentFrameTalent36Slot",
+ "PlayerTalentFrameTalent36Stock",
+ "PlayerTalentFrameTalent37",
+ "PlayerTalentFrameTalent37Count",
+ "PlayerTalentFrameTalent37IconTexture",
+ "PlayerTalentFrameTalent37NormalTexture",
+ "PlayerTalentFrameTalent37Rank",
+ "PlayerTalentFrameTalent37RankBorder",
+ "PlayerTalentFrameTalent37Slot",
+ "PlayerTalentFrameTalent37Stock",
+ "PlayerTalentFrameTalent38",
+ "PlayerTalentFrameTalent38Count",
+ "PlayerTalentFrameTalent38IconTexture",
+ "PlayerTalentFrameTalent38NormalTexture",
+ "PlayerTalentFrameTalent38Rank",
+ "PlayerTalentFrameTalent38RankBorder",
+ "PlayerTalentFrameTalent38Slot",
+ "PlayerTalentFrameTalent38Stock",
+ "PlayerTalentFrameTalent39",
+ "PlayerTalentFrameTalent39Count",
+ "PlayerTalentFrameTalent39IconTexture",
+ "PlayerTalentFrameTalent39NormalTexture",
+ "PlayerTalentFrameTalent39Rank",
+ "PlayerTalentFrameTalent39RankBorder",
+ "PlayerTalentFrameTalent39Slot",
+ "PlayerTalentFrameTalent39Stock",
+ "PlayerTalentFrameTalent3Count",
+ "PlayerTalentFrameTalent3IconTexture",
+ "PlayerTalentFrameTalent3NormalTexture",
+ "PlayerTalentFrameTalent3Rank",
+ "PlayerTalentFrameTalent3RankBorder",
+ "PlayerTalentFrameTalent3Slot",
+ "PlayerTalentFrameTalent3Stock",
+ "PlayerTalentFrameTalent4",
+ "PlayerTalentFrameTalent40",
+ "PlayerTalentFrameTalent40Count",
+ "PlayerTalentFrameTalent40IconTexture",
+ "PlayerTalentFrameTalent40NormalTexture",
+ "PlayerTalentFrameTalent40Rank",
+ "PlayerTalentFrameTalent40RankBorder",
+ "PlayerTalentFrameTalent40Slot",
+ "PlayerTalentFrameTalent40Stock",
+ "PlayerTalentFrameTalent4Count",
+ "PlayerTalentFrameTalent4IconTexture",
+ "PlayerTalentFrameTalent4NormalTexture",
+ "PlayerTalentFrameTalent4Rank",
+ "PlayerTalentFrameTalent4RankBorder",
+ "PlayerTalentFrameTalent4Slot",
+ "PlayerTalentFrameTalent4Stock",
+ "PlayerTalentFrameTalent5",
+ "PlayerTalentFrameTalent5Count",
+ "PlayerTalentFrameTalent5IconTexture",
+ "PlayerTalentFrameTalent5NormalTexture",
+ "PlayerTalentFrameTalent5Rank",
+ "PlayerTalentFrameTalent5RankBorder",
+ "PlayerTalentFrameTalent5Slot",
+ "PlayerTalentFrameTalent5Stock",
+ "PlayerTalentFrameTalent6",
+ "PlayerTalentFrameTalent6Count",
+ "PlayerTalentFrameTalent6IconTexture",
+ "PlayerTalentFrameTalent6NormalTexture",
+ "PlayerTalentFrameTalent6Rank",
+ "PlayerTalentFrameTalent6RankBorder",
+ "PlayerTalentFrameTalent6Slot",
+ "PlayerTalentFrameTalent6Stock",
+ "PlayerTalentFrameTalent7",
+ "PlayerTalentFrameTalent7Count",
+ "PlayerTalentFrameTalent7IconTexture",
+ "PlayerTalentFrameTalent7NormalTexture",
+ "PlayerTalentFrameTalent7Rank",
+ "PlayerTalentFrameTalent7RankBorder",
+ "PlayerTalentFrameTalent7Slot",
+ "PlayerTalentFrameTalent7Stock",
+ "PlayerTalentFrameTalent8",
+ "PlayerTalentFrameTalent8Count",
+ "PlayerTalentFrameTalent8IconTexture",
+ "PlayerTalentFrameTalent8NormalTexture",
+ "PlayerTalentFrameTalent8Rank",
+ "PlayerTalentFrameTalent8RankBorder",
+ "PlayerTalentFrameTalent8Slot",
+ "PlayerTalentFrameTalent8Stock",
+ "PlayerTalentFrameTalent9",
+ "PlayerTalentFrameTalent9Count",
+ "PlayerTalentFrameTalent9IconTexture",
+ "PlayerTalentFrameTalent9NormalTexture",
+ "PlayerTalentFrameTalent9Rank",
+ "PlayerTalentFrameTalent9RankBorder",
+ "PlayerTalentFrameTalent9Slot",
+ "PlayerTalentFrameTalent9Stock",
+ "PlayerTalentFrameTalentPointsText",
+ "PlayerTalentFrameTalent_OnClick",
+ "PlayerTalentFrameTalent_OnEnter",
+ "PlayerTalentFrameTalent_OnEvent",
+ "PlayerTalentFrameTitleText",
+ "PlayerTalentFrameTopLeft",
+ "PlayerTalentFrameTopRight",
+ "PlayerTalentFrame_HideGlyphFrame",
+ "PlayerTalentFrame_OnEvent",
+ "PlayerTalentFrame_OnHide",
+ "PlayerTalentFrame_OnLoad",
+ "PlayerTalentFrame_OnShow",
+ "PlayerTalentFrame_Open",
+ "PlayerTalentFrame_OpenGlyphFrame",
+ "PlayerTalentFrame_Refresh",
+ "PlayerTalentFrame_ShowGlyphFrame",
+ "PlayerTalentFrame_Toggle",
+ "PlayerTalentFrame_ToggleGlyphFrame",
+ "PlayerTalentFrame_Update",
+ "PlayerTalentFrame_UpdateActiveSpec",
+ "PlayerTalentFrame_UpdateControls",
+ "PlayerTalentFrame_UpdateSpecs",
+ "PlayerTalentFrame_UpdateTabs",
+ "PlayerTalentTab_GetBestDefaultTab",
+ "PlayerTalentTab_OnClick",
+ "PlayerTalentTab_OnEvent",
+ "PlayerTalentTab_OnLoad",
+ "PlayerTitleButton_OnClick",
+ "PlayerTitleFrame",
+ "PlayerTitleFrameButton",
+ "PlayerTitleFrameButtonHighlightTexture",
+ "PlayerTitleFrameButtonNormalTexture",
+ "PlayerTitleFrameButtonPushedTexture",
+ "PlayerTitleFrameLeft",
+ "PlayerTitleFrameMiddle",
+ "PlayerTitleFrameRight",
+ "PlayerTitleFrameText",
+ "PlayerTitleFrame_UpdateTitles",
+ "PlayerTitlePickerFrame",
+ "PlayerTitlePickerFrame_Toggle",
+ "PlayerTitlePickerScrollFrame",
+ "PlayerTitlePickerScrollFrameButton1",
+ "PlayerTitlePickerScrollFrameButton1Check",
+ "PlayerTitlePickerScrollFrameButton1TitleText",
+ "PlayerTitlePickerScrollFrameButton2",
+ "PlayerTitlePickerScrollFrameButton2Check",
+ "PlayerTitlePickerScrollFrameButton2TitleText",
+ "PlayerTitlePickerScrollFrameButton3",
+ "PlayerTitlePickerScrollFrameButton3Check",
+ "PlayerTitlePickerScrollFrameButton3TitleText",
+ "PlayerTitlePickerScrollFrameButton4",
+ "PlayerTitlePickerScrollFrameButton4Check",
+ "PlayerTitlePickerScrollFrameButton4TitleText",
+ "PlayerTitlePickerScrollFrameButton5",
+ "PlayerTitlePickerScrollFrameButton5Check",
+ "PlayerTitlePickerScrollFrameButton5TitleText",
+ "PlayerTitlePickerScrollFrameButton6",
+ "PlayerTitlePickerScrollFrameButton6Check",
+ "PlayerTitlePickerScrollFrameButton6TitleText",
+ "PlayerTitlePickerScrollFrameButton7",
+ "PlayerTitlePickerScrollFrameButton7Check",
+ "PlayerTitlePickerScrollFrameButton7TitleText",
+ "PlayerTitlePickerScrollFrameButton8",
+ "PlayerTitlePickerScrollFrameButton8Check",
+ "PlayerTitlePickerScrollFrameButton8TitleText",
+ "PlayerTitlePickerScrollFrameScrollBar",
+ "PlayerTitlePickerScrollFrameScrollBarBG",
+ "PlayerTitlePickerScrollFrameScrollBarBottom",
+ "PlayerTitlePickerScrollFrameScrollBarMiddle",
+ "PlayerTitlePickerScrollFrameScrollBarScrollDownButton",
+ "PlayerTitlePickerScrollFrameScrollBarScrollUpButton",
+ "PlayerTitlePickerScrollFrameScrollBarThumbTexture",
+ "PlayerTitlePickerScrollFrameScrollBarTop",
+ "PlayerTitlePickerScrollFrameScrollChild",
+ "PlayerTitlePickerScrollFrame_OnLoad",
+ "PlayerTitlePickerScrollFrame_Update",
+ "PositionMiniWorldMapArrowFrame",
+ "PositionWorldMapArrowFrame",
+ "PossessBackground1",
+ "PossessBackground2",
+ "PossessBarFrame",
+ "PossessBar_OnEvent",
+ "PossessBar_OnLoad",
+ "PossessBar_Update",
+ "PossessBar_UpdateState",
+ "PossessButton1",
+ "PossessButton1Border",
+ "PossessButton1Cooldown",
+ "PossessButton1Count",
+ "PossessButton1Flash",
+ "PossessButton1HotKey",
+ "PossessButton1Icon",
+ "PossessButton1Name",
+ "PossessButton1NormalTexture",
+ "PossessButton2",
+ "PossessButton2Border",
+ "PossessButton2Cooldown",
+ "PossessButton2Count",
+ "PossessButton2Flash",
+ "PossessButton2HotKey",
+ "PossessButton2Icon",
+ "PossessButton2Name",
+ "PossessButton2NormalTexture",
+ "PossessButton_OnClick",
+ "PossessButton_OnEnter",
+ "PowerBarColor",
+ "PrevView",
+ "PriceDropDown",
+ "PriceDropDownButton",
+ "PriceDropDownButtonDisabledTexture",
+ "PriceDropDownButtonHighlightTexture",
+ "PriceDropDownButtonNormalTexture",
+ "PriceDropDownButtonPushedTexture",
+ "PriceDropDownLeft",
+ "PriceDropDownMiddle",
+ "PriceDropDownRight",
+ "PriceDropDownText",
+ "PriceDropDown_Initialize",
+ "PriceDropDown_OnClick",
+ "PriceDropDown_OnLoad",
+ "ProcessMapClick",
+ "ProcessQuestLogRewardFactions",
+ "PromoteToAssistant",
+ "PromoteToLeader",
+ "PurchaseSlot",
+ "PutItemInBackpack",
+ "PutItemInBag",
+ "PutKeyInKeyRing",
+ "QUEST_POI_SWAP_BUTTONS",
+ "QUEST_TEMPLATE_DETAIL1",
+ "QUEST_TEMPLATE_DETAIL2",
+ "QUEST_TEMPLATE_LOG",
+ "QUEST_TEMPLATE_MAP1",
+ "QUEST_TEMPLATE_MAP2",
+ "QUEST_TEMPLATE_REWARD",
+ "QueryAuctionItems",
+ "QueryCastSequence",
+ "QueryGuildBankLog",
+ "QueryGuildBankTab",
+ "QueryGuildBankText",
+ "QueryGuildEventLog",
+ "QueryQuestsCompleted",
+ "QuestChooseRewardError",
+ "QuestDetailAcceptButton_OnClick",
+ "QuestDetailDeclineButton_OnClick",
+ "QuestDetailScrollChildFrame",
+ "QuestDetailScrollFrame",
+ "QuestDetailScrollFrameScrollBar",
+ "QuestDetailScrollFrameScrollBarScrollDownButton",
+ "QuestDetailScrollFrameScrollBarScrollUpButton",
+ "QuestDetailScrollFrameScrollBarThumbTexture",
+ "QuestDifficultyColors",
+ "QuestDifficulty_Difficult",
+ "QuestDifficulty_Header",
+ "QuestDifficulty_Impossible",
+ "QuestDifficulty_Standard",
+ "QuestDifficulty_Trivial",
+ "QuestDifficulty_VeryDifficult",
+ "QuestFlagsPVP",
+ "QuestFont",
+ "QuestFontHighlight",
+ "QuestFontLeft",
+ "QuestFontNormalSmall",
+ "QuestFont_Large",
+ "QuestFont_Shadow_Huge",
+ "QuestFrame",
+ "QuestFrameAcceptButton",
+ "QuestFrameAcceptButtonText",
+ "QuestFrameCancelButton",
+ "QuestFrameCancelButtonText",
+ "QuestFrameCloseButton",
+ "QuestFrameCompleteButton",
+ "QuestFrameCompleteButtonText",
+ "QuestFrameCompleteQuestButton",
+ "QuestFrameCompleteQuestButtonText",
+ "QuestFrameDeclineButton",
+ "QuestFrameDeclineButtonText",
+ "QuestFrameDetailPanel",
+ "QuestFrameDetailPanelBotRight",
+ "QuestFrameDetailPanelMaterialBotLeft",
+ "QuestFrameDetailPanelMaterialBotRight",
+ "QuestFrameDetailPanelMaterialTopLeft",
+ "QuestFrameDetailPanelMaterialTopRight",
+ "QuestFrameDetailPanel_OnShow",
+ "QuestFrameGoodbyeButton",
+ "QuestFrameGoodbyeButtonText",
+ "QuestFrameGreetingGoodbyeButton",
+ "QuestFrameGreetingGoodbyeButtonText",
+ "QuestFrameGreetingPanel",
+ "QuestFrameGreetingPanelBotRight",
+ "QuestFrameGreetingPanelMaterialBotLeft",
+ "QuestFrameGreetingPanelMaterialBotRight",
+ "QuestFrameGreetingPanelMaterialTopLeft",
+ "QuestFrameGreetingPanelMaterialTopRight",
+ "QuestFrameGreetingPanel_OnShow",
+ "QuestFrameNpcNameText",
+ "QuestFramePortrait",
+ "QuestFrameProgressItems_Update",
+ "QuestFrameProgressPanel",
+ "QuestFrameProgressPanelBotRight",
+ "QuestFrameProgressPanelMaterialBotLeft",
+ "QuestFrameProgressPanelMaterialBotRight",
+ "QuestFrameProgressPanelMaterialTopLeft",
+ "QuestFrameProgressPanelMaterialTopRight",
+ "QuestFrameProgressPanel_OnShow",
+ "QuestFrameRewardPanel",
+ "QuestFrameRewardPanelBotRight",
+ "QuestFrameRewardPanelMaterialBotLeft",
+ "QuestFrameRewardPanelMaterialBotRight",
+ "QuestFrameRewardPanelMaterialTopLeft",
+ "QuestFrameRewardPanelMaterialTopRight",
+ "QuestFrameRewardPanel_OnShow",
+ "QuestFrame_GetMaterial",
+ "QuestFrame_OnEvent",
+ "QuestFrame_OnHide",
+ "QuestFrame_OnLoad",
+ "QuestFrame_OnShow",
+ "QuestFrame_SetMaterial",
+ "QuestFrame_SetPortrait",
+ "QuestFrame_SetTextColor",
+ "QuestFrame_SetTitleTextColor",
+ "QuestGetAutoAccept",
+ "QuestGoodbyeButton_OnClick",
+ "QuestGreetingFrameHorizontalBreak",
+ "QuestGreetingScrollChildFrame",
+ "QuestGreetingScrollFrame",
+ "QuestGreetingScrollFrameScrollBar",
+ "QuestGreetingScrollFrameScrollBarScrollDownButton",
+ "QuestGreetingScrollFrameScrollBarScrollUpButton",
+ "QuestGreetingScrollFrameScrollBarThumbTexture",
+ "QuestInfoAnchor",
+ "QuestInfoArenaPointsFrame",
+ "QuestInfoArenaPointsFrameIcon",
+ "QuestInfoArenaPointsFramePoints",
+ "QuestInfoArenaPointsFrameReceiveText",
+ "QuestInfoDescriptionHeader",
+ "QuestInfoDescriptionText",
+ "QuestInfoFadingFrame",
+ "QuestInfoFadingFrame_OnUpdate",
+ "QuestInfoFrame",
+ "QuestInfoGroupSize",
+ "QuestInfoHonorFrame",
+ "QuestInfoHonorFrameIcon",
+ "QuestInfoHonorFramePoints",
+ "QuestInfoHonorFrameReceiveText",
+ "QuestInfoItem1",
+ "QuestInfoItem10",
+ "QuestInfoItem10Count",
+ "QuestInfoItem10IconTexture",
+ "QuestInfoItem10Name",
+ "QuestInfoItem10NameFrame",
+ "QuestInfoItem1Count",
+ "QuestInfoItem1IconTexture",
+ "QuestInfoItem1Name",
+ "QuestInfoItem1NameFrame",
+ "QuestInfoItem2",
+ "QuestInfoItem2Count",
+ "QuestInfoItem2IconTexture",
+ "QuestInfoItem2Name",
+ "QuestInfoItem2NameFrame",
+ "QuestInfoItem3",
+ "QuestInfoItem3Count",
+ "QuestInfoItem3IconTexture",
+ "QuestInfoItem3Name",
+ "QuestInfoItem3NameFrame",
+ "QuestInfoItem4",
+ "QuestInfoItem4Count",
+ "QuestInfoItem4IconTexture",
+ "QuestInfoItem4Name",
+ "QuestInfoItem4NameFrame",
+ "QuestInfoItem5",
+ "QuestInfoItem5Count",
+ "QuestInfoItem5IconTexture",
+ "QuestInfoItem5Name",
+ "QuestInfoItem5NameFrame",
+ "QuestInfoItem6",
+ "QuestInfoItem6Count",
+ "QuestInfoItem6IconTexture",
+ "QuestInfoItem6Name",
+ "QuestInfoItem6NameFrame",
+ "QuestInfoItem7",
+ "QuestInfoItem7Count",
+ "QuestInfoItem7IconTexture",
+ "QuestInfoItem7Name",
+ "QuestInfoItem7NameFrame",
+ "QuestInfoItem8",
+ "QuestInfoItem8Count",
+ "QuestInfoItem8IconTexture",
+ "QuestInfoItem8Name",
+ "QuestInfoItem8NameFrame",
+ "QuestInfoItem9",
+ "QuestInfoItem9Count",
+ "QuestInfoItem9IconTexture",
+ "QuestInfoItem9Name",
+ "QuestInfoItem9NameFrame",
+ "QuestInfoItemChooseText",
+ "QuestInfoItemHighlight",
+ "QuestInfoItemReceiveText",
+ "QuestInfoItem_OnClick",
+ "QuestInfoMoneyFrame",
+ "QuestInfoMoneyFrameCopperButton",
+ "QuestInfoMoneyFrameCopperButtonText",
+ "QuestInfoMoneyFrameGoldButton",
+ "QuestInfoMoneyFrameGoldButtonText",
+ "QuestInfoMoneyFrameSilverButton",
+ "QuestInfoMoneyFrameSilverButtonText",
+ "QuestInfoObjective1",
+ "QuestInfoObjective10",
+ "QuestInfoObjective2",
+ "QuestInfoObjective3",
+ "QuestInfoObjective4",
+ "QuestInfoObjective5",
+ "QuestInfoObjective6",
+ "QuestInfoObjective7",
+ "QuestInfoObjective8",
+ "QuestInfoObjective9",
+ "QuestInfoObjectivesFrame",
+ "QuestInfoObjectivesHeader",
+ "QuestInfoObjectivesText",
+ "QuestInfoPlayerTitleFrame",
+ "QuestInfoPlayerTitleFrameIconTexture",
+ "QuestInfoPlayerTitleFrameTitle",
+ "QuestInfoPlayerTitleFrameTitleFrameCenter",
+ "QuestInfoPlayerTitleFrameTitleFrameLeft",
+ "QuestInfoPlayerTitleFrameTitleLabel",
+ "QuestInfoReputation1",
+ "QuestInfoReputation10",
+ "QuestInfoReputation10Amount",
+ "QuestInfoReputation10Faction",
+ "QuestInfoReputation1Amount",
+ "QuestInfoReputation1Faction",
+ "QuestInfoReputation2",
+ "QuestInfoReputation2Amount",
+ "QuestInfoReputation2Faction",
+ "QuestInfoReputation3",
+ "QuestInfoReputation3Amount",
+ "QuestInfoReputation3Faction",
+ "QuestInfoReputation4",
+ "QuestInfoReputation4Amount",
+ "QuestInfoReputation4Faction",
+ "QuestInfoReputation5",
+ "QuestInfoReputation5Amount",
+ "QuestInfoReputation5Faction",
+ "QuestInfoReputation6",
+ "QuestInfoReputation6Amount",
+ "QuestInfoReputation6Faction",
+ "QuestInfoReputation7",
+ "QuestInfoReputation7Amount",
+ "QuestInfoReputation7Faction",
+ "QuestInfoReputation8",
+ "QuestInfoReputation8Amount",
+ "QuestInfoReputation8Faction",
+ "QuestInfoReputation9",
+ "QuestInfoReputation9Amount",
+ "QuestInfoReputation9Faction",
+ "QuestInfoReputationText",
+ "QuestInfoReputationsFrame",
+ "QuestInfoRequiredMoneyDisplay",
+ "QuestInfoRequiredMoneyDisplayCopperButton",
+ "QuestInfoRequiredMoneyDisplayCopperButtonText",
+ "QuestInfoRequiredMoneyDisplayGoldButton",
+ "QuestInfoRequiredMoneyDisplayGoldButtonText",
+ "QuestInfoRequiredMoneyDisplaySilverButton",
+ "QuestInfoRequiredMoneyDisplaySilverButtonText",
+ "QuestInfoRequiredMoneyFrame",
+ "QuestInfoRequiredMoneyText",
+ "QuestInfoRewardText",
+ "QuestInfoRewardsFrame",
+ "QuestInfoRewardsHeader",
+ "QuestInfoSpacerFrame",
+ "QuestInfoSpellLearnText",
+ "QuestInfoTalentFrame",
+ "QuestInfoTalentFramePoints",
+ "QuestInfoTalentFrameReceiveText",
+ "QuestInfoTimerFrame",
+ "QuestInfoTimerFrame_OnUpdate",
+ "QuestInfoTimerText",
+ "QuestInfoTitleHeader",
+ "QuestInfoXPFrame",
+ "QuestInfoXPFramePoints",
+ "QuestInfoXPFrameReceiveText",
+ "QuestInfo_Display",
+ "QuestInfo_DoReputations",
+ "QuestInfo_ShowAnchor",
+ "QuestInfo_ShowDescriptionHeader",
+ "QuestInfo_ShowDescriptionText",
+ "QuestInfo_ShowFadingFrame",
+ "QuestInfo_ShowGroupSize",
+ "QuestInfo_ShowObjectives",
+ "QuestInfo_ShowObjectivesHeader",
+ "QuestInfo_ShowObjectivesText",
+ "QuestInfo_ShowRequiredMoney",
+ "QuestInfo_ShowRewardText",
+ "QuestInfo_ShowRewards",
+ "QuestInfo_ShowSpacer",
+ "QuestInfo_ShowTimer",
+ "QuestInfo_ShowTitle",
+ "QuestInfo_ToggleRewardElement",
+ "QuestIsDaily",
+ "QuestIsWeekly",
+ "QuestLogControlPanel",
+ "QuestLogControlPanel_UpdatePosition",
+ "QuestLogControlPanel_UpdateState",
+ "QuestLogCount",
+ "QuestLogCountBottomLeft",
+ "QuestLogCountBottomMiddle",
+ "QuestLogCountBottomRight",
+ "QuestLogCountLeft",
+ "QuestLogCountMiddleMiddle",
+ "QuestLogCountRight",
+ "QuestLogCountTopLeft",
+ "QuestLogCountTopMiddle",
+ "QuestLogCountTopRight",
+ "QuestLogDailyQuestCount",
+ "QuestLogDailyQuestCountMouseOverFrame",
+ "QuestLogDetailFrame",
+ "QuestLogDetailFrameBackgroundBottomLeft",
+ "QuestLogDetailFrameBackgroundBottomRight",
+ "QuestLogDetailFrameBackgroundTopLeft",
+ "QuestLogDetailFrameBackgroundTopRight",
+ "QuestLogDetailFrameCloseButton",
+ "QuestLogDetailFrame_AttachToQuestLog",
+ "QuestLogDetailFrame_DetachFromQuestLog",
+ "QuestLogDetailFrame_OnHide",
+ "QuestLogDetailFrame_OnLoad",
+ "QuestLogDetailFrame_OnShow",
+ "QuestLogDetailScrollChildFrame",
+ "QuestLogDetailScrollFrame",
+ "QuestLogDetailScrollFrameScrollBackgroundBottomRight",
+ "QuestLogDetailScrollFrameScrollBackgroundTopLeft",
+ "QuestLogDetailScrollFrameScrollBar",
+ "QuestLogDetailScrollFrameScrollBarScrollDownButton",
+ "QuestLogDetailScrollFrameScrollBarScrollUpButton",
+ "QuestLogDetailScrollFrameScrollBarThumbTexture",
+ "QuestLogDetailTitleText",
+ "QuestLogFrame",
+ "QuestLogFrameAbandonButton",
+ "QuestLogFrameAbandonButtonText",
+ "QuestLogFrameCancelButton",
+ "QuestLogFrameCancelButtonText",
+ "QuestLogFrameCloseButton",
+ "QuestLogFramePushQuestButton",
+ "QuestLogFramePushQuestButtonText",
+ "QuestLogFrameShowMapButton",
+ "QuestLogFrameShowMapButtonHighlight",
+ "QuestLogFrameShowMapButtonText",
+ "QuestLogFrameShowMapButtonTexture",
+ "QuestLogFrameTrackButton",
+ "QuestLogFrameTrackButtonText",
+ "QuestLogFrameTrackButton_OnClick",
+ "QuestLogHighlightFrame",
+ "QuestLogMapFrame",
+ "QuestLogMapFrame1",
+ "QuestLogMapFrame10",
+ "QuestLogMapFrame11",
+ "QuestLogMapFrame12",
+ "QuestLogMapFrame2",
+ "QuestLogMapFrame3",
+ "QuestLogMapFrame4",
+ "QuestLogMapFrame5",
+ "QuestLogMapFrame6",
+ "QuestLogMapFrame7",
+ "QuestLogMapFrame8",
+ "QuestLogMapFrame9",
+ "QuestLogMicroButton",
+ "QuestLogNoQuestsText",
+ "QuestLogPushQuest",
+ "QuestLogQuestCount",
+ "QuestLogScrollFrame",
+ "QuestLogScrollFrameButton1",
+ "QuestLogScrollFrameButton10",
+ "QuestLogScrollFrameButton10Check",
+ "QuestLogScrollFrameButton10GroupMates",
+ "QuestLogScrollFrameButton10Highlight",
+ "QuestLogScrollFrameButton10NormalText",
+ "QuestLogScrollFrameButton10Tag",
+ "QuestLogScrollFrameButton11",
+ "QuestLogScrollFrameButton11Check",
+ "QuestLogScrollFrameButton11GroupMates",
+ "QuestLogScrollFrameButton11Highlight",
+ "QuestLogScrollFrameButton11NormalText",
+ "QuestLogScrollFrameButton11Tag",
+ "QuestLogScrollFrameButton12",
+ "QuestLogScrollFrameButton12Check",
+ "QuestLogScrollFrameButton12GroupMates",
+ "QuestLogScrollFrameButton12Highlight",
+ "QuestLogScrollFrameButton12NormalText",
+ "QuestLogScrollFrameButton12Tag",
+ "QuestLogScrollFrameButton13",
+ "QuestLogScrollFrameButton13Check",
+ "QuestLogScrollFrameButton13GroupMates",
+ "QuestLogScrollFrameButton13Highlight",
+ "QuestLogScrollFrameButton13NormalText",
+ "QuestLogScrollFrameButton13Tag",
+ "QuestLogScrollFrameButton14",
+ "QuestLogScrollFrameButton14Check",
+ "QuestLogScrollFrameButton14GroupMates",
+ "QuestLogScrollFrameButton14Highlight",
+ "QuestLogScrollFrameButton14NormalText",
+ "QuestLogScrollFrameButton14Tag",
+ "QuestLogScrollFrameButton15",
+ "QuestLogScrollFrameButton15Check",
+ "QuestLogScrollFrameButton15GroupMates",
+ "QuestLogScrollFrameButton15Highlight",
+ "QuestLogScrollFrameButton15NormalText",
+ "QuestLogScrollFrameButton15Tag",
+ "QuestLogScrollFrameButton16",
+ "QuestLogScrollFrameButton16Check",
+ "QuestLogScrollFrameButton16GroupMates",
+ "QuestLogScrollFrameButton16Highlight",
+ "QuestLogScrollFrameButton16NormalText",
+ "QuestLogScrollFrameButton16Tag",
+ "QuestLogScrollFrameButton17",
+ "QuestLogScrollFrameButton17Check",
+ "QuestLogScrollFrameButton17GroupMates",
+ "QuestLogScrollFrameButton17Highlight",
+ "QuestLogScrollFrameButton17NormalText",
+ "QuestLogScrollFrameButton17Tag",
+ "QuestLogScrollFrameButton18",
+ "QuestLogScrollFrameButton18Check",
+ "QuestLogScrollFrameButton18GroupMates",
+ "QuestLogScrollFrameButton18Highlight",
+ "QuestLogScrollFrameButton18NormalText",
+ "QuestLogScrollFrameButton18Tag",
+ "QuestLogScrollFrameButton19",
+ "QuestLogScrollFrameButton19Check",
+ "QuestLogScrollFrameButton19GroupMates",
+ "QuestLogScrollFrameButton19Highlight",
+ "QuestLogScrollFrameButton19NormalText",
+ "QuestLogScrollFrameButton19Tag",
+ "QuestLogScrollFrameButton1Check",
+ "QuestLogScrollFrameButton1GroupMates",
+ "QuestLogScrollFrameButton1Highlight",
+ "QuestLogScrollFrameButton1NormalText",
+ "QuestLogScrollFrameButton1Tag",
+ "QuestLogScrollFrameButton2",
+ "QuestLogScrollFrameButton20",
+ "QuestLogScrollFrameButton20Check",
+ "QuestLogScrollFrameButton20GroupMates",
+ "QuestLogScrollFrameButton20Highlight",
+ "QuestLogScrollFrameButton20NormalText",
+ "QuestLogScrollFrameButton20Tag",
+ "QuestLogScrollFrameButton21",
+ "QuestLogScrollFrameButton21Check",
+ "QuestLogScrollFrameButton21GroupMates",
+ "QuestLogScrollFrameButton21Highlight",
+ "QuestLogScrollFrameButton21NormalText",
+ "QuestLogScrollFrameButton21Tag",
+ "QuestLogScrollFrameButton22",
+ "QuestLogScrollFrameButton22Check",
+ "QuestLogScrollFrameButton22GroupMates",
+ "QuestLogScrollFrameButton22Highlight",
+ "QuestLogScrollFrameButton22NormalText",
+ "QuestLogScrollFrameButton22Tag",
+ "QuestLogScrollFrameButton2Check",
+ "QuestLogScrollFrameButton2GroupMates",
+ "QuestLogScrollFrameButton2Highlight",
+ "QuestLogScrollFrameButton2NormalText",
+ "QuestLogScrollFrameButton2Tag",
+ "QuestLogScrollFrameButton3",
+ "QuestLogScrollFrameButton3Check",
+ "QuestLogScrollFrameButton3GroupMates",
+ "QuestLogScrollFrameButton3Highlight",
+ "QuestLogScrollFrameButton3NormalText",
+ "QuestLogScrollFrameButton3Tag",
+ "QuestLogScrollFrameButton4",
+ "QuestLogScrollFrameButton4Check",
+ "QuestLogScrollFrameButton4GroupMates",
+ "QuestLogScrollFrameButton4Highlight",
+ "QuestLogScrollFrameButton4NormalText",
+ "QuestLogScrollFrameButton4Tag",
+ "QuestLogScrollFrameButton5",
+ "QuestLogScrollFrameButton5Check",
+ "QuestLogScrollFrameButton5GroupMates",
+ "QuestLogScrollFrameButton5Highlight",
+ "QuestLogScrollFrameButton5NormalText",
+ "QuestLogScrollFrameButton5Tag",
+ "QuestLogScrollFrameButton6",
+ "QuestLogScrollFrameButton6Check",
+ "QuestLogScrollFrameButton6GroupMates",
+ "QuestLogScrollFrameButton6Highlight",
+ "QuestLogScrollFrameButton6NormalText",
+ "QuestLogScrollFrameButton6Tag",
+ "QuestLogScrollFrameButton7",
+ "QuestLogScrollFrameButton7Check",
+ "QuestLogScrollFrameButton7GroupMates",
+ "QuestLogScrollFrameButton7Highlight",
+ "QuestLogScrollFrameButton7NormalText",
+ "QuestLogScrollFrameButton7Tag",
+ "QuestLogScrollFrameButton8",
+ "QuestLogScrollFrameButton8Check",
+ "QuestLogScrollFrameButton8GroupMates",
+ "QuestLogScrollFrameButton8Highlight",
+ "QuestLogScrollFrameButton8NormalText",
+ "QuestLogScrollFrameButton8Tag",
+ "QuestLogScrollFrameButton9",
+ "QuestLogScrollFrameButton9Check",
+ "QuestLogScrollFrameButton9GroupMates",
+ "QuestLogScrollFrameButton9Highlight",
+ "QuestLogScrollFrameButton9NormalText",
+ "QuestLogScrollFrameButton9Tag",
+ "QuestLogScrollFrameScrollBar",
+ "QuestLogScrollFrameScrollBarBG",
+ "QuestLogScrollFrameScrollBarBottom",
+ "QuestLogScrollFrameScrollBarMiddle",
+ "QuestLogScrollFrameScrollBarScrollDownButton",
+ "QuestLogScrollFrameScrollBarScrollUpButton",
+ "QuestLogScrollFrameScrollBarThumbTexture",
+ "QuestLogScrollFrameScrollBarTop",
+ "QuestLogScrollFrameScrollChild",
+ "QuestLogScrollFrame_OnLoad",
+ "QuestLogShowMapPOI_UpdatePosition",
+ "QuestLogSkillHighlight",
+ "QuestLogTitleButton_OnClick",
+ "QuestLogTitleButton_OnEnter",
+ "QuestLogTitleButton_OnEvent",
+ "QuestLogTitleButton_OnLeave",
+ "QuestLogTitleButton_OnLoad",
+ "QuestLogTitleButton_Resize",
+ "QuestLogTitleText",
+ "QuestLog_GetFirstSelectableQuest",
+ "QuestLog_OnEvent",
+ "QuestLog_OnHide",
+ "QuestLog_OnLoad",
+ "QuestLog_OnShow",
+ "QuestLog_OnUpdate",
+ "QuestLog_OpenToQuest",
+ "QuestLog_SetFirstValidSelection",
+ "QuestLog_SetNearestValidSelection",
+ "QuestLog_SetSelection",
+ "QuestLog_UnsetSelection",
+ "QuestLog_Update",
+ "QuestLog_UpdateMap",
+ "QuestLog_UpdateMapButton",
+ "QuestLog_UpdatePartyInfoTooltip",
+ "QuestLog_UpdateQuestCount",
+ "QuestLog_UpdateQuestDetails",
+ "QuestMapUpdateAllQuests",
+ "QuestNpcNameFrame",
+ "QuestPOIButton_OnMouseDown",
+ "QuestPOIButton_OnMouseUp",
+ "QuestPOIGetIconInfo",
+ "QuestPOIGetQuestIDByIndex",
+ "QuestPOIGetQuestIDByVisibleIndex",
+ "QuestPOIUpdateIcons",
+ "QuestPOIUpdateTexture",
+ "QuestPOI_DeselectButton",
+ "QuestPOI_DeselectButtonByParent",
+ "QuestPOI_DisplayButton",
+ "QuestPOI_HideAllButtons",
+ "QuestPOI_HideButtons",
+ "QuestPOI_SelectButton",
+ "QuestPOI_SelectButtonByIndex",
+ "QuestPOI_SelectButtonByQuestId",
+ "QuestPOI_SetTextColor",
+ "QuestProgressCompleteButton_OnClick",
+ "QuestProgressItem1",
+ "QuestProgressItem1Count",
+ "QuestProgressItem1IconTexture",
+ "QuestProgressItem1Name",
+ "QuestProgressItem1NameFrame",
+ "QuestProgressItem2",
+ "QuestProgressItem2Count",
+ "QuestProgressItem2IconTexture",
+ "QuestProgressItem2Name",
+ "QuestProgressItem2NameFrame",
+ "QuestProgressItem3",
+ "QuestProgressItem3Count",
+ "QuestProgressItem3IconTexture",
+ "QuestProgressItem3Name",
+ "QuestProgressItem3NameFrame",
+ "QuestProgressItem4",
+ "QuestProgressItem4Count",
+ "QuestProgressItem4IconTexture",
+ "QuestProgressItem4Name",
+ "QuestProgressItem4NameFrame",
+ "QuestProgressItem5",
+ "QuestProgressItem5Count",
+ "QuestProgressItem5IconTexture",
+ "QuestProgressItem5Name",
+ "QuestProgressItem5NameFrame",
+ "QuestProgressItem6",
+ "QuestProgressItem6Count",
+ "QuestProgressItem6IconTexture",
+ "QuestProgressItem6Name",
+ "QuestProgressItem6NameFrame",
+ "QuestProgressRequiredItemsText",
+ "QuestProgressRequiredMoneyFrame",
+ "QuestProgressRequiredMoneyFrameCopperButton",
+ "QuestProgressRequiredMoneyFrameCopperButtonText",
+ "QuestProgressRequiredMoneyFrameGoldButton",
+ "QuestProgressRequiredMoneyFrameGoldButtonText",
+ "QuestProgressRequiredMoneyFrameSilverButton",
+ "QuestProgressRequiredMoneyFrameSilverButtonText",
+ "QuestProgressRequiredMoneyText",
+ "QuestProgressScrollChildFrame",
+ "QuestProgressScrollFrame",
+ "QuestProgressScrollFrameScrollBar",
+ "QuestProgressScrollFrameScrollBarScrollDownButton",
+ "QuestProgressScrollFrameScrollBarScrollUpButton",
+ "QuestProgressScrollFrameScrollBarThumbTexture",
+ "QuestProgressText",
+ "QuestProgressTitleText",
+ "QuestRewardCancelButton_OnClick",
+ "QuestRewardCompleteButton_OnClick",
+ "QuestRewardItem_OnClick",
+ "QuestRewardScrollChildFrame",
+ "QuestRewardScrollFrame",
+ "QuestRewardScrollFrameScrollBar",
+ "QuestRewardScrollFrameScrollBarScrollDownButton",
+ "QuestRewardScrollFrameScrollBarScrollUpButton",
+ "QuestRewardScrollFrameScrollBarThumbTexture",
+ "QuestTitleButton1",
+ "QuestTitleButton10",
+ "QuestTitleButton10QuestIcon",
+ "QuestTitleButton11",
+ "QuestTitleButton11QuestIcon",
+ "QuestTitleButton12",
+ "QuestTitleButton12QuestIcon",
+ "QuestTitleButton13",
+ "QuestTitleButton13QuestIcon",
+ "QuestTitleButton14",
+ "QuestTitleButton14QuestIcon",
+ "QuestTitleButton15",
+ "QuestTitleButton15QuestIcon",
+ "QuestTitleButton16",
+ "QuestTitleButton16QuestIcon",
+ "QuestTitleButton17",
+ "QuestTitleButton17QuestIcon",
+ "QuestTitleButton18",
+ "QuestTitleButton18QuestIcon",
+ "QuestTitleButton19",
+ "QuestTitleButton19QuestIcon",
+ "QuestTitleButton1QuestIcon",
+ "QuestTitleButton2",
+ "QuestTitleButton20",
+ "QuestTitleButton20QuestIcon",
+ "QuestTitleButton21",
+ "QuestTitleButton21QuestIcon",
+ "QuestTitleButton22",
+ "QuestTitleButton22QuestIcon",
+ "QuestTitleButton23",
+ "QuestTitleButton23QuestIcon",
+ "QuestTitleButton24",
+ "QuestTitleButton24QuestIcon",
+ "QuestTitleButton25",
+ "QuestTitleButton25QuestIcon",
+ "QuestTitleButton26",
+ "QuestTitleButton26QuestIcon",
+ "QuestTitleButton27",
+ "QuestTitleButton27QuestIcon",
+ "QuestTitleButton28",
+ "QuestTitleButton28QuestIcon",
+ "QuestTitleButton29",
+ "QuestTitleButton29QuestIcon",
+ "QuestTitleButton2QuestIcon",
+ "QuestTitleButton3",
+ "QuestTitleButton30",
+ "QuestTitleButton30QuestIcon",
+ "QuestTitleButton31",
+ "QuestTitleButton31QuestIcon",
+ "QuestTitleButton32",
+ "QuestTitleButton32QuestIcon",
+ "QuestTitleButton3QuestIcon",
+ "QuestTitleButton4",
+ "QuestTitleButton4QuestIcon",
+ "QuestTitleButton5",
+ "QuestTitleButton5QuestIcon",
+ "QuestTitleButton6",
+ "QuestTitleButton6QuestIcon",
+ "QuestTitleButton7",
+ "QuestTitleButton7QuestIcon",
+ "QuestTitleButton8",
+ "QuestTitleButton8QuestIcon",
+ "QuestTitleButton9",
+ "QuestTitleButton9QuestIcon",
+ "QuestTitleButton_OnClick",
+ "QuestTitleFont",
+ "QuestTitleFontBlackShadow",
+ "Quit",
+ "RAID_CLASS_BUTTONS",
+ "RAID_CLASS_COLORS",
+ "RAID_PULLOUT_POSITIONS",
+ "RAID_PULLOUT_SAVED_SETTINGS",
+ "RAID_SINGLE_POSITIONS",
+ "RAID_SUBGROUP_LISTS",
+ "RED_FONT_COLOR",
+ "RaidBossEmoteFrame",
+ "RaidBossEmoteFrameSlot1",
+ "RaidBossEmoteFrameSlot2",
+ "RaidBossEmoteFrame_OnEvent",
+ "RaidBossEmoteFrame_OnLoad",
+ "RaidButton_OnClick",
+ "RaidClassButton1",
+ "RaidClassButton10",
+ "RaidClassButton10Count",
+ "RaidClassButton10IconTexture",
+ "RaidClassButton11",
+ "RaidClassButton11Count",
+ "RaidClassButton11IconTexture",
+ "RaidClassButton12",
+ "RaidClassButton12Count",
+ "RaidClassButton12IconTexture",
+ "RaidClassButton13",
+ "RaidClassButton13Count",
+ "RaidClassButton13IconTexture",
+ "RaidClassButton1Count",
+ "RaidClassButton1IconTexture",
+ "RaidClassButton2",
+ "RaidClassButton2Count",
+ "RaidClassButton2IconTexture",
+ "RaidClassButton3",
+ "RaidClassButton3Count",
+ "RaidClassButton3IconTexture",
+ "RaidClassButton4",
+ "RaidClassButton4Count",
+ "RaidClassButton4IconTexture",
+ "RaidClassButton5",
+ "RaidClassButton5Count",
+ "RaidClassButton5IconTexture",
+ "RaidClassButton6",
+ "RaidClassButton6Count",
+ "RaidClassButton6IconTexture",
+ "RaidClassButton7",
+ "RaidClassButton7Count",
+ "RaidClassButton7IconTexture",
+ "RaidClassButton8",
+ "RaidClassButton8Count",
+ "RaidClassButton8IconTexture",
+ "RaidClassButton9",
+ "RaidClassButton9Count",
+ "RaidClassButton9IconTexture",
+ "RaidClassButton_OnEnter",
+ "RaidClassButton_OnLoad",
+ "RaidClassButton_Update",
+ "RaidFrame",
+ "RaidFrameConvertToRaidButton",
+ "RaidFrameConvertToRaidButtonText",
+ "RaidFrameDropDown_Initialize",
+ "RaidFrameNotInRaid",
+ "RaidFrameNotInRaidRaidBrowserButton",
+ "RaidFrameNotInRaidRaidBrowserButtonLeft",
+ "RaidFrameNotInRaidRaidBrowserButtonMiddle",
+ "RaidFrameNotInRaidRaidBrowserButtonRight",
+ "RaidFrameNotInRaidRaidBrowserButtonText",
+ "RaidFrameRaidBrowserButton",
+ "RaidFrameRaidBrowserButtonText",
+ "RaidFrameRaidBrowserButton_Update",
+ "RaidFrameRaidBrowserDescription",
+ "RaidFrameRaidDescription",
+ "RaidFrameRaidInfoButton",
+ "RaidFrameRaidInfoButtonText",
+ "RaidFrameReadyCheckButton",
+ "RaidFrameReadyCheckButtonText",
+ "RaidFrameReadyCheckButton_Update",
+ "RaidFrame_LoadUI",
+ "RaidFrame_OnEvent",
+ "RaidFrame_OnLoad",
+ "RaidFrame_Update",
+ "RaidGroup1",
+ "RaidGroup1Label",
+ "RaidGroup1Slot1",
+ "RaidGroup1Slot2",
+ "RaidGroup1Slot3",
+ "RaidGroup1Slot4",
+ "RaidGroup1Slot5",
+ "RaidGroup2",
+ "RaidGroup2Label",
+ "RaidGroup2Slot1",
+ "RaidGroup2Slot2",
+ "RaidGroup2Slot3",
+ "RaidGroup2Slot4",
+ "RaidGroup2Slot5",
+ "RaidGroup3",
+ "RaidGroup3Label",
+ "RaidGroup3Slot1",
+ "RaidGroup3Slot2",
+ "RaidGroup3Slot3",
+ "RaidGroup3Slot4",
+ "RaidGroup3Slot5",
+ "RaidGroup4",
+ "RaidGroup4Label",
+ "RaidGroup4Slot1",
+ "RaidGroup4Slot2",
+ "RaidGroup4Slot3",
+ "RaidGroup4Slot4",
+ "RaidGroup4Slot5",
+ "RaidGroup5",
+ "RaidGroup5Label",
+ "RaidGroup5Slot1",
+ "RaidGroup5Slot2",
+ "RaidGroup5Slot3",
+ "RaidGroup5Slot4",
+ "RaidGroup5Slot5",
+ "RaidGroup6",
+ "RaidGroup6Label",
+ "RaidGroup6Slot1",
+ "RaidGroup6Slot2",
+ "RaidGroup6Slot3",
+ "RaidGroup6Slot4",
+ "RaidGroup6Slot5",
+ "RaidGroup7",
+ "RaidGroup7Label",
+ "RaidGroup7Slot1",
+ "RaidGroup7Slot2",
+ "RaidGroup7Slot3",
+ "RaidGroup7Slot4",
+ "RaidGroup7Slot5",
+ "RaidGroup8",
+ "RaidGroup8Label",
+ "RaidGroup8Slot1",
+ "RaidGroup8Slot2",
+ "RaidGroup8Slot3",
+ "RaidGroup8Slot4",
+ "RaidGroup8Slot5",
+ "RaidGroupButton1",
+ "RaidGroupButton10",
+ "RaidGroupButton10Class",
+ "RaidGroupButton10Level",
+ "RaidGroupButton10Loot",
+ "RaidGroupButton10LootTexture",
+ "RaidGroupButton10Name",
+ "RaidGroupButton10Rank",
+ "RaidGroupButton10RankTexture",
+ "RaidGroupButton10ReadyCheck",
+ "RaidGroupButton10ReadyCheckTexture",
+ "RaidGroupButton10Role",
+ "RaidGroupButton10RoleTexture",
+ "RaidGroupButton11",
+ "RaidGroupButton11Class",
+ "RaidGroupButton11Level",
+ "RaidGroupButton11Loot",
+ "RaidGroupButton11LootTexture",
+ "RaidGroupButton11Name",
+ "RaidGroupButton11Rank",
+ "RaidGroupButton11RankTexture",
+ "RaidGroupButton11ReadyCheck",
+ "RaidGroupButton11ReadyCheckTexture",
+ "RaidGroupButton11Role",
+ "RaidGroupButton11RoleTexture",
+ "RaidGroupButton12",
+ "RaidGroupButton12Class",
+ "RaidGroupButton12Level",
+ "RaidGroupButton12Loot",
+ "RaidGroupButton12LootTexture",
+ "RaidGroupButton12Name",
+ "RaidGroupButton12Rank",
+ "RaidGroupButton12RankTexture",
+ "RaidGroupButton12ReadyCheck",
+ "RaidGroupButton12ReadyCheckTexture",
+ "RaidGroupButton12Role",
+ "RaidGroupButton12RoleTexture",
+ "RaidGroupButton13",
+ "RaidGroupButton13Class",
+ "RaidGroupButton13Level",
+ "RaidGroupButton13Loot",
+ "RaidGroupButton13LootTexture",
+ "RaidGroupButton13Name",
+ "RaidGroupButton13Rank",
+ "RaidGroupButton13RankTexture",
+ "RaidGroupButton13ReadyCheck",
+ "RaidGroupButton13ReadyCheckTexture",
+ "RaidGroupButton13Role",
+ "RaidGroupButton13RoleTexture",
+ "RaidGroupButton14",
+ "RaidGroupButton14Class",
+ "RaidGroupButton14Level",
+ "RaidGroupButton14Loot",
+ "RaidGroupButton14LootTexture",
+ "RaidGroupButton14Name",
+ "RaidGroupButton14Rank",
+ "RaidGroupButton14RankTexture",
+ "RaidGroupButton14ReadyCheck",
+ "RaidGroupButton14ReadyCheckTexture",
+ "RaidGroupButton14Role",
+ "RaidGroupButton14RoleTexture",
+ "RaidGroupButton15",
+ "RaidGroupButton15Class",
+ "RaidGroupButton15Level",
+ "RaidGroupButton15Loot",
+ "RaidGroupButton15LootTexture",
+ "RaidGroupButton15Name",
+ "RaidGroupButton15Rank",
+ "RaidGroupButton15RankTexture",
+ "RaidGroupButton15ReadyCheck",
+ "RaidGroupButton15ReadyCheckTexture",
+ "RaidGroupButton15Role",
+ "RaidGroupButton15RoleTexture",
+ "RaidGroupButton16",
+ "RaidGroupButton16Class",
+ "RaidGroupButton16Level",
+ "RaidGroupButton16Loot",
+ "RaidGroupButton16LootTexture",
+ "RaidGroupButton16Name",
+ "RaidGroupButton16Rank",
+ "RaidGroupButton16RankTexture",
+ "RaidGroupButton16ReadyCheck",
+ "RaidGroupButton16ReadyCheckTexture",
+ "RaidGroupButton16Role",
+ "RaidGroupButton16RoleTexture",
+ "RaidGroupButton17",
+ "RaidGroupButton17Class",
+ "RaidGroupButton17Level",
+ "RaidGroupButton17Loot",
+ "RaidGroupButton17LootTexture",
+ "RaidGroupButton17Name",
+ "RaidGroupButton17Rank",
+ "RaidGroupButton17RankTexture",
+ "RaidGroupButton17ReadyCheck",
+ "RaidGroupButton17ReadyCheckTexture",
+ "RaidGroupButton17Role",
+ "RaidGroupButton17RoleTexture",
+ "RaidGroupButton18",
+ "RaidGroupButton18Class",
+ "RaidGroupButton18Level",
+ "RaidGroupButton18Loot",
+ "RaidGroupButton18LootTexture",
+ "RaidGroupButton18Name",
+ "RaidGroupButton18Rank",
+ "RaidGroupButton18RankTexture",
+ "RaidGroupButton18ReadyCheck",
+ "RaidGroupButton18ReadyCheckTexture",
+ "RaidGroupButton18Role",
+ "RaidGroupButton18RoleTexture",
+ "RaidGroupButton19",
+ "RaidGroupButton19Class",
+ "RaidGroupButton19Level",
+ "RaidGroupButton19Loot",
+ "RaidGroupButton19LootTexture",
+ "RaidGroupButton19Name",
+ "RaidGroupButton19Rank",
+ "RaidGroupButton19RankTexture",
+ "RaidGroupButton19ReadyCheck",
+ "RaidGroupButton19ReadyCheckTexture",
+ "RaidGroupButton19Role",
+ "RaidGroupButton19RoleTexture",
+ "RaidGroupButton1Class",
+ "RaidGroupButton1Level",
+ "RaidGroupButton1Loot",
+ "RaidGroupButton1LootTexture",
+ "RaidGroupButton1Name",
+ "RaidGroupButton1Rank",
+ "RaidGroupButton1RankTexture",
+ "RaidGroupButton1ReadyCheck",
+ "RaidGroupButton1ReadyCheckTexture",
+ "RaidGroupButton1Role",
+ "RaidGroupButton1RoleTexture",
+ "RaidGroupButton2",
+ "RaidGroupButton20",
+ "RaidGroupButton20Class",
+ "RaidGroupButton20Level",
+ "RaidGroupButton20Loot",
+ "RaidGroupButton20LootTexture",
+ "RaidGroupButton20Name",
+ "RaidGroupButton20Rank",
+ "RaidGroupButton20RankTexture",
+ "RaidGroupButton20ReadyCheck",
+ "RaidGroupButton20ReadyCheckTexture",
+ "RaidGroupButton20Role",
+ "RaidGroupButton20RoleTexture",
+ "RaidGroupButton21",
+ "RaidGroupButton21Class",
+ "RaidGroupButton21Level",
+ "RaidGroupButton21Loot",
+ "RaidGroupButton21LootTexture",
+ "RaidGroupButton21Name",
+ "RaidGroupButton21Rank",
+ "RaidGroupButton21RankTexture",
+ "RaidGroupButton21ReadyCheck",
+ "RaidGroupButton21ReadyCheckTexture",
+ "RaidGroupButton21Role",
+ "RaidGroupButton21RoleTexture",
+ "RaidGroupButton22",
+ "RaidGroupButton22Class",
+ "RaidGroupButton22Level",
+ "RaidGroupButton22Loot",
+ "RaidGroupButton22LootTexture",
+ "RaidGroupButton22Name",
+ "RaidGroupButton22Rank",
+ "RaidGroupButton22RankTexture",
+ "RaidGroupButton22ReadyCheck",
+ "RaidGroupButton22ReadyCheckTexture",
+ "RaidGroupButton22Role",
+ "RaidGroupButton22RoleTexture",
+ "RaidGroupButton23",
+ "RaidGroupButton23Class",
+ "RaidGroupButton23Level",
+ "RaidGroupButton23Loot",
+ "RaidGroupButton23LootTexture",
+ "RaidGroupButton23Name",
+ "RaidGroupButton23Rank",
+ "RaidGroupButton23RankTexture",
+ "RaidGroupButton23ReadyCheck",
+ "RaidGroupButton23ReadyCheckTexture",
+ "RaidGroupButton23Role",
+ "RaidGroupButton23RoleTexture",
+ "RaidGroupButton24",
+ "RaidGroupButton24Class",
+ "RaidGroupButton24Level",
+ "RaidGroupButton24Loot",
+ "RaidGroupButton24LootTexture",
+ "RaidGroupButton24Name",
+ "RaidGroupButton24Rank",
+ "RaidGroupButton24RankTexture",
+ "RaidGroupButton24ReadyCheck",
+ "RaidGroupButton24ReadyCheckTexture",
+ "RaidGroupButton24Role",
+ "RaidGroupButton24RoleTexture",
+ "RaidGroupButton25",
+ "RaidGroupButton25Class",
+ "RaidGroupButton25Level",
+ "RaidGroupButton25Loot",
+ "RaidGroupButton25LootTexture",
+ "RaidGroupButton25Name",
+ "RaidGroupButton25Rank",
+ "RaidGroupButton25RankTexture",
+ "RaidGroupButton25ReadyCheck",
+ "RaidGroupButton25ReadyCheckTexture",
+ "RaidGroupButton25Role",
+ "RaidGroupButton25RoleTexture",
+ "RaidGroupButton26",
+ "RaidGroupButton26Class",
+ "RaidGroupButton26Level",
+ "RaidGroupButton26Loot",
+ "RaidGroupButton26LootTexture",
+ "RaidGroupButton26Name",
+ "RaidGroupButton26Rank",
+ "RaidGroupButton26RankTexture",
+ "RaidGroupButton26ReadyCheck",
+ "RaidGroupButton26ReadyCheckTexture",
+ "RaidGroupButton26Role",
+ "RaidGroupButton26RoleTexture",
+ "RaidGroupButton27",
+ "RaidGroupButton27Class",
+ "RaidGroupButton27Level",
+ "RaidGroupButton27Loot",
+ "RaidGroupButton27LootTexture",
+ "RaidGroupButton27Name",
+ "RaidGroupButton27Rank",
+ "RaidGroupButton27RankTexture",
+ "RaidGroupButton27ReadyCheck",
+ "RaidGroupButton27ReadyCheckTexture",
+ "RaidGroupButton27Role",
+ "RaidGroupButton27RoleTexture",
+ "RaidGroupButton28",
+ "RaidGroupButton28Class",
+ "RaidGroupButton28Level",
+ "RaidGroupButton28Loot",
+ "RaidGroupButton28LootTexture",
+ "RaidGroupButton28Name",
+ "RaidGroupButton28Rank",
+ "RaidGroupButton28RankTexture",
+ "RaidGroupButton28ReadyCheck",
+ "RaidGroupButton28ReadyCheckTexture",
+ "RaidGroupButton28Role",
+ "RaidGroupButton28RoleTexture",
+ "RaidGroupButton29",
+ "RaidGroupButton29Class",
+ "RaidGroupButton29Level",
+ "RaidGroupButton29Loot",
+ "RaidGroupButton29LootTexture",
+ "RaidGroupButton29Name",
+ "RaidGroupButton29Rank",
+ "RaidGroupButton29RankTexture",
+ "RaidGroupButton29ReadyCheck",
+ "RaidGroupButton29ReadyCheckTexture",
+ "RaidGroupButton29Role",
+ "RaidGroupButton29RoleTexture",
+ "RaidGroupButton2Class",
+ "RaidGroupButton2Level",
+ "RaidGroupButton2Loot",
+ "RaidGroupButton2LootTexture",
+ "RaidGroupButton2Name",
+ "RaidGroupButton2Rank",
+ "RaidGroupButton2RankTexture",
+ "RaidGroupButton2ReadyCheck",
+ "RaidGroupButton2ReadyCheckTexture",
+ "RaidGroupButton2Role",
+ "RaidGroupButton2RoleTexture",
+ "RaidGroupButton3",
+ "RaidGroupButton30",
+ "RaidGroupButton30Class",
+ "RaidGroupButton30Level",
+ "RaidGroupButton30Loot",
+ "RaidGroupButton30LootTexture",
+ "RaidGroupButton30Name",
+ "RaidGroupButton30Rank",
+ "RaidGroupButton30RankTexture",
+ "RaidGroupButton30ReadyCheck",
+ "RaidGroupButton30ReadyCheckTexture",
+ "RaidGroupButton30Role",
+ "RaidGroupButton30RoleTexture",
+ "RaidGroupButton31",
+ "RaidGroupButton31Class",
+ "RaidGroupButton31Level",
+ "RaidGroupButton31Loot",
+ "RaidGroupButton31LootTexture",
+ "RaidGroupButton31Name",
+ "RaidGroupButton31Rank",
+ "RaidGroupButton31RankTexture",
+ "RaidGroupButton31ReadyCheck",
+ "RaidGroupButton31ReadyCheckTexture",
+ "RaidGroupButton31Role",
+ "RaidGroupButton31RoleTexture",
+ "RaidGroupButton32",
+ "RaidGroupButton32Class",
+ "RaidGroupButton32Level",
+ "RaidGroupButton32Loot",
+ "RaidGroupButton32LootTexture",
+ "RaidGroupButton32Name",
+ "RaidGroupButton32Rank",
+ "RaidGroupButton32RankTexture",
+ "RaidGroupButton32ReadyCheck",
+ "RaidGroupButton32ReadyCheckTexture",
+ "RaidGroupButton32Role",
+ "RaidGroupButton32RoleTexture",
+ "RaidGroupButton33",
+ "RaidGroupButton33Class",
+ "RaidGroupButton33Level",
+ "RaidGroupButton33Loot",
+ "RaidGroupButton33LootTexture",
+ "RaidGroupButton33Name",
+ "RaidGroupButton33Rank",
+ "RaidGroupButton33RankTexture",
+ "RaidGroupButton33ReadyCheck",
+ "RaidGroupButton33ReadyCheckTexture",
+ "RaidGroupButton33Role",
+ "RaidGroupButton33RoleTexture",
+ "RaidGroupButton34",
+ "RaidGroupButton34Class",
+ "RaidGroupButton34Level",
+ "RaidGroupButton34Loot",
+ "RaidGroupButton34LootTexture",
+ "RaidGroupButton34Name",
+ "RaidGroupButton34Rank",
+ "RaidGroupButton34RankTexture",
+ "RaidGroupButton34ReadyCheck",
+ "RaidGroupButton34ReadyCheckTexture",
+ "RaidGroupButton34Role",
+ "RaidGroupButton34RoleTexture",
+ "RaidGroupButton35",
+ "RaidGroupButton35Class",
+ "RaidGroupButton35Level",
+ "RaidGroupButton35Loot",
+ "RaidGroupButton35LootTexture",
+ "RaidGroupButton35Name",
+ "RaidGroupButton35Rank",
+ "RaidGroupButton35RankTexture",
+ "RaidGroupButton35ReadyCheck",
+ "RaidGroupButton35ReadyCheckTexture",
+ "RaidGroupButton35Role",
+ "RaidGroupButton35RoleTexture",
+ "RaidGroupButton36",
+ "RaidGroupButton36Class",
+ "RaidGroupButton36Level",
+ "RaidGroupButton36Loot",
+ "RaidGroupButton36LootTexture",
+ "RaidGroupButton36Name",
+ "RaidGroupButton36Rank",
+ "RaidGroupButton36RankTexture",
+ "RaidGroupButton36ReadyCheck",
+ "RaidGroupButton36ReadyCheckTexture",
+ "RaidGroupButton36Role",
+ "RaidGroupButton36RoleTexture",
+ "RaidGroupButton37",
+ "RaidGroupButton37Class",
+ "RaidGroupButton37Level",
+ "RaidGroupButton37Loot",
+ "RaidGroupButton37LootTexture",
+ "RaidGroupButton37Name",
+ "RaidGroupButton37Rank",
+ "RaidGroupButton37RankTexture",
+ "RaidGroupButton37ReadyCheck",
+ "RaidGroupButton37ReadyCheckTexture",
+ "RaidGroupButton37Role",
+ "RaidGroupButton37RoleTexture",
+ "RaidGroupButton38",
+ "RaidGroupButton38Class",
+ "RaidGroupButton38Level",
+ "RaidGroupButton38Loot",
+ "RaidGroupButton38LootTexture",
+ "RaidGroupButton38Name",
+ "RaidGroupButton38Rank",
+ "RaidGroupButton38RankTexture",
+ "RaidGroupButton38ReadyCheck",
+ "RaidGroupButton38ReadyCheckTexture",
+ "RaidGroupButton38Role",
+ "RaidGroupButton38RoleTexture",
+ "RaidGroupButton39",
+ "RaidGroupButton39Class",
+ "RaidGroupButton39Level",
+ "RaidGroupButton39Loot",
+ "RaidGroupButton39LootTexture",
+ "RaidGroupButton39Name",
+ "RaidGroupButton39Rank",
+ "RaidGroupButton39RankTexture",
+ "RaidGroupButton39ReadyCheck",
+ "RaidGroupButton39ReadyCheckTexture",
+ "RaidGroupButton39Role",
+ "RaidGroupButton39RoleTexture",
+ "RaidGroupButton3Class",
+ "RaidGroupButton3Level",
+ "RaidGroupButton3Loot",
+ "RaidGroupButton3LootTexture",
+ "RaidGroupButton3Name",
+ "RaidGroupButton3Rank",
+ "RaidGroupButton3RankTexture",
+ "RaidGroupButton3ReadyCheck",
+ "RaidGroupButton3ReadyCheckTexture",
+ "RaidGroupButton3Role",
+ "RaidGroupButton3RoleTexture",
+ "RaidGroupButton4",
+ "RaidGroupButton40",
+ "RaidGroupButton40Class",
+ "RaidGroupButton40Level",
+ "RaidGroupButton40Loot",
+ "RaidGroupButton40LootTexture",
+ "RaidGroupButton40Name",
+ "RaidGroupButton40Rank",
+ "RaidGroupButton40RankTexture",
+ "RaidGroupButton40ReadyCheck",
+ "RaidGroupButton40ReadyCheckTexture",
+ "RaidGroupButton40Role",
+ "RaidGroupButton40RoleTexture",
+ "RaidGroupButton4Class",
+ "RaidGroupButton4Level",
+ "RaidGroupButton4Loot",
+ "RaidGroupButton4LootTexture",
+ "RaidGroupButton4Name",
+ "RaidGroupButton4Rank",
+ "RaidGroupButton4RankTexture",
+ "RaidGroupButton4ReadyCheck",
+ "RaidGroupButton4ReadyCheckTexture",
+ "RaidGroupButton4Role",
+ "RaidGroupButton4RoleTexture",
+ "RaidGroupButton5",
+ "RaidGroupButton5Class",
+ "RaidGroupButton5Level",
+ "RaidGroupButton5Loot",
+ "RaidGroupButton5LootTexture",
+ "RaidGroupButton5Name",
+ "RaidGroupButton5Rank",
+ "RaidGroupButton5RankTexture",
+ "RaidGroupButton5ReadyCheck",
+ "RaidGroupButton5ReadyCheckTexture",
+ "RaidGroupButton5Role",
+ "RaidGroupButton5RoleTexture",
+ "RaidGroupButton6",
+ "RaidGroupButton6Class",
+ "RaidGroupButton6Level",
+ "RaidGroupButton6Loot",
+ "RaidGroupButton6LootTexture",
+ "RaidGroupButton6Name",
+ "RaidGroupButton6Rank",
+ "RaidGroupButton6RankTexture",
+ "RaidGroupButton6ReadyCheck",
+ "RaidGroupButton6ReadyCheckTexture",
+ "RaidGroupButton6Role",
+ "RaidGroupButton6RoleTexture",
+ "RaidGroupButton7",
+ "RaidGroupButton7Class",
+ "RaidGroupButton7Level",
+ "RaidGroupButton7Loot",
+ "RaidGroupButton7LootTexture",
+ "RaidGroupButton7Name",
+ "RaidGroupButton7Rank",
+ "RaidGroupButton7RankTexture",
+ "RaidGroupButton7ReadyCheck",
+ "RaidGroupButton7ReadyCheckTexture",
+ "RaidGroupButton7Role",
+ "RaidGroupButton7RoleTexture",
+ "RaidGroupButton8",
+ "RaidGroupButton8Class",
+ "RaidGroupButton8Level",
+ "RaidGroupButton8Loot",
+ "RaidGroupButton8LootTexture",
+ "RaidGroupButton8Name",
+ "RaidGroupButton8Rank",
+ "RaidGroupButton8RankTexture",
+ "RaidGroupButton8ReadyCheck",
+ "RaidGroupButton8ReadyCheckTexture",
+ "RaidGroupButton8Role",
+ "RaidGroupButton8RoleTexture",
+ "RaidGroupButton9",
+ "RaidGroupButton9Class",
+ "RaidGroupButton9Level",
+ "RaidGroupButton9Loot",
+ "RaidGroupButton9LootTexture",
+ "RaidGroupButton9Name",
+ "RaidGroupButton9Rank",
+ "RaidGroupButton9RankTexture",
+ "RaidGroupButton9ReadyCheck",
+ "RaidGroupButton9ReadyCheckTexture",
+ "RaidGroupButton9Role",
+ "RaidGroupButton9RoleTexture",
+ "RaidGroupButton_OnDragStart",
+ "RaidGroupButton_OnDragStop",
+ "RaidGroupButton_OnEnter",
+ "RaidGroupButton_OnLoad",
+ "RaidGroupButton_ShowMenu",
+ "RaidGroupFrame_OnEvent",
+ "RaidGroupFrame_OnHide",
+ "RaidGroupFrame_OnLoad",
+ "RaidGroupFrame_OnUpdate",
+ "RaidGroupFrame_ReadyCheckFinished",
+ "RaidGroupFrame_Update",
+ "RaidGroupFrame_UpdateHealth",
+ "RaidGroupFrame_UpdateLevel",
+ "RaidGroup_ResetSlotButtons",
+ "RaidInfoCancelButton",
+ "RaidInfoCancelButtonLeft",
+ "RaidInfoCancelButtonMiddle",
+ "RaidInfoCancelButtonRight",
+ "RaidInfoCancelButtonText",
+ "RaidInfoCloseButton",
+ "RaidInfoDetailCorner",
+ "RaidInfoDetailFooter",
+ "RaidInfoDetailHeader",
+ "RaidInfoExtendButton",
+ "RaidInfoExtendButtonLeft",
+ "RaidInfoExtendButtonMiddle",
+ "RaidInfoExtendButtonRight",
+ "RaidInfoExtendButtonText",
+ "RaidInfoExtendButton_OnClick",
+ "RaidInfoFrame",
+ "RaidInfoFrameHeader",
+ "RaidInfoFrameHeaderText",
+ "RaidInfoFrame_Update",
+ "RaidInfoFrame_UpdateSelectedIndex",
+ "RaidInfoIDLabel",
+ "RaidInfoIDLabelLeft",
+ "RaidInfoIDLabelMiddle",
+ "RaidInfoIDLabelRight",
+ "RaidInfoInstanceLabel",
+ "RaidInfoInstanceLabelLeft",
+ "RaidInfoInstanceLabelMiddle",
+ "RaidInfoInstanceLabelRight",
+ "RaidInfoInstance_OnClick",
+ "RaidInfoInstance_OnEnter",
+ "RaidInfoInstance_OnMouseDown",
+ "RaidInfoInstance_OnMouseUp",
+ "RaidInfoScrollFrame",
+ "RaidInfoScrollFrameButton1",
+ "RaidInfoScrollFrameButton1Difficulty",
+ "RaidInfoScrollFrameButton1Extended",
+ "RaidInfoScrollFrameButton1Name",
+ "RaidInfoScrollFrameButton1Reset",
+ "RaidInfoScrollFrameButton2",
+ "RaidInfoScrollFrameButton2Difficulty",
+ "RaidInfoScrollFrameButton2Extended",
+ "RaidInfoScrollFrameButton2Name",
+ "RaidInfoScrollFrameButton2Reset",
+ "RaidInfoScrollFrameButton3",
+ "RaidInfoScrollFrameButton3Difficulty",
+ "RaidInfoScrollFrameButton3Extended",
+ "RaidInfoScrollFrameButton3Name",
+ "RaidInfoScrollFrameButton3Reset",
+ "RaidInfoScrollFrameButton4",
+ "RaidInfoScrollFrameButton4Difficulty",
+ "RaidInfoScrollFrameButton4Extended",
+ "RaidInfoScrollFrameButton4Name",
+ "RaidInfoScrollFrameButton4Reset",
+ "RaidInfoScrollFrameButton5",
+ "RaidInfoScrollFrameButton5Difficulty",
+ "RaidInfoScrollFrameButton5Extended",
+ "RaidInfoScrollFrameButton5Name",
+ "RaidInfoScrollFrameButton5Reset",
+ "RaidInfoScrollFrameButton6",
+ "RaidInfoScrollFrameButton6Difficulty",
+ "RaidInfoScrollFrameButton6Extended",
+ "RaidInfoScrollFrameButton6Name",
+ "RaidInfoScrollFrameButton6Reset",
+ "RaidInfoScrollFrameButton7",
+ "RaidInfoScrollFrameButton7Difficulty",
+ "RaidInfoScrollFrameButton7Extended",
+ "RaidInfoScrollFrameButton7Name",
+ "RaidInfoScrollFrameButton7Reset",
+ "RaidInfoScrollFrameScrollBar",
+ "RaidInfoScrollFrameScrollBarBG",
+ "RaidInfoScrollFrameScrollBarBottom",
+ "RaidInfoScrollFrameScrollBarMiddle",
+ "RaidInfoScrollFrameScrollBarScrollDownButton",
+ "RaidInfoScrollFrameScrollBarScrollUpButton",
+ "RaidInfoScrollFrameScrollBarThumbTexture",
+ "RaidInfoScrollFrameScrollBarTop",
+ "RaidInfoScrollFrameScrollChild",
+ "RaidInfoScrollFrame_OnLoad",
+ "RaidNotice_AddMessage",
+ "RaidNotice_FadeInit",
+ "RaidNotice_OnUpdate",
+ "RaidNotice_SetSlot",
+ "RaidNotice_UpdateSlot",
+ "RaidOptionsFrame_UpdatePartyFrames",
+ "RaidPulloutButton_OnDragStart",
+ "RaidPulloutButton_OnEvent",
+ "RaidPulloutButton_OnLoad",
+ "RaidPulloutButton_ShowMenu",
+ "RaidPulloutButton_UpdateDead",
+ "RaidPulloutButton_UpdateSwapFrames",
+ "RaidPulloutButton_UpdateVoice",
+ "RaidPulloutDropDown_Initialize",
+ "RaidPulloutDropDown_OnLoad",
+ "RaidPulloutStopMoving",
+ "RaidPullout_GeneratePulloutFrame",
+ "RaidPullout_GetFrame",
+ "RaidPullout_MatchName",
+ "RaidPullout_OnEvent",
+ "RaidPullout_OnUpdate",
+ "RaidPullout_ReadyCheckFinishFunc",
+ "RaidPullout_ReadyCheckFinished",
+ "RaidPullout_RenewFrames",
+ "RaidPullout_SaveFrames",
+ "RaidPullout_Update",
+ "RaidPullout_UpdateTarget",
+ "RaidWarningFrame",
+ "RaidWarningFrameSlot1",
+ "RaidWarningFrameSlot2",
+ "RaidWarningFrame_OnEvent",
+ "RaidWarningFrame_OnLoad",
+ "RaiseFrameLevel",
+ "RaiseFrameLevelByTwo",
+ "RandomRoll",
+ "RatingMenuAge",
+ "RatingMenuButtonOkay",
+ "RatingMenuButtonOkayText",
+ "RatingMenuDrugs",
+ "RatingMenuFrame",
+ "RatingMenuFrameHeader",
+ "RatingMenuFrameText",
+ "RatingMenuViolence",
+ "ReadFile",
+ "ReadyCheckFrame",
+ "ReadyCheckFrameNoButton",
+ "ReadyCheckFrameNoButtonText",
+ "ReadyCheckFrameText",
+ "ReadyCheckFrameYesButton",
+ "ReadyCheckFrameYesButtonText",
+ "ReadyCheckFrame_OnEvent",
+ "ReadyCheckFrame_OnHide",
+ "ReadyCheckFrame_OnLoad",
+ "ReadyCheckListenerFrame",
+ "ReadyCheckPortrait",
+ "ReadyCheck_Confirm",
+ "ReadyCheck_Finish",
+ "ReadyCheck_OnUpdate",
+ "ReadyCheck_Start",
+ "RealPartyIsFull",
+ "RecalculateGearManagerDialogPopup",
+ "RecentTimeDate",
+ "RecordLoopbackSoundButton",
+ "RecordLoopbackSoundButtonText",
+ "RecordLoopbackSoundButtonTexture",
+ "RecordLoopbackSoundButton_OnUpdate",
+ "RefreshAuras",
+ "RefreshBuffs",
+ "RefreshDebuffs",
+ "RefreshEquipmentSetIconInfo",
+ "RefreshLFGList",
+ "RefreshMoneyFrame",
+ "RegisterAutoHide",
+ "RegisterCVar",
+ "RegisterForSave",
+ "RegisterForSavePerCharacter",
+ "RegisterStateDriver",
+ "RegisterStaticConstants",
+ "RegisterUnitWatch",
+ "RegistrationText",
+ "RejectProposal",
+ "ReloadUI",
+ "RemoveChatWindowChannel",
+ "RemoveChatWindowMessages",
+ "RemoveFriend",
+ "RemoveGlyphFromSocket",
+ "RemoveQuestWatch",
+ "RemoveSkillUp",
+ "RemoveTrackedAchievement",
+ "RenameEquipmentSet",
+ "RenamePetition",
+ "RepairAllItems",
+ "ReplaceEnchant",
+ "ReplaceTradeEnchant",
+ "RepopMe",
+ "ReportBug",
+ "ReportPlayerIsPVPAFK",
+ "ReportSuggestion",
+ "ReputationBar1",
+ "ReputationBar10",
+ "ReputationBar10Background",
+ "ReputationBar10BottomLine",
+ "ReputationBar10ExpandOrCollapseButton",
+ "ReputationBar10ExpandOrCollapseButtonHighlight",
+ "ReputationBar10FactionName",
+ "ReputationBar10LeftLine",
+ "ReputationBar10ReputationBar",
+ "ReputationBar10ReputationBarAtWarHighlight1",
+ "ReputationBar10ReputationBarAtWarHighlight2",
+ "ReputationBar10ReputationBarFactionStanding",
+ "ReputationBar10ReputationBarHighlight1",
+ "ReputationBar10ReputationBarHighlight2",
+ "ReputationBar10ReputationBarLeftTexture",
+ "ReputationBar10ReputationBarRightTexture",
+ "ReputationBar11",
+ "ReputationBar11Background",
+ "ReputationBar11BottomLine",
+ "ReputationBar11ExpandOrCollapseButton",
+ "ReputationBar11ExpandOrCollapseButtonHighlight",
+ "ReputationBar11FactionName",
+ "ReputationBar11LeftLine",
+ "ReputationBar11ReputationBar",
+ "ReputationBar11ReputationBarAtWarHighlight1",
+ "ReputationBar11ReputationBarAtWarHighlight2",
+ "ReputationBar11ReputationBarFactionStanding",
+ "ReputationBar11ReputationBarHighlight1",
+ "ReputationBar11ReputationBarHighlight2",
+ "ReputationBar11ReputationBarLeftTexture",
+ "ReputationBar11ReputationBarRightTexture",
+ "ReputationBar12",
+ "ReputationBar12Background",
+ "ReputationBar12BottomLine",
+ "ReputationBar12ExpandOrCollapseButton",
+ "ReputationBar12ExpandOrCollapseButtonHighlight",
+ "ReputationBar12FactionName",
+ "ReputationBar12LeftLine",
+ "ReputationBar12ReputationBar",
+ "ReputationBar12ReputationBarAtWarHighlight1",
+ "ReputationBar12ReputationBarAtWarHighlight2",
+ "ReputationBar12ReputationBarFactionStanding",
+ "ReputationBar12ReputationBarHighlight1",
+ "ReputationBar12ReputationBarHighlight2",
+ "ReputationBar12ReputationBarLeftTexture",
+ "ReputationBar12ReputationBarRightTexture",
+ "ReputationBar13",
+ "ReputationBar13Background",
+ "ReputationBar13BottomLine",
+ "ReputationBar13ExpandOrCollapseButton",
+ "ReputationBar13ExpandOrCollapseButtonHighlight",
+ "ReputationBar13FactionName",
+ "ReputationBar13LeftLine",
+ "ReputationBar13ReputationBar",
+ "ReputationBar13ReputationBarAtWarHighlight1",
+ "ReputationBar13ReputationBarAtWarHighlight2",
+ "ReputationBar13ReputationBarFactionStanding",
+ "ReputationBar13ReputationBarHighlight1",
+ "ReputationBar13ReputationBarHighlight2",
+ "ReputationBar13ReputationBarLeftTexture",
+ "ReputationBar13ReputationBarRightTexture",
+ "ReputationBar14",
+ "ReputationBar14Background",
+ "ReputationBar14BottomLine",
+ "ReputationBar14ExpandOrCollapseButton",
+ "ReputationBar14ExpandOrCollapseButtonHighlight",
+ "ReputationBar14FactionName",
+ "ReputationBar14LeftLine",
+ "ReputationBar14ReputationBar",
+ "ReputationBar14ReputationBarAtWarHighlight1",
+ "ReputationBar14ReputationBarAtWarHighlight2",
+ "ReputationBar14ReputationBarFactionStanding",
+ "ReputationBar14ReputationBarHighlight1",
+ "ReputationBar14ReputationBarHighlight2",
+ "ReputationBar14ReputationBarLeftTexture",
+ "ReputationBar14ReputationBarRightTexture",
+ "ReputationBar15",
+ "ReputationBar15Background",
+ "ReputationBar15BottomLine",
+ "ReputationBar15ExpandOrCollapseButton",
+ "ReputationBar15ExpandOrCollapseButtonHighlight",
+ "ReputationBar15FactionName",
+ "ReputationBar15LeftLine",
+ "ReputationBar15ReputationBar",
+ "ReputationBar15ReputationBarAtWarHighlight1",
+ "ReputationBar15ReputationBarAtWarHighlight2",
+ "ReputationBar15ReputationBarFactionStanding",
+ "ReputationBar15ReputationBarHighlight1",
+ "ReputationBar15ReputationBarHighlight2",
+ "ReputationBar15ReputationBarLeftTexture",
+ "ReputationBar15ReputationBarRightTexture",
+ "ReputationBar1Background",
+ "ReputationBar1BottomLine",
+ "ReputationBar1ExpandOrCollapseButton",
+ "ReputationBar1ExpandOrCollapseButtonHighlight",
+ "ReputationBar1FactionName",
+ "ReputationBar1LeftLine",
+ "ReputationBar1ReputationBar",
+ "ReputationBar1ReputationBarAtWarHighlight1",
+ "ReputationBar1ReputationBarAtWarHighlight2",
+ "ReputationBar1ReputationBarFactionStanding",
+ "ReputationBar1ReputationBarHighlight1",
+ "ReputationBar1ReputationBarHighlight2",
+ "ReputationBar1ReputationBarLeftTexture",
+ "ReputationBar1ReputationBarRightTexture",
+ "ReputationBar2",
+ "ReputationBar2Background",
+ "ReputationBar2BottomLine",
+ "ReputationBar2ExpandOrCollapseButton",
+ "ReputationBar2ExpandOrCollapseButtonHighlight",
+ "ReputationBar2FactionName",
+ "ReputationBar2LeftLine",
+ "ReputationBar2ReputationBar",
+ "ReputationBar2ReputationBarAtWarHighlight1",
+ "ReputationBar2ReputationBarAtWarHighlight2",
+ "ReputationBar2ReputationBarFactionStanding",
+ "ReputationBar2ReputationBarHighlight1",
+ "ReputationBar2ReputationBarHighlight2",
+ "ReputationBar2ReputationBarLeftTexture",
+ "ReputationBar2ReputationBarRightTexture",
+ "ReputationBar3",
+ "ReputationBar3Background",
+ "ReputationBar3BottomLine",
+ "ReputationBar3ExpandOrCollapseButton",
+ "ReputationBar3ExpandOrCollapseButtonHighlight",
+ "ReputationBar3FactionName",
+ "ReputationBar3LeftLine",
+ "ReputationBar3ReputationBar",
+ "ReputationBar3ReputationBarAtWarHighlight1",
+ "ReputationBar3ReputationBarAtWarHighlight2",
+ "ReputationBar3ReputationBarFactionStanding",
+ "ReputationBar3ReputationBarHighlight1",
+ "ReputationBar3ReputationBarHighlight2",
+ "ReputationBar3ReputationBarLeftTexture",
+ "ReputationBar3ReputationBarRightTexture",
+ "ReputationBar4",
+ "ReputationBar4Background",
+ "ReputationBar4BottomLine",
+ "ReputationBar4ExpandOrCollapseButton",
+ "ReputationBar4ExpandOrCollapseButtonHighlight",
+ "ReputationBar4FactionName",
+ "ReputationBar4LeftLine",
+ "ReputationBar4ReputationBar",
+ "ReputationBar4ReputationBarAtWarHighlight1",
+ "ReputationBar4ReputationBarAtWarHighlight2",
+ "ReputationBar4ReputationBarFactionStanding",
+ "ReputationBar4ReputationBarHighlight1",
+ "ReputationBar4ReputationBarHighlight2",
+ "ReputationBar4ReputationBarLeftTexture",
+ "ReputationBar4ReputationBarRightTexture",
+ "ReputationBar5",
+ "ReputationBar5Background",
+ "ReputationBar5BottomLine",
+ "ReputationBar5ExpandOrCollapseButton",
+ "ReputationBar5ExpandOrCollapseButtonHighlight",
+ "ReputationBar5FactionName",
+ "ReputationBar5LeftLine",
+ "ReputationBar5ReputationBar",
+ "ReputationBar5ReputationBarAtWarHighlight1",
+ "ReputationBar5ReputationBarAtWarHighlight2",
+ "ReputationBar5ReputationBarFactionStanding",
+ "ReputationBar5ReputationBarHighlight1",
+ "ReputationBar5ReputationBarHighlight2",
+ "ReputationBar5ReputationBarLeftTexture",
+ "ReputationBar5ReputationBarRightTexture",
+ "ReputationBar6",
+ "ReputationBar6Background",
+ "ReputationBar6BottomLine",
+ "ReputationBar6ExpandOrCollapseButton",
+ "ReputationBar6ExpandOrCollapseButtonHighlight",
+ "ReputationBar6FactionName",
+ "ReputationBar6LeftLine",
+ "ReputationBar6ReputationBar",
+ "ReputationBar6ReputationBarAtWarHighlight1",
+ "ReputationBar6ReputationBarAtWarHighlight2",
+ "ReputationBar6ReputationBarFactionStanding",
+ "ReputationBar6ReputationBarHighlight1",
+ "ReputationBar6ReputationBarHighlight2",
+ "ReputationBar6ReputationBarLeftTexture",
+ "ReputationBar6ReputationBarRightTexture",
+ "ReputationBar7",
+ "ReputationBar7Background",
+ "ReputationBar7BottomLine",
+ "ReputationBar7ExpandOrCollapseButton",
+ "ReputationBar7ExpandOrCollapseButtonHighlight",
+ "ReputationBar7FactionName",
+ "ReputationBar7LeftLine",
+ "ReputationBar7ReputationBar",
+ "ReputationBar7ReputationBarAtWarHighlight1",
+ "ReputationBar7ReputationBarAtWarHighlight2",
+ "ReputationBar7ReputationBarFactionStanding",
+ "ReputationBar7ReputationBarHighlight1",
+ "ReputationBar7ReputationBarHighlight2",
+ "ReputationBar7ReputationBarLeftTexture",
+ "ReputationBar7ReputationBarRightTexture",
+ "ReputationBar8",
+ "ReputationBar8Background",
+ "ReputationBar8BottomLine",
+ "ReputationBar8ExpandOrCollapseButton",
+ "ReputationBar8ExpandOrCollapseButtonHighlight",
+ "ReputationBar8FactionName",
+ "ReputationBar8LeftLine",
+ "ReputationBar8ReputationBar",
+ "ReputationBar8ReputationBarAtWarHighlight1",
+ "ReputationBar8ReputationBarAtWarHighlight2",
+ "ReputationBar8ReputationBarFactionStanding",
+ "ReputationBar8ReputationBarHighlight1",
+ "ReputationBar8ReputationBarHighlight2",
+ "ReputationBar8ReputationBarLeftTexture",
+ "ReputationBar8ReputationBarRightTexture",
+ "ReputationBar9",
+ "ReputationBar9Background",
+ "ReputationBar9BottomLine",
+ "ReputationBar9ExpandOrCollapseButton",
+ "ReputationBar9ExpandOrCollapseButtonHighlight",
+ "ReputationBar9FactionName",
+ "ReputationBar9LeftLine",
+ "ReputationBar9ReputationBar",
+ "ReputationBar9ReputationBarAtWarHighlight1",
+ "ReputationBar9ReputationBarAtWarHighlight2",
+ "ReputationBar9ReputationBarFactionStanding",
+ "ReputationBar9ReputationBarHighlight1",
+ "ReputationBar9ReputationBarHighlight2",
+ "ReputationBar9ReputationBarLeftTexture",
+ "ReputationBar9ReputationBarRightTexture",
+ "ReputationBar_DrawHorizontalLine",
+ "ReputationBar_DrawVerticalLine",
+ "ReputationBar_OnClick",
+ "ReputationDetailAtWarCheckBox",
+ "ReputationDetailAtWarCheckBoxText",
+ "ReputationDetailCloseButton",
+ "ReputationDetailCorner",
+ "ReputationDetailDivider",
+ "ReputationDetailFactionDescription",
+ "ReputationDetailFactionName",
+ "ReputationDetailFont",
+ "ReputationDetailFrame",
+ "ReputationDetailInactiveCheckBox",
+ "ReputationDetailInactiveCheckBoxText",
+ "ReputationDetailMainScreenCheckBox",
+ "ReputationDetailMainScreenCheckBoxText",
+ "ReputationFrame",
+ "ReputationFrameFactionLabel",
+ "ReputationFrameStandingLabel",
+ "ReputationFrameTopTreeTexture",
+ "ReputationFrameTopTreeTexture2",
+ "ReputationFrame_OnEvent",
+ "ReputationFrame_OnLoad",
+ "ReputationFrame_OnShow",
+ "ReputationFrame_SetRowType",
+ "ReputationFrame_Update",
+ "ReputationListScrollFrame",
+ "ReputationListScrollFrameScrollBar",
+ "ReputationListScrollFrameScrollBarScrollDownButton",
+ "ReputationListScrollFrameScrollBarScrollUpButton",
+ "ReputationListScrollFrameScrollBarThumbTexture",
+ "ReputationListScrollFrameScrollChildFrame",
+ "ReputationWatchBar",
+ "ReputationWatchBarOverlayFrame",
+ "ReputationWatchBarTexture0",
+ "ReputationWatchBarTexture1",
+ "ReputationWatchBarTexture2",
+ "ReputationWatchBarTexture3",
+ "ReputationWatchBar_Update",
+ "ReputationWatchStatusBar",
+ "ReputationWatchStatusBarBackground",
+ "ReputationWatchStatusBarText",
+ "ReputationXPBarTexture0",
+ "ReputationXPBarTexture1",
+ "ReputationXPBarTexture2",
+ "ReputationXPBarTexture3",
+ "RequestBattlefieldPositions",
+ "RequestBattlefieldScoreData",
+ "RequestBattlegroundInstanceInfo",
+ "RequestInspectHonorData",
+ "RequestLFDPartyLockInfo",
+ "RequestLFDPlayerLockInfo",
+ "RequestRaidInfo",
+ "RequestTimePlayed",
+ "ResetCPUUsage",
+ "ResetChatColors",
+ "ResetChatWindows",
+ "ResetCursor",
+ "ResetDisabledAddOns",
+ "ResetGroupPreviewTalentPoints",
+ "ResetInstances",
+ "ResetPerformanceValues",
+ "ResetPreviewTalentPoints",
+ "ResetTutorials",
+ "ResetView",
+ "ResolutionPanelOptions",
+ "RespondInstanceLock",
+ "RespondMailLockSendItem",
+ "RestartGx",
+ "RestoreVideoEffectsDefaults",
+ "RestoreVideoResolutionDefaults",
+ "RestoreVideoStereoDefaults",
+ "ResurrectGetOfferer",
+ "ResurrectHasSickness",
+ "ResurrectHasTimer",
+ "RetrieveCorpse",
+ "ReturnInboxItem",
+ "RollOnLoot",
+ "Round",
+ "RunBinding",
+ "RunMacro",
+ "RunMacroText",
+ "RunScript",
+ "RuneButtonIndividual1",
+ "RuneButtonIndividual1Border",
+ "RuneButtonIndividual1BorderTexture",
+ "RuneButtonIndividual1Cooldown",
+ "RuneButtonIndividual1Rune",
+ "RuneButtonIndividual1Shine",
+ "RuneButtonIndividual1ShineTexture",
+ "RuneButtonIndividual2",
+ "RuneButtonIndividual2Border",
+ "RuneButtonIndividual2BorderTexture",
+ "RuneButtonIndividual2Cooldown",
+ "RuneButtonIndividual2Rune",
+ "RuneButtonIndividual2Shine",
+ "RuneButtonIndividual2ShineTexture",
+ "RuneButtonIndividual3",
+ "RuneButtonIndividual3Border",
+ "RuneButtonIndividual3BorderTexture",
+ "RuneButtonIndividual3Cooldown",
+ "RuneButtonIndividual3Rune",
+ "RuneButtonIndividual3Shine",
+ "RuneButtonIndividual3ShineTexture",
+ "RuneButtonIndividual4",
+ "RuneButtonIndividual4Border",
+ "RuneButtonIndividual4BorderTexture",
+ "RuneButtonIndividual4Cooldown",
+ "RuneButtonIndividual4Rune",
+ "RuneButtonIndividual4Shine",
+ "RuneButtonIndividual4ShineTexture",
+ "RuneButtonIndividual5",
+ "RuneButtonIndividual5Border",
+ "RuneButtonIndividual5BorderTexture",
+ "RuneButtonIndividual5Cooldown",
+ "RuneButtonIndividual5Rune",
+ "RuneButtonIndividual5Shine",
+ "RuneButtonIndividual5ShineTexture",
+ "RuneButtonIndividual6",
+ "RuneButtonIndividual6Border",
+ "RuneButtonIndividual6BorderTexture",
+ "RuneButtonIndividual6Cooldown",
+ "RuneButtonIndividual6Rune",
+ "RuneButtonIndividual6Shine",
+ "RuneButtonIndividual6ShineTexture",
+ "RuneButton_OnEnter",
+ "RuneButton_OnLeave",
+ "RuneButton_OnLoad",
+ "RuneButton_OnUpdate",
+ "RuneButton_ShineFadeIn",
+ "RuneButton_ShineFadeOut",
+ "RuneButton_Update",
+ "RuneFrame",
+ "RuneFrame_AddRune",
+ "RuneFrame_FixRunes",
+ "RuneFrame_OnEvent",
+ "RuneFrame_OnLoad",
+ "SCHOOL_MASK_ARCANE",
+ "SCHOOL_MASK_FIRE",
+ "SCHOOL_MASK_FROST",
+ "SCHOOL_MASK_HOLY",
+ "SCHOOL_MASK_NATURE",
+ "SCHOOL_MASK_NONE",
+ "SCHOOL_MASK_PHYSICAL",
+ "SCHOOL_MASK_SHADOW",
+ "SELECTED_DOCK_FRAME",
+ "SEND_MAIL_TAB_LIST",
+ "SHINES_TO_ANIMATE",
+ "SHOW_COMBAT_TEXT",
+ "SPELLBOOK_PAGENUMBERS",
+ "SPELL_PASSIVE",
+ "SPELL_POWER_ENERGY",
+ "SPELL_POWER_FOCUS",
+ "SPELL_POWER_HAPPINESS",
+ "SPELL_POWER_MANA",
+ "SPELL_POWER_RAGE",
+ "SPELL_POWER_RUNES",
+ "SPELL_POWER_RUNIC_POWER",
+ "STATICPOPUP_NUMDIALOGS",
+ "STATIC_CONSTANTS",
+ "STAT_FUNCTIONS",
+ "STRING_SCHOOL_ARCANE",
+ "STRING_SCHOOL_FIRE",
+ "STRING_SCHOOL_FROST",
+ "STRING_SCHOOL_HOLY",
+ "STRING_SCHOOL_NATURE",
+ "STRING_SCHOOL_PHYSICAL",
+ "STRING_SCHOOL_SHADOW",
+ "STRING_SCHOOL_UNKNOWN",
+ "SUBTRACTED_PLAYERS",
+ "SaveBindings",
+ "SaveEquipmentSet",
+ "SavePendingGuildBankTabPermissions",
+ "SaveView",
+ "ScorePlayerDropDown",
+ "ScorePlayerDropDownButton",
+ "ScorePlayerDropDownButtonDisabledTexture",
+ "ScorePlayerDropDownButtonHighlightTexture",
+ "ScorePlayerDropDownButtonNormalTexture",
+ "ScorePlayerDropDownButtonPushedTexture",
+ "ScorePlayerDropDownLeft",
+ "ScorePlayerDropDownMiddle",
+ "ScorePlayerDropDownRight",
+ "ScorePlayerDropDownText",
+ "ScorePlayerDropDown_Cancel",
+ "ScorePlayerDropDown_Initialize",
+ "ScorePlayerDropDown_OnClick",
+ "ScorePlayer_OnMouseUp",
+ "Screenshot",
+ "ScriptErrorsFrame",
+ "ScriptErrorsFrameBottom",
+ "ScriptErrorsFrameBottomLeft",
+ "ScriptErrorsFrameBottomRight",
+ "ScriptErrorsFrameButton_OnClick",
+ "ScriptErrorsFrameClose",
+ "ScriptErrorsFrameDialogBG",
+ "ScriptErrorsFrameLeft",
+ "ScriptErrorsFrameRight",
+ "ScriptErrorsFrameScrollFrame",
+ "ScriptErrorsFrameScrollFrameScrollBar",
+ "ScriptErrorsFrameScrollFrameScrollBarScrollDownButton",
+ "ScriptErrorsFrameScrollFrameScrollBarScrollUpButton",
+ "ScriptErrorsFrameScrollFrameScrollBarThumbTexture",
+ "ScriptErrorsFrameScrollFrameText",
+ "ScriptErrorsFrameText",
+ "ScriptErrorsFrameTitleBG",
+ "ScriptErrorsFrameTitleButton",
+ "ScriptErrorsFrameTop",
+ "ScriptErrorsFrameTopLeft",
+ "ScriptErrorsFrameTopRight",
+ "ScriptErrorsFrame_DeleteError",
+ "ScriptErrorsFrame_OnError",
+ "ScriptErrorsFrame_OnLoad",
+ "ScriptErrorsFrame_OnShow",
+ "ScriptErrorsFrame_Update",
+ "ScriptErrorsFrame_UpdateButtons",
+ "ScrollFrameTemplate_OnMouseWheel",
+ "ScrollFrame_OnLoad",
+ "ScrollFrame_OnScrollRangeChanged",
+ "ScrollingEdit_OnCursorChanged",
+ "ScrollingEdit_OnTextChanged",
+ "ScrollingEdit_OnUpdate",
+ "SearchButton_OnUpdate",
+ "SearchLFGGetEncounterResults",
+ "SearchLFGGetJoinedID",
+ "SearchLFGGetNumResults",
+ "SearchLFGGetPartyResults",
+ "SearchLFGGetResults",
+ "SearchLFGJoin",
+ "SearchLFGLeave",
+ "SearchLFGSort",
+ "SeatIndicator_Pulse",
+ "SecondsToTime",
+ "SecondsToTimeAbbrev",
+ "SecureActionButton_OnClick",
+ "SecureButton_GetAttribute",
+ "SecureButton_GetButtonSuffix",
+ "SecureButton_GetEffectiveButton",
+ "SecureButton_GetModifiedAttribute",
+ "SecureButton_GetModifiedUnit",
+ "SecureButton_GetModifierPrefix",
+ "SecureButton_GetUnit",
+ "SecureButton_ParseModifierString",
+ "SecureCmdItemParse",
+ "SecureCmdOptionParse",
+ "SecureCmdUseItem",
+ "SecureGroupHeader_OnAttributeChanged",
+ "SecureGroupHeader_OnEvent",
+ "SecureGroupHeader_OnLoad",
+ "SecureGroupHeader_Update",
+ "SecureGroupPetHeader_OnAttributeChanged",
+ "SecureGroupPetHeader_OnEvent",
+ "SecureGroupPetHeader_OnLoad",
+ "SecureGroupPetHeader_Update",
+ "SecureHandlerExecute",
+ "SecureHandlerSetFrameRef",
+ "SecureHandlerUnwrapScript",
+ "SecureHandlerWrapScript",
+ "SecureHandler_AttributeOnAttributeChanged",
+ "SecureHandler_OnClick",
+ "SecureHandler_OnDragEvent",
+ "SecureHandler_OnLoad",
+ "SecureHandler_OnMouseUpDown",
+ "SecureHandler_OnMouseWheel",
+ "SecureHandler_OnSimpleEvent",
+ "SecureHandler_StateOnAttributeChanged",
+ "SecureHandlersUpdateFrame",
+ "SecureHoverDriverManager",
+ "SecureStateDriverManager",
+ "SecureUnitButton_OnClick",
+ "SecureUnitButton_OnLoad",
+ "SelectActiveQuest",
+ "SelectAvailableQuest",
+ "SelectGossipActiveQuest",
+ "SelectGossipAvailableQuest",
+ "SelectGossipOption",
+ "SelectPackage",
+ "SelectQuestLogEntry",
+ "SelectStationery",
+ "SelectTradeSkill",
+ "SelectTrainerService",
+ "SendAddonMessage",
+ "SendChatMessage",
+ "SendMail",
+ "SendMailAttachment1",
+ "SendMailAttachment10",
+ "SendMailAttachment10Count",
+ "SendMailAttachment11",
+ "SendMailAttachment11Count",
+ "SendMailAttachment12",
+ "SendMailAttachment12Count",
+ "SendMailAttachment13",
+ "SendMailAttachment13Count",
+ "SendMailAttachment14",
+ "SendMailAttachment14Count",
+ "SendMailAttachment15",
+ "SendMailAttachment15Count",
+ "SendMailAttachment16",
+ "SendMailAttachment16Count",
+ "SendMailAttachment1Count",
+ "SendMailAttachment2",
+ "SendMailAttachment2Count",
+ "SendMailAttachment3",
+ "SendMailAttachment3Count",
+ "SendMailAttachment4",
+ "SendMailAttachment4Count",
+ "SendMailAttachment5",
+ "SendMailAttachment5Count",
+ "SendMailAttachment6",
+ "SendMailAttachment6Count",
+ "SendMailAttachment7",
+ "SendMailAttachment7Count",
+ "SendMailAttachment8",
+ "SendMailAttachment8Count",
+ "SendMailAttachment9",
+ "SendMailAttachment9Count",
+ "SendMailAttachmentButton_OnClick",
+ "SendMailAttachmentButton_OnDropAny",
+ "SendMailAttachment_OnEnter",
+ "SendMailBodyEditBox",
+ "SendMailCODButton",
+ "SendMailCODButtonText",
+ "SendMailCancelButton",
+ "SendMailCancelButtonText",
+ "SendMailCostMoneyFrame",
+ "SendMailCostMoneyFrameCopperButton",
+ "SendMailCostMoneyFrameCopperButtonText",
+ "SendMailCostMoneyFrameGoldButton",
+ "SendMailCostMoneyFrameGoldButtonText",
+ "SendMailCostMoneyFrameSilverButton",
+ "SendMailCostMoneyFrameSilverButtonText",
+ "SendMailErrorCoin",
+ "SendMailErrorText",
+ "SendMailFrame",
+ "SendMailFrameLockSendMail",
+ "SendMailFrameLockSendMailBlackFilter",
+ "SendMailFrame_CanSend",
+ "SendMailFrame_Reset",
+ "SendMailFrame_SendMail",
+ "SendMailFrame_Update",
+ "SendMailHorizontalBarLeft",
+ "SendMailHorizontalBarLeft2",
+ "SendMailMailButton",
+ "SendMailMailButtonText",
+ "SendMailMailButton_OnClick",
+ "SendMailMoney",
+ "SendMailMoneyButton",
+ "SendMailMoneyButton_OnClick",
+ "SendMailMoneyCopper",
+ "SendMailMoneyCopperLeft",
+ "SendMailMoneyCopperMiddle",
+ "SendMailMoneyCopperRight",
+ "SendMailMoneyFrame",
+ "SendMailMoneyFrameCopperButton",
+ "SendMailMoneyFrameCopperButtonText",
+ "SendMailMoneyFrameGoldButton",
+ "SendMailMoneyFrameGoldButtonText",
+ "SendMailMoneyFrameSilverButton",
+ "SendMailMoneyFrameSilverButtonText",
+ "SendMailMoneyGold",
+ "SendMailMoneyGoldLeft",
+ "SendMailMoneyGoldMiddle",
+ "SendMailMoneyGoldRight",
+ "SendMailMoneySilver",
+ "SendMailMoneySilverLeft",
+ "SendMailMoneySilverMiddle",
+ "SendMailMoneySilverRight",
+ "SendMailMoneyText",
+ "SendMailNameEditBox",
+ "SendMailNameEditBoxLeft",
+ "SendMailNameEditBoxMiddle",
+ "SendMailNameEditBoxRight",
+ "SendMailRadioButton_OnClick",
+ "SendMailScrollChildFrame",
+ "SendMailScrollFrame",
+ "SendMailScrollFrameScrollBar",
+ "SendMailScrollFrameScrollBarScrollDownButton",
+ "SendMailScrollFrameScrollBarScrollUpButton",
+ "SendMailScrollFrameScrollBarThumbTexture",
+ "SendMailSendMoneyButton",
+ "SendMailSendMoneyButtonText",
+ "SendMailSubjectEditBox",
+ "SendMailSubjectEditBoxLeft",
+ "SendMailSubjectEditBoxMiddle",
+ "SendMailSubjectEditBoxRight",
+ "SendMailTitleText",
+ "SendScrollBarBackgroundTop",
+ "SendStationeryBackgroundLeft",
+ "SendStationeryBackgroundRight",
+ "SendSystemMessage",
+ "SendWho",
+ "SetAbandonQuest",
+ "SetAchievementComparisonUnit",
+ "SetActionBarToggles",
+ "SetActiveTalentGroup",
+ "SetActiveVoiceChannel",
+ "SetActiveVoiceChannelBySessionID",
+ "SetAllowLowLevelRaid",
+ "SetArenaTeamRosterSelection",
+ "SetArenaTeamRosterShowOffline",
+ "SetAuctionDressUpBackground",
+ "SetAuctionsTabShowing",
+ "SetBagPortraitTexture",
+ "SetBaseMip",
+ "SetBattlefieldScoreFaction",
+ "SetBinding",
+ "SetBindingClick",
+ "SetBindingItem",
+ "SetBindingMacro",
+ "SetBindingSpell",
+ "SetButtonPulse",
+ "SetCVar",
+ "SetChannelOwner",
+ "SetChannelPassword",
+ "SetChannelWatch",
+ "SetChatColorNameByClass",
+ "SetChatMouseOverDelay",
+ "SetChatUnitColor",
+ "SetChatWindowAlpha",
+ "SetChatWindowColor",
+ "SetChatWindowDocked",
+ "SetChatWindowLocked",
+ "SetChatWindowName",
+ "SetChatWindowSavedDimensions",
+ "SetChatWindowSavedPosition",
+ "SetChatWindowShown",
+ "SetChatWindowSize",
+ "SetChatWindowUninteractable",
+ "SetConsoleKey",
+ "SetContainer",
+ "SetCurrencyBackpack",
+ "SetCurrencyUnused",
+ "SetCurrentGuildBankTab",
+ "SetCurrentTitle",
+ "SetCursor",
+ "SetDesaturation",
+ "SetDressUpBackground",
+ "SetDungeonDifficulty",
+ "SetDungeonMapLevel",
+ "SetEuropeanNumbers",
+ "SetFactionActive",
+ "SetFactionInactive",
+ "SetFarclip",
+ "SetFriendNotes",
+ "SetGamma",
+ "SetGuildBankTabInfo",
+ "SetGuildBankTabPermissions",
+ "SetGuildBankTabWithdraw",
+ "SetGuildBankText",
+ "SetGuildBankWithdrawLimit",
+ "SetGuildInfoText",
+ "SetGuildRosterSelection",
+ "SetGuildRosterShowOffline",
+ "SetInventoryPortraitTexture",
+ "SetItemButtonCount",
+ "SetItemButtonDesaturated",
+ "SetItemButtonNameFrameVertexColor",
+ "SetItemButtonNormalTextureVertexColor",
+ "SetItemButtonSlotVertexColor",
+ "SetItemButtonStock",
+ "SetItemButtonTexture",
+ "SetItemButtonTextureVertexColor",
+ "SetItemRef",
+ "SetLFGBootVote",
+ "SetLFGComment",
+ "SetLFGDungeon",
+ "SetLFGDungeonEnabled",
+ "SetLFGHeaderCollapsed",
+ "SetLFGRoles",
+ "SetLayoutMode",
+ "SetLootMethod",
+ "SetLootPortrait",
+ "SetLootThreshold",
+ "SetMacroItem",
+ "SetMacroSpell",
+ "SetMapByID",
+ "SetMapToCurrentZone",
+ "SetMapZoom",
+ "SetMaxStackSize",
+ "SetModifiedClick",
+ "SetMoneyFrameColor",
+ "SetMouselookOverrideBinding",
+ "SetMultiCastSpell",
+ "SetMultisampleFormat",
+ "SetNextBarberShopStyle",
+ "SetOptOutOfLoot",
+ "SetOverrideBinding",
+ "SetOverrideBindingClick",
+ "SetOverrideBindingItem",
+ "SetOverrideBindingMacro",
+ "SetOverrideBindingSpell",
+ "SetPOIIconOverlapDistance",
+ "SetPOIIconOverlapPushDistance",
+ "SetPVP",
+ "SetPartyAssignment",
+ "SetPendingGuildBankTabPermissions",
+ "SetPendingGuildBankTabWithdraw",
+ "SetPetStablePaperdoll",
+ "SetPortraitTexture",
+ "SetPortraitToTexture",
+ "SetRaidDifficulty",
+ "SetRaidRosterSelection",
+ "SetRaidSubgroup",
+ "SetRaidTarget",
+ "SetRaidTargetIcon",
+ "SetRaidTargetIconTexture",
+ "SetSavedInstanceExtend",
+ "SetScreenResolution",
+ "SetSelectedAuctionItem",
+ "SetSelectedBattlefield",
+ "SetSelectedDisplayChannel",
+ "SetSelectedFaction",
+ "SetSelectedFriend",
+ "SetSelectedIgnore",
+ "SetSelectedMute",
+ "SetSelectedSkill",
+ "SetSelfMuteState",
+ "SetSendMailCOD",
+ "SetSendMailMoney",
+ "SetSendMailShowing",
+ "SetSpellNameColor",
+ "SetTableColor",
+ "SetTalentButtonLocation",
+ "SetTargetSpellbarAspect",
+ "SetTaxiBenchmarkMode",
+ "SetTaxiMap",
+ "SetTerrainMip",
+ "SetTexLodBias",
+ "SetTextStatusBarText",
+ "SetTextStatusBarTextPrefix",
+ "SetTextStatusBarTextZeroText",
+ "SetTitleByName",
+ "SetTooltipMoney",
+ "SetTracking",
+ "SetTradeMoney",
+ "SetTradeSkillInvSlotFilter",
+ "SetTradeSkillItemLevelFilter",
+ "SetTradeSkillItemNameFilter",
+ "SetTradeSkillSubClassFilter",
+ "SetTrainerServiceTypeFilter",
+ "SetTrainerSkillLineFilter",
+ "SetUIVisibility",
+ "SetUpAnimation",
+ "SetView",
+ "SetWatchedFactionIndex",
+ "SetWaterDetail",
+ "SetWhoToUI",
+ "SetZoneText",
+ "SetupFullscreenScale",
+ "SetupUnitButtonConfiguration",
+ "ShapeshiftBarFrame",
+ "ShapeshiftBarLeft",
+ "ShapeshiftBarMiddle",
+ "ShapeshiftBarRight",
+ "ShapeshiftBar_ChangeForm",
+ "ShapeshiftBar_OnEvent",
+ "ShapeshiftBar_OnLoad",
+ "ShapeshiftBar_Update",
+ "ShapeshiftBar_UpdateState",
+ "ShapeshiftButton1",
+ "ShapeshiftButton10",
+ "ShapeshiftButton10Border",
+ "ShapeshiftButton10Cooldown",
+ "ShapeshiftButton10Count",
+ "ShapeshiftButton10Flash",
+ "ShapeshiftButton10HotKey",
+ "ShapeshiftButton10Icon",
+ "ShapeshiftButton10Name",
+ "ShapeshiftButton10NormalTexture",
+ "ShapeshiftButton1Border",
+ "ShapeshiftButton1Cooldown",
+ "ShapeshiftButton1Count",
+ "ShapeshiftButton1Flash",
+ "ShapeshiftButton1HotKey",
+ "ShapeshiftButton1Icon",
+ "ShapeshiftButton1Name",
+ "ShapeshiftButton1NormalTexture",
+ "ShapeshiftButton2",
+ "ShapeshiftButton2Border",
+ "ShapeshiftButton2Cooldown",
+ "ShapeshiftButton2Count",
+ "ShapeshiftButton2Flash",
+ "ShapeshiftButton2HotKey",
+ "ShapeshiftButton2Icon",
+ "ShapeshiftButton2Name",
+ "ShapeshiftButton2NormalTexture",
+ "ShapeshiftButton3",
+ "ShapeshiftButton3Border",
+ "ShapeshiftButton3Cooldown",
+ "ShapeshiftButton3Count",
+ "ShapeshiftButton3Flash",
+ "ShapeshiftButton3HotKey",
+ "ShapeshiftButton3Icon",
+ "ShapeshiftButton3Name",
+ "ShapeshiftButton3NormalTexture",
+ "ShapeshiftButton4",
+ "ShapeshiftButton4Border",
+ "ShapeshiftButton4Cooldown",
+ "ShapeshiftButton4Count",
+ "ShapeshiftButton4Flash",
+ "ShapeshiftButton4HotKey",
+ "ShapeshiftButton4Icon",
+ "ShapeshiftButton4Name",
+ "ShapeshiftButton4NormalTexture",
+ "ShapeshiftButton5",
+ "ShapeshiftButton5Border",
+ "ShapeshiftButton5Cooldown",
+ "ShapeshiftButton5Count",
+ "ShapeshiftButton5Flash",
+ "ShapeshiftButton5HotKey",
+ "ShapeshiftButton5Icon",
+ "ShapeshiftButton5Name",
+ "ShapeshiftButton5NormalTexture",
+ "ShapeshiftButton6",
+ "ShapeshiftButton6Border",
+ "ShapeshiftButton6Cooldown",
+ "ShapeshiftButton6Count",
+ "ShapeshiftButton6Flash",
+ "ShapeshiftButton6HotKey",
+ "ShapeshiftButton6Icon",
+ "ShapeshiftButton6Name",
+ "ShapeshiftButton6NormalTexture",
+ "ShapeshiftButton7",
+ "ShapeshiftButton7Border",
+ "ShapeshiftButton7Cooldown",
+ "ShapeshiftButton7Count",
+ "ShapeshiftButton7Flash",
+ "ShapeshiftButton7HotKey",
+ "ShapeshiftButton7Icon",
+ "ShapeshiftButton7Name",
+ "ShapeshiftButton7NormalTexture",
+ "ShapeshiftButton8",
+ "ShapeshiftButton8Border",
+ "ShapeshiftButton8Cooldown",
+ "ShapeshiftButton8Count",
+ "ShapeshiftButton8Flash",
+ "ShapeshiftButton8HotKey",
+ "ShapeshiftButton8Icon",
+ "ShapeshiftButton8Name",
+ "ShapeshiftButton8NormalTexture",
+ "ShapeshiftButton9",
+ "ShapeshiftButton9Border",
+ "ShapeshiftButton9Cooldown",
+ "ShapeshiftButton9Count",
+ "ShapeshiftButton9Flash",
+ "ShapeshiftButton9HotKey",
+ "ShapeshiftButton9Icon",
+ "ShapeshiftButton9Name",
+ "ShapeshiftButton9NormalTexture",
+ "ShiftQuestWatches",
+ "ShoppingTooltip1",
+ "ShoppingTooltip1TextLeft1",
+ "ShoppingTooltip1TextLeft2",
+ "ShoppingTooltip1TextLeft3",
+ "ShoppingTooltip1TextLeft4",
+ "ShoppingTooltip1TextRight1",
+ "ShoppingTooltip1TextRight2",
+ "ShoppingTooltip1TextRight3",
+ "ShoppingTooltip1TextRight4",
+ "ShoppingTooltip1Texture1",
+ "ShoppingTooltip1Texture2",
+ "ShoppingTooltip1Texture3",
+ "ShoppingTooltip2",
+ "ShoppingTooltip2TextLeft1",
+ "ShoppingTooltip2TextLeft2",
+ "ShoppingTooltip2TextLeft3",
+ "ShoppingTooltip2TextLeft4",
+ "ShoppingTooltip2TextRight1",
+ "ShoppingTooltip2TextRight2",
+ "ShoppingTooltip2TextRight3",
+ "ShoppingTooltip2TextRight4",
+ "ShoppingTooltip2Texture1",
+ "ShoppingTooltip2Texture2",
+ "ShoppingTooltip2Texture3",
+ "ShoppingTooltip3",
+ "ShoppingTooltip3TextLeft1",
+ "ShoppingTooltip3TextLeft2",
+ "ShoppingTooltip3TextLeft3",
+ "ShoppingTooltip3TextLeft4",
+ "ShoppingTooltip3TextRight1",
+ "ShoppingTooltip3TextRight2",
+ "ShoppingTooltip3TextRight3",
+ "ShoppingTooltip3TextRight4",
+ "ShoppingTooltip3Texture1",
+ "ShoppingTooltip3Texture2",
+ "ShoppingTooltip3Texture3",
+ "ShowAllSpellRanksCheckBox",
+ "ShowAllSpellRanksCheckBoxText",
+ "ShowBonusActionBar",
+ "ShowBuybackSellCursor",
+ "ShowCloak",
+ "ShowContainerSellCursor",
+ "ShowFriends",
+ "ShowHelm",
+ "ShowInspectCursor",
+ "ShowInventorySellCursor",
+ "ShowMacroFrame",
+ "ShowMerchantSellCursor",
+ "ShowMiniWorldMapArrowFrame",
+ "ShowMultiCastActionBar",
+ "ShowNumericThreat",
+ "ShowOnPlayerCheckButton",
+ "ShowOnPlayerCheckButtonText",
+ "ShowPartyFrame",
+ "ShowPetActionBar",
+ "ShowQuickButton",
+ "ShowReadyCheck",
+ "ShowRepairCursor",
+ "ShowResurrectRequest",
+ "ShowTextStatusBarText",
+ "ShowUIPanel",
+ "ShowWatchedReputationBarText",
+ "ShowWhoPanel",
+ "ShowWorldMapArrowFrame",
+ "ShowingCloak",
+ "ShowingHelm",
+ "SignPetition",
+ "SilenceMember",
+ "SitStandOrDescendStart",
+ "SkillBar_OnClick",
+ "SkillDetailCostText",
+ "SkillDetailDescriptionText",
+ "SkillDetailFrame_SetStatusBar",
+ "SkillDetailScrollChildFrame",
+ "SkillDetailScrollFrame",
+ "SkillDetailScrollFrameScrollBar",
+ "SkillDetailScrollFrameScrollBarScrollDownButton",
+ "SkillDetailScrollFrameScrollBarScrollUpButton",
+ "SkillDetailScrollFrameScrollBarThumbTexture",
+ "SkillDetailStatusBar",
+ "SkillDetailStatusBarBackground",
+ "SkillDetailStatusBarBar",
+ "SkillDetailStatusBarBorder",
+ "SkillDetailStatusBarFillBar",
+ "SkillDetailStatusBarLearnSkillButton",
+ "SkillDetailStatusBarLeftArrow",
+ "SkillDetailStatusBarRightArrow",
+ "SkillDetailStatusBarSkillName",
+ "SkillDetailStatusBarSkillRank",
+ "SkillDetailStatusBarUnlearnButton",
+ "SkillFrame",
+ "SkillFrameCancelButton",
+ "SkillFrameCancelButtonText",
+ "SkillFrameCollapseAllButton",
+ "SkillFrameCollapseAllButtonNormalTexture",
+ "SkillFrameExpandButtonFrame",
+ "SkillFrameExpandTabLeft",
+ "SkillFrameExpandTabMiddle",
+ "SkillFrameExpandTabRight",
+ "SkillFrameHorizontalBarLeft",
+ "SkillFrame_OnEvent",
+ "SkillFrame_OnLoad",
+ "SkillFrame_OnShow",
+ "SkillFrame_SetStatusBar",
+ "SkillFrame_UpdateSkills",
+ "SkillListScrollFrame",
+ "SkillListScrollFrameScrollBar",
+ "SkillListScrollFrameScrollBarScrollDownButton",
+ "SkillListScrollFrameScrollBarScrollUpButton",
+ "SkillListScrollFrameScrollBarThumbTexture",
+ "SkillListScrollFrameScrollChildFrame",
+ "SkillRankFrame1",
+ "SkillRankFrame10",
+ "SkillRankFrame10Background",
+ "SkillRankFrame10Bar",
+ "SkillRankFrame10Border",
+ "SkillRankFrame10BorderHighlight",
+ "SkillRankFrame10BorderNormal",
+ "SkillRankFrame10FillBar",
+ "SkillRankFrame10SkillName",
+ "SkillRankFrame10SkillRank",
+ "SkillRankFrame11",
+ "SkillRankFrame11Background",
+ "SkillRankFrame11Bar",
+ "SkillRankFrame11Border",
+ "SkillRankFrame11BorderHighlight",
+ "SkillRankFrame11BorderNormal",
+ "SkillRankFrame11FillBar",
+ "SkillRankFrame11SkillName",
+ "SkillRankFrame11SkillRank",
+ "SkillRankFrame12",
+ "SkillRankFrame12Background",
+ "SkillRankFrame12Bar",
+ "SkillRankFrame12Border",
+ "SkillRankFrame12BorderHighlight",
+ "SkillRankFrame12BorderNormal",
+ "SkillRankFrame12FillBar",
+ "SkillRankFrame12SkillName",
+ "SkillRankFrame12SkillRank",
+ "SkillRankFrame1Background",
+ "SkillRankFrame1Bar",
+ "SkillRankFrame1Border",
+ "SkillRankFrame1BorderHighlight",
+ "SkillRankFrame1BorderNormal",
+ "SkillRankFrame1FillBar",
+ "SkillRankFrame1SkillName",
+ "SkillRankFrame1SkillRank",
+ "SkillRankFrame2",
+ "SkillRankFrame2Background",
+ "SkillRankFrame2Bar",
+ "SkillRankFrame2Border",
+ "SkillRankFrame2BorderHighlight",
+ "SkillRankFrame2BorderNormal",
+ "SkillRankFrame2FillBar",
+ "SkillRankFrame2SkillName",
+ "SkillRankFrame2SkillRank",
+ "SkillRankFrame3",
+ "SkillRankFrame3Background",
+ "SkillRankFrame3Bar",
+ "SkillRankFrame3Border",
+ "SkillRankFrame3BorderHighlight",
+ "SkillRankFrame3BorderNormal",
+ "SkillRankFrame3FillBar",
+ "SkillRankFrame3SkillName",
+ "SkillRankFrame3SkillRank",
+ "SkillRankFrame4",
+ "SkillRankFrame4Background",
+ "SkillRankFrame4Bar",
+ "SkillRankFrame4Border",
+ "SkillRankFrame4BorderHighlight",
+ "SkillRankFrame4BorderNormal",
+ "SkillRankFrame4FillBar",
+ "SkillRankFrame4SkillName",
+ "SkillRankFrame4SkillRank",
+ "SkillRankFrame5",
+ "SkillRankFrame5Background",
+ "SkillRankFrame5Bar",
+ "SkillRankFrame5Border",
+ "SkillRankFrame5BorderHighlight",
+ "SkillRankFrame5BorderNormal",
+ "SkillRankFrame5FillBar",
+ "SkillRankFrame5SkillName",
+ "SkillRankFrame5SkillRank",
+ "SkillRankFrame6",
+ "SkillRankFrame6Background",
+ "SkillRankFrame6Bar",
+ "SkillRankFrame6Border",
+ "SkillRankFrame6BorderHighlight",
+ "SkillRankFrame6BorderNormal",
+ "SkillRankFrame6FillBar",
+ "SkillRankFrame6SkillName",
+ "SkillRankFrame6SkillRank",
+ "SkillRankFrame7",
+ "SkillRankFrame7Background",
+ "SkillRankFrame7Bar",
+ "SkillRankFrame7Border",
+ "SkillRankFrame7BorderHighlight",
+ "SkillRankFrame7BorderNormal",
+ "SkillRankFrame7FillBar",
+ "SkillRankFrame7SkillName",
+ "SkillRankFrame7SkillRank",
+ "SkillRankFrame8",
+ "SkillRankFrame8Background",
+ "SkillRankFrame8Bar",
+ "SkillRankFrame8Border",
+ "SkillRankFrame8BorderHighlight",
+ "SkillRankFrame8BorderNormal",
+ "SkillRankFrame8FillBar",
+ "SkillRankFrame8SkillName",
+ "SkillRankFrame8SkillRank",
+ "SkillRankFrame9",
+ "SkillRankFrame9Background",
+ "SkillRankFrame9Bar",
+ "SkillRankFrame9Border",
+ "SkillRankFrame9BorderHighlight",
+ "SkillRankFrame9BorderNormal",
+ "SkillRankFrame9FillBar",
+ "SkillRankFrame9SkillName",
+ "SkillRankFrame9SkillRank",
+ "SkillTypeLabel1",
+ "SkillTypeLabel10",
+ "SkillTypeLabel10NormalTexture",
+ "SkillTypeLabel11",
+ "SkillTypeLabel11NormalTexture",
+ "SkillTypeLabel12",
+ "SkillTypeLabel12NormalTexture",
+ "SkillTypeLabel1NormalTexture",
+ "SkillTypeLabel2",
+ "SkillTypeLabel2NormalTexture",
+ "SkillTypeLabel3",
+ "SkillTypeLabel3NormalTexture",
+ "SkillTypeLabel4",
+ "SkillTypeLabel4NormalTexture",
+ "SkillTypeLabel5",
+ "SkillTypeLabel5NormalTexture",
+ "SkillTypeLabel6",
+ "SkillTypeLabel6NormalTexture",
+ "SkillTypeLabel7",
+ "SkillTypeLabel7NormalTexture",
+ "SkillTypeLabel8",
+ "SkillTypeLabel8NormalTexture",
+ "SkillTypeLabel9",
+ "SkillTypeLabel9NormalTexture",
+ "SlashCmdList",
+ "SlidingActionBarTexture0",
+ "SlidingActionBarTexture1",
+ "SmallMoneyFrame_OnLoad",
+ "SmallTextTooltip",
+ "SmallTextTooltipText",
+ "SocialPanelOptions",
+ "SocialsMicroButton",
+ "SocketContainerItem",
+ "SocketInventoryItem",
+ "SortArenaTeamRoster",
+ "SortAuctionApplySort",
+ "SortAuctionClearSort",
+ "SortAuctionItems",
+ "SortAuctionSetSort",
+ "SortBGList",
+ "SortBattlefieldScoreData",
+ "SortButton_UpdateArrow",
+ "SortGuildRoster",
+ "SortQuestWatches",
+ "SortWho",
+ "SoundPanelOptions",
+ "Sound_ChatSystem_GetInputDriverNameByIndex",
+ "Sound_ChatSystem_GetNumInputDrivers",
+ "Sound_ChatSystem_GetNumOutputDrivers",
+ "Sound_ChatSystem_GetOutputDriverNameByIndex",
+ "Sound_GameSystem_GetInputDriverNameByIndex",
+ "Sound_GameSystem_GetNumInputDrivers",
+ "Sound_GameSystem_GetNumOutputDrivers",
+ "Sound_GameSystem_GetOutputDriverNameByIndex",
+ "Sound_GameSystem_RestartSoundSystem",
+ "Sound_MasterVolumeDown",
+ "Sound_MasterVolumeUp",
+ "Sound_ToggleMusic",
+ "Sound_ToggleSound",
+ "SparkleDimensions",
+ "SparkleFrame",
+ "SpellBookCloseButton",
+ "SpellBookFrame",
+ "SpellBookFrameBotLeft",
+ "SpellBookFrameBotRight",
+ "SpellBookFrameIcon",
+ "SpellBookFrameTabButton1",
+ "SpellBookFrameTabButton2",
+ "SpellBookFrameTabButton3",
+ "SpellBookFrameTabButton_OnClick",
+ "SpellBookFrameTopLeft",
+ "SpellBookFrameTopRight",
+ "SpellBookFrame_HideSpells",
+ "SpellBookFrame_OnEvent",
+ "SpellBookFrame_OnHide",
+ "SpellBookFrame_OnLoad",
+ "SpellBookFrame_OnShow",
+ "SpellBookFrame_PlayCloseSound",
+ "SpellBookFrame_PlayOpenSound",
+ "SpellBookFrame_SetTabType",
+ "SpellBookFrame_ShowSpells",
+ "SpellBookFrame_Update",
+ "SpellBookFrame_UpdatePages",
+ "SpellBookNextPageButton",
+ "SpellBookNextPageButton_OnClick",
+ "SpellBookPageText",
+ "SpellBookPrevPageButton",
+ "SpellBookPrevPageButton_OnClick",
+ "SpellBookSkillLineTab1",
+ "SpellBookSkillLineTab1Flash",
+ "SpellBookSkillLineTab2",
+ "SpellBookSkillLineTab2Flash",
+ "SpellBookSkillLineTab3",
+ "SpellBookSkillLineTab3Flash",
+ "SpellBookSkillLineTab4",
+ "SpellBookSkillLineTab4Flash",
+ "SpellBookSkillLineTab5",
+ "SpellBookSkillLineTab5Flash",
+ "SpellBookSkillLineTab6",
+ "SpellBookSkillLineTab6Flash",
+ "SpellBookSkillLineTab7",
+ "SpellBookSkillLineTab7Flash",
+ "SpellBookSkillLineTab8",
+ "SpellBookSkillLineTab8Flash",
+ "SpellBookSkillLineTab_OnClick",
+ "SpellBookTabFlashFrame",
+ "SpellBookTitleText",
+ "SpellBook_GetAutoCastShine",
+ "SpellBook_GetCurrentPage",
+ "SpellBook_GetSpellID",
+ "SpellBook_GetTabInfo",
+ "SpellBook_ReleaseAutoCastShine",
+ "SpellBook_UpdatePageArrows",
+ "SpellButton1",
+ "SpellButton10",
+ "SpellButton10AutoCastable",
+ "SpellButton10Background",
+ "SpellButton10Cooldown",
+ "SpellButton10Highlight",
+ "SpellButton10IconTexture",
+ "SpellButton10NormalTexture",
+ "SpellButton10SpellName",
+ "SpellButton10SubSpellName",
+ "SpellButton11",
+ "SpellButton11AutoCastable",
+ "SpellButton11Background",
+ "SpellButton11Cooldown",
+ "SpellButton11Highlight",
+ "SpellButton11IconTexture",
+ "SpellButton11NormalTexture",
+ "SpellButton11SpellName",
+ "SpellButton11SubSpellName",
+ "SpellButton12",
+ "SpellButton12AutoCastable",
+ "SpellButton12Background",
+ "SpellButton12Cooldown",
+ "SpellButton12Highlight",
+ "SpellButton12IconTexture",
+ "SpellButton12NormalTexture",
+ "SpellButton12SpellName",
+ "SpellButton12SubSpellName",
+ "SpellButton1AutoCastable",
+ "SpellButton1Background",
+ "SpellButton1Cooldown",
+ "SpellButton1Highlight",
+ "SpellButton1IconTexture",
+ "SpellButton1NormalTexture",
+ "SpellButton1SpellName",
+ "SpellButton1SubSpellName",
+ "SpellButton2",
+ "SpellButton2AutoCastable",
+ "SpellButton2Background",
+ "SpellButton2Cooldown",
+ "SpellButton2Highlight",
+ "SpellButton2IconTexture",
+ "SpellButton2NormalTexture",
+ "SpellButton2SpellName",
+ "SpellButton2SubSpellName",
+ "SpellButton3",
+ "SpellButton3AutoCastable",
+ "SpellButton3Background",
+ "SpellButton3Cooldown",
+ "SpellButton3Highlight",
+ "SpellButton3IconTexture",
+ "SpellButton3NormalTexture",
+ "SpellButton3SpellName",
+ "SpellButton3SubSpellName",
+ "SpellButton4",
+ "SpellButton4AutoCastable",
+ "SpellButton4Background",
+ "SpellButton4Cooldown",
+ "SpellButton4Highlight",
+ "SpellButton4IconTexture",
+ "SpellButton4NormalTexture",
+ "SpellButton4SpellName",
+ "SpellButton4SubSpellName",
+ "SpellButton5",
+ "SpellButton5AutoCastable",
+ "SpellButton5Background",
+ "SpellButton5Cooldown",
+ "SpellButton5Highlight",
+ "SpellButton5IconTexture",
+ "SpellButton5NormalTexture",
+ "SpellButton5SpellName",
+ "SpellButton5SubSpellName",
+ "SpellButton6",
+ "SpellButton6AutoCastable",
+ "SpellButton6Background",
+ "SpellButton6Cooldown",
+ "SpellButton6Highlight",
+ "SpellButton6IconTexture",
+ "SpellButton6NormalTexture",
+ "SpellButton6SpellName",
+ "SpellButton6SubSpellName",
+ "SpellButton7",
+ "SpellButton7AutoCastable",
+ "SpellButton7Background",
+ "SpellButton7Cooldown",
+ "SpellButton7Highlight",
+ "SpellButton7IconTexture",
+ "SpellButton7NormalTexture",
+ "SpellButton7SpellName",
+ "SpellButton7SubSpellName",
+ "SpellButton8",
+ "SpellButton8AutoCastable",
+ "SpellButton8Background",
+ "SpellButton8Cooldown",
+ "SpellButton8Highlight",
+ "SpellButton8IconTexture",
+ "SpellButton8NormalTexture",
+ "SpellButton8SpellName",
+ "SpellButton8SubSpellName",
+ "SpellButton9",
+ "SpellButton9AutoCastable",
+ "SpellButton9Background",
+ "SpellButton9Cooldown",
+ "SpellButton9Highlight",
+ "SpellButton9IconTexture",
+ "SpellButton9NormalTexture",
+ "SpellButton9SpellName",
+ "SpellButton9SubSpellName",
+ "SpellButton_OnClick",
+ "SpellButton_OnDrag",
+ "SpellButton_OnEnter",
+ "SpellButton_OnEvent",
+ "SpellButton_OnHide",
+ "SpellButton_OnLoad",
+ "SpellButton_OnModifiedClick",
+ "SpellButton_OnShow",
+ "SpellButton_UpdateButton",
+ "SpellButton_UpdateSelection",
+ "SpellCanTargetGlyph",
+ "SpellCanTargetItem",
+ "SpellCanTargetUnit",
+ "SpellColor_OpenColorPicker",
+ "SpellFont_Small",
+ "SpellHasRange",
+ "SpellIsTargeting",
+ "SpellStopCasting",
+ "SpellStopTargeting",
+ "SpellTargetItem",
+ "SpellTargetUnit",
+ "SpellbookMicroButton",
+ "SplitContainerItem",
+ "SplitGuildBankItem",
+ "StablePet",
+ "StackSplitCancelButton",
+ "StackSplitCancelButtonText",
+ "StackSplitFrame",
+ "StackSplitFrameCancel_Click",
+ "StackSplitFrameLeft_Click",
+ "StackSplitFrameOkay_Click",
+ "StackSplitFrameRight_Click",
+ "StackSplitFrame_OnChar",
+ "StackSplitFrame_OnHide",
+ "StackSplitFrame_OnKeyDown",
+ "StackSplitFrame_OnKeyUp",
+ "StackSplitLeftButton",
+ "StackSplitOkayButton",
+ "StackSplitOkayButtonText",
+ "StackSplitRightButton",
+ "StackSplitText",
+ "StandingMouseOver",
+ "StartAttack",
+ "StartAuction",
+ "StartDuel",
+ "StartPrice",
+ "StartPriceCopper",
+ "StartPriceCopperLeft",
+ "StartPriceCopperMiddle",
+ "StartPriceCopperRight",
+ "StartPriceGold",
+ "StartPriceGoldLeft",
+ "StartPriceGoldMiddle",
+ "StartPriceGoldRight",
+ "StartPriceSilver",
+ "StartPriceSilverLeft",
+ "StartPriceSilverMiddle",
+ "StartPriceSilverRight",
+ "StaticPopup1",
+ "StaticPopup1AlertIcon",
+ "StaticPopup1Button1",
+ "StaticPopup1Button1Text",
+ "StaticPopup1Button2",
+ "StaticPopup1Button2Text",
+ "StaticPopup1Button3",
+ "StaticPopup1Button3Text",
+ "StaticPopup1CloseButton",
+ "StaticPopup1EditBox",
+ "StaticPopup1ExtraFrame",
+ "StaticPopup1ItemFrame",
+ "StaticPopup1ItemFrameCount",
+ "StaticPopup1ItemFrameIconTexture",
+ "StaticPopup1ItemFrameNameFrame",
+ "StaticPopup1ItemFrameNormalTexture",
+ "StaticPopup1ItemFrameStock",
+ "StaticPopup1ItemFrameText",
+ "StaticPopup1MoneyFrame",
+ "StaticPopup1MoneyFrameCopperButton",
+ "StaticPopup1MoneyFrameCopperButtonText",
+ "StaticPopup1MoneyFrameGoldButton",
+ "StaticPopup1MoneyFrameGoldButtonText",
+ "StaticPopup1MoneyFrameSilverButton",
+ "StaticPopup1MoneyFrameSilverButtonText",
+ "StaticPopup1MoneyInputFrame",
+ "StaticPopup1MoneyInputFrameCopper",
+ "StaticPopup1MoneyInputFrameCopperLeft",
+ "StaticPopup1MoneyInputFrameCopperMiddle",
+ "StaticPopup1MoneyInputFrameCopperRight",
+ "StaticPopup1MoneyInputFrameGold",
+ "StaticPopup1MoneyInputFrameGoldLeft",
+ "StaticPopup1MoneyInputFrameGoldMiddle",
+ "StaticPopup1MoneyInputFrameGoldRight",
+ "StaticPopup1MoneyInputFrameSilver",
+ "StaticPopup1MoneyInputFrameSilverLeft",
+ "StaticPopup1MoneyInputFrameSilverMiddle",
+ "StaticPopup1MoneyInputFrameSilverRight",
+ "StaticPopup1Text",
+ "StaticPopup1WideEditBox",
+ "StaticPopup1WideEditBoxLeft",
+ "StaticPopup1WideEditBoxRight",
+ "StaticPopup2",
+ "StaticPopup2AlertIcon",
+ "StaticPopup2Button1",
+ "StaticPopup2Button1Text",
+ "StaticPopup2Button2",
+ "StaticPopup2Button2Text",
+ "StaticPopup2Button3",
+ "StaticPopup2Button3Text",
+ "StaticPopup2CloseButton",
+ "StaticPopup2EditBox",
+ "StaticPopup2ExtraFrame",
+ "StaticPopup2ItemFrame",
+ "StaticPopup2ItemFrameCount",
+ "StaticPopup2ItemFrameIconTexture",
+ "StaticPopup2ItemFrameNameFrame",
+ "StaticPopup2ItemFrameNormalTexture",
+ "StaticPopup2ItemFrameStock",
+ "StaticPopup2ItemFrameText",
+ "StaticPopup2MoneyFrame",
+ "StaticPopup2MoneyFrameCopperButton",
+ "StaticPopup2MoneyFrameCopperButtonText",
+ "StaticPopup2MoneyFrameGoldButton",
+ "StaticPopup2MoneyFrameGoldButtonText",
+ "StaticPopup2MoneyFrameSilverButton",
+ "StaticPopup2MoneyFrameSilverButtonText",
+ "StaticPopup2MoneyInputFrame",
+ "StaticPopup2MoneyInputFrameCopper",
+ "StaticPopup2MoneyInputFrameCopperLeft",
+ "StaticPopup2MoneyInputFrameCopperMiddle",
+ "StaticPopup2MoneyInputFrameCopperRight",
+ "StaticPopup2MoneyInputFrameGold",
+ "StaticPopup2MoneyInputFrameGoldLeft",
+ "StaticPopup2MoneyInputFrameGoldMiddle",
+ "StaticPopup2MoneyInputFrameGoldRight",
+ "StaticPopup2MoneyInputFrameSilver",
+ "StaticPopup2MoneyInputFrameSilverLeft",
+ "StaticPopup2MoneyInputFrameSilverMiddle",
+ "StaticPopup2MoneyInputFrameSilverRight",
+ "StaticPopup2Text",
+ "StaticPopup2WideEditBox",
+ "StaticPopup2WideEditBoxLeft",
+ "StaticPopup2WideEditBoxRight",
+ "StaticPopup3",
+ "StaticPopup3AlertIcon",
+ "StaticPopup3Button1",
+ "StaticPopup3Button1Text",
+ "StaticPopup3Button2",
+ "StaticPopup3Button2Text",
+ "StaticPopup3Button3",
+ "StaticPopup3Button3Text",
+ "StaticPopup3CloseButton",
+ "StaticPopup3EditBox",
+ "StaticPopup3ExtraFrame",
+ "StaticPopup3ItemFrame",
+ "StaticPopup3ItemFrameCount",
+ "StaticPopup3ItemFrameIconTexture",
+ "StaticPopup3ItemFrameNameFrame",
+ "StaticPopup3ItemFrameNormalTexture",
+ "StaticPopup3ItemFrameStock",
+ "StaticPopup3ItemFrameText",
+ "StaticPopup3MoneyFrame",
+ "StaticPopup3MoneyFrameCopperButton",
+ "StaticPopup3MoneyFrameCopperButtonText",
+ "StaticPopup3MoneyFrameGoldButton",
+ "StaticPopup3MoneyFrameGoldButtonText",
+ "StaticPopup3MoneyFrameSilverButton",
+ "StaticPopup3MoneyFrameSilverButtonText",
+ "StaticPopup3MoneyInputFrame",
+ "StaticPopup3MoneyInputFrameCopper",
+ "StaticPopup3MoneyInputFrameCopperLeft",
+ "StaticPopup3MoneyInputFrameCopperMiddle",
+ "StaticPopup3MoneyInputFrameCopperRight",
+ "StaticPopup3MoneyInputFrameGold",
+ "StaticPopup3MoneyInputFrameGoldLeft",
+ "StaticPopup3MoneyInputFrameGoldMiddle",
+ "StaticPopup3MoneyInputFrameGoldRight",
+ "StaticPopup3MoneyInputFrameSilver",
+ "StaticPopup3MoneyInputFrameSilverLeft",
+ "StaticPopup3MoneyInputFrameSilverMiddle",
+ "StaticPopup3MoneyInputFrameSilverRight",
+ "StaticPopup3Text",
+ "StaticPopup3WideEditBox",
+ "StaticPopup3WideEditBoxLeft",
+ "StaticPopup3WideEditBoxRight",
+ "StaticPopup4",
+ "StaticPopup4AlertIcon",
+ "StaticPopup4Button1",
+ "StaticPopup4Button1Text",
+ "StaticPopup4Button2",
+ "StaticPopup4Button2Text",
+ "StaticPopup4Button3",
+ "StaticPopup4Button3Text",
+ "StaticPopup4CloseButton",
+ "StaticPopup4EditBox",
+ "StaticPopup4ExtraFrame",
+ "StaticPopup4ItemFrame",
+ "StaticPopup4ItemFrameCount",
+ "StaticPopup4ItemFrameIconTexture",
+ "StaticPopup4ItemFrameNameFrame",
+ "StaticPopup4ItemFrameNormalTexture",
+ "StaticPopup4ItemFrameStock",
+ "StaticPopup4ItemFrameText",
+ "StaticPopup4MoneyFrame",
+ "StaticPopup4MoneyFrameCopperButton",
+ "StaticPopup4MoneyFrameCopperButtonText",
+ "StaticPopup4MoneyFrameGoldButton",
+ "StaticPopup4MoneyFrameGoldButtonText",
+ "StaticPopup4MoneyFrameSilverButton",
+ "StaticPopup4MoneyFrameSilverButtonText",
+ "StaticPopup4MoneyInputFrame",
+ "StaticPopup4MoneyInputFrameCopper",
+ "StaticPopup4MoneyInputFrameCopperLeft",
+ "StaticPopup4MoneyInputFrameCopperMiddle",
+ "StaticPopup4MoneyInputFrameCopperRight",
+ "StaticPopup4MoneyInputFrameGold",
+ "StaticPopup4MoneyInputFrameGoldLeft",
+ "StaticPopup4MoneyInputFrameGoldMiddle",
+ "StaticPopup4MoneyInputFrameGoldRight",
+ "StaticPopup4MoneyInputFrameSilver",
+ "StaticPopup4MoneyInputFrameSilverLeft",
+ "StaticPopup4MoneyInputFrameSilverMiddle",
+ "StaticPopup4MoneyInputFrameSilverRight",
+ "StaticPopup4Text",
+ "StaticPopup4WideEditBox",
+ "StaticPopup4WideEditBoxLeft",
+ "StaticPopup4WideEditBoxRight",
+ "StaticPopupDialogs",
+ "StaticPopupSpecial_Hide",
+ "StaticPopupSpecial_Show",
+ "StaticPopup_CollapseTable",
+ "StaticPopup_DisplayedFrames",
+ "StaticPopup_EditBoxOnEnterPressed",
+ "StaticPopup_EditBoxOnEscapePressed",
+ "StaticPopup_EditBoxOnTextChanged",
+ "StaticPopup_EscapePressed",
+ "StaticPopup_FindVisible",
+ "StaticPopup_Hide",
+ "StaticPopup_HideExclusive",
+ "StaticPopup_IsLastDisplayedFrame",
+ "StaticPopup_OnClick",
+ "StaticPopup_OnEvent",
+ "StaticPopup_OnHide",
+ "StaticPopup_OnKeyDown",
+ "StaticPopup_OnShow",
+ "StaticPopup_OnUpdate",
+ "StaticPopup_Resize",
+ "StaticPopup_SetUpPosition",
+ "StaticPopup_Show",
+ "StaticPopup_Visible",
+ "StationeryPopupButton1",
+ "StationeryPopupButton1Icon",
+ "StationeryPopupButton1MoneyFrame",
+ "StationeryPopupButton1MoneyFrameCopperButton",
+ "StationeryPopupButton1MoneyFrameCopperButtonText",
+ "StationeryPopupButton1MoneyFrameGoldButton",
+ "StationeryPopupButton1MoneyFrameGoldButtonText",
+ "StationeryPopupButton1MoneyFrameSilverButton",
+ "StationeryPopupButton1MoneyFrameSilverButtonText",
+ "StationeryPopupButton1Name",
+ "StationeryPopupButton1NameFrame",
+ "StationeryPopupButton2",
+ "StationeryPopupButton2Icon",
+ "StationeryPopupButton2MoneyFrame",
+ "StationeryPopupButton2MoneyFrameCopperButton",
+ "StationeryPopupButton2MoneyFrameCopperButtonText",
+ "StationeryPopupButton2MoneyFrameGoldButton",
+ "StationeryPopupButton2MoneyFrameGoldButtonText",
+ "StationeryPopupButton2MoneyFrameSilverButton",
+ "StationeryPopupButton2MoneyFrameSilverButtonText",
+ "StationeryPopupButton2Name",
+ "StationeryPopupButton2NameFrame",
+ "StationeryPopupButton3",
+ "StationeryPopupButton3Icon",
+ "StationeryPopupButton3MoneyFrame",
+ "StationeryPopupButton3MoneyFrameCopperButton",
+ "StationeryPopupButton3MoneyFrameCopperButtonText",
+ "StationeryPopupButton3MoneyFrameGoldButton",
+ "StationeryPopupButton3MoneyFrameGoldButtonText",
+ "StationeryPopupButton3MoneyFrameSilverButton",
+ "StationeryPopupButton3MoneyFrameSilverButtonText",
+ "StationeryPopupButton3Name",
+ "StationeryPopupButton3NameFrame",
+ "StationeryPopupButton4",
+ "StationeryPopupButton4Icon",
+ "StationeryPopupButton4MoneyFrame",
+ "StationeryPopupButton4MoneyFrameCopperButton",
+ "StationeryPopupButton4MoneyFrameCopperButtonText",
+ "StationeryPopupButton4MoneyFrameGoldButton",
+ "StationeryPopupButton4MoneyFrameGoldButtonText",
+ "StationeryPopupButton4MoneyFrameSilverButton",
+ "StationeryPopupButton4MoneyFrameSilverButtonText",
+ "StationeryPopupButton4Name",
+ "StationeryPopupButton4NameFrame",
+ "StationeryPopupButton5",
+ "StationeryPopupButton5Icon",
+ "StationeryPopupButton5MoneyFrame",
+ "StationeryPopupButton5MoneyFrameCopperButton",
+ "StationeryPopupButton5MoneyFrameCopperButtonText",
+ "StationeryPopupButton5MoneyFrameGoldButton",
+ "StationeryPopupButton5MoneyFrameGoldButtonText",
+ "StationeryPopupButton5MoneyFrameSilverButton",
+ "StationeryPopupButton5MoneyFrameSilverButtonText",
+ "StationeryPopupButton5Name",
+ "StationeryPopupButton5NameFrame",
+ "StationeryPopupButton_OnClick",
+ "StationeryPopupCancelButton",
+ "StationeryPopupCancelButtonText",
+ "StationeryPopupFrame",
+ "StationeryPopupFrame_Update",
+ "StationeryPopupOkayButton",
+ "StationeryPopupOkayButtonText",
+ "StationeryPopupScrollFrame",
+ "StationeryPopupScrollFrameScrollBar",
+ "StationeryPopupScrollFrameScrollBarScrollDownButton",
+ "StationeryPopupScrollFrameScrollBarScrollUpButton",
+ "StationeryPopupScrollFrameScrollBarThumbTexture",
+ "StationeryPopupScrollFrameScrollChildFrame",
+ "StatsFrame",
+ "StatsFrameText",
+ "StatsFrame_OnLoad",
+ "StatsFrame_OnUpdate",
+ "StatusTextPanelOptions",
+ "StopAttack",
+ "StopCinematic",
+ "StopMacro",
+ "StopMusic",
+ "StopTradeSkillRepeat",
+ "StopwatchCloseButton",
+ "StopwatchCloseButton_OnClick",
+ "StopwatchFrame",
+ "StopwatchFrameBackgroundLeft",
+ "StopwatchFrame_OnDragStart",
+ "StopwatchFrame_OnDragStop",
+ "StopwatchFrame_OnEvent",
+ "StopwatchFrame_OnHide",
+ "StopwatchFrame_OnLoad",
+ "StopwatchFrame_OnMouseDown",
+ "StopwatchFrame_OnMouseUp",
+ "StopwatchFrame_OnShow",
+ "StopwatchFrame_OnUpdate",
+ "StopwatchPlayPauseButton",
+ "StopwatchPlayPauseButton_OnClick",
+ "StopwatchResetButton",
+ "StopwatchResetButton_OnClick",
+ "StopwatchTabFrame",
+ "StopwatchTabFrameLeft",
+ "StopwatchTabFrameMiddle",
+ "StopwatchTabFrameRight",
+ "StopwatchTicker",
+ "StopwatchTickerHour",
+ "StopwatchTickerMinute",
+ "StopwatchTickerSecond",
+ "StopwatchTicker_OnUpdate",
+ "StopwatchTicker_Update",
+ "StopwatchTitle",
+ "Stopwatch_Clear",
+ "Stopwatch_FinishCountdown",
+ "Stopwatch_IsPlaying",
+ "Stopwatch_Pause",
+ "Stopwatch_Play",
+ "Stopwatch_StartCountdown",
+ "Stopwatch_Toggle",
+ "StrafeLeftStart",
+ "StrafeLeftStop",
+ "StrafeRightStart",
+ "StrafeRightStop",
+ "Stuck",
+ "SubSpellFont",
+ "SubZoneTextFont",
+ "SubZoneTextFrame",
+ "SubZoneTextString",
+ "SubZoneText_OnLoad",
+ "SummonFriend",
+ "SummonRandomCritter",
+ "SwapRaidSubgroup",
+ "SynchronizeBNetStatus",
+ "SystemFont_Huge1",
+ "SystemFont_InverseShadow_Small",
+ "SystemFont_Large",
+ "SystemFont_Med1",
+ "SystemFont_Med2",
+ "SystemFont_Med3",
+ "SystemFont_Outline",
+ "SystemFont_OutlineThick_Huge2",
+ "SystemFont_OutlineThick_Huge4",
+ "SystemFont_OutlineThick_WTF",
+ "SystemFont_Outline_Small",
+ "SystemFont_Shadow_Huge1",
+ "SystemFont_Shadow_Huge3",
+ "SystemFont_Shadow_Large",
+ "SystemFont_Shadow_Med1",
+ "SystemFont_Shadow_Med2",
+ "SystemFont_Shadow_Med3",
+ "SystemFont_Shadow_Outline_Huge2",
+ "SystemFont_Shadow_Small",
+ "SystemFont_Small",
+ "SystemFont_Tiny",
+ "TALENT_ACTIVATION_SPELLS",
+ "TALENT_ARROW_TEXTURECOORDS",
+ "TALENT_BRANCH_TEXTURECOORDS",
+ "TALENT_SORT_ORDER",
+ "TEXT",
+ "TOOLTIP_DEFAULT_BACKGROUND_COLOR",
+ "TOOLTIP_DEFAULT_COLOR",
+ "TOTEM_MULTI_CAST_RECALL_SPELLS",
+ "TOTEM_MULTI_CAST_SUMMON_SPELLS",
+ "TOTEM_PRIORITIES",
+ "TabardCharacterModelFrame_OnLoad",
+ "TabardCharacterModelFrame_OnUpdate",
+ "TabardCharacterModelRotateLeftButton",
+ "TabardCharacterModelRotateLeftButton_OnClick",
+ "TabardCharacterModelRotateRightButton",
+ "TabardCharacterModelRotateRightButton_OnClick",
+ "TabardCustomization_Left",
+ "TabardCustomization_Right",
+ "TabardFrame",
+ "TabardFrameAcceptButton",
+ "TabardFrameAcceptButtonText",
+ "TabardFrameBackground",
+ "TabardFrameCancelButton",
+ "TabardFrameCancelButtonText",
+ "TabardFrameCloseButton",
+ "TabardFrameCostFrame",
+ "TabardFrameCostLabel",
+ "TabardFrameCostMoneyFrame",
+ "TabardFrameCostMoneyFrameCopperButton",
+ "TabardFrameCostMoneyFrameCopperButtonText",
+ "TabardFrameCostMoneyFrameGoldButton",
+ "TabardFrameCostMoneyFrameGoldButtonText",
+ "TabardFrameCostMoneyFrameSilverButton",
+ "TabardFrameCostMoneyFrameSilverButtonText",
+ "TabardFrameCustomization1",
+ "TabardFrameCustomization1Left",
+ "TabardFrameCustomization1LeftButton",
+ "TabardFrameCustomization1Middle",
+ "TabardFrameCustomization1Right",
+ "TabardFrameCustomization1RightButton",
+ "TabardFrameCustomization1Text",
+ "TabardFrameCustomization2",
+ "TabardFrameCustomization2Left",
+ "TabardFrameCustomization2LeftButton",
+ "TabardFrameCustomization2Middle",
+ "TabardFrameCustomization2Right",
+ "TabardFrameCustomization2RightButton",
+ "TabardFrameCustomization2Text",
+ "TabardFrameCustomization3",
+ "TabardFrameCustomization3Left",
+ "TabardFrameCustomization3LeftButton",
+ "TabardFrameCustomization3Middle",
+ "TabardFrameCustomization3Right",
+ "TabardFrameCustomization3RightButton",
+ "TabardFrameCustomization3Text",
+ "TabardFrameCustomization4",
+ "TabardFrameCustomization4Left",
+ "TabardFrameCustomization4LeftButton",
+ "TabardFrameCustomization4Middle",
+ "TabardFrameCustomization4Right",
+ "TabardFrameCustomization4RightButton",
+ "TabardFrameCustomization4Text",
+ "TabardFrameCustomization5",
+ "TabardFrameCustomization5Left",
+ "TabardFrameCustomization5LeftButton",
+ "TabardFrameCustomization5Middle",
+ "TabardFrameCustomization5Right",
+ "TabardFrameCustomization5RightButton",
+ "TabardFrameCustomization5Text",
+ "TabardFrameCustomizationBorder",
+ "TabardFrameCustomizationFrame",
+ "TabardFrameEmblemBottomLeft",
+ "TabardFrameEmblemBottomRight",
+ "TabardFrameEmblemTopLeft",
+ "TabardFrameEmblemTopRight",
+ "TabardFrameGreetingText",
+ "TabardFrameMoneyFrame",
+ "TabardFrameMoneyFrameCopperButton",
+ "TabardFrameMoneyFrameCopperButtonText",
+ "TabardFrameMoneyFrameGoldButton",
+ "TabardFrameMoneyFrameGoldButtonText",
+ "TabardFrameMoneyFrameSilverButton",
+ "TabardFrameMoneyFrameSilverButtonText",
+ "TabardFrameNameText",
+ "TabardFrameOuterFrameBottom",
+ "TabardFrameOuterFrameBottomLeft",
+ "TabardFrameOuterFrameBottomRight",
+ "TabardFrameOuterFrameLeftBottom",
+ "TabardFrameOuterFrameLeftTop",
+ "TabardFrameOuterFrameRightBottom",
+ "TabardFrameOuterFrameRightTop",
+ "TabardFrameOuterFrameTop",
+ "TabardFrameOuterFrameTopLeft",
+ "TabardFrameOuterFrameTopRight",
+ "TabardFramePortrait",
+ "TabardFrame_OnEvent",
+ "TabardFrame_OnLoad",
+ "TabardFrame_UpdateButtons",
+ "TabardFrame_UpdateTextures",
+ "TabardModel",
+ "TakeInboxItem",
+ "TakeInboxMoney",
+ "TakeInboxTextItem",
+ "TakeScreenshot",
+ "TakeTaxiNode",
+ "TalentFrame_DrawLines",
+ "TalentFrame_GetArrowTexture",
+ "TalentFrame_GetArrowTextureCount",
+ "TalentFrame_GetBranchTexture",
+ "TalentFrame_GetBranchTextureCount",
+ "TalentFrame_Load",
+ "TalentFrame_LoadUI",
+ "TalentFrame_ResetArrowTextureCount",
+ "TalentFrame_ResetBranchTextureCount",
+ "TalentFrame_ResetBranches",
+ "TalentFrame_SetArrowTexture",
+ "TalentFrame_SetBranchTexture",
+ "TalentFrame_SetPrereqs",
+ "TalentFrame_Update",
+ "TalentFrame_UpdateSpecInfoCache",
+ "TalentFrame_UpdateTalentPoints",
+ "TalentMicroButton",
+ "TalentMicroButton_OnEvent",
+ "TargetDirectionEnemy",
+ "TargetDirectionFinished",
+ "TargetDirectionFriend",
+ "TargetFrame",
+ "TargetFrameBackground",
+ "TargetFrameBuffs",
+ "TargetFrameDebuffs",
+ "TargetFrameDropDown",
+ "TargetFrameDropDownButton",
+ "TargetFrameDropDownButtonDisabledTexture",
+ "TargetFrameDropDownButtonHighlightTexture",
+ "TargetFrameDropDownButtonNormalTexture",
+ "TargetFrameDropDownButtonPushedTexture",
+ "TargetFrameDropDownLeft",
+ "TargetFrameDropDownMiddle",
+ "TargetFrameDropDownRight",
+ "TargetFrameDropDownText",
+ "TargetFrameDropDown_Initialize",
+ "TargetFrameFlash",
+ "TargetFrameHealthBar",
+ "TargetFrameManaBar",
+ "TargetFrameNameBackground",
+ "TargetFrameNumericalThreat",
+ "TargetFrameNumericalThreatBG",
+ "TargetFrameNumericalThreatValue",
+ "TargetFramePortrait",
+ "TargetFrameSpellBar",
+ "TargetFrameSpellBarBorder",
+ "TargetFrameSpellBarBorderShield",
+ "TargetFrameSpellBarFlash",
+ "TargetFrameSpellBarIcon",
+ "TargetFrameSpellBarSpark",
+ "TargetFrameSpellBarText",
+ "TargetFrameTextureFrame",
+ "TargetFrameTextureFrameDeadText",
+ "TargetFrameTextureFrameHealthBarText",
+ "TargetFrameTextureFrameHighLevelTexture",
+ "TargetFrameTextureFrameLeaderIcon",
+ "TargetFrameTextureFrameLevelText",
+ "TargetFrameTextureFrameManaBarText",
+ "TargetFrameTextureFrameName",
+ "TargetFrameTextureFramePVPIcon",
+ "TargetFrameTextureFrameRaidTargetIcon",
+ "TargetFrameTextureFrameTexture",
+ "TargetFrameToT",
+ "TargetFrameToTBackground",
+ "TargetFrameToTDebuff1",
+ "TargetFrameToTDebuff1Border",
+ "TargetFrameToTDebuff1Cooldown",
+ "TargetFrameToTDebuff1Icon",
+ "TargetFrameToTDebuff2",
+ "TargetFrameToTDebuff2Border",
+ "TargetFrameToTDebuff2Cooldown",
+ "TargetFrameToTDebuff2Icon",
+ "TargetFrameToTDebuff3",
+ "TargetFrameToTDebuff3Border",
+ "TargetFrameToTDebuff3Cooldown",
+ "TargetFrameToTDebuff3Icon",
+ "TargetFrameToTDebuff4",
+ "TargetFrameToTDebuff4Border",
+ "TargetFrameToTDebuff4Cooldown",
+ "TargetFrameToTDebuff4Icon",
+ "TargetFrameToTHealthBar",
+ "TargetFrameToTManaBar",
+ "TargetFrameToTPortrait",
+ "TargetFrameToTTextureFrame",
+ "TargetFrameToTTextureFrameDeadText",
+ "TargetFrameToTTextureFrameName",
+ "TargetFrameToTTextureFrameTexture",
+ "TargetFrame_CheckClassification",
+ "TargetFrame_CheckDead",
+ "TargetFrame_CheckFaction",
+ "TargetFrame_CheckLevel",
+ "TargetFrame_CreateSpellbar",
+ "TargetFrame_CreateTargetofTarget",
+ "TargetFrame_HealthUpdate",
+ "TargetFrame_OnEvent",
+ "TargetFrame_OnHide",
+ "TargetFrame_OnLoad",
+ "TargetFrame_OnUpdate",
+ "TargetFrame_Update",
+ "TargetFrame_UpdateAuraPositions",
+ "TargetFrame_UpdateAuras",
+ "TargetFrame_UpdateBuffAnchor",
+ "TargetFrame_UpdateDebuffAnchor",
+ "TargetFrame_UpdateRaidTargetIcon",
+ "TargetHealthCheck",
+ "TargetLastEnemy",
+ "TargetLastFriend",
+ "TargetLastTarget",
+ "TargetNearest",
+ "TargetNearestEnemy",
+ "TargetNearestEnemyPlayer",
+ "TargetNearestFriend",
+ "TargetNearestFriendPlayer",
+ "TargetNearestPartyMember",
+ "TargetNearestRaidMember",
+ "TargetTotem",
+ "TargetUnit",
+ "Target_Spellbar_AdjustPosition",
+ "Target_Spellbar_OnEvent",
+ "TargetofTargetHealthCheck",
+ "TargetofTarget_CheckDead",
+ "TargetofTarget_OnHide",
+ "TargetofTarget_Update",
+ "TaxiButtonTypes",
+ "TaxiCloseButton",
+ "TaxiFrame",
+ "TaxiFrame_OnEvent",
+ "TaxiFrame_OnLoad",
+ "TaxiGetDestX",
+ "TaxiGetDestY",
+ "TaxiGetSrcX",
+ "TaxiGetSrcY",
+ "TaxiMap",
+ "TaxiMerchant",
+ "TaxiNodeCost",
+ "TaxiNodeGetType",
+ "TaxiNodeName",
+ "TaxiNodeOnButtonEnter",
+ "TaxiNodePosition",
+ "TaxiNodeSetCurrent",
+ "TaxiPortrait",
+ "TaxiRouteMap",
+ "TeleportToDebugObject",
+ "TempEnchant1",
+ "TempEnchant1Border",
+ "TempEnchant1Count",
+ "TempEnchant1Duration",
+ "TempEnchant1Icon",
+ "TempEnchant2",
+ "TempEnchant2Border",
+ "TempEnchant2Count",
+ "TempEnchant2Duration",
+ "TempEnchant2Icon",
+ "TempEnchantButton_OnClick",
+ "TempEnchantButton_OnEnter",
+ "TempEnchantButton_OnLoad",
+ "TempEnchantButton_OnUpdate",
+ "TemporaryEnchantFrame",
+ "TemporaryEnchantFrame_Hide",
+ "TemporaryEnchantFrame_OnUpdate",
+ "TextEmoteSort",
+ "TextEmoteSpeechList",
+ "TextStatusBarText",
+ "TextStatusBarTextLarge",
+ "TextStatusBar_CapDisplayOfNumericValue",
+ "TextStatusBar_Initialize",
+ "TextStatusBar_OnEvent",
+ "TextStatusBar_OnValueChanged",
+ "TextStatusBar_UpdateTextString",
+ "TexturePoolMixin",
+ "TexturePool_Hide",
+ "TexturePool_HideAndClearAnchors",
+ "TicketStatusFrame",
+ "TicketStatusFrameButton",
+ "TicketStatusFrameButton_OnClick",
+ "TicketStatusFrameButton_OnLoad",
+ "TicketStatusFrameIcon",
+ "TicketStatusFrame_OnEvent",
+ "TicketStatusFrame_OnHide",
+ "TicketStatusFrame_OnLoad",
+ "TicketStatusFrame_OnShow",
+ "TicketStatusFrame_OnUpdate",
+ "TicketStatusTime",
+ "TicketStatusTitleText",
+ "TimeManagerAMPMDummyText",
+ "TimeManagerAlarmAMPMDropDown",
+ "TimeManagerAlarmAMPMDropDownButton",
+ "TimeManagerAlarmAMPMDropDownButtonDisabledTexture",
+ "TimeManagerAlarmAMPMDropDownButtonHighlightTexture",
+ "TimeManagerAlarmAMPMDropDownButtonNormalTexture",
+ "TimeManagerAlarmAMPMDropDownButtonPushedTexture",
+ "TimeManagerAlarmAMPMDropDownLeft",
+ "TimeManagerAlarmAMPMDropDownMiddle",
+ "TimeManagerAlarmAMPMDropDownRight",
+ "TimeManagerAlarmAMPMDropDownText",
+ "TimeManagerAlarmAMPMDropDown_Initialize",
+ "TimeManagerAlarmAMPMDropDown_OnClick",
+ "TimeManagerAlarmAMPMDropDown_OnHide",
+ "TimeManagerAlarmAMPMDropDown_OnShow",
+ "TimeManagerAlarmEnabledButton",
+ "TimeManagerAlarmEnabledButtonText",
+ "TimeManagerAlarmEnabledButton_OnClick",
+ "TimeManagerAlarmEnabledButton_Update",
+ "TimeManagerAlarmFiredTexture",
+ "TimeManagerAlarmHourDropDown",
+ "TimeManagerAlarmHourDropDownButton",
+ "TimeManagerAlarmHourDropDownButtonDisabledTexture",
+ "TimeManagerAlarmHourDropDownButtonHighlightTexture",
+ "TimeManagerAlarmHourDropDownButtonNormalTexture",
+ "TimeManagerAlarmHourDropDownButtonPushedTexture",
+ "TimeManagerAlarmHourDropDownLeft",
+ "TimeManagerAlarmHourDropDownMiddle",
+ "TimeManagerAlarmHourDropDownRight",
+ "TimeManagerAlarmHourDropDownText",
+ "TimeManagerAlarmHourDropDown_Initialize",
+ "TimeManagerAlarmHourDropDown_OnClick",
+ "TimeManagerAlarmMessageEditBox",
+ "TimeManagerAlarmMessageEditBoxLeft",
+ "TimeManagerAlarmMessageEditBoxMiddle",
+ "TimeManagerAlarmMessageEditBoxRight",
+ "TimeManagerAlarmMessageEditBox_OnEditFocusLost",
+ "TimeManagerAlarmMessageEditBox_OnEnterPressed",
+ "TimeManagerAlarmMessageEditBox_OnEscapePressed",
+ "TimeManagerAlarmMessageFrame",
+ "TimeManagerAlarmMessageLabel",
+ "TimeManagerAlarmMinuteDropDown",
+ "TimeManagerAlarmMinuteDropDownButton",
+ "TimeManagerAlarmMinuteDropDownButtonDisabledTexture",
+ "TimeManagerAlarmMinuteDropDownButtonHighlightTexture",
+ "TimeManagerAlarmMinuteDropDownButtonNormalTexture",
+ "TimeManagerAlarmMinuteDropDownButtonPushedTexture",
+ "TimeManagerAlarmMinuteDropDownLeft",
+ "TimeManagerAlarmMinuteDropDownMiddle",
+ "TimeManagerAlarmMinuteDropDownRight",
+ "TimeManagerAlarmMinuteDropDownText",
+ "TimeManagerAlarmMinuteDropDown_Initialize",
+ "TimeManagerAlarmMinuteDropDown_OnClick",
+ "TimeManagerAlarmTimeFrame",
+ "TimeManagerAlarmTimeLabel",
+ "TimeManagerClockButton",
+ "TimeManagerClockButton_Hide",
+ "TimeManagerClockButton_OnClick",
+ "TimeManagerClockButton_OnEnter",
+ "TimeManagerClockButton_OnLeave",
+ "TimeManagerClockButton_OnLoad",
+ "TimeManagerClockButton_OnUpdate",
+ "TimeManagerClockButton_OnUpdateWithTooltip",
+ "TimeManagerClockButton_Show",
+ "TimeManagerClockButton_Update",
+ "TimeManagerClockButton_UpdateTooltip",
+ "TimeManagerClockTicker",
+ "TimeManagerCloseButton",
+ "TimeManagerCloseButton_OnClick",
+ "TimeManagerFrame",
+ "TimeManagerFrameTicker",
+ "TimeManagerFrame_OnHide",
+ "TimeManagerFrame_OnLoad",
+ "TimeManagerFrame_OnShow",
+ "TimeManagerFrame_OnUpdate",
+ "TimeManagerGlobe",
+ "TimeManagerLocalTimeCheck",
+ "TimeManagerLocalTimeCheckText",
+ "TimeManagerLocalTimeCheck_OnClick",
+ "TimeManagerMilitaryTimeCheck",
+ "TimeManagerMilitaryTimeCheckText",
+ "TimeManagerMilitaryTimeCheck_OnClick",
+ "TimeManagerStopwatchCheck",
+ "TimeManagerStopwatchCheck_OnClick",
+ "TimeManagerStopwatchFrame",
+ "TimeManagerStopwatchFrameBackground",
+ "TimeManagerStopwatchFrameText",
+ "TimeManager_CheckAlarm",
+ "TimeManager_FireAlarm",
+ "TimeManager_FireAlarmWarning",
+ "TimeManager_IsAlarmFiring",
+ "TimeManager_LoadUI",
+ "TimeManager_ShouldCheckAlarm",
+ "TimeManager_StartCheckingAlarm",
+ "TimeManager_Toggle",
+ "TimeManager_ToggleLocalTime",
+ "TimeManager_ToggleTimeFormat",
+ "TimeManager_TurnOffAlarm",
+ "TimeManager_Update",
+ "TimeManager_UpdateAlarmTime",
+ "TimeManager_UpdateTimeTicker",
+ "ToggleAchievementFrame",
+ "ToggleAutoRun",
+ "ToggleBackpack",
+ "ToggleBag",
+ "ToggleBattlefieldMinimap",
+ "ToggleCalendar",
+ "ToggleCharacter",
+ "ToggleChatChannel",
+ "ToggleChatColorNamesByClassGroup",
+ "ToggleChatMessageGroup",
+ "ToggleCollision",
+ "ToggleCollisionDisplay",
+ "ToggleDropDownMenu",
+ "ToggleFrame",
+ "ToggleFramerate",
+ "ToggleFriendsFrame",
+ "ToggleFriendsPanel",
+ "ToggleGameMenu",
+ "ToggleGlyphFrame",
+ "ToggleGuildEventLog",
+ "ToggleGuildInfoFrame",
+ "ToggleHelpFrame",
+ "ToggleIgnorePanel",
+ "ToggleKeyRing",
+ "ToggleLFDParentFrame",
+ "ToggleLFRParentFrame",
+ "ToggleMapFramerate",
+ "ToggleMessageDest",
+ "ToggleMessageSource",
+ "ToggleMessageType",
+ "ToggleMessageTypeGroup",
+ "ToggleMiniMapRotation",
+ "ToggleMinimap",
+ "TogglePVP",
+ "TogglePVPFrame",
+ "TogglePerformanceDisplay",
+ "TogglePerformancePause",
+ "TogglePerformanceValues",
+ "TogglePetAutocast",
+ "TogglePlayerBounds",
+ "TogglePortals",
+ "ToggleRun",
+ "ToggleSheath",
+ "ToggleSpellAutocast",
+ "ToggleSpellBook",
+ "ToggleStats",
+ "ToggleTalentFrame",
+ "ToggleTimeManager",
+ "ToggleTris",
+ "ToggleWorldStateScoreFrame",
+ "TokenButtonLinkButton_OnClick",
+ "TokenButton_OnClick",
+ "TokenButton_OnLoad",
+ "TokenFrame",
+ "TokenFrameCancelButton",
+ "TokenFrameCancelButtonText",
+ "TokenFrameContainer",
+ "TokenFrameContainerButton1",
+ "TokenFrameContainerButton10",
+ "TokenFrameContainerButton10CategoryLeft",
+ "TokenFrameContainerButton10CategoryRight",
+ "TokenFrameContainerButton10Check",
+ "TokenFrameContainerButton10Count",
+ "TokenFrameContainerButton10ExpandIcon",
+ "TokenFrameContainerButton10Highlight",
+ "TokenFrameContainerButton10Icon",
+ "TokenFrameContainerButton10Name",
+ "TokenFrameContainerButton10Stripe",
+ "TokenFrameContainerButton11",
+ "TokenFrameContainerButton11CategoryLeft",
+ "TokenFrameContainerButton11CategoryRight",
+ "TokenFrameContainerButton11Check",
+ "TokenFrameContainerButton11Count",
+ "TokenFrameContainerButton11ExpandIcon",
+ "TokenFrameContainerButton11Highlight",
+ "TokenFrameContainerButton11Icon",
+ "TokenFrameContainerButton11Name",
+ "TokenFrameContainerButton11Stripe",
+ "TokenFrameContainerButton12",
+ "TokenFrameContainerButton12CategoryLeft",
+ "TokenFrameContainerButton12CategoryRight",
+ "TokenFrameContainerButton12Check",
+ "TokenFrameContainerButton12Count",
+ "TokenFrameContainerButton12ExpandIcon",
+ "TokenFrameContainerButton12Highlight",
+ "TokenFrameContainerButton12Icon",
+ "TokenFrameContainerButton12Name",
+ "TokenFrameContainerButton12Stripe",
+ "TokenFrameContainerButton13",
+ "TokenFrameContainerButton13CategoryLeft",
+ "TokenFrameContainerButton13CategoryRight",
+ "TokenFrameContainerButton13Check",
+ "TokenFrameContainerButton13Count",
+ "TokenFrameContainerButton13ExpandIcon",
+ "TokenFrameContainerButton13Highlight",
+ "TokenFrameContainerButton13Icon",
+ "TokenFrameContainerButton13Name",
+ "TokenFrameContainerButton13Stripe",
+ "TokenFrameContainerButton14",
+ "TokenFrameContainerButton14CategoryLeft",
+ "TokenFrameContainerButton14CategoryRight",
+ "TokenFrameContainerButton14Check",
+ "TokenFrameContainerButton14Count",
+ "TokenFrameContainerButton14ExpandIcon",
+ "TokenFrameContainerButton14Highlight",
+ "TokenFrameContainerButton14Icon",
+ "TokenFrameContainerButton14Name",
+ "TokenFrameContainerButton14Stripe",
+ "TokenFrameContainerButton15",
+ "TokenFrameContainerButton15CategoryLeft",
+ "TokenFrameContainerButton15CategoryRight",
+ "TokenFrameContainerButton15Check",
+ "TokenFrameContainerButton15Count",
+ "TokenFrameContainerButton15ExpandIcon",
+ "TokenFrameContainerButton15Highlight",
+ "TokenFrameContainerButton15Icon",
+ "TokenFrameContainerButton15Name",
+ "TokenFrameContainerButton15Stripe",
+ "TokenFrameContainerButton16",
+ "TokenFrameContainerButton16CategoryLeft",
+ "TokenFrameContainerButton16CategoryRight",
+ "TokenFrameContainerButton16Check",
+ "TokenFrameContainerButton16Count",
+ "TokenFrameContainerButton16ExpandIcon",
+ "TokenFrameContainerButton16Highlight",
+ "TokenFrameContainerButton16Icon",
+ "TokenFrameContainerButton16Name",
+ "TokenFrameContainerButton16Stripe",
+ "TokenFrameContainerButton17",
+ "TokenFrameContainerButton17CategoryLeft",
+ "TokenFrameContainerButton17CategoryRight",
+ "TokenFrameContainerButton17Check",
+ "TokenFrameContainerButton17Count",
+ "TokenFrameContainerButton17ExpandIcon",
+ "TokenFrameContainerButton17Highlight",
+ "TokenFrameContainerButton17Icon",
+ "TokenFrameContainerButton17Name",
+ "TokenFrameContainerButton17Stripe",
+ "TokenFrameContainerButton18",
+ "TokenFrameContainerButton18CategoryLeft",
+ "TokenFrameContainerButton18CategoryRight",
+ "TokenFrameContainerButton18Check",
+ "TokenFrameContainerButton18Count",
+ "TokenFrameContainerButton18ExpandIcon",
+ "TokenFrameContainerButton18Highlight",
+ "TokenFrameContainerButton18Icon",
+ "TokenFrameContainerButton18Name",
+ "TokenFrameContainerButton18Stripe",
+ "TokenFrameContainerButton19",
+ "TokenFrameContainerButton19CategoryLeft",
+ "TokenFrameContainerButton19CategoryRight",
+ "TokenFrameContainerButton19Check",
+ "TokenFrameContainerButton19Count",
+ "TokenFrameContainerButton19ExpandIcon",
+ "TokenFrameContainerButton19Highlight",
+ "TokenFrameContainerButton19Icon",
+ "TokenFrameContainerButton19Name",
+ "TokenFrameContainerButton19Stripe",
+ "TokenFrameContainerButton1CategoryLeft",
+ "TokenFrameContainerButton1CategoryRight",
+ "TokenFrameContainerButton1Check",
+ "TokenFrameContainerButton1Count",
+ "TokenFrameContainerButton1ExpandIcon",
+ "TokenFrameContainerButton1Highlight",
+ "TokenFrameContainerButton1Icon",
+ "TokenFrameContainerButton1Name",
+ "TokenFrameContainerButton1Stripe",
+ "TokenFrameContainerButton2",
+ "TokenFrameContainerButton20",
+ "TokenFrameContainerButton20CategoryLeft",
+ "TokenFrameContainerButton20CategoryRight",
+ "TokenFrameContainerButton20Check",
+ "TokenFrameContainerButton20Count",
+ "TokenFrameContainerButton20ExpandIcon",
+ "TokenFrameContainerButton20Highlight",
+ "TokenFrameContainerButton20Icon",
+ "TokenFrameContainerButton20Name",
+ "TokenFrameContainerButton20Stripe",
+ "TokenFrameContainerButton21",
+ "TokenFrameContainerButton21CategoryLeft",
+ "TokenFrameContainerButton21CategoryRight",
+ "TokenFrameContainerButton21Check",
+ "TokenFrameContainerButton21Count",
+ "TokenFrameContainerButton21ExpandIcon",
+ "TokenFrameContainerButton21Highlight",
+ "TokenFrameContainerButton21Icon",
+ "TokenFrameContainerButton21Name",
+ "TokenFrameContainerButton21Stripe",
+ "TokenFrameContainerButton2CategoryLeft",
+ "TokenFrameContainerButton2CategoryRight",
+ "TokenFrameContainerButton2Check",
+ "TokenFrameContainerButton2Count",
+ "TokenFrameContainerButton2ExpandIcon",
+ "TokenFrameContainerButton2Highlight",
+ "TokenFrameContainerButton2Icon",
+ "TokenFrameContainerButton2Name",
+ "TokenFrameContainerButton2Stripe",
+ "TokenFrameContainerButton3",
+ "TokenFrameContainerButton3CategoryLeft",
+ "TokenFrameContainerButton3CategoryRight",
+ "TokenFrameContainerButton3Check",
+ "TokenFrameContainerButton3Count",
+ "TokenFrameContainerButton3ExpandIcon",
+ "TokenFrameContainerButton3Highlight",
+ "TokenFrameContainerButton3Icon",
+ "TokenFrameContainerButton3Name",
+ "TokenFrameContainerButton3Stripe",
+ "TokenFrameContainerButton4",
+ "TokenFrameContainerButton4CategoryLeft",
+ "TokenFrameContainerButton4CategoryRight",
+ "TokenFrameContainerButton4Check",
+ "TokenFrameContainerButton4Count",
+ "TokenFrameContainerButton4ExpandIcon",
+ "TokenFrameContainerButton4Highlight",
+ "TokenFrameContainerButton4Icon",
+ "TokenFrameContainerButton4Name",
+ "TokenFrameContainerButton4Stripe",
+ "TokenFrameContainerButton5",
+ "TokenFrameContainerButton5CategoryLeft",
+ "TokenFrameContainerButton5CategoryRight",
+ "TokenFrameContainerButton5Check",
+ "TokenFrameContainerButton5Count",
+ "TokenFrameContainerButton5ExpandIcon",
+ "TokenFrameContainerButton5Highlight",
+ "TokenFrameContainerButton5Icon",
+ "TokenFrameContainerButton5Name",
+ "TokenFrameContainerButton5Stripe",
+ "TokenFrameContainerButton6",
+ "TokenFrameContainerButton6CategoryLeft",
+ "TokenFrameContainerButton6CategoryRight",
+ "TokenFrameContainerButton6Check",
+ "TokenFrameContainerButton6Count",
+ "TokenFrameContainerButton6ExpandIcon",
+ "TokenFrameContainerButton6Highlight",
+ "TokenFrameContainerButton6Icon",
+ "TokenFrameContainerButton6Name",
+ "TokenFrameContainerButton6Stripe",
+ "TokenFrameContainerButton7",
+ "TokenFrameContainerButton7CategoryLeft",
+ "TokenFrameContainerButton7CategoryRight",
+ "TokenFrameContainerButton7Check",
+ "TokenFrameContainerButton7Count",
+ "TokenFrameContainerButton7ExpandIcon",
+ "TokenFrameContainerButton7Highlight",
+ "TokenFrameContainerButton7Icon",
+ "TokenFrameContainerButton7Name",
+ "TokenFrameContainerButton7Stripe",
+ "TokenFrameContainerButton8",
+ "TokenFrameContainerButton8CategoryLeft",
+ "TokenFrameContainerButton8CategoryRight",
+ "TokenFrameContainerButton8Check",
+ "TokenFrameContainerButton8Count",
+ "TokenFrameContainerButton8ExpandIcon",
+ "TokenFrameContainerButton8Highlight",
+ "TokenFrameContainerButton8Icon",
+ "TokenFrameContainerButton8Name",
+ "TokenFrameContainerButton8Stripe",
+ "TokenFrameContainerButton9",
+ "TokenFrameContainerButton9CategoryLeft",
+ "TokenFrameContainerButton9CategoryRight",
+ "TokenFrameContainerButton9Check",
+ "TokenFrameContainerButton9Count",
+ "TokenFrameContainerButton9ExpandIcon",
+ "TokenFrameContainerButton9Highlight",
+ "TokenFrameContainerButton9Icon",
+ "TokenFrameContainerButton9Name",
+ "TokenFrameContainerButton9Stripe",
+ "TokenFrameContainerScrollBar",
+ "TokenFrameContainerScrollBarBG",
+ "TokenFrameContainerScrollBarBottom",
+ "TokenFrameContainerScrollBarMiddle",
+ "TokenFrameContainerScrollBarScrollDownButton",
+ "TokenFrameContainerScrollBarScrollUpButton",
+ "TokenFrameContainerScrollBarThumbTexture",
+ "TokenFrameContainerScrollBarTop",
+ "TokenFrameContainerScrollChild",
+ "TokenFrameMoneyFrame",
+ "TokenFrameMoneyFrameCopperButton",
+ "TokenFrameMoneyFrameCopperButtonText",
+ "TokenFrameMoneyFrameGoldButton",
+ "TokenFrameMoneyFrameGoldButtonText",
+ "TokenFrameMoneyFrameSilverButton",
+ "TokenFrameMoneyFrameSilverButtonText",
+ "TokenFramePopup",
+ "TokenFramePopupBackpackCheckBox",
+ "TokenFramePopupBackpackCheckBoxText",
+ "TokenFramePopupCloseButton",
+ "TokenFramePopupCorner",
+ "TokenFramePopupInactiveCheckBox",
+ "TokenFramePopupInactiveCheckBoxText",
+ "TokenFramePopupTitle",
+ "TokenFramePopup_CloseIfHidden",
+ "TokenFrame_LoadUI",
+ "TokenFrame_OnLoad",
+ "TokenFrame_OnShow",
+ "TokenFrame_Update",
+ "TokenFrame_UpdatePopup",
+ "Tooltip_Med",
+ "Tooltip_Small",
+ "TotemButton_OnClick",
+ "TotemButton_OnLoad",
+ "TotemButton_OnUpdate",
+ "TotemButton_Update",
+ "TotemFrame",
+ "TotemFrameTotem1",
+ "TotemFrameTotem1Background",
+ "TotemFrameTotem1Duration",
+ "TotemFrameTotem1Icon",
+ "TotemFrameTotem1IconCooldown",
+ "TotemFrameTotem1IconTexture",
+ "TotemFrameTotem2",
+ "TotemFrameTotem2Background",
+ "TotemFrameTotem2Duration",
+ "TotemFrameTotem2Icon",
+ "TotemFrameTotem2IconCooldown",
+ "TotemFrameTotem2IconTexture",
+ "TotemFrameTotem3",
+ "TotemFrameTotem3Background",
+ "TotemFrameTotem3Duration",
+ "TotemFrameTotem3Icon",
+ "TotemFrameTotem3IconCooldown",
+ "TotemFrameTotem3IconTexture",
+ "TotemFrameTotem4",
+ "TotemFrameTotem4Background",
+ "TotemFrameTotem4Duration",
+ "TotemFrameTotem4Icon",
+ "TotemFrameTotem4IconCooldown",
+ "TotemFrameTotem4IconTexture",
+ "TotemFrame_OnEvent",
+ "TotemFrame_OnLoad",
+ "TotemFrame_Update",
+ "TradeFrame",
+ "TradeFrameCancelButton",
+ "TradeFrameCancelButton_OnClick",
+ "TradeFrameCloseButton",
+ "TradeFramePlayerEnchantText",
+ "TradeFramePlayerNameText",
+ "TradeFramePlayerPortrait",
+ "TradeFrameRecipientEnchantText",
+ "TradeFrameRecipientNameText",
+ "TradeFrameRecipientPortrait",
+ "TradeFrameTradeButton",
+ "TradeFrameTradeButton_Disable",
+ "TradeFrameTradeButton_Enable",
+ "TradeFrameTradeButton_SetToEnabledState",
+ "TradeFrame_GetAvailableSlot",
+ "TradeFrame_OnEvent",
+ "TradeFrame_OnHide",
+ "TradeFrame_OnLoad",
+ "TradeFrame_OnMouseUp",
+ "TradeFrame_OnShow",
+ "TradeFrame_SetAcceptState",
+ "TradeFrame_Update",
+ "TradeFrame_UpdateMoney",
+ "TradeFrame_UpdatePlayerItem",
+ "TradeFrame_UpdateTargetItem",
+ "TradeHighlightPlayer",
+ "TradeHighlightPlayerBottom",
+ "TradeHighlightPlayerEnchant",
+ "TradeHighlightPlayerEnchantBottom",
+ "TradeHighlightPlayerEnchantMiddle",
+ "TradeHighlightPlayerEnchantTop",
+ "TradeHighlightPlayerMiddle",
+ "TradeHighlightPlayerTop",
+ "TradeHighlightRecipient",
+ "TradeHighlightRecipientBottom",
+ "TradeHighlightRecipientEnchant",
+ "TradeHighlightRecipientEnchantBottom",
+ "TradeHighlightRecipientEnchantMiddle",
+ "TradeHighlightRecipientEnchantTop",
+ "TradeHighlightRecipientMiddle",
+ "TradeHighlightRecipientTop",
+ "TradePlayerInputMoneyFrame",
+ "TradePlayerInputMoneyFrameCopper",
+ "TradePlayerInputMoneyFrameCopperLeft",
+ "TradePlayerInputMoneyFrameCopperMiddle",
+ "TradePlayerInputMoneyFrameCopperRight",
+ "TradePlayerInputMoneyFrameGold",
+ "TradePlayerInputMoneyFrameGoldLeft",
+ "TradePlayerInputMoneyFrameGoldMiddle",
+ "TradePlayerInputMoneyFrameGoldRight",
+ "TradePlayerInputMoneyFrameSilver",
+ "TradePlayerInputMoneyFrameSilverLeft",
+ "TradePlayerInputMoneyFrameSilverMiddle",
+ "TradePlayerInputMoneyFrameSilverRight",
+ "TradePlayerItem1",
+ "TradePlayerItem1ItemButton",
+ "TradePlayerItem1ItemButtonCount",
+ "TradePlayerItem1ItemButtonIconTexture",
+ "TradePlayerItem1ItemButtonNormalTexture",
+ "TradePlayerItem1ItemButtonStock",
+ "TradePlayerItem1Name",
+ "TradePlayerItem1NameFrame",
+ "TradePlayerItem1SlotTexture",
+ "TradePlayerItem2",
+ "TradePlayerItem2ItemButton",
+ "TradePlayerItem2ItemButtonCount",
+ "TradePlayerItem2ItemButtonIconTexture",
+ "TradePlayerItem2ItemButtonNormalTexture",
+ "TradePlayerItem2ItemButtonStock",
+ "TradePlayerItem2Name",
+ "TradePlayerItem2NameFrame",
+ "TradePlayerItem2SlotTexture",
+ "TradePlayerItem3",
+ "TradePlayerItem3ItemButton",
+ "TradePlayerItem3ItemButtonCount",
+ "TradePlayerItem3ItemButtonIconTexture",
+ "TradePlayerItem3ItemButtonNormalTexture",
+ "TradePlayerItem3ItemButtonStock",
+ "TradePlayerItem3Name",
+ "TradePlayerItem3NameFrame",
+ "TradePlayerItem3SlotTexture",
+ "TradePlayerItem4",
+ "TradePlayerItem4ItemButton",
+ "TradePlayerItem4ItemButtonCount",
+ "TradePlayerItem4ItemButtonIconTexture",
+ "TradePlayerItem4ItemButtonNormalTexture",
+ "TradePlayerItem4ItemButtonStock",
+ "TradePlayerItem4Name",
+ "TradePlayerItem4NameFrame",
+ "TradePlayerItem4SlotTexture",
+ "TradePlayerItem5",
+ "TradePlayerItem5ItemButton",
+ "TradePlayerItem5ItemButtonCount",
+ "TradePlayerItem5ItemButtonIconTexture",
+ "TradePlayerItem5ItemButtonNormalTexture",
+ "TradePlayerItem5ItemButtonStock",
+ "TradePlayerItem5Name",
+ "TradePlayerItem5NameFrame",
+ "TradePlayerItem5SlotTexture",
+ "TradePlayerItem6",
+ "TradePlayerItem6ItemButton",
+ "TradePlayerItem6ItemButtonCount",
+ "TradePlayerItem6ItemButtonIconTexture",
+ "TradePlayerItem6ItemButtonNormalTexture",
+ "TradePlayerItem6ItemButtonStock",
+ "TradePlayerItem6Name",
+ "TradePlayerItem6NameFrame",
+ "TradePlayerItem6SlotTexture",
+ "TradePlayerItem7",
+ "TradePlayerItem7ItemButton",
+ "TradePlayerItem7ItemButtonCount",
+ "TradePlayerItem7ItemButtonIconTexture",
+ "TradePlayerItem7ItemButtonNormalTexture",
+ "TradePlayerItem7ItemButtonStock",
+ "TradePlayerItem7Name",
+ "TradePlayerItem7NameFrame",
+ "TradePlayerItem7SlotTexture",
+ "TradeRecipientItem1",
+ "TradeRecipientItem1ItemButton",
+ "TradeRecipientItem1ItemButtonCount",
+ "TradeRecipientItem1ItemButtonIconTexture",
+ "TradeRecipientItem1ItemButtonNormalTexture",
+ "TradeRecipientItem1ItemButtonStock",
+ "TradeRecipientItem1Name",
+ "TradeRecipientItem1NameFrame",
+ "TradeRecipientItem1SlotTexture",
+ "TradeRecipientItem2",
+ "TradeRecipientItem2ItemButton",
+ "TradeRecipientItem2ItemButtonCount",
+ "TradeRecipientItem2ItemButtonIconTexture",
+ "TradeRecipientItem2ItemButtonNormalTexture",
+ "TradeRecipientItem2ItemButtonStock",
+ "TradeRecipientItem2Name",
+ "TradeRecipientItem2NameFrame",
+ "TradeRecipientItem2SlotTexture",
+ "TradeRecipientItem3",
+ "TradeRecipientItem3ItemButton",
+ "TradeRecipientItem3ItemButtonCount",
+ "TradeRecipientItem3ItemButtonIconTexture",
+ "TradeRecipientItem3ItemButtonNormalTexture",
+ "TradeRecipientItem3ItemButtonStock",
+ "TradeRecipientItem3Name",
+ "TradeRecipientItem3NameFrame",
+ "TradeRecipientItem3SlotTexture",
+ "TradeRecipientItem4",
+ "TradeRecipientItem4ItemButton",
+ "TradeRecipientItem4ItemButtonCount",
+ "TradeRecipientItem4ItemButtonIconTexture",
+ "TradeRecipientItem4ItemButtonNormalTexture",
+ "TradeRecipientItem4ItemButtonStock",
+ "TradeRecipientItem4Name",
+ "TradeRecipientItem4NameFrame",
+ "TradeRecipientItem4SlotTexture",
+ "TradeRecipientItem5",
+ "TradeRecipientItem5ItemButton",
+ "TradeRecipientItem5ItemButtonCount",
+ "TradeRecipientItem5ItemButtonIconTexture",
+ "TradeRecipientItem5ItemButtonNormalTexture",
+ "TradeRecipientItem5ItemButtonStock",
+ "TradeRecipientItem5Name",
+ "TradeRecipientItem5NameFrame",
+ "TradeRecipientItem5SlotTexture",
+ "TradeRecipientItem6",
+ "TradeRecipientItem6ItemButton",
+ "TradeRecipientItem6ItemButtonCount",
+ "TradeRecipientItem6ItemButtonIconTexture",
+ "TradeRecipientItem6ItemButtonNormalTexture",
+ "TradeRecipientItem6ItemButtonStock",
+ "TradeRecipientItem6Name",
+ "TradeRecipientItem6NameFrame",
+ "TradeRecipientItem6SlotTexture",
+ "TradeRecipientItem7",
+ "TradeRecipientItem7ItemButton",
+ "TradeRecipientItem7ItemButtonCount",
+ "TradeRecipientItem7ItemButtonIconTexture",
+ "TradeRecipientItem7ItemButtonNormalTexture",
+ "TradeRecipientItem7ItemButtonStock",
+ "TradeRecipientItem7Name",
+ "TradeRecipientItem7NameFrame",
+ "TradeRecipientItem7SlotTexture",
+ "TradeRecipientMoneyFrame",
+ "TradeRecipientMoneyFrameCopperButton",
+ "TradeRecipientMoneyFrameCopperButtonText",
+ "TradeRecipientMoneyFrameGoldButton",
+ "TradeRecipientMoneyFrameGoldButtonText",
+ "TradeRecipientMoneyFrameSilverButton",
+ "TradeRecipientMoneyFrameSilverButtonText",
+ "TradeSkillCancelButton",
+ "TradeSkillCancelButtonText",
+ "TradeSkillCollapseAllButton",
+ "TradeSkillCollapseAllButtonHighlight",
+ "TradeSkillCollapseAllButtonSubText",
+ "TradeSkillCollapseAllButtonText",
+ "TradeSkillCollapseAllButton_OnClick",
+ "TradeSkillCreateAllButton",
+ "TradeSkillCreateAllButtonMask",
+ "TradeSkillCreateAllButtonText",
+ "TradeSkillCreateButton",
+ "TradeSkillCreateButtonMask",
+ "TradeSkillCreateButtonText",
+ "TradeSkillDecrementButton",
+ "TradeSkillDescription",
+ "TradeSkillDetailHeaderLeft",
+ "TradeSkillDetailScrollChildFrame",
+ "TradeSkillDetailScrollFrame",
+ "TradeSkillDetailScrollFrameBottom",
+ "TradeSkillDetailScrollFrameScrollBar",
+ "TradeSkillDetailScrollFrameScrollBarScrollDownButton",
+ "TradeSkillDetailScrollFrameScrollBarScrollUpButton",
+ "TradeSkillDetailScrollFrameScrollBarThumbTexture",
+ "TradeSkillDetailScrollFrameTop",
+ "TradeSkillExpandButtonFrame",
+ "TradeSkillExpandTabLeft",
+ "TradeSkillExpandTabMiddle",
+ "TradeSkillExpandTabRight",
+ "TradeSkillFilterFrame_InvSlotName",
+ "TradeSkillFilterFrame_LoadInvSlots",
+ "TradeSkillFilterFrame_LoadSubClasses",
+ "TradeSkillFilter_OnTextChanged",
+ "TradeSkillFrame",
+ "TradeSkillFrameAvailableFilterCheckButton",
+ "TradeSkillFrameAvailableFilterCheckButtonText",
+ "TradeSkillFrameBottomLeftTexture",
+ "TradeSkillFrameBottomRightTexture",
+ "TradeSkillFrameCloseButton",
+ "TradeSkillFrameDecrement_OnClick",
+ "TradeSkillFrameDummyString",
+ "TradeSkillFrameEditBox",
+ "TradeSkillFrameEditBoxLeft",
+ "TradeSkillFrameEditBoxMiddle",
+ "TradeSkillFrameEditBoxRight",
+ "TradeSkillFrameIncrement_OnClick",
+ "TradeSkillFramePortrait",
+ "TradeSkillFrameTitleText",
+ "TradeSkillFrame_Hide",
+ "TradeSkillFrame_LoadUI",
+ "TradeSkillFrame_OnEvent",
+ "TradeSkillFrame_OnLoad",
+ "TradeSkillFrame_PlaytimeUpdate",
+ "TradeSkillFrame_SetSelection",
+ "TradeSkillFrame_Show",
+ "TradeSkillFrame_ShowFailed",
+ "TradeSkillFrame_Update",
+ "TradeSkillHighlight",
+ "TradeSkillHighlightFrame",
+ "TradeSkillHorizontalBarLeft",
+ "TradeSkillIncrementButton",
+ "TradeSkillInputBox",
+ "TradeSkillInputBoxLeft",
+ "TradeSkillInputBoxMiddle",
+ "TradeSkillInputBoxRight",
+ "TradeSkillInvSlotDropDown",
+ "TradeSkillInvSlotDropDownButton",
+ "TradeSkillInvSlotDropDownButtonDisabledTexture",
+ "TradeSkillInvSlotDropDownButtonHighlightTexture",
+ "TradeSkillInvSlotDropDownButtonNormalTexture",
+ "TradeSkillInvSlotDropDownButtonPushedTexture",
+ "TradeSkillInvSlotDropDownButton_OnClick",
+ "TradeSkillInvSlotDropDownLeft",
+ "TradeSkillInvSlotDropDownMiddle",
+ "TradeSkillInvSlotDropDownRight",
+ "TradeSkillInvSlotDropDownText",
+ "TradeSkillInvSlotDropDown_Initialize",
+ "TradeSkillInvSlotDropDown_OnLoad",
+ "TradeSkillItem_OnEnter",
+ "TradeSkillLinkButton",
+ "TradeSkillListScrollFrame",
+ "TradeSkillListScrollFrameScrollBar",
+ "TradeSkillListScrollFrameScrollBarScrollDownButton",
+ "TradeSkillListScrollFrameScrollBarScrollUpButton",
+ "TradeSkillListScrollFrameScrollBarThumbTexture",
+ "TradeSkillListScrollFrameScrollChildFrame",
+ "TradeSkillOnlyShowMakeable",
+ "TradeSkillOnlyShowSkillUps",
+ "TradeSkillRankFrame",
+ "TradeSkillRankFrameBackground",
+ "TradeSkillRankFrameBar",
+ "TradeSkillRankFrameBorder",
+ "TradeSkillRankFrameSkillRank",
+ "TradeSkillReagent1",
+ "TradeSkillReagent1Count",
+ "TradeSkillReagent1IconTexture",
+ "TradeSkillReagent1Name",
+ "TradeSkillReagent1NameFrame",
+ "TradeSkillReagent2",
+ "TradeSkillReagent2Count",
+ "TradeSkillReagent2IconTexture",
+ "TradeSkillReagent2Name",
+ "TradeSkillReagent2NameFrame",
+ "TradeSkillReagent3",
+ "TradeSkillReagent3Count",
+ "TradeSkillReagent3IconTexture",
+ "TradeSkillReagent3Name",
+ "TradeSkillReagent3NameFrame",
+ "TradeSkillReagent4",
+ "TradeSkillReagent4Count",
+ "TradeSkillReagent4IconTexture",
+ "TradeSkillReagent4Name",
+ "TradeSkillReagent4NameFrame",
+ "TradeSkillReagent5",
+ "TradeSkillReagent5Count",
+ "TradeSkillReagent5IconTexture",
+ "TradeSkillReagent5Name",
+ "TradeSkillReagent5NameFrame",
+ "TradeSkillReagent6",
+ "TradeSkillReagent6Count",
+ "TradeSkillReagent6IconTexture",
+ "TradeSkillReagent6Name",
+ "TradeSkillReagent6NameFrame",
+ "TradeSkillReagent7",
+ "TradeSkillReagent7Count",
+ "TradeSkillReagent7IconTexture",
+ "TradeSkillReagent7Name",
+ "TradeSkillReagent7NameFrame",
+ "TradeSkillReagent8",
+ "TradeSkillReagent8Count",
+ "TradeSkillReagent8IconTexture",
+ "TradeSkillReagent8Name",
+ "TradeSkillReagent8NameFrame",
+ "TradeSkillReagentLabel",
+ "TradeSkillRequirementLabel",
+ "TradeSkillRequirementText",
+ "TradeSkillSkill1",
+ "TradeSkillSkill1Count",
+ "TradeSkillSkill1Highlight",
+ "TradeSkillSkill1SubText",
+ "TradeSkillSkill1Text",
+ "TradeSkillSkill2",
+ "TradeSkillSkill2Count",
+ "TradeSkillSkill2Highlight",
+ "TradeSkillSkill2SubText",
+ "TradeSkillSkill2Text",
+ "TradeSkillSkill3",
+ "TradeSkillSkill3Count",
+ "TradeSkillSkill3Highlight",
+ "TradeSkillSkill3SubText",
+ "TradeSkillSkill3Text",
+ "TradeSkillSkill4",
+ "TradeSkillSkill4Count",
+ "TradeSkillSkill4Highlight",
+ "TradeSkillSkill4SubText",
+ "TradeSkillSkill4Text",
+ "TradeSkillSkill5",
+ "TradeSkillSkill5Count",
+ "TradeSkillSkill5Highlight",
+ "TradeSkillSkill5SubText",
+ "TradeSkillSkill5Text",
+ "TradeSkillSkill6",
+ "TradeSkillSkill6Count",
+ "TradeSkillSkill6Highlight",
+ "TradeSkillSkill6SubText",
+ "TradeSkillSkill6Text",
+ "TradeSkillSkill7",
+ "TradeSkillSkill7Count",
+ "TradeSkillSkill7Highlight",
+ "TradeSkillSkill7SubText",
+ "TradeSkillSkill7Text",
+ "TradeSkillSkill8",
+ "TradeSkillSkill8Count",
+ "TradeSkillSkill8Highlight",
+ "TradeSkillSkill8SubText",
+ "TradeSkillSkill8Text",
+ "TradeSkillSkillButton_OnClick",
+ "TradeSkillSkillCooldown",
+ "TradeSkillSkillIcon",
+ "TradeSkillSkillIconCount",
+ "TradeSkillSkillName",
+ "TradeSkillSubClassDropDown",
+ "TradeSkillSubClassDropDownButton",
+ "TradeSkillSubClassDropDownButtonDisabledTexture",
+ "TradeSkillSubClassDropDownButtonHighlightTexture",
+ "TradeSkillSubClassDropDownButtonNormalTexture",
+ "TradeSkillSubClassDropDownButtonPushedTexture",
+ "TradeSkillSubClassDropDownButton_OnClick",
+ "TradeSkillSubClassDropDownLeft",
+ "TradeSkillSubClassDropDownMiddle",
+ "TradeSkillSubClassDropDownRight",
+ "TradeSkillSubClassDropDownText",
+ "TradeSkillSubClassDropDown_Initialize",
+ "TradeSkillSubClassDropDown_OnLoad",
+ "TradeSkillTypeColor",
+ "TradeSkillTypePrefix",
+ "TriggerTutorial",
+ "TurnInArenaPetition",
+ "TurnInGuildCharter",
+ "TurnInPetition",
+ "TurnLeftStart",
+ "TurnLeftStop",
+ "TurnOrActionStart",
+ "TurnOrActionStop",
+ "TurnRightStart",
+ "TurnRightStop",
+ "TutorialFrame",
+ "TutorialFrameAlertButton",
+ "TutorialFrameAlertButtonBadge",
+ "TutorialFrameAlertButtonBadgeText",
+ "TutorialFrameArrowCurveDownLeft",
+ "TutorialFrameArrowCurveDownRight",
+ "TutorialFrameArrowCurveLeftDown",
+ "TutorialFrameArrowCurveLeftUp",
+ "TutorialFrameArrowCurveRightDown",
+ "TutorialFrameArrowCurveRightUp",
+ "TutorialFrameArrowCurveUpLeft",
+ "TutorialFrameArrowCurveUpRight",
+ "TutorialFrameArrowDown",
+ "TutorialFrameArrowLeft",
+ "TutorialFrameArrowRight",
+ "TutorialFrameArrowUp",
+ "TutorialFrameBackground",
+ "TutorialFrameBottom",
+ "TutorialFrameCallOut",
+ "TutorialFrameCallOutPulser",
+ "TutorialFrameImage1",
+ "TutorialFrameImage2",
+ "TutorialFrameImage3",
+ "TutorialFrameKey1",
+ "TutorialFrameKey2",
+ "TutorialFrameKey3",
+ "TutorialFrameKey4",
+ "TutorialFrameKeyString1",
+ "TutorialFrameKeyString2",
+ "TutorialFrameKeyString3",
+ "TutorialFrameKeyString4",
+ "TutorialFrameLeft1",
+ "TutorialFrameLeft10",
+ "TutorialFrameLeft11",
+ "TutorialFrameLeft12",
+ "TutorialFrameLeft13",
+ "TutorialFrameLeft14",
+ "TutorialFrameLeft15",
+ "TutorialFrameLeft16",
+ "TutorialFrameLeft17",
+ "TutorialFrameLeft18",
+ "TutorialFrameLeft19",
+ "TutorialFrameLeft2",
+ "TutorialFrameLeft20",
+ "TutorialFrameLeft21",
+ "TutorialFrameLeft22",
+ "TutorialFrameLeft23",
+ "TutorialFrameLeft24",
+ "TutorialFrameLeft25",
+ "TutorialFrameLeft26",
+ "TutorialFrameLeft27",
+ "TutorialFrameLeft28",
+ "TutorialFrameLeft29",
+ "TutorialFrameLeft3",
+ "TutorialFrameLeft30",
+ "TutorialFrameLeft4",
+ "TutorialFrameLeft5",
+ "TutorialFrameLeft6",
+ "TutorialFrameLeft7",
+ "TutorialFrameLeft8",
+ "TutorialFrameLeft9",
+ "TutorialFrameMouseBothClick",
+ "TutorialFrameMouseLeftClick",
+ "TutorialFrameMouseRightClick",
+ "TutorialFrameMouseWheel",
+ "TutorialFrameNextButton",
+ "TutorialFrameNextButton_OnClick",
+ "TutorialFrameOkayButton",
+ "TutorialFramePrevButton",
+ "TutorialFramePrevButton_OnClick",
+ "TutorialFrameRight1",
+ "TutorialFrameRight10",
+ "TutorialFrameRight11",
+ "TutorialFrameRight12",
+ "TutorialFrameRight13",
+ "TutorialFrameRight14",
+ "TutorialFrameRight15",
+ "TutorialFrameRight16",
+ "TutorialFrameRight17",
+ "TutorialFrameRight18",
+ "TutorialFrameRight19",
+ "TutorialFrameRight2",
+ "TutorialFrameRight20",
+ "TutorialFrameRight21",
+ "TutorialFrameRight22",
+ "TutorialFrameRight23",
+ "TutorialFrameRight24",
+ "TutorialFrameRight25",
+ "TutorialFrameRight26",
+ "TutorialFrameRight27",
+ "TutorialFrameRight28",
+ "TutorialFrameRight29",
+ "TutorialFrameRight3",
+ "TutorialFrameRight30",
+ "TutorialFrameRight4",
+ "TutorialFrameRight5",
+ "TutorialFrameRight6",
+ "TutorialFrameRight7",
+ "TutorialFrameRight8",
+ "TutorialFrameRight9",
+ "TutorialFrameText",
+ "TutorialFrameTextScrollChildFrame",
+ "TutorialFrameTextScrollFrame",
+ "TutorialFrameTextScrollFrameScrollBar",
+ "TutorialFrameTextScrollFrameScrollBarScrollDownButton",
+ "TutorialFrameTextScrollFrameScrollBarScrollUpButton",
+ "TutorialFrameTextScrollFrameScrollBarThumbTexture",
+ "TutorialFrameTitle",
+ "TutorialFrameTop",
+ "TutorialFrame_AlertButton_OnClick",
+ "TutorialFrame_CheckBadge",
+ "TutorialFrame_CheckNextPrevButtons",
+ "TutorialFrame_ClearQueue",
+ "TutorialFrame_ClearTextures",
+ "TutorialFrame_Hide",
+ "TutorialFrame_NewTutorial",
+ "TutorialFrame_OnHide",
+ "TutorialFrame_OnLoad",
+ "TutorialFrame_OnShow",
+ "TutorialFrame_Update",
+ "TutorialTextBorder",
+ "UIChildWindows",
+ "UIDROPDOWNMENU_INIT_MENU",
+ "UIDROPDOWNMENU_MENU_VALUE",
+ "UIDoFramesIntersect",
+ "UIDropDownMenuButton_GetChecked",
+ "UIDropDownMenuButton_GetName",
+ "UIDropDownMenuButton_OnClick",
+ "UIDropDownMenuButton_OpenColorPicker",
+ "UIDropDownMenuDelegate_OnAttributeChanged",
+ "UIDropDownMenu_AddButton",
+ "UIDropDownMenu_ClearAll",
+ "UIDropDownMenu_CreateFrames",
+ "UIDropDownMenu_CreateInfo",
+ "UIDropDownMenu_DisableButton",
+ "UIDropDownMenu_DisableDropDown",
+ "UIDropDownMenu_EnableButton",
+ "UIDropDownMenu_EnableDropDown",
+ "UIDropDownMenu_GetCurrentDropDown",
+ "UIDropDownMenu_GetSelectedID",
+ "UIDropDownMenu_GetSelectedName",
+ "UIDropDownMenu_GetSelectedValue",
+ "UIDropDownMenu_GetText",
+ "UIDropDownMenu_GetValue",
+ "UIDropDownMenu_Initialize",
+ "UIDropDownMenu_InitializeHelper",
+ "UIDropDownMenu_IsEnabled",
+ "UIDropDownMenu_JustifyText",
+ "UIDropDownMenu_OnHide",
+ "UIDropDownMenu_OnUpdate",
+ "UIDropDownMenu_Refresh",
+ "UIDropDownMenu_SetAnchor",
+ "UIDropDownMenu_SetButtonText",
+ "UIDropDownMenu_SetButtonWidth",
+ "UIDropDownMenu_SetSelectedID",
+ "UIDropDownMenu_SetSelectedName",
+ "UIDropDownMenu_SetSelectedValue",
+ "UIDropDownMenu_SetText",
+ "UIDropDownMenu_SetWidth",
+ "UIDropDownMenu_StartCounting",
+ "UIDropDownMenu_StopCounting",
+ "UIErrorsFrame",
+ "UIErrorsFrame_OnEvent",
+ "UIErrorsFrame_OnLoad",
+ "UIFrameCache",
+ "UIFrameFade",
+ "UIFrameFadeIn",
+ "UIFrameFadeOut",
+ "UIFrameFadeRemoveFrame",
+ "UIFrameFade_OnUpdate",
+ "UIFrameFlash",
+ "UIFrameFlashRemoveFrame",
+ "UIFrameFlashStop",
+ "UIFrameFlash_OnUpdate",
+ "UIFrameIsFading",
+ "UIFrameIsFlashing",
+ "UIMenuButton_OnClick",
+ "UIMenuButton_OnEnter",
+ "UIMenuButton_OnLeave",
+ "UIMenuButton_OnLoad",
+ "UIMenu_AddButton",
+ "UIMenu_AutoSize",
+ "UIMenu_FinishInitializing",
+ "UIMenu_GetNumButtons",
+ "UIMenu_Initialize",
+ "UIMenu_OnShow",
+ "UIMenu_OnUpdate",
+ "UIMenu_StartCounting",
+ "UIMenu_StopCounting",
+ "UIMenus",
+ "UIPARENT_MANAGED_FRAME_POSITIONS",
+ "UIPanelWindows",
+ "UIParent",
+ "UIParentLoadAddOn",
+ "UIParent_ManageFramePosition",
+ "UIParent_ManageFramePositions",
+ "UIParent_OnEvent",
+ "UIParent_OnLoad",
+ "UISpecialFrames",
+ "UnSilenceMember",
+ "UninviteUnit",
+ "UnitAffectingCombat",
+ "UnitArmor",
+ "UnitAttackBothHands",
+ "UnitAttackPower",
+ "UnitAttackSpeed",
+ "UnitAura",
+ "UnitBuff",
+ "UnitCanAssist",
+ "UnitCanAttack",
+ "UnitCanCooperate",
+ "UnitCastingInfo",
+ "UnitChannelInfo",
+ "UnitCharacterPoints",
+ "UnitClass",
+ "UnitClassBase",
+ "UnitClassification",
+ "UnitControllingVehicle",
+ "UnitCreatureFamily",
+ "UnitCreatureType",
+ "UnitDamage",
+ "UnitDebuff",
+ "UnitDefense",
+ "UnitDetailedThreatSituation",
+ "UnitExists",
+ "UnitFactionGroup",
+ "UnitFrameHealthBar_Initialize",
+ "UnitFrameHealthBar_OnEvent",
+ "UnitFrameHealthBar_OnUpdate",
+ "UnitFrameHealthBar_OnValueChanged",
+ "UnitFrameHealthBar_Update",
+ "UnitFrameManaBar_Initialize",
+ "UnitFrameManaBar_OnEvent",
+ "UnitFrameManaBar_OnUpdate",
+ "UnitFrameManaBar_RegisterDefaultEvents",
+ "UnitFrameManaBar_UnregisterDefaultEvents",
+ "UnitFrameManaBar_Update",
+ "UnitFrameManaBar_UpdateType",
+ "UnitFramePanelOptions",
+ "UnitFramePortrait_Update",
+ "UnitFrameThreatIndicator_Initialize",
+ "UnitFrameThreatIndicator_OnEvent",
+ "UnitFrame_Initialize",
+ "UnitFrame_OnEnter",
+ "UnitFrame_OnEvent",
+ "UnitFrame_OnLeave",
+ "UnitFrame_SetUnit",
+ "UnitFrame_Update",
+ "UnitFrame_UpdateThreatIndicator",
+ "UnitFrame_UpdateTooltip",
+ "UnitGUID",
+ "UnitGroupRolesAssigned",
+ "UnitHasLFGDeserter",
+ "UnitHasLFGRandomCooldown",
+ "UnitHasMana",
+ "UnitHasRelicSlot",
+ "UnitHasVehicleUI",
+ "UnitHealth",
+ "UnitHealthMax",
+ "UnitInBattleground",
+ "UnitInParty",
+ "UnitInRaid",
+ "UnitInRange",
+ "UnitInVehicle",
+ "UnitInVehicleControlSeat",
+ "UnitIsAFK",
+ "UnitIsCharmed",
+ "UnitIsConnected",
+ "UnitIsControlling",
+ "UnitIsCorpse",
+ "UnitIsDND",
+ "UnitIsDead",
+ "UnitIsDeadOrGhost",
+ "UnitIsEnemy",
+ "UnitIsFeignDeath",
+ "UnitIsFriend",
+ "UnitIsGhost",
+ "UnitIsInMyGuild",
+ "UnitIsPVP",
+ "UnitIsPVPFreeForAll",
+ "UnitIsPVPSanctuary",
+ "UnitIsPartyLeader",
+ "UnitIsPlayer",
+ "UnitIsPossessed",
+ "UnitIsRaidOfficer",
+ "UnitIsSameServer",
+ "UnitIsSilenced",
+ "UnitIsTalking",
+ "UnitIsTapped",
+ "UnitIsTappedByAllThreatList",
+ "UnitIsTappedByPlayer",
+ "UnitIsTrivial",
+ "UnitIsUnit",
+ "UnitIsVisible",
+ "UnitLevel",
+ "UnitLootMethod",
+ "UnitMana",
+ "UnitManaMax",
+ "UnitName",
+ "UnitOnTaxi",
+ "UnitPVPName",
+ "UnitPVPRank",
+ "UnitPlayerControlled",
+ "UnitPlayerOrPetInParty",
+ "UnitPlayerOrPetInRaid",
+ "UnitPopupButtons",
+ "UnitPopupFrames",
+ "UnitPopupMenus",
+ "UnitPopupShown",
+ "UnitPopup_HideButtons",
+ "UnitPopup_OnClick",
+ "UnitPopup_OnUpdate",
+ "UnitPopup_ShowMenu",
+ "UnitPower",
+ "UnitPowerMax",
+ "UnitPowerType",
+ "UnitRace",
+ "UnitRangedAttack",
+ "UnitRangedAttackPower",
+ "UnitRangedDamage",
+ "UnitReaction",
+ "UnitResistance",
+ "UnitSelectionColor",
+ "UnitSex",
+ "UnitStat",
+ "UnitSwitchToVehicleSeat",
+ "UnitTargetsVehicleInRaidUI",
+ "UnitThreatSituation",
+ "UnitUsingVehicle",
+ "UnitVehicleSeatCount",
+ "UnitVehicleSeatInfo",
+ "UnitVehicleSkin",
+ "UnitWatchRegistered",
+ "UnitXP",
+ "UnitXPMax",
+ "UnlockMultiCastActionBar",
+ "UnlockPetActionBar",
+ "UnregisterAutoHide",
+ "UnregisterStateDriver",
+ "UnregisterUnitWatch",
+ "UnstablePet",
+ "UpdateAddOnCPUUsage",
+ "UpdateAddOnMemoryUsage",
+ "UpdateArenaEnemyBackground",
+ "UpdateBagButtonHighlight",
+ "UpdateBagSlotStatus",
+ "UpdateCoinPickupFrame",
+ "UpdateDeposit",
+ "UpdateGMTicket",
+ "UpdateInventoryAlertStatus",
+ "UpdateMapHighlight",
+ "UpdateMaximumButtons",
+ "UpdateMenuBarTop",
+ "UpdateMicroButtons",
+ "UpdatePaperdollStats",
+ "UpdatePartyMemberBackground",
+ "UpdateSpells",
+ "UpdateStackSplitFrame",
+ "UpdateSubCategoryEnabledState",
+ "UpdateUIPanelPositions",
+ "UpdateWorldMapArrowFrames",
+ "UploadSettings",
+ "UpperBlackBar",
+ "UseAction",
+ "UseContainerItem",
+ "UseEquipmentSet",
+ "UseInventoryItem",
+ "UseItemByName",
+ "UseQuestLogSpecialItem",
+ "UseSoulstone",
+ "UsesGUID",
+ "VEHICLE_TEXTURES",
+ "VIEWABLE_ACTION_BAR_PAGES",
+ "VISIBLE_WATCHES",
+ "VOICECHAT_TALKERS",
+ "ValidateFramePosition",
+ "VehicleActionButton_OnClick",
+ "VehicleAimDecrement",
+ "VehicleAimDownStart",
+ "VehicleAimDownStop",
+ "VehicleAimGetAngle",
+ "VehicleAimGetNormAngle",
+ "VehicleAimGetNormPower",
+ "VehicleAimIncrement",
+ "VehicleAimRequestAngle",
+ "VehicleAimRequestNormAngle",
+ "VehicleAimSetNormPower",
+ "VehicleAimUpStart",
+ "VehicleAimUpStop",
+ "VehicleCameraZoomIn",
+ "VehicleCameraZoomOut",
+ "VehicleExit",
+ "VehicleMenuBar",
+ "VehicleMenuBarActionButton1",
+ "VehicleMenuBarActionButton1Border",
+ "VehicleMenuBarActionButton1Cooldown",
+ "VehicleMenuBarActionButton1Count",
+ "VehicleMenuBarActionButton1Flash",
+ "VehicleMenuBarActionButton1HotKey",
+ "VehicleMenuBarActionButton1Icon",
+ "VehicleMenuBarActionButton1Name",
+ "VehicleMenuBarActionButton1NormalTexture",
+ "VehicleMenuBarActionButton2",
+ "VehicleMenuBarActionButton2Border",
+ "VehicleMenuBarActionButton2Cooldown",
+ "VehicleMenuBarActionButton2Count",
+ "VehicleMenuBarActionButton2Flash",
+ "VehicleMenuBarActionButton2HotKey",
+ "VehicleMenuBarActionButton2Icon",
+ "VehicleMenuBarActionButton2Name",
+ "VehicleMenuBarActionButton2NormalTexture",
+ "VehicleMenuBarActionButton3",
+ "VehicleMenuBarActionButton3Border",
+ "VehicleMenuBarActionButton3Cooldown",
+ "VehicleMenuBarActionButton3Count",
+ "VehicleMenuBarActionButton3Flash",
+ "VehicleMenuBarActionButton3HotKey",
+ "VehicleMenuBarActionButton3Icon",
+ "VehicleMenuBarActionButton3Name",
+ "VehicleMenuBarActionButton3NormalTexture",
+ "VehicleMenuBarActionButton4",
+ "VehicleMenuBarActionButton4Border",
+ "VehicleMenuBarActionButton4Cooldown",
+ "VehicleMenuBarActionButton4Count",
+ "VehicleMenuBarActionButton4Flash",
+ "VehicleMenuBarActionButton4HotKey",
+ "VehicleMenuBarActionButton4Icon",
+ "VehicleMenuBarActionButton4Name",
+ "VehicleMenuBarActionButton4NormalTexture",
+ "VehicleMenuBarActionButton5",
+ "VehicleMenuBarActionButton5Border",
+ "VehicleMenuBarActionButton5Cooldown",
+ "VehicleMenuBarActionButton5Count",
+ "VehicleMenuBarActionButton5Flash",
+ "VehicleMenuBarActionButton5HotKey",
+ "VehicleMenuBarActionButton5Icon",
+ "VehicleMenuBarActionButton5Name",
+ "VehicleMenuBarActionButton5NormalTexture",
+ "VehicleMenuBarActionButton6",
+ "VehicleMenuBarActionButton6Border",
+ "VehicleMenuBarActionButton6Cooldown",
+ "VehicleMenuBarActionButton6Count",
+ "VehicleMenuBarActionButton6Flash",
+ "VehicleMenuBarActionButton6HotKey",
+ "VehicleMenuBarActionButton6Icon",
+ "VehicleMenuBarActionButton6Name",
+ "VehicleMenuBarActionButton6NormalTexture",
+ "VehicleMenuBarActionButtonFrame",
+ "VehicleMenuBarArtFrame",
+ "VehicleMenuBarArtFrameARTWORK1",
+ "VehicleMenuBarArtFrameARTWORK10",
+ "VehicleMenuBarArtFrameARTWORK2",
+ "VehicleMenuBarArtFrameARTWORK3",
+ "VehicleMenuBarArtFrameARTWORK4",
+ "VehicleMenuBarArtFrameARTWORK5",
+ "VehicleMenuBarArtFrameARTWORK6",
+ "VehicleMenuBarArtFrameARTWORK7",
+ "VehicleMenuBarArtFrameARTWORK8",
+ "VehicleMenuBarArtFrameARTWORK9",
+ "VehicleMenuBarArtFrameBACKGROUND1",
+ "VehicleMenuBarArtFrameBACKGROUND2",
+ "VehicleMenuBarArtFrameBACKGROUND3",
+ "VehicleMenuBarArtFrameBORDER1",
+ "VehicleMenuBarArtFrameBORDER2",
+ "VehicleMenuBarArtFrameBORDER3",
+ "VehicleMenuBarArtFrameBORDER4",
+ "VehicleMenuBarArtFrameBORDER5",
+ "VehicleMenuBarArtFrameBORDER6",
+ "VehicleMenuBarArtFrameBORDER7",
+ "VehicleMenuBarArtFrameOVERLAY1",
+ "VehicleMenuBarArtFrameOVERLAY2",
+ "VehicleMenuBarArtFrameOVERLAY3",
+ "VehicleMenuBarArtFrameOVERLAY4",
+ "VehicleMenuBarHealthBar",
+ "VehicleMenuBarHealthBarBackground",
+ "VehicleMenuBarHealthBarOverlay",
+ "VehicleMenuBarHealthBarText",
+ "VehicleMenuBarLeaveButton",
+ "VehicleMenuBarPitchDownButton",
+ "VehicleMenuBarPitchSlider",
+ "VehicleMenuBarPitchSliderBG",
+ "VehicleMenuBarPitchSliderMarker",
+ "VehicleMenuBarPitchSliderOverlayThing",
+ "VehicleMenuBarPitchUpButton",
+ "VehicleMenuBarPitch_OnClick",
+ "VehicleMenuBarPitch_OnEvent",
+ "VehicleMenuBarPitch_OnLoad",
+ "VehicleMenuBarPitch_SetValue",
+ "VehicleMenuBarPowerBar",
+ "VehicleMenuBarPowerBarBackground",
+ "VehicleMenuBarPowerBarOverlay",
+ "VehicleMenuBarPowerBarText",
+ "VehicleMenuBarStatusBarText",
+ "VehicleMenuBarStatusBars_ShowTooltip",
+ "VehicleMenuBar_MoveMicroButtons",
+ "VehicleMenuBar_OnEvent",
+ "VehicleMenuBar_OnLoad",
+ "VehicleMenuBar_ReleaseSkins",
+ "VehicleMenuBar_SetSkin",
+ "VehicleMenuBar_UpdateActionBars",
+ "VehicleNextSeat",
+ "VehiclePrevSeat",
+ "VehicleSeatIndicator",
+ "VehicleSeatIndicatorBackgroundTexture",
+ "VehicleSeatIndicatorButton_OnClick",
+ "VehicleSeatIndicatorButton_OnEnter",
+ "VehicleSeatIndicatorButton_OnLeave",
+ "VehicleSeatIndicatorDropDown",
+ "VehicleSeatIndicatorDropDownButton",
+ "VehicleSeatIndicatorDropDownButtonDisabledTexture",
+ "VehicleSeatIndicatorDropDownButtonHighlightTexture",
+ "VehicleSeatIndicatorDropDownButtonNormalTexture",
+ "VehicleSeatIndicatorDropDownButtonPushedTexture",
+ "VehicleSeatIndicatorDropDownLeft",
+ "VehicleSeatIndicatorDropDownMiddle",
+ "VehicleSeatIndicatorDropDownRight",
+ "VehicleSeatIndicatorDropDownText",
+ "VehicleSeatIndicatorDropDown_Initialize",
+ "VehicleSeatIndicatorDropDown_OnClick",
+ "VehicleSeatIndicator_OnEvent",
+ "VehicleSeatIndicator_OnLoad",
+ "VehicleSeatIndicator_SetUpVehicle",
+ "VehicleSeatIndicator_UnloadTextures",
+ "VehicleSeatIndicator_Update",
+ "VideoOptionsEffectsPanel",
+ "VideoOptionsEffectsPanelClutterDensity",
+ "VideoOptionsEffectsPanelClutterDensityHigh",
+ "VideoOptionsEffectsPanelClutterDensityLow",
+ "VideoOptionsEffectsPanelClutterDensityText",
+ "VideoOptionsEffectsPanelClutterDensityThumb",
+ "VideoOptionsEffectsPanelClutterRadius",
+ "VideoOptionsEffectsPanelClutterRadiusHigh",
+ "VideoOptionsEffectsPanelClutterRadiusLow",
+ "VideoOptionsEffectsPanelClutterRadiusText",
+ "VideoOptionsEffectsPanelClutterRadiusThumb",
+ "VideoOptionsEffectsPanelDeathEffect",
+ "VideoOptionsEffectsPanelDeathEffectText",
+ "VideoOptionsEffectsPanelEnvironmentDetail",
+ "VideoOptionsEffectsPanelEnvironmentDetailHigh",
+ "VideoOptionsEffectsPanelEnvironmentDetailLow",
+ "VideoOptionsEffectsPanelEnvironmentDetailText",
+ "VideoOptionsEffectsPanelEnvironmentDetailThumb",
+ "VideoOptionsEffectsPanelFullScreenGlow",
+ "VideoOptionsEffectsPanelFullScreenGlowText",
+ "VideoOptionsEffectsPanelParticleDensity",
+ "VideoOptionsEffectsPanelParticleDensityHigh",
+ "VideoOptionsEffectsPanelParticleDensityLow",
+ "VideoOptionsEffectsPanelParticleDensityText",
+ "VideoOptionsEffectsPanelParticleDensityThumb",
+ "VideoOptionsEffectsPanelPlayerTexture",
+ "VideoOptionsEffectsPanelPlayerTextureHigh",
+ "VideoOptionsEffectsPanelPlayerTextureLow",
+ "VideoOptionsEffectsPanelPlayerTextureText",
+ "VideoOptionsEffectsPanelPlayerTextureThumb",
+ "VideoOptionsEffectsPanelProjectedTextures",
+ "VideoOptionsEffectsPanelProjectedTexturesText",
+ "VideoOptionsEffectsPanelQuality",
+ "VideoOptionsEffectsPanelQualityLabel",
+ "VideoOptionsEffectsPanelQualitySlider",
+ "VideoOptionsEffectsPanelQualitySliderCustom",
+ "VideoOptionsEffectsPanelQualitySliderHigh",
+ "VideoOptionsEffectsPanelQualitySliderLow",
+ "VideoOptionsEffectsPanelQualitySliderText",
+ "VideoOptionsEffectsPanelQualitySliderThumb",
+ "VideoOptionsEffectsPanelQualitySubText",
+ "VideoOptionsEffectsPanelQualityTitle",
+ "VideoOptionsEffectsPanelShaders",
+ "VideoOptionsEffectsPanelShadersTitle",
+ "VideoOptionsEffectsPanelShadowQuality",
+ "VideoOptionsEffectsPanelShadowQualityHigh",
+ "VideoOptionsEffectsPanelShadowQualityLow",
+ "VideoOptionsEffectsPanelShadowQualityText",
+ "VideoOptionsEffectsPanelShadowQualityThumb",
+ "VideoOptionsEffectsPanelSlider_OnValueChanged",
+ "VideoOptionsEffectsPanelSpecularLighting",
+ "VideoOptionsEffectsPanelSpecularLightingText",
+ "VideoOptionsEffectsPanelSubText",
+ "VideoOptionsEffectsPanelTerrainDetail",
+ "VideoOptionsEffectsPanelTerrainDetailHigh",
+ "VideoOptionsEffectsPanelTerrainDetailLow",
+ "VideoOptionsEffectsPanelTerrainDetailText",
+ "VideoOptionsEffectsPanelTerrainDetailThumb",
+ "VideoOptionsEffectsPanelTextureFiltering",
+ "VideoOptionsEffectsPanelTextureFilteringHigh",
+ "VideoOptionsEffectsPanelTextureFilteringLow",
+ "VideoOptionsEffectsPanelTextureFilteringText",
+ "VideoOptionsEffectsPanelTextureFilteringThumb",
+ "VideoOptionsEffectsPanelTextureResolution",
+ "VideoOptionsEffectsPanelTextureResolutionHigh",
+ "VideoOptionsEffectsPanelTextureResolutionLow",
+ "VideoOptionsEffectsPanelTextureResolutionText",
+ "VideoOptionsEffectsPanelTextureResolutionThumb",
+ "VideoOptionsEffectsPanelTitle",
+ "VideoOptionsEffectsPanelViewDistance",
+ "VideoOptionsEffectsPanelViewDistanceHigh",
+ "VideoOptionsEffectsPanelViewDistanceLow",
+ "VideoOptionsEffectsPanelViewDistanceText",
+ "VideoOptionsEffectsPanelViewDistanceThumb",
+ "VideoOptionsEffectsPanelWeatherIntensity",
+ "VideoOptionsEffectsPanelWeatherIntensityHigh",
+ "VideoOptionsEffectsPanelWeatherIntensityLow",
+ "VideoOptionsEffectsPanelWeatherIntensityText",
+ "VideoOptionsEffectsPanelWeatherIntensityThumb",
+ "VideoOptionsEffectsPanel_Default",
+ "VideoOptionsEffectsPanel_FixupQualityLevels",
+ "VideoOptionsEffectsPanel_GetVideoQuality",
+ "VideoOptionsEffectsPanel_OnEvent",
+ "VideoOptionsEffectsPanel_OnLoad",
+ "VideoOptionsEffectsPanel_Refresh",
+ "VideoOptionsEffectsPanel_SetCustomQuality",
+ "VideoOptionsEffectsPanel_SetPresetQuality",
+ "VideoOptionsEffectsPanel_SetVideoQuality",
+ "VideoOptionsEffectsPanel_SetVideoQualityLabels",
+ "VideoOptionsEffectsPanel_UpdateVideoQuality",
+ "VideoOptionsFrame",
+ "VideoOptionsFrameApply",
+ "VideoOptionsFrameApplyText",
+ "VideoOptionsFrameCancel",
+ "VideoOptionsFrameCancelText",
+ "VideoOptionsFrameCancel_OnClick",
+ "VideoOptionsFrameCategoryFrame",
+ "VideoOptionsFrameCategoryFrameBottom",
+ "VideoOptionsFrameCategoryFrameBottomLeft",
+ "VideoOptionsFrameCategoryFrameBottomRight",
+ "VideoOptionsFrameCategoryFrameButton1",
+ "VideoOptionsFrameCategoryFrameButton10",
+ "VideoOptionsFrameCategoryFrameButton10Text",
+ "VideoOptionsFrameCategoryFrameButton10Toggle",
+ "VideoOptionsFrameCategoryFrameButton10ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton10ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton10TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton11",
+ "VideoOptionsFrameCategoryFrameButton11Text",
+ "VideoOptionsFrameCategoryFrameButton11Toggle",
+ "VideoOptionsFrameCategoryFrameButton11ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton11ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton11TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton12",
+ "VideoOptionsFrameCategoryFrameButton12Text",
+ "VideoOptionsFrameCategoryFrameButton12Toggle",
+ "VideoOptionsFrameCategoryFrameButton12ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton12ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton12TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton13",
+ "VideoOptionsFrameCategoryFrameButton13Text",
+ "VideoOptionsFrameCategoryFrameButton13Toggle",
+ "VideoOptionsFrameCategoryFrameButton13ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton13ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton13TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton14",
+ "VideoOptionsFrameCategoryFrameButton14Text",
+ "VideoOptionsFrameCategoryFrameButton14Toggle",
+ "VideoOptionsFrameCategoryFrameButton14ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton14ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton14TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton15",
+ "VideoOptionsFrameCategoryFrameButton15Text",
+ "VideoOptionsFrameCategoryFrameButton15Toggle",
+ "VideoOptionsFrameCategoryFrameButton15ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton15ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton15TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton16",
+ "VideoOptionsFrameCategoryFrameButton16Text",
+ "VideoOptionsFrameCategoryFrameButton16Toggle",
+ "VideoOptionsFrameCategoryFrameButton16ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton16ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton16TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton17",
+ "VideoOptionsFrameCategoryFrameButton17Text",
+ "VideoOptionsFrameCategoryFrameButton17Toggle",
+ "VideoOptionsFrameCategoryFrameButton17ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton17ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton17TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton18",
+ "VideoOptionsFrameCategoryFrameButton18Text",
+ "VideoOptionsFrameCategoryFrameButton18Toggle",
+ "VideoOptionsFrameCategoryFrameButton18ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton18ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton18TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton19",
+ "VideoOptionsFrameCategoryFrameButton19Text",
+ "VideoOptionsFrameCategoryFrameButton19Toggle",
+ "VideoOptionsFrameCategoryFrameButton19ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton19ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton19TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton1Text",
+ "VideoOptionsFrameCategoryFrameButton1Toggle",
+ "VideoOptionsFrameCategoryFrameButton1ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton1ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton1TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton2",
+ "VideoOptionsFrameCategoryFrameButton20",
+ "VideoOptionsFrameCategoryFrameButton20Text",
+ "VideoOptionsFrameCategoryFrameButton20Toggle",
+ "VideoOptionsFrameCategoryFrameButton20ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton20ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton20TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton21",
+ "VideoOptionsFrameCategoryFrameButton21Text",
+ "VideoOptionsFrameCategoryFrameButton21Toggle",
+ "VideoOptionsFrameCategoryFrameButton21ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton21ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton21TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton22",
+ "VideoOptionsFrameCategoryFrameButton22Text",
+ "VideoOptionsFrameCategoryFrameButton22Toggle",
+ "VideoOptionsFrameCategoryFrameButton22ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton22ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton22TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton23",
+ "VideoOptionsFrameCategoryFrameButton23Text",
+ "VideoOptionsFrameCategoryFrameButton23Toggle",
+ "VideoOptionsFrameCategoryFrameButton23ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton23ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton23TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton2Text",
+ "VideoOptionsFrameCategoryFrameButton2Toggle",
+ "VideoOptionsFrameCategoryFrameButton2ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton2ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton2TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton3",
+ "VideoOptionsFrameCategoryFrameButton3Text",
+ "VideoOptionsFrameCategoryFrameButton3Toggle",
+ "VideoOptionsFrameCategoryFrameButton3ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton3ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton3TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton4",
+ "VideoOptionsFrameCategoryFrameButton4Text",
+ "VideoOptionsFrameCategoryFrameButton4Toggle",
+ "VideoOptionsFrameCategoryFrameButton4ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton4ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton4TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton5",
+ "VideoOptionsFrameCategoryFrameButton5Text",
+ "VideoOptionsFrameCategoryFrameButton5Toggle",
+ "VideoOptionsFrameCategoryFrameButton5ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton5ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton5TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton6",
+ "VideoOptionsFrameCategoryFrameButton6Text",
+ "VideoOptionsFrameCategoryFrameButton6Toggle",
+ "VideoOptionsFrameCategoryFrameButton6ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton6ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton6TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton7",
+ "VideoOptionsFrameCategoryFrameButton7Text",
+ "VideoOptionsFrameCategoryFrameButton7Toggle",
+ "VideoOptionsFrameCategoryFrameButton7ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton7ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton7TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton8",
+ "VideoOptionsFrameCategoryFrameButton8Text",
+ "VideoOptionsFrameCategoryFrameButton8Toggle",
+ "VideoOptionsFrameCategoryFrameButton8ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton8ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton8TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameButton9",
+ "VideoOptionsFrameCategoryFrameButton9Text",
+ "VideoOptionsFrameCategoryFrameButton9Toggle",
+ "VideoOptionsFrameCategoryFrameButton9ToggleHighlightTexture",
+ "VideoOptionsFrameCategoryFrameButton9ToggleNormalTexture",
+ "VideoOptionsFrameCategoryFrameButton9TogglePushedTexture",
+ "VideoOptionsFrameCategoryFrameLeft",
+ "VideoOptionsFrameCategoryFrameList",
+ "VideoOptionsFrameCategoryFrameListScrollBar",
+ "VideoOptionsFrameCategoryFrameListScrollBarScrollDownButton",
+ "VideoOptionsFrameCategoryFrameListScrollBarScrollUpButton",
+ "VideoOptionsFrameCategoryFrameListScrollBarThumbTexture",
+ "VideoOptionsFrameCategoryFrameListScrollChildFrame",
+ "VideoOptionsFrameCategoryFrameRight",
+ "VideoOptionsFrameCategoryFrameTop",
+ "VideoOptionsFrameCategoryFrameTopLeft",
+ "VideoOptionsFrameCategoryFrameTopRight",
+ "VideoOptionsFrameDefault_OnClick",
+ "VideoOptionsFrameDefaults",
+ "VideoOptionsFrameHeader",
+ "VideoOptionsFrameHeaderText",
+ "VideoOptionsFrameOkay",
+ "VideoOptionsFrameOkayText",
+ "VideoOptionsFrameOkay_OnClick",
+ "VideoOptionsFramePanelContainer",
+ "VideoOptionsFrame_OnHide",
+ "VideoOptionsFrame_OnLoad",
+ "VideoOptionsFrame_SetAllToDefaults",
+ "VideoOptionsFrame_SetCurrentToDefaults",
+ "VideoOptionsFrame_Toggle",
+ "VideoOptionsPanel_Cancel",
+ "VideoOptionsPanel_Default",
+ "VideoOptionsPanel_Okay",
+ "VideoOptionsPanel_OnLoad",
+ "VideoOptionsResolutionPanel",
+ "VideoOptionsResolutionPanelBrightness",
+ "VideoOptionsResolutionPanelBrightnessGrayScale",
+ "VideoOptionsResolutionPanelBrightnessTitle",
+ "VideoOptionsResolutionPanelDesktopGamma",
+ "VideoOptionsResolutionPanelDesktopGammaText",
+ "VideoOptionsResolutionPanelDisableResize",
+ "VideoOptionsResolutionPanelDisableResizeText",
+ "VideoOptionsResolutionPanelFixInputLag",
+ "VideoOptionsResolutionPanelFixInputLagText",
+ "VideoOptionsResolutionPanelGammaSlider",
+ "VideoOptionsResolutionPanelGammaSliderHigh",
+ "VideoOptionsResolutionPanelGammaSliderLow",
+ "VideoOptionsResolutionPanelGammaSliderText",
+ "VideoOptionsResolutionPanelGammaSliderThumb",
+ "VideoOptionsResolutionPanelHardwareCursor",
+ "VideoOptionsResolutionPanelHardwareCursorText",
+ "VideoOptionsResolutionPanelMaximized",
+ "VideoOptionsResolutionPanelMaximizedText",
+ "VideoOptionsResolutionPanelMultiSampleDropDown",
+ "VideoOptionsResolutionPanelMultiSampleDropDownButton",
+ "VideoOptionsResolutionPanelMultiSampleDropDownButtonDisabledTexture",
+ "VideoOptionsResolutionPanelMultiSampleDropDownButtonHighlightTexture",
+ "VideoOptionsResolutionPanelMultiSampleDropDownButtonNormalTexture",
+ "VideoOptionsResolutionPanelMultiSampleDropDownButtonPushedTexture",
+ "VideoOptionsResolutionPanelMultiSampleDropDownLabel",
+ "VideoOptionsResolutionPanelMultiSampleDropDownLeft",
+ "VideoOptionsResolutionPanelMultiSampleDropDownMiddle",
+ "VideoOptionsResolutionPanelMultiSampleDropDownRight",
+ "VideoOptionsResolutionPanelMultiSampleDropDownText",
+ "VideoOptionsResolutionPanelMultiSampleDropDown_Initialize",
+ "VideoOptionsResolutionPanelMultiSampleDropDown_OnClick",
+ "VideoOptionsResolutionPanelMultiSampleDropDown_OnLoad",
+ "VideoOptionsResolutionPanelRefreshDropDown",
+ "VideoOptionsResolutionPanelRefreshDropDownButton",
+ "VideoOptionsResolutionPanelRefreshDropDownButtonDisabledTexture",
+ "VideoOptionsResolutionPanelRefreshDropDownButtonHighlightTexture",
+ "VideoOptionsResolutionPanelRefreshDropDownButtonNormalTexture",
+ "VideoOptionsResolutionPanelRefreshDropDownButtonPushedTexture",
+ "VideoOptionsResolutionPanelRefreshDropDownLabel",
+ "VideoOptionsResolutionPanelRefreshDropDownLeft",
+ "VideoOptionsResolutionPanelRefreshDropDownMiddle",
+ "VideoOptionsResolutionPanelRefreshDropDownRight",
+ "VideoOptionsResolutionPanelRefreshDropDownText",
+ "VideoOptionsResolutionPanelRefreshDropDown_Initialize",
+ "VideoOptionsResolutionPanelRefreshDropDown_OnClick",
+ "VideoOptionsResolutionPanelRefreshDropDown_OnLoad",
+ "VideoOptionsResolutionPanelResolutionDropDown",
+ "VideoOptionsResolutionPanelResolutionDropDownButton",
+ "VideoOptionsResolutionPanelResolutionDropDownButtonDisabledTexture",
+ "VideoOptionsResolutionPanelResolutionDropDownButtonHighlightTexture",
+ "VideoOptionsResolutionPanelResolutionDropDownButtonNormalTexture",
+ "VideoOptionsResolutionPanelResolutionDropDownButtonPushedTexture",
+ "VideoOptionsResolutionPanelResolutionDropDownLabel",
+ "VideoOptionsResolutionPanelResolutionDropDownLeft",
+ "VideoOptionsResolutionPanelResolutionDropDownMiddle",
+ "VideoOptionsResolutionPanelResolutionDropDownRight",
+ "VideoOptionsResolutionPanelResolutionDropDownText",
+ "VideoOptionsResolutionPanelResolutionDropDown_Initialize",
+ "VideoOptionsResolutionPanelResolutionDropDown_LoadResolutions",
+ "VideoOptionsResolutionPanelResolutionDropDown_OnClick",
+ "VideoOptionsResolutionPanelResolutionDropDown_OnLoad",
+ "VideoOptionsResolutionPanelSubText",
+ "VideoOptionsResolutionPanelTitle",
+ "VideoOptionsResolutionPanelTripleBuffer",
+ "VideoOptionsResolutionPanelTripleBufferText",
+ "VideoOptionsResolutionPanelUIScaleSlider",
+ "VideoOptionsResolutionPanelUIScaleSliderHigh",
+ "VideoOptionsResolutionPanelUIScaleSliderLow",
+ "VideoOptionsResolutionPanelUIScaleSliderText",
+ "VideoOptionsResolutionPanelUIScaleSliderThumb",
+ "VideoOptionsResolutionPanelUseUIScale",
+ "VideoOptionsResolutionPanelUseUIScaleText",
+ "VideoOptionsResolutionPanelVSync",
+ "VideoOptionsResolutionPanelVSyncText",
+ "VideoOptionsResolutionPanelWindowed",
+ "VideoOptionsResolutionPanelWindowedText",
+ "VideoOptionsResolutionPanel_Default",
+ "VideoOptionsResolutionPanel_GetMultisampleFormats",
+ "VideoOptionsResolutionPanel_GetRefreshRates",
+ "VideoOptionsResolutionPanel_OnEvent",
+ "VideoOptionsResolutionPanel_OnLoad",
+ "VideoOptionsResolutionPanel_Refresh",
+ "VideoOptionsResolutionPanel_RefreshGammaControls",
+ "VideoOptionsResolutionPanel_SetGamma",
+ "VideoOptionsResolutionPanel_SetWindowed",
+ "VideoOptionsStereoPanel",
+ "VideoOptionsStereoPanelConvergence",
+ "VideoOptionsStereoPanelConvergenceHigh",
+ "VideoOptionsStereoPanelConvergenceLow",
+ "VideoOptionsStereoPanelConvergenceText",
+ "VideoOptionsStereoPanelConvergenceThumb",
+ "VideoOptionsStereoPanelEnabled",
+ "VideoOptionsStereoPanelEnabledText",
+ "VideoOptionsStereoPanelEyeSeparation",
+ "VideoOptionsStereoPanelEyeSeparationHigh",
+ "VideoOptionsStereoPanelEyeSeparationLow",
+ "VideoOptionsStereoPanelEyeSeparationText",
+ "VideoOptionsStereoPanelEyeSeparationThumb",
+ "VideoOptionsStereoPanelHardwareCursor",
+ "VideoOptionsStereoPanelHardwareCursorText",
+ "VideoOptionsStereoPanelSubText",
+ "VideoOptionsStereoPanelTitle",
+ "VideoOptionsStereoPanel_Default",
+ "VideoOptionsStereoPanel_OnEvent",
+ "VideoOptionsStereoPanel_OnLoad",
+ "VideoStereoPanelOptions",
+ "VoiceChatShine",
+ "VoiceChatShineFadeIn",
+ "VoiceChatShineFadeOut",
+ "VoiceChatTalkers",
+ "VoiceChatTalkersButton1",
+ "VoiceChatTalkersButton1SecureButton",
+ "VoiceChatTalkersButton1Speaker",
+ "VoiceChatTalkersButton1Text",
+ "VoiceChatTalkersSpeaker",
+ "VoiceChatTalkers_CanHide",
+ "VoiceChatTalkers_CreateButtons",
+ "VoiceChatTalkers_FadeOut",
+ "VoiceChatTalkers_OnEvent",
+ "VoiceChatTalkers_OnLoad",
+ "VoiceChatTalkers_OnUpdate",
+ "VoiceChatTalkers_ResizeFrame",
+ "VoiceChatTalkers_Update",
+ "VoiceChat_ActivatePrimaryCaptureCallback",
+ "VoiceChat_Animate",
+ "VoiceChat_GetCurrentMicrophoneSignalLevel",
+ "VoiceChat_IsPlayingLoopbackSound",
+ "VoiceChat_IsRecordingLoopbackSound",
+ "VoiceChat_OnUpdate",
+ "VoiceChat_PlayLoopbackSound",
+ "VoiceChat_RecordLoopbackSound",
+ "VoiceChat_StartCapture",
+ "VoiceChat_StopCapture",
+ "VoiceChat_StopPlayingLoopbackSound",
+ "VoiceChat_StopRecordingLoopbackSound",
+ "VoiceChat_Toggle",
+ "VoiceEnumerateCaptureDevices",
+ "VoiceEnumerateOutputDevices",
+ "VoiceGetCurrentCaptureDevice",
+ "VoiceGetCurrentOutputDevice",
+ "VoiceIsDisabledByClient",
+ "VoiceMacroMenu",
+ "VoiceMacroMenuButton1",
+ "VoiceMacroMenuButton10",
+ "VoiceMacroMenuButton10ShortcutText",
+ "VoiceMacroMenuButton11",
+ "VoiceMacroMenuButton11ShortcutText",
+ "VoiceMacroMenuButton12",
+ "VoiceMacroMenuButton12ShortcutText",
+ "VoiceMacroMenuButton13",
+ "VoiceMacroMenuButton13ShortcutText",
+ "VoiceMacroMenuButton14",
+ "VoiceMacroMenuButton14ShortcutText",
+ "VoiceMacroMenuButton15",
+ "VoiceMacroMenuButton15ShortcutText",
+ "VoiceMacroMenuButton16",
+ "VoiceMacroMenuButton16ShortcutText",
+ "VoiceMacroMenuButton17",
+ "VoiceMacroMenuButton17ShortcutText",
+ "VoiceMacroMenuButton18",
+ "VoiceMacroMenuButton18ShortcutText",
+ "VoiceMacroMenuButton19",
+ "VoiceMacroMenuButton19ShortcutText",
+ "VoiceMacroMenuButton1ShortcutText",
+ "VoiceMacroMenuButton2",
+ "VoiceMacroMenuButton20",
+ "VoiceMacroMenuButton20ShortcutText",
+ "VoiceMacroMenuButton21",
+ "VoiceMacroMenuButton21ShortcutText",
+ "VoiceMacroMenuButton22",
+ "VoiceMacroMenuButton22ShortcutText",
+ "VoiceMacroMenuButton23",
+ "VoiceMacroMenuButton23ShortcutText",
+ "VoiceMacroMenuButton24",
+ "VoiceMacroMenuButton24ShortcutText",
+ "VoiceMacroMenuButton25",
+ "VoiceMacroMenuButton25ShortcutText",
+ "VoiceMacroMenuButton26",
+ "VoiceMacroMenuButton26ShortcutText",
+ "VoiceMacroMenuButton27",
+ "VoiceMacroMenuButton27ShortcutText",
+ "VoiceMacroMenuButton28",
+ "VoiceMacroMenuButton28ShortcutText",
+ "VoiceMacroMenuButton29",
+ "VoiceMacroMenuButton29ShortcutText",
+ "VoiceMacroMenuButton2ShortcutText",
+ "VoiceMacroMenuButton3",
+ "VoiceMacroMenuButton30",
+ "VoiceMacroMenuButton30ShortcutText",
+ "VoiceMacroMenuButton31",
+ "VoiceMacroMenuButton31ShortcutText",
+ "VoiceMacroMenuButton32",
+ "VoiceMacroMenuButton32ShortcutText",
+ "VoiceMacroMenuButton3ShortcutText",
+ "VoiceMacroMenuButton4",
+ "VoiceMacroMenuButton4ShortcutText",
+ "VoiceMacroMenuButton5",
+ "VoiceMacroMenuButton5ShortcutText",
+ "VoiceMacroMenuButton6",
+ "VoiceMacroMenuButton6ShortcutText",
+ "VoiceMacroMenuButton7",
+ "VoiceMacroMenuButton7ShortcutText",
+ "VoiceMacroMenuButton8",
+ "VoiceMacroMenuButton8ShortcutText",
+ "VoiceMacroMenuButton9",
+ "VoiceMacroMenuButton9ShortcutText",
+ "VoiceMacroMenu_Click",
+ "VoiceMacroMenu_OnLoad",
+ "VoicePanelOptions",
+ "VoicePushToTalkStart",
+ "VoicePushToTalkStop",
+ "VoiceSelectCaptureDevice",
+ "VoiceSelectOutputDevice",
+ "WARLOCK_PET_BONUS",
+ "WATCHFRAME_ACHIEVEMENTLINES",
+ "WATCHFRAME_FLAGS",
+ "WATCHFRAME_LINKBUTTONS",
+ "WATCHFRAME_OBJECTIVEHANDLERS",
+ "WATCHFRAME_QUESTLINES",
+ "WATCHFRAME_TIMEDCRITERIA",
+ "WATCHFRAME_TIMERLINES",
+ "WHOFRAME_DROPDOWN_LIST",
+ "WORLDMAP_DEBUG_ICON_INFO",
+ "WORLDMAP_SETTINGS",
+ "WORLDSTATEALWAYSUPFRAME_SUSPENDEDCHATFRAMES",
+ "WatchFrame",
+ "WatchFrameCollapseExpandButton",
+ "WatchFrameDropDown",
+ "WatchFrameDropDownButton",
+ "WatchFrameDropDownButtonDisabledTexture",
+ "WatchFrameDropDownButtonHighlightTexture",
+ "WatchFrameDropDownButtonNormalTexture",
+ "WatchFrameDropDownButtonPushedTexture",
+ "WatchFrameDropDownLeft",
+ "WatchFrameDropDownMiddle",
+ "WatchFrameDropDownRight",
+ "WatchFrameDropDownText",
+ "WatchFrameDropDown_Initialize",
+ "WatchFrameDropDown_OnHide",
+ "WatchFrameDropDown_OnLoad",
+ "WatchFrameHeader",
+ "WatchFrameHeaderDropDown",
+ "WatchFrameHeaderDropDownButton",
+ "WatchFrameHeaderDropDownButtonDisabledTexture",
+ "WatchFrameHeaderDropDownButtonHighlightTexture",
+ "WatchFrameHeaderDropDownButtonNormalTexture",
+ "WatchFrameHeaderDropDownButtonPushedTexture",
+ "WatchFrameHeaderDropDownLeft",
+ "WatchFrameHeaderDropDownMiddle",
+ "WatchFrameHeaderDropDownRight",
+ "WatchFrameHeaderDropDownText",
+ "WatchFrameHeaderDropDown_Initialize",
+ "WatchFrameHeaderDropDown_OnLoad",
+ "WatchFrameHeader_OnClick",
+ "WatchFrameItem_OnClick",
+ "WatchFrameItem_OnEnter",
+ "WatchFrameItem_OnEvent",
+ "WatchFrameItem_OnHide",
+ "WatchFrameItem_OnLoad",
+ "WatchFrameItem_OnShow",
+ "WatchFrameItem_OnUpdate",
+ "WatchFrameItem_UpdateCooldown",
+ "WatchFrameLine1",
+ "WatchFrameLine1Border",
+ "WatchFrameLine1Dash",
+ "WatchFrameLine1Icon",
+ "WatchFrameLine1Text",
+ "WatchFrameLineTemplate_OnLoad",
+ "WatchFrameLines",
+ "WatchFrameLines_AddUpdateFunction",
+ "WatchFrameLines_OnUpdate",
+ "WatchFrameLines_RemoveUpdateFunction",
+ "WatchFrameLinkButtonTemplate_Highlight",
+ "WatchFrameLinkButtonTemplate_OnClick",
+ "WatchFrameLinkButtonTemplate_OnLeftClick",
+ "WatchFrameQuestPOI_OnClick",
+ "WatchFrameTitle",
+ "WatchFrame_AbandonQuest",
+ "WatchFrame_AddObjectiveHandler",
+ "WatchFrame_ClearDisplay",
+ "WatchFrame_Collapse",
+ "WatchFrame_CollapseExpandButton_OnClick",
+ "WatchFrame_DisplayQuestTimers",
+ "WatchFrame_DisplayTrackedAchievements",
+ "WatchFrame_DisplayTrackedQuests",
+ "WatchFrame_Expand",
+ "WatchFrame_GetCurrentMapQuests",
+ "WatchFrame_GetVisibleIndex",
+ "WatchFrame_HandleDisplayQuestTimers",
+ "WatchFrame_HandleDisplayTrackedAchievements",
+ "WatchFrame_HandleQuestTimerUpdate",
+ "WatchFrame_MoveQuest",
+ "WatchFrame_OnEvent",
+ "WatchFrame_OnLoad",
+ "WatchFrame_OnSizeChanged",
+ "WatchFrame_OnUpdate",
+ "WatchFrame_OpenAchievementFrame",
+ "WatchFrame_OpenMapToQuest",
+ "WatchFrame_OpenQuestLog",
+ "WatchFrame_QuestTimerUpdateFunction",
+ "WatchFrame_RemoveObjectiveHandler",
+ "WatchFrame_ReverseQuestObjective",
+ "WatchFrame_SetFilter",
+ "WatchFrame_SetLine",
+ "WatchFrame_SetSorting",
+ "WatchFrame_SetWidth",
+ "WatchFrame_ShareQuest",
+ "WatchFrame_StopTrackingAchievement",
+ "WatchFrame_StopTrackingQuest",
+ "WatchFrame_Update",
+ "WatchFrame_UpdateTimedAchievements",
+ "WhoFrame",
+ "WhoFrameAddFriendButton",
+ "WhoFrameAddFriendButtonText",
+ "WhoFrameButton1",
+ "WhoFrameButton10",
+ "WhoFrameButton10Class",
+ "WhoFrameButton10Level",
+ "WhoFrameButton10Name",
+ "WhoFrameButton10Variable",
+ "WhoFrameButton11",
+ "WhoFrameButton11Class",
+ "WhoFrameButton11Level",
+ "WhoFrameButton11Name",
+ "WhoFrameButton11Variable",
+ "WhoFrameButton12",
+ "WhoFrameButton12Class",
+ "WhoFrameButton12Level",
+ "WhoFrameButton12Name",
+ "WhoFrameButton12Variable",
+ "WhoFrameButton13",
+ "WhoFrameButton13Class",
+ "WhoFrameButton13Level",
+ "WhoFrameButton13Name",
+ "WhoFrameButton13Variable",
+ "WhoFrameButton14",
+ "WhoFrameButton14Class",
+ "WhoFrameButton14Level",
+ "WhoFrameButton14Name",
+ "WhoFrameButton14Variable",
+ "WhoFrameButton15",
+ "WhoFrameButton15Class",
+ "WhoFrameButton15Level",
+ "WhoFrameButton15Name",
+ "WhoFrameButton15Variable",
+ "WhoFrameButton16",
+ "WhoFrameButton16Class",
+ "WhoFrameButton16Level",
+ "WhoFrameButton16Name",
+ "WhoFrameButton16Variable",
+ "WhoFrameButton17",
+ "WhoFrameButton17Class",
+ "WhoFrameButton17Level",
+ "WhoFrameButton17Name",
+ "WhoFrameButton17Variable",
+ "WhoFrameButton1Class",
+ "WhoFrameButton1Level",
+ "WhoFrameButton1Name",
+ "WhoFrameButton1Variable",
+ "WhoFrameButton2",
+ "WhoFrameButton2Class",
+ "WhoFrameButton2Level",
+ "WhoFrameButton2Name",
+ "WhoFrameButton2Variable",
+ "WhoFrameButton3",
+ "WhoFrameButton3Class",
+ "WhoFrameButton3Level",
+ "WhoFrameButton3Name",
+ "WhoFrameButton3Variable",
+ "WhoFrameButton4",
+ "WhoFrameButton4Class",
+ "WhoFrameButton4Level",
+ "WhoFrameButton4Name",
+ "WhoFrameButton4Variable",
+ "WhoFrameButton5",
+ "WhoFrameButton5Class",
+ "WhoFrameButton5Level",
+ "WhoFrameButton5Name",
+ "WhoFrameButton5Variable",
+ "WhoFrameButton6",
+ "WhoFrameButton6Class",
+ "WhoFrameButton6Level",
+ "WhoFrameButton6Name",
+ "WhoFrameButton6Variable",
+ "WhoFrameButton7",
+ "WhoFrameButton7Class",
+ "WhoFrameButton7Level",
+ "WhoFrameButton7Name",
+ "WhoFrameButton7Variable",
+ "WhoFrameButton8",
+ "WhoFrameButton8Class",
+ "WhoFrameButton8Level",
+ "WhoFrameButton8Name",
+ "WhoFrameButton8Variable",
+ "WhoFrameButton9",
+ "WhoFrameButton9Class",
+ "WhoFrameButton9Level",
+ "WhoFrameButton9Name",
+ "WhoFrameButton9Variable",
+ "WhoFrameColumnHeader1",
+ "WhoFrameColumnHeader1HighlightTexture",
+ "WhoFrameColumnHeader1Left",
+ "WhoFrameColumnHeader1Middle",
+ "WhoFrameColumnHeader1Right",
+ "WhoFrameColumnHeader2",
+ "WhoFrameColumnHeader2HighlightTexture",
+ "WhoFrameColumnHeader2Left",
+ "WhoFrameColumnHeader2Middle",
+ "WhoFrameColumnHeader2Right",
+ "WhoFrameColumnHeader3",
+ "WhoFrameColumnHeader3HighlightTexture",
+ "WhoFrameColumnHeader3Left",
+ "WhoFrameColumnHeader3Middle",
+ "WhoFrameColumnHeader3Right",
+ "WhoFrameColumnHeader4",
+ "WhoFrameColumnHeader4HighlightTexture",
+ "WhoFrameColumnHeader4Left",
+ "WhoFrameColumnHeader4Middle",
+ "WhoFrameColumnHeader4Right",
+ "WhoFrameColumn_SetWidth",
+ "WhoFrameDropDown",
+ "WhoFrameDropDownButton",
+ "WhoFrameDropDownButtonDisabledTexture",
+ "WhoFrameDropDownButtonHighlightTexture",
+ "WhoFrameDropDownButtonNormalTexture",
+ "WhoFrameDropDownButtonPushedTexture",
+ "WhoFrameDropDownButton_OnClick",
+ "WhoFrameDropDownHighlightTexture",
+ "WhoFrameDropDownLeft",
+ "WhoFrameDropDownMiddle",
+ "WhoFrameDropDownRight",
+ "WhoFrameDropDownText",
+ "WhoFrameDropDown_Initialize",
+ "WhoFrameDropDown_OnLoad",
+ "WhoFrameEditBox",
+ "WhoFrameEditBox_OnEnterPressed",
+ "WhoFrameGroupInviteButton",
+ "WhoFrameGroupInviteButtonText",
+ "WhoFrameTotals",
+ "WhoFrameWhoButton",
+ "WhoFrameWhoButtonText",
+ "WhoFrame_GetDefaultWhoCommand",
+ "WhoListScrollFrame",
+ "WhoListScrollFrameScrollBar",
+ "WhoListScrollFrameScrollBarScrollDownButton",
+ "WhoListScrollFrameScrollBarScrollUpButton",
+ "WhoListScrollFrameScrollBarThumbTexture",
+ "WhoListScrollFrameScrollChildFrame",
+ "WhoList_Update",
+ "WintergraspTimer",
+ "WintergraspTimer_OnLoad",
+ "WintergraspTimer_OnUpdate",
+ "WithdrawGoldEditBox_Update",
+ "WithdrawGuildBankMoney",
+ "WorldFrame",
+ "WorldFrame_OnLoad",
+ "WorldFrame_OnUpdate",
+ "WorldMapBlobFrame",
+ "WorldMapBlobFrameTexture",
+ "WorldMapBlobFrame_CalculateHitTranslations",
+ "WorldMapBlobFrame_OnLoad",
+ "WorldMapBlobFrame_OnUpdate",
+ "WorldMapButton",
+ "WorldMapButton_OnClick",
+ "WorldMapButton_OnUpdate",
+ "WorldMapCompareTooltip1",
+ "WorldMapCompareTooltip1TextLeft1",
+ "WorldMapCompareTooltip1TextLeft2",
+ "WorldMapCompareTooltip1TextLeft3",
+ "WorldMapCompareTooltip1TextLeft4",
+ "WorldMapCompareTooltip1TextRight1",
+ "WorldMapCompareTooltip1TextRight2",
+ "WorldMapCompareTooltip1TextRight3",
+ "WorldMapCompareTooltip1TextRight4",
+ "WorldMapCompareTooltip1Texture1",
+ "WorldMapCompareTooltip1Texture2",
+ "WorldMapCompareTooltip1Texture3",
+ "WorldMapCompareTooltip2",
+ "WorldMapCompareTooltip2TextLeft1",
+ "WorldMapCompareTooltip2TextLeft2",
+ "WorldMapCompareTooltip2TextLeft3",
+ "WorldMapCompareTooltip2TextLeft4",
+ "WorldMapCompareTooltip2TextRight1",
+ "WorldMapCompareTooltip2TextRight2",
+ "WorldMapCompareTooltip2TextRight3",
+ "WorldMapCompareTooltip2TextRight4",
+ "WorldMapCompareTooltip2Texture1",
+ "WorldMapCompareTooltip2Texture2",
+ "WorldMapCompareTooltip2Texture3",
+ "WorldMapCompareTooltip3",
+ "WorldMapCompareTooltip3TextLeft1",
+ "WorldMapCompareTooltip3TextLeft2",
+ "WorldMapCompareTooltip3TextLeft3",
+ "WorldMapCompareTooltip3TextLeft4",
+ "WorldMapCompareTooltip3TextRight1",
+ "WorldMapCompareTooltip3TextRight2",
+ "WorldMapCompareTooltip3TextRight3",
+ "WorldMapCompareTooltip3TextRight4",
+ "WorldMapCompareTooltip3Texture1",
+ "WorldMapCompareTooltip3Texture2",
+ "WorldMapCompareTooltip3Texture3",
+ "WorldMapContinentButton_OnClick",
+ "WorldMapContinentDropDown",
+ "WorldMapContinentDropDownButton",
+ "WorldMapContinentDropDownButtonDisabledTexture",
+ "WorldMapContinentDropDownButtonHighlightTexture",
+ "WorldMapContinentDropDownButtonNormalTexture",
+ "WorldMapContinentDropDownButtonPushedTexture",
+ "WorldMapContinentDropDownLeft",
+ "WorldMapContinentDropDownMiddle",
+ "WorldMapContinentDropDownRight",
+ "WorldMapContinentDropDownText",
+ "WorldMapContinentsDropDown_Initialize",
+ "WorldMapContinentsDropDown_Update",
+ "WorldMapCorpse",
+ "WorldMapDeathRelease",
+ "WorldMapDetailFrame",
+ "WorldMapDetailTile1",
+ "WorldMapDetailTile10",
+ "WorldMapDetailTile11",
+ "WorldMapDetailTile12",
+ "WorldMapDetailTile2",
+ "WorldMapDetailTile3",
+ "WorldMapDetailTile4",
+ "WorldMapDetailTile5",
+ "WorldMapDetailTile6",
+ "WorldMapDetailTile7",
+ "WorldMapDetailTile8",
+ "WorldMapDetailTile9",
+ "WorldMapFlag1",
+ "WorldMapFlag1Texture",
+ "WorldMapFlag2",
+ "WorldMapFlag2Texture",
+ "WorldMapFrame",
+ "WorldMapFrameAreaDescription",
+ "WorldMapFrameAreaFrame",
+ "WorldMapFrameAreaLabel",
+ "WorldMapFrameCloseButton",
+ "WorldMapFrameMiniBorderLeft",
+ "WorldMapFrameMiniBorderRight",
+ "WorldMapFrameSizeDownButton",
+ "WorldMapFrameSizeUpButton",
+ "WorldMapFrameTexture1",
+ "WorldMapFrameTexture10",
+ "WorldMapFrameTexture11",
+ "WorldMapFrameTexture12",
+ "WorldMapFrameTexture13",
+ "WorldMapFrameTexture14",
+ "WorldMapFrameTexture15",
+ "WorldMapFrameTexture16",
+ "WorldMapFrameTexture17",
+ "WorldMapFrameTexture18",
+ "WorldMapFrameTexture2",
+ "WorldMapFrameTexture3",
+ "WorldMapFrameTexture4",
+ "WorldMapFrameTexture5",
+ "WorldMapFrameTexture6",
+ "WorldMapFrameTexture7",
+ "WorldMapFrameTexture8",
+ "WorldMapFrameTexture9",
+ "WorldMapFrameTitle",
+ "WorldMapFrame_ChangeOpacity",
+ "WorldMapFrame_ClearQuestPOIs",
+ "WorldMapFrame_DisplayQuestPOI",
+ "WorldMapFrame_DisplayQuests",
+ "WorldMapFrame_GetQuestFrame",
+ "WorldMapFrame_LoadContinents",
+ "WorldMapFrame_LoadZones",
+ "WorldMapFrame_OnEvent",
+ "WorldMapFrame_OnHide",
+ "WorldMapFrame_OnKeyDown",
+ "WorldMapFrame_OnLoad",
+ "WorldMapFrame_OnShow",
+ "WorldMapFrame_OnUpdate",
+ "WorldMapFrame_PingPlayerPosition",
+ "WorldMapFrame_ResetFrameLevels",
+ "WorldMapFrame_ResetQuestColors",
+ "WorldMapFrame_ReverseQuestObjective",
+ "WorldMapFrame_SaveOpacity",
+ "WorldMapFrame_SelectQuestById",
+ "WorldMapFrame_SelectQuestFrame",
+ "WorldMapFrame_SetFullMapView",
+ "WorldMapFrame_SetMapName",
+ "WorldMapFrame_SetMiniMode",
+ "WorldMapFrame_SetOpacity",
+ "WorldMapFrame_SetPOIMaxBounds",
+ "WorldMapFrame_SetQuestMapView",
+ "WorldMapFrame_ToggleAdvanced",
+ "WorldMapFrame_ToggleWindowSize",
+ "WorldMapFrame_Update",
+ "WorldMapFrame_UpdateMap",
+ "WorldMapFrame_UpdateQuests",
+ "WorldMapFrame_UpdateUnits",
+ "WorldMapHighlight",
+ "WorldMapLevelButton_OnClick",
+ "WorldMapLevelDownButton",
+ "WorldMapLevelDown_OnClick",
+ "WorldMapLevelDropDown",
+ "WorldMapLevelDropDownButton",
+ "WorldMapLevelDropDownButtonDisabledTexture",
+ "WorldMapLevelDropDownButtonHighlightTexture",
+ "WorldMapLevelDropDownButtonNormalTexture",
+ "WorldMapLevelDropDownButtonPushedTexture",
+ "WorldMapLevelDropDownLeft",
+ "WorldMapLevelDropDownMiddle",
+ "WorldMapLevelDropDownRight",
+ "WorldMapLevelDropDownText",
+ "WorldMapLevelDropDown_Initialize",
+ "WorldMapLevelDropDown_Update",
+ "WorldMapLevelUpButton",
+ "WorldMapLevelUp_OnClick",
+ "WorldMapMagnifyingGlassButton",
+ "WorldMapPOIFrame",
+ "WorldMapPOI_OnClick",
+ "WorldMapPOI_OnEnter",
+ "WorldMapPOI_OnLeave",
+ "WorldMapParty1",
+ "WorldMapParty1Icon",
+ "WorldMapParty2",
+ "WorldMapParty2Icon",
+ "WorldMapParty3",
+ "WorldMapParty3Icon",
+ "WorldMapParty4",
+ "WorldMapParty4Icon",
+ "WorldMapPing",
+ "WorldMapPlayer",
+ "WorldMapPositioningGuide",
+ "WorldMapQuestDetailScrollChildFrame",
+ "WorldMapQuestDetailScrollFrame",
+ "WorldMapQuestDetailScrollFrameScrollBar",
+ "WorldMapQuestDetailScrollFrameScrollBarScrollDownButton",
+ "WorldMapQuestDetailScrollFrameScrollBarScrollUpButton",
+ "WorldMapQuestDetailScrollFrameScrollBarThumbTexture",
+ "WorldMapQuestDetailScrollFrameTrack",
+ "WorldMapQuestFrame0",
+ "WorldMapQuestFrame0Check",
+ "WorldMapQuestFrame0Dashes",
+ "WorldMapQuestFrame0Objectives",
+ "WorldMapQuestFrame0Title",
+ "WorldMapQuestFrame_OnEnter",
+ "WorldMapQuestFrame_OnLeave",
+ "WorldMapQuestFrame_OnMouseDown",
+ "WorldMapQuestFrame_OnMouseUp",
+ "WorldMapQuestFrame_UpdateMouseOver",
+ "WorldMapQuestHighlightBar",
+ "WorldMapQuestHighlightedFrame",
+ "WorldMapQuestPOI_OnClick",
+ "WorldMapQuestPOI_OnEnter",
+ "WorldMapQuestPOI_OnLeave",
+ "WorldMapQuestPOI_SetTooltip",
+ "WorldMapQuestRewardScrollChildFrame",
+ "WorldMapQuestRewardScrollFrame",
+ "WorldMapQuestRewardScrollFrameScrollBar",
+ "WorldMapQuestRewardScrollFrameScrollBarScrollDownButton",
+ "WorldMapQuestRewardScrollFrameScrollBarScrollUpButton",
+ "WorldMapQuestRewardScrollFrameScrollBarThumbTexture",
+ "WorldMapQuestRewardScrollFrameTrack",
+ "WorldMapQuestScrollChildFrame",
+ "WorldMapQuestScrollFrame",
+ "WorldMapQuestScrollFrameScrollBar",
+ "WorldMapQuestScrollFrameScrollBarScrollDownButton",
+ "WorldMapQuestScrollFrameScrollBarScrollUpButton",
+ "WorldMapQuestScrollFrameScrollBarThumbTexture",
+ "WorldMapQuestSelectBar",
+ "WorldMapQuestSelectedFrame",
+ "WorldMapQuestShowObjectives",
+ "WorldMapQuestShowObjectivesText",
+ "WorldMapQuestShowObjectives_AdjustPosition",
+ "WorldMapQuestShowObjectives_Toggle",
+ "WorldMapRaid1",
+ "WorldMapRaid10",
+ "WorldMapRaid10Icon",
+ "WorldMapRaid11",
+ "WorldMapRaid11Icon",
+ "WorldMapRaid12",
+ "WorldMapRaid12Icon",
+ "WorldMapRaid13",
+ "WorldMapRaid13Icon",
+ "WorldMapRaid14",
+ "WorldMapRaid14Icon",
+ "WorldMapRaid15",
+ "WorldMapRaid15Icon",
+ "WorldMapRaid16",
+ "WorldMapRaid16Icon",
+ "WorldMapRaid17",
+ "WorldMapRaid17Icon",
+ "WorldMapRaid18",
+ "WorldMapRaid18Icon",
+ "WorldMapRaid19",
+ "WorldMapRaid19Icon",
+ "WorldMapRaid1Icon",
+ "WorldMapRaid2",
+ "WorldMapRaid20",
+ "WorldMapRaid20Icon",
+ "WorldMapRaid21",
+ "WorldMapRaid21Icon",
+ "WorldMapRaid22",
+ "WorldMapRaid22Icon",
+ "WorldMapRaid23",
+ "WorldMapRaid23Icon",
+ "WorldMapRaid24",
+ "WorldMapRaid24Icon",
+ "WorldMapRaid25",
+ "WorldMapRaid25Icon",
+ "WorldMapRaid26",
+ "WorldMapRaid26Icon",
+ "WorldMapRaid27",
+ "WorldMapRaid27Icon",
+ "WorldMapRaid28",
+ "WorldMapRaid28Icon",
+ "WorldMapRaid29",
+ "WorldMapRaid29Icon",
+ "WorldMapRaid2Icon",
+ "WorldMapRaid3",
+ "WorldMapRaid30",
+ "WorldMapRaid30Icon",
+ "WorldMapRaid31",
+ "WorldMapRaid31Icon",
+ "WorldMapRaid32",
+ "WorldMapRaid32Icon",
+ "WorldMapRaid33",
+ "WorldMapRaid33Icon",
+ "WorldMapRaid34",
+ "WorldMapRaid34Icon",
+ "WorldMapRaid35",
+ "WorldMapRaid35Icon",
+ "WorldMapRaid36",
+ "WorldMapRaid36Icon",
+ "WorldMapRaid37",
+ "WorldMapRaid37Icon",
+ "WorldMapRaid38",
+ "WorldMapRaid38Icon",
+ "WorldMapRaid39",
+ "WorldMapRaid39Icon",
+ "WorldMapRaid3Icon",
+ "WorldMapRaid4",
+ "WorldMapRaid40",
+ "WorldMapRaid40Icon",
+ "WorldMapRaid4Icon",
+ "WorldMapRaid5",
+ "WorldMapRaid5Icon",
+ "WorldMapRaid6",
+ "WorldMapRaid6Icon",
+ "WorldMapRaid7",
+ "WorldMapRaid7Icon",
+ "WorldMapRaid8",
+ "WorldMapRaid8Icon",
+ "WorldMapRaid9",
+ "WorldMapRaid9Icon",
+ "WorldMapScreenAnchor",
+ "WorldMapTextFont",
+ "WorldMapTitleButton",
+ "WorldMapTitleButton_OnClick",
+ "WorldMapTitleButton_OnDragStart",
+ "WorldMapTitleButton_OnDragStop",
+ "WorldMapTitleButton_OnLoad",
+ "WorldMapTitleDropDown",
+ "WorldMapTitleDropDownButton",
+ "WorldMapTitleDropDownButtonDisabledTexture",
+ "WorldMapTitleDropDownButtonHighlightTexture",
+ "WorldMapTitleDropDownButtonNormalTexture",
+ "WorldMapTitleDropDownButtonPushedTexture",
+ "WorldMapTitleDropDownLeft",
+ "WorldMapTitleDropDownMiddle",
+ "WorldMapTitleDropDownRight",
+ "WorldMapTitleDropDownText",
+ "WorldMapTitleDropDown_Initialize",
+ "WorldMapTitleDropDown_ToggleLock",
+ "WorldMapTitleDropDown_ToggleOpacity",
+ "WorldMapTooltip",
+ "WorldMapTooltipStatusBar",
+ "WorldMapTooltipStatusBarTexture",
+ "WorldMapTooltipTextLeft1",
+ "WorldMapTooltipTextLeft2",
+ "WorldMapTooltipTextLeft3",
+ "WorldMapTooltipTextLeft4",
+ "WorldMapTooltipTextLeft5",
+ "WorldMapTooltipTextLeft6",
+ "WorldMapTooltipTextLeft7",
+ "WorldMapTooltipTextLeft8",
+ "WorldMapTooltipTextRight1",
+ "WorldMapTooltipTextRight2",
+ "WorldMapTooltipTextRight3",
+ "WorldMapTooltipTextRight4",
+ "WorldMapTooltipTextRight5",
+ "WorldMapTooltipTextRight6",
+ "WorldMapTooltipTextRight7",
+ "WorldMapTooltipTextRight8",
+ "WorldMapTooltipTexture1",
+ "WorldMapTooltipTexture10",
+ "WorldMapTooltipTexture2",
+ "WorldMapTooltipTexture3",
+ "WorldMapTooltipTexture4",
+ "WorldMapTooltipTexture5",
+ "WorldMapTooltipTexture6",
+ "WorldMapTooltipTexture7",
+ "WorldMapTooltipTexture8",
+ "WorldMapTooltipTexture9",
+ "WorldMapTrackQuest",
+ "WorldMapTrackQuestText",
+ "WorldMapTrackQuest_Toggle",
+ "WorldMapUnitDropDown",
+ "WorldMapUnitDropDownButton",
+ "WorldMapUnitDropDownButtonDisabledTexture",
+ "WorldMapUnitDropDownButtonHighlightTexture",
+ "WorldMapUnitDropDownButtonNormalTexture",
+ "WorldMapUnitDropDownButtonPushedTexture",
+ "WorldMapUnitDropDownLeft",
+ "WorldMapUnitDropDownMiddle",
+ "WorldMapUnitDropDownRight",
+ "WorldMapUnitDropDownText",
+ "WorldMapUnitDropDown_Initialize",
+ "WorldMapUnitDropDown_OnClick",
+ "WorldMapUnitDropDown_ReportAll_OnClick",
+ "WorldMapUnit_OnEnter",
+ "WorldMapUnit_OnEvent",
+ "WorldMapUnit_OnHide",
+ "WorldMapUnit_OnLeave",
+ "WorldMapUnit_OnLoad",
+ "WorldMapUnit_OnMouseUp",
+ "WorldMapUnit_OnShow",
+ "WorldMapUnit_Update",
+ "WorldMapZoneButton_OnClick",
+ "WorldMapZoneDropDown",
+ "WorldMapZoneDropDownButton",
+ "WorldMapZoneDropDownButtonDisabledTexture",
+ "WorldMapZoneDropDownButtonHighlightTexture",
+ "WorldMapZoneDropDownButtonNormalTexture",
+ "WorldMapZoneDropDownButtonPushedTexture",
+ "WorldMapZoneDropDownLeft",
+ "WorldMapZoneDropDownMiddle",
+ "WorldMapZoneDropDownRight",
+ "WorldMapZoneDropDownText",
+ "WorldMapZoneDropDown_Initialize",
+ "WorldMapZoneDropDown_Update",
+ "WorldMapZoneInfo",
+ "WorldMapZoneMinimapDropDown",
+ "WorldMapZoneMinimapDropDownButton",
+ "WorldMapZoneMinimapDropDownButtonDisabledTexture",
+ "WorldMapZoneMinimapDropDownButtonHighlightTexture",
+ "WorldMapZoneMinimapDropDownButtonNormalTexture",
+ "WorldMapZoneMinimapDropDownButtonPushedTexture",
+ "WorldMapZoneMinimapDropDownLeft",
+ "WorldMapZoneMinimapDropDownMiddle",
+ "WorldMapZoneMinimapDropDownRight",
+ "WorldMapZoneMinimapDropDownText",
+ "WorldMapZoneMinimapDropDown_GetText",
+ "WorldMapZoneMinimapDropDown_Initialize",
+ "WorldMapZoneMinimapDropDown_OnClick",
+ "WorldMapZoneMinimapDropDown_Update",
+ "WorldMapZoomOutButton",
+ "WorldMapZoomOutButtonText",
+ "WorldMapZoomOutButton_OnClick",
+ "WorldMap_ClearTextures",
+ "WorldMap_CreatePOI",
+ "WorldMap_GetPOITextureCoords",
+ "WorldMap_GetVehicleTexture",
+ "WorldMap_LoadTextures",
+ "WorldMap_OpenToQuest",
+ "WorldMap_ToggleSizeDown",
+ "WorldMap_ToggleSizeUp",
+ "WorldStateAlwaysUpFrame",
+ "WorldStateAlwaysUpFrame_FilterChatMsgLoot",
+ "WorldStateAlwaysUpFrame_FilterChatMsgSystem",
+ "WorldStateAlwaysUpFrame_OnEvent",
+ "WorldStateAlwaysUpFrame_OnLoad",
+ "WorldStateAlwaysUpFrame_OnUpdate",
+ "WorldStateAlwaysUpFrame_StartBGChatFilter",
+ "WorldStateAlwaysUpFrame_StopBGChatFilter",
+ "WorldStateAlwaysUpFrame_Update",
+ "WorldStateFrame_CanShowBattlefieldMinimap",
+ "WorldStateFrame_ToggleBattlefieldMinimap",
+ "WorldStateScoreBattlegroundRunTime",
+ "WorldStateScoreButton1",
+ "WorldStateScoreButton10",
+ "WorldStateScoreButton10ClassButton",
+ "WorldStateScoreButton10ClassButtonIcon",
+ "WorldStateScoreButton10Column1Icon",
+ "WorldStateScoreButton10Column1Text",
+ "WorldStateScoreButton10Column2Icon",
+ "WorldStateScoreButton10Column2Text",
+ "WorldStateScoreButton10Column3Icon",
+ "WorldStateScoreButton10Column3Text",
+ "WorldStateScoreButton10Column4Icon",
+ "WorldStateScoreButton10Column4Text",
+ "WorldStateScoreButton10Column5Icon",
+ "WorldStateScoreButton10Column5Text",
+ "WorldStateScoreButton10Column6Icon",
+ "WorldStateScoreButton10Column6Text",
+ "WorldStateScoreButton10Column7Icon",
+ "WorldStateScoreButton10Column7Text",
+ "WorldStateScoreButton10Damage",
+ "WorldStateScoreButton10Deaths",
+ "WorldStateScoreButton10FactionLeft",
+ "WorldStateScoreButton10FactionRight",
+ "WorldStateScoreButton10Healing",
+ "WorldStateScoreButton10HonorGained",
+ "WorldStateScoreButton10HonorableKills",
+ "WorldStateScoreButton10KillingBlows",
+ "WorldStateScoreButton10Name",
+ "WorldStateScoreButton10NameText",
+ "WorldStateScoreButton10Team",
+ "WorldStateScoreButton10TeamSkill",
+ "WorldStateScoreButton11",
+ "WorldStateScoreButton11ClassButton",
+ "WorldStateScoreButton11ClassButtonIcon",
+ "WorldStateScoreButton11Column1Icon",
+ "WorldStateScoreButton11Column1Text",
+ "WorldStateScoreButton11Column2Icon",
+ "WorldStateScoreButton11Column2Text",
+ "WorldStateScoreButton11Column3Icon",
+ "WorldStateScoreButton11Column3Text",
+ "WorldStateScoreButton11Column4Icon",
+ "WorldStateScoreButton11Column4Text",
+ "WorldStateScoreButton11Column5Icon",
+ "WorldStateScoreButton11Column5Text",
+ "WorldStateScoreButton11Column6Icon",
+ "WorldStateScoreButton11Column6Text",
+ "WorldStateScoreButton11Column7Icon",
+ "WorldStateScoreButton11Column7Text",
+ "WorldStateScoreButton11Damage",
+ "WorldStateScoreButton11Deaths",
+ "WorldStateScoreButton11FactionLeft",
+ "WorldStateScoreButton11FactionRight",
+ "WorldStateScoreButton11Healing",
+ "WorldStateScoreButton11HonorGained",
+ "WorldStateScoreButton11HonorableKills",
+ "WorldStateScoreButton11KillingBlows",
+ "WorldStateScoreButton11Name",
+ "WorldStateScoreButton11NameText",
+ "WorldStateScoreButton11Team",
+ "WorldStateScoreButton11TeamSkill",
+ "WorldStateScoreButton12",
+ "WorldStateScoreButton12ClassButton",
+ "WorldStateScoreButton12ClassButtonIcon",
+ "WorldStateScoreButton12Column1Icon",
+ "WorldStateScoreButton12Column1Text",
+ "WorldStateScoreButton12Column2Icon",
+ "WorldStateScoreButton12Column2Text",
+ "WorldStateScoreButton12Column3Icon",
+ "WorldStateScoreButton12Column3Text",
+ "WorldStateScoreButton12Column4Icon",
+ "WorldStateScoreButton12Column4Text",
+ "WorldStateScoreButton12Column5Icon",
+ "WorldStateScoreButton12Column5Text",
+ "WorldStateScoreButton12Column6Icon",
+ "WorldStateScoreButton12Column6Text",
+ "WorldStateScoreButton12Column7Icon",
+ "WorldStateScoreButton12Column7Text",
+ "WorldStateScoreButton12Damage",
+ "WorldStateScoreButton12Deaths",
+ "WorldStateScoreButton12FactionLeft",
+ "WorldStateScoreButton12FactionRight",
+ "WorldStateScoreButton12Healing",
+ "WorldStateScoreButton12HonorGained",
+ "WorldStateScoreButton12HonorableKills",
+ "WorldStateScoreButton12KillingBlows",
+ "WorldStateScoreButton12Name",
+ "WorldStateScoreButton12NameText",
+ "WorldStateScoreButton12Team",
+ "WorldStateScoreButton12TeamSkill",
+ "WorldStateScoreButton13",
+ "WorldStateScoreButton13ClassButton",
+ "WorldStateScoreButton13ClassButtonIcon",
+ "WorldStateScoreButton13Column1Icon",
+ "WorldStateScoreButton13Column1Text",
+ "WorldStateScoreButton13Column2Icon",
+ "WorldStateScoreButton13Column2Text",
+ "WorldStateScoreButton13Column3Icon",
+ "WorldStateScoreButton13Column3Text",
+ "WorldStateScoreButton13Column4Icon",
+ "WorldStateScoreButton13Column4Text",
+ "WorldStateScoreButton13Column5Icon",
+ "WorldStateScoreButton13Column5Text",
+ "WorldStateScoreButton13Column6Icon",
+ "WorldStateScoreButton13Column6Text",
+ "WorldStateScoreButton13Column7Icon",
+ "WorldStateScoreButton13Column7Text",
+ "WorldStateScoreButton13Damage",
+ "WorldStateScoreButton13Deaths",
+ "WorldStateScoreButton13FactionLeft",
+ "WorldStateScoreButton13FactionRight",
+ "WorldStateScoreButton13Healing",
+ "WorldStateScoreButton13HonorGained",
+ "WorldStateScoreButton13HonorableKills",
+ "WorldStateScoreButton13KillingBlows",
+ "WorldStateScoreButton13Name",
+ "WorldStateScoreButton13NameText",
+ "WorldStateScoreButton13Team",
+ "WorldStateScoreButton13TeamSkill",
+ "WorldStateScoreButton14",
+ "WorldStateScoreButton14ClassButton",
+ "WorldStateScoreButton14ClassButtonIcon",
+ "WorldStateScoreButton14Column1Icon",
+ "WorldStateScoreButton14Column1Text",
+ "WorldStateScoreButton14Column2Icon",
+ "WorldStateScoreButton14Column2Text",
+ "WorldStateScoreButton14Column3Icon",
+ "WorldStateScoreButton14Column3Text",
+ "WorldStateScoreButton14Column4Icon",
+ "WorldStateScoreButton14Column4Text",
+ "WorldStateScoreButton14Column5Icon",
+ "WorldStateScoreButton14Column5Text",
+ "WorldStateScoreButton14Column6Icon",
+ "WorldStateScoreButton14Column6Text",
+ "WorldStateScoreButton14Column7Icon",
+ "WorldStateScoreButton14Column7Text",
+ "WorldStateScoreButton14Damage",
+ "WorldStateScoreButton14Deaths",
+ "WorldStateScoreButton14FactionLeft",
+ "WorldStateScoreButton14FactionRight",
+ "WorldStateScoreButton14Healing",
+ "WorldStateScoreButton14HonorGained",
+ "WorldStateScoreButton14HonorableKills",
+ "WorldStateScoreButton14KillingBlows",
+ "WorldStateScoreButton14Name",
+ "WorldStateScoreButton14NameText",
+ "WorldStateScoreButton14Team",
+ "WorldStateScoreButton14TeamSkill",
+ "WorldStateScoreButton15",
+ "WorldStateScoreButton15ClassButton",
+ "WorldStateScoreButton15ClassButtonIcon",
+ "WorldStateScoreButton15Column1Icon",
+ "WorldStateScoreButton15Column1Text",
+ "WorldStateScoreButton15Column2Icon",
+ "WorldStateScoreButton15Column2Text",
+ "WorldStateScoreButton15Column3Icon",
+ "WorldStateScoreButton15Column3Text",
+ "WorldStateScoreButton15Column4Icon",
+ "WorldStateScoreButton15Column4Text",
+ "WorldStateScoreButton15Column5Icon",
+ "WorldStateScoreButton15Column5Text",
+ "WorldStateScoreButton15Column6Icon",
+ "WorldStateScoreButton15Column6Text",
+ "WorldStateScoreButton15Column7Icon",
+ "WorldStateScoreButton15Column7Text",
+ "WorldStateScoreButton15Damage",
+ "WorldStateScoreButton15Deaths",
+ "WorldStateScoreButton15FactionLeft",
+ "WorldStateScoreButton15FactionRight",
+ "WorldStateScoreButton15Healing",
+ "WorldStateScoreButton15HonorGained",
+ "WorldStateScoreButton15HonorableKills",
+ "WorldStateScoreButton15KillingBlows",
+ "WorldStateScoreButton15Name",
+ "WorldStateScoreButton15NameText",
+ "WorldStateScoreButton15Team",
+ "WorldStateScoreButton15TeamSkill",
+ "WorldStateScoreButton16",
+ "WorldStateScoreButton16ClassButton",
+ "WorldStateScoreButton16ClassButtonIcon",
+ "WorldStateScoreButton16Column1Icon",
+ "WorldStateScoreButton16Column1Text",
+ "WorldStateScoreButton16Column2Icon",
+ "WorldStateScoreButton16Column2Text",
+ "WorldStateScoreButton16Column3Icon",
+ "WorldStateScoreButton16Column3Text",
+ "WorldStateScoreButton16Column4Icon",
+ "WorldStateScoreButton16Column4Text",
+ "WorldStateScoreButton16Column5Icon",
+ "WorldStateScoreButton16Column5Text",
+ "WorldStateScoreButton16Column6Icon",
+ "WorldStateScoreButton16Column6Text",
+ "WorldStateScoreButton16Column7Icon",
+ "WorldStateScoreButton16Column7Text",
+ "WorldStateScoreButton16Damage",
+ "WorldStateScoreButton16Deaths",
+ "WorldStateScoreButton16FactionLeft",
+ "WorldStateScoreButton16FactionRight",
+ "WorldStateScoreButton16Healing",
+ "WorldStateScoreButton16HonorGained",
+ "WorldStateScoreButton16HonorableKills",
+ "WorldStateScoreButton16KillingBlows",
+ "WorldStateScoreButton16Name",
+ "WorldStateScoreButton16NameText",
+ "WorldStateScoreButton16Team",
+ "WorldStateScoreButton16TeamSkill",
+ "WorldStateScoreButton17",
+ "WorldStateScoreButton17ClassButton",
+ "WorldStateScoreButton17ClassButtonIcon",
+ "WorldStateScoreButton17Column1Icon",
+ "WorldStateScoreButton17Column1Text",
+ "WorldStateScoreButton17Column2Icon",
+ "WorldStateScoreButton17Column2Text",
+ "WorldStateScoreButton17Column3Icon",
+ "WorldStateScoreButton17Column3Text",
+ "WorldStateScoreButton17Column4Icon",
+ "WorldStateScoreButton17Column4Text",
+ "WorldStateScoreButton17Column5Icon",
+ "WorldStateScoreButton17Column5Text",
+ "WorldStateScoreButton17Column6Icon",
+ "WorldStateScoreButton17Column6Text",
+ "WorldStateScoreButton17Column7Icon",
+ "WorldStateScoreButton17Column7Text",
+ "WorldStateScoreButton17Damage",
+ "WorldStateScoreButton17Deaths",
+ "WorldStateScoreButton17FactionLeft",
+ "WorldStateScoreButton17FactionRight",
+ "WorldStateScoreButton17Healing",
+ "WorldStateScoreButton17HonorGained",
+ "WorldStateScoreButton17HonorableKills",
+ "WorldStateScoreButton17KillingBlows",
+ "WorldStateScoreButton17Name",
+ "WorldStateScoreButton17NameText",
+ "WorldStateScoreButton17Team",
+ "WorldStateScoreButton17TeamSkill",
+ "WorldStateScoreButton18",
+ "WorldStateScoreButton18ClassButton",
+ "WorldStateScoreButton18ClassButtonIcon",
+ "WorldStateScoreButton18Column1Icon",
+ "WorldStateScoreButton18Column1Text",
+ "WorldStateScoreButton18Column2Icon",
+ "WorldStateScoreButton18Column2Text",
+ "WorldStateScoreButton18Column3Icon",
+ "WorldStateScoreButton18Column3Text",
+ "WorldStateScoreButton18Column4Icon",
+ "WorldStateScoreButton18Column4Text",
+ "WorldStateScoreButton18Column5Icon",
+ "WorldStateScoreButton18Column5Text",
+ "WorldStateScoreButton18Column6Icon",
+ "WorldStateScoreButton18Column6Text",
+ "WorldStateScoreButton18Column7Icon",
+ "WorldStateScoreButton18Column7Text",
+ "WorldStateScoreButton18Damage",
+ "WorldStateScoreButton18Deaths",
+ "WorldStateScoreButton18FactionLeft",
+ "WorldStateScoreButton18FactionRight",
+ "WorldStateScoreButton18Healing",
+ "WorldStateScoreButton18HonorGained",
+ "WorldStateScoreButton18HonorableKills",
+ "WorldStateScoreButton18KillingBlows",
+ "WorldStateScoreButton18Name",
+ "WorldStateScoreButton18NameText",
+ "WorldStateScoreButton18Team",
+ "WorldStateScoreButton18TeamSkill",
+ "WorldStateScoreButton19",
+ "WorldStateScoreButton19ClassButton",
+ "WorldStateScoreButton19ClassButtonIcon",
+ "WorldStateScoreButton19Column1Icon",
+ "WorldStateScoreButton19Column1Text",
+ "WorldStateScoreButton19Column2Icon",
+ "WorldStateScoreButton19Column2Text",
+ "WorldStateScoreButton19Column3Icon",
+ "WorldStateScoreButton19Column3Text",
+ "WorldStateScoreButton19Column4Icon",
+ "WorldStateScoreButton19Column4Text",
+ "WorldStateScoreButton19Column5Icon",
+ "WorldStateScoreButton19Column5Text",
+ "WorldStateScoreButton19Column6Icon",
+ "WorldStateScoreButton19Column6Text",
+ "WorldStateScoreButton19Column7Icon",
+ "WorldStateScoreButton19Column7Text",
+ "WorldStateScoreButton19Damage",
+ "WorldStateScoreButton19Deaths",
+ "WorldStateScoreButton19FactionLeft",
+ "WorldStateScoreButton19FactionRight",
+ "WorldStateScoreButton19Healing",
+ "WorldStateScoreButton19HonorGained",
+ "WorldStateScoreButton19HonorableKills",
+ "WorldStateScoreButton19KillingBlows",
+ "WorldStateScoreButton19Name",
+ "WorldStateScoreButton19NameText",
+ "WorldStateScoreButton19Team",
+ "WorldStateScoreButton19TeamSkill",
+ "WorldStateScoreButton1ClassButton",
+ "WorldStateScoreButton1ClassButtonIcon",
+ "WorldStateScoreButton1Column1Icon",
+ "WorldStateScoreButton1Column1Text",
+ "WorldStateScoreButton1Column2Icon",
+ "WorldStateScoreButton1Column2Text",
+ "WorldStateScoreButton1Column3Icon",
+ "WorldStateScoreButton1Column3Text",
+ "WorldStateScoreButton1Column4Icon",
+ "WorldStateScoreButton1Column4Text",
+ "WorldStateScoreButton1Column5Icon",
+ "WorldStateScoreButton1Column5Text",
+ "WorldStateScoreButton1Column6Icon",
+ "WorldStateScoreButton1Column6Text",
+ "WorldStateScoreButton1Column7Icon",
+ "WorldStateScoreButton1Column7Text",
+ "WorldStateScoreButton1Damage",
+ "WorldStateScoreButton1Deaths",
+ "WorldStateScoreButton1FactionLeft",
+ "WorldStateScoreButton1FactionRight",
+ "WorldStateScoreButton1Healing",
+ "WorldStateScoreButton1HonorGained",
+ "WorldStateScoreButton1HonorableKills",
+ "WorldStateScoreButton1KillingBlows",
+ "WorldStateScoreButton1Name",
+ "WorldStateScoreButton1NameText",
+ "WorldStateScoreButton1Team",
+ "WorldStateScoreButton1TeamSkill",
+ "WorldStateScoreButton2",
+ "WorldStateScoreButton20",
+ "WorldStateScoreButton20ClassButton",
+ "WorldStateScoreButton20ClassButtonIcon",
+ "WorldStateScoreButton20Column1Icon",
+ "WorldStateScoreButton20Column1Text",
+ "WorldStateScoreButton20Column2Icon",
+ "WorldStateScoreButton20Column2Text",
+ "WorldStateScoreButton20Column3Icon",
+ "WorldStateScoreButton20Column3Text",
+ "WorldStateScoreButton20Column4Icon",
+ "WorldStateScoreButton20Column4Text",
+ "WorldStateScoreButton20Column5Icon",
+ "WorldStateScoreButton20Column5Text",
+ "WorldStateScoreButton20Column6Icon",
+ "WorldStateScoreButton20Column6Text",
+ "WorldStateScoreButton20Column7Icon",
+ "WorldStateScoreButton20Column7Text",
+ "WorldStateScoreButton20Damage",
+ "WorldStateScoreButton20Deaths",
+ "WorldStateScoreButton20FactionLeft",
+ "WorldStateScoreButton20FactionRight",
+ "WorldStateScoreButton20Healing",
+ "WorldStateScoreButton20HonorGained",
+ "WorldStateScoreButton20HonorableKills",
+ "WorldStateScoreButton20KillingBlows",
+ "WorldStateScoreButton20Name",
+ "WorldStateScoreButton20NameText",
+ "WorldStateScoreButton20Team",
+ "WorldStateScoreButton20TeamSkill",
+ "WorldStateScoreButton2ClassButton",
+ "WorldStateScoreButton2ClassButtonIcon",
+ "WorldStateScoreButton2Column1Icon",
+ "WorldStateScoreButton2Column1Text",
+ "WorldStateScoreButton2Column2Icon",
+ "WorldStateScoreButton2Column2Text",
+ "WorldStateScoreButton2Column3Icon",
+ "WorldStateScoreButton2Column3Text",
+ "WorldStateScoreButton2Column4Icon",
+ "WorldStateScoreButton2Column4Text",
+ "WorldStateScoreButton2Column5Icon",
+ "WorldStateScoreButton2Column5Text",
+ "WorldStateScoreButton2Column6Icon",
+ "WorldStateScoreButton2Column6Text",
+ "WorldStateScoreButton2Column7Icon",
+ "WorldStateScoreButton2Column7Text",
+ "WorldStateScoreButton2Damage",
+ "WorldStateScoreButton2Deaths",
+ "WorldStateScoreButton2FactionLeft",
+ "WorldStateScoreButton2FactionRight",
+ "WorldStateScoreButton2Healing",
+ "WorldStateScoreButton2HonorGained",
+ "WorldStateScoreButton2HonorableKills",
+ "WorldStateScoreButton2KillingBlows",
+ "WorldStateScoreButton2Name",
+ "WorldStateScoreButton2NameText",
+ "WorldStateScoreButton2Team",
+ "WorldStateScoreButton2TeamSkill",
+ "WorldStateScoreButton3",
+ "WorldStateScoreButton3ClassButton",
+ "WorldStateScoreButton3ClassButtonIcon",
+ "WorldStateScoreButton3Column1Icon",
+ "WorldStateScoreButton3Column1Text",
+ "WorldStateScoreButton3Column2Icon",
+ "WorldStateScoreButton3Column2Text",
+ "WorldStateScoreButton3Column3Icon",
+ "WorldStateScoreButton3Column3Text",
+ "WorldStateScoreButton3Column4Icon",
+ "WorldStateScoreButton3Column4Text",
+ "WorldStateScoreButton3Column5Icon",
+ "WorldStateScoreButton3Column5Text",
+ "WorldStateScoreButton3Column6Icon",
+ "WorldStateScoreButton3Column6Text",
+ "WorldStateScoreButton3Column7Icon",
+ "WorldStateScoreButton3Column7Text",
+ "WorldStateScoreButton3Damage",
+ "WorldStateScoreButton3Deaths",
+ "WorldStateScoreButton3FactionLeft",
+ "WorldStateScoreButton3FactionRight",
+ "WorldStateScoreButton3Healing",
+ "WorldStateScoreButton3HonorGained",
+ "WorldStateScoreButton3HonorableKills",
+ "WorldStateScoreButton3KillingBlows",
+ "WorldStateScoreButton3Name",
+ "WorldStateScoreButton3NameText",
+ "WorldStateScoreButton3Team",
+ "WorldStateScoreButton3TeamSkill",
+ "WorldStateScoreButton4",
+ "WorldStateScoreButton4ClassButton",
+ "WorldStateScoreButton4ClassButtonIcon",
+ "WorldStateScoreButton4Column1Icon",
+ "WorldStateScoreButton4Column1Text",
+ "WorldStateScoreButton4Column2Icon",
+ "WorldStateScoreButton4Column2Text",
+ "WorldStateScoreButton4Column3Icon",
+ "WorldStateScoreButton4Column3Text",
+ "WorldStateScoreButton4Column4Icon",
+ "WorldStateScoreButton4Column4Text",
+ "WorldStateScoreButton4Column5Icon",
+ "WorldStateScoreButton4Column5Text",
+ "WorldStateScoreButton4Column6Icon",
+ "WorldStateScoreButton4Column6Text",
+ "WorldStateScoreButton4Column7Icon",
+ "WorldStateScoreButton4Column7Text",
+ "WorldStateScoreButton4Damage",
+ "WorldStateScoreButton4Deaths",
+ "WorldStateScoreButton4FactionLeft",
+ "WorldStateScoreButton4FactionRight",
+ "WorldStateScoreButton4Healing",
+ "WorldStateScoreButton4HonorGained",
+ "WorldStateScoreButton4HonorableKills",
+ "WorldStateScoreButton4KillingBlows",
+ "WorldStateScoreButton4Name",
+ "WorldStateScoreButton4NameText",
+ "WorldStateScoreButton4Team",
+ "WorldStateScoreButton4TeamSkill",
+ "WorldStateScoreButton5",
+ "WorldStateScoreButton5ClassButton",
+ "WorldStateScoreButton5ClassButtonIcon",
+ "WorldStateScoreButton5Column1Icon",
+ "WorldStateScoreButton5Column1Text",
+ "WorldStateScoreButton5Column2Icon",
+ "WorldStateScoreButton5Column2Text",
+ "WorldStateScoreButton5Column3Icon",
+ "WorldStateScoreButton5Column3Text",
+ "WorldStateScoreButton5Column4Icon",
+ "WorldStateScoreButton5Column4Text",
+ "WorldStateScoreButton5Column5Icon",
+ "WorldStateScoreButton5Column5Text",
+ "WorldStateScoreButton5Column6Icon",
+ "WorldStateScoreButton5Column6Text",
+ "WorldStateScoreButton5Column7Icon",
+ "WorldStateScoreButton5Column7Text",
+ "WorldStateScoreButton5Damage",
+ "WorldStateScoreButton5Deaths",
+ "WorldStateScoreButton5FactionLeft",
+ "WorldStateScoreButton5FactionRight",
+ "WorldStateScoreButton5Healing",
+ "WorldStateScoreButton5HonorGained",
+ "WorldStateScoreButton5HonorableKills",
+ "WorldStateScoreButton5KillingBlows",
+ "WorldStateScoreButton5Name",
+ "WorldStateScoreButton5NameText",
+ "WorldStateScoreButton5Team",
+ "WorldStateScoreButton5TeamSkill",
+ "WorldStateScoreButton6",
+ "WorldStateScoreButton6ClassButton",
+ "WorldStateScoreButton6ClassButtonIcon",
+ "WorldStateScoreButton6Column1Icon",
+ "WorldStateScoreButton6Column1Text",
+ "WorldStateScoreButton6Column2Icon",
+ "WorldStateScoreButton6Column2Text",
+ "WorldStateScoreButton6Column3Icon",
+ "WorldStateScoreButton6Column3Text",
+ "WorldStateScoreButton6Column4Icon",
+ "WorldStateScoreButton6Column4Text",
+ "WorldStateScoreButton6Column5Icon",
+ "WorldStateScoreButton6Column5Text",
+ "WorldStateScoreButton6Column6Icon",
+ "WorldStateScoreButton6Column6Text",
+ "WorldStateScoreButton6Column7Icon",
+ "WorldStateScoreButton6Column7Text",
+ "WorldStateScoreButton6Damage",
+ "WorldStateScoreButton6Deaths",
+ "WorldStateScoreButton6FactionLeft",
+ "WorldStateScoreButton6FactionRight",
+ "WorldStateScoreButton6Healing",
+ "WorldStateScoreButton6HonorGained",
+ "WorldStateScoreButton6HonorableKills",
+ "WorldStateScoreButton6KillingBlows",
+ "WorldStateScoreButton6Name",
+ "WorldStateScoreButton6NameText",
+ "WorldStateScoreButton6Team",
+ "WorldStateScoreButton6TeamSkill",
+ "WorldStateScoreButton7",
+ "WorldStateScoreButton7ClassButton",
+ "WorldStateScoreButton7ClassButtonIcon",
+ "WorldStateScoreButton7Column1Icon",
+ "WorldStateScoreButton7Column1Text",
+ "WorldStateScoreButton7Column2Icon",
+ "WorldStateScoreButton7Column2Text",
+ "WorldStateScoreButton7Column3Icon",
+ "WorldStateScoreButton7Column3Text",
+ "WorldStateScoreButton7Column4Icon",
+ "WorldStateScoreButton7Column4Text",
+ "WorldStateScoreButton7Column5Icon",
+ "WorldStateScoreButton7Column5Text",
+ "WorldStateScoreButton7Column6Icon",
+ "WorldStateScoreButton7Column6Text",
+ "WorldStateScoreButton7Column7Icon",
+ "WorldStateScoreButton7Column7Text",
+ "WorldStateScoreButton7Damage",
+ "WorldStateScoreButton7Deaths",
+ "WorldStateScoreButton7FactionLeft",
+ "WorldStateScoreButton7FactionRight",
+ "WorldStateScoreButton7Healing",
+ "WorldStateScoreButton7HonorGained",
+ "WorldStateScoreButton7HonorableKills",
+ "WorldStateScoreButton7KillingBlows",
+ "WorldStateScoreButton7Name",
+ "WorldStateScoreButton7NameText",
+ "WorldStateScoreButton7Team",
+ "WorldStateScoreButton7TeamSkill",
+ "WorldStateScoreButton8",
+ "WorldStateScoreButton8ClassButton",
+ "WorldStateScoreButton8ClassButtonIcon",
+ "WorldStateScoreButton8Column1Icon",
+ "WorldStateScoreButton8Column1Text",
+ "WorldStateScoreButton8Column2Icon",
+ "WorldStateScoreButton8Column2Text",
+ "WorldStateScoreButton8Column3Icon",
+ "WorldStateScoreButton8Column3Text",
+ "WorldStateScoreButton8Column4Icon",
+ "WorldStateScoreButton8Column4Text",
+ "WorldStateScoreButton8Column5Icon",
+ "WorldStateScoreButton8Column5Text",
+ "WorldStateScoreButton8Column6Icon",
+ "WorldStateScoreButton8Column6Text",
+ "WorldStateScoreButton8Column7Icon",
+ "WorldStateScoreButton8Column7Text",
+ "WorldStateScoreButton8Damage",
+ "WorldStateScoreButton8Deaths",
+ "WorldStateScoreButton8FactionLeft",
+ "WorldStateScoreButton8FactionRight",
+ "WorldStateScoreButton8Healing",
+ "WorldStateScoreButton8HonorGained",
+ "WorldStateScoreButton8HonorableKills",
+ "WorldStateScoreButton8KillingBlows",
+ "WorldStateScoreButton8Name",
+ "WorldStateScoreButton8NameText",
+ "WorldStateScoreButton8Team",
+ "WorldStateScoreButton8TeamSkill",
+ "WorldStateScoreButton9",
+ "WorldStateScoreButton9ClassButton",
+ "WorldStateScoreButton9ClassButtonIcon",
+ "WorldStateScoreButton9Column1Icon",
+ "WorldStateScoreButton9Column1Text",
+ "WorldStateScoreButton9Column2Icon",
+ "WorldStateScoreButton9Column2Text",
+ "WorldStateScoreButton9Column3Icon",
+ "WorldStateScoreButton9Column3Text",
+ "WorldStateScoreButton9Column4Icon",
+ "WorldStateScoreButton9Column4Text",
+ "WorldStateScoreButton9Column5Icon",
+ "WorldStateScoreButton9Column5Text",
+ "WorldStateScoreButton9Column6Icon",
+ "WorldStateScoreButton9Column6Text",
+ "WorldStateScoreButton9Column7Icon",
+ "WorldStateScoreButton9Column7Text",
+ "WorldStateScoreButton9Damage",
+ "WorldStateScoreButton9Deaths",
+ "WorldStateScoreButton9FactionLeft",
+ "WorldStateScoreButton9FactionRight",
+ "WorldStateScoreButton9Healing",
+ "WorldStateScoreButton9HonorGained",
+ "WorldStateScoreButton9HonorableKills",
+ "WorldStateScoreButton9KillingBlows",
+ "WorldStateScoreButton9Name",
+ "WorldStateScoreButton9NameText",
+ "WorldStateScoreButton9Team",
+ "WorldStateScoreButton9TeamSkill",
+ "WorldStateScoreColumn1",
+ "WorldStateScoreColumn1Text",
+ "WorldStateScoreColumn2",
+ "WorldStateScoreColumn2Text",
+ "WorldStateScoreColumn3",
+ "WorldStateScoreColumn3Text",
+ "WorldStateScoreColumn4",
+ "WorldStateScoreColumn4Text",
+ "WorldStateScoreColumn5",
+ "WorldStateScoreColumn5Text",
+ "WorldStateScoreColumn6",
+ "WorldStateScoreColumn6Text",
+ "WorldStateScoreColumn7",
+ "WorldStateScoreColumn7Text",
+ "WorldStateScoreFrame",
+ "WorldStateScoreFrameBottom",
+ "WorldStateScoreFrameBottomLeft",
+ "WorldStateScoreFrameBottomRight",
+ "WorldStateScoreFrameClass",
+ "WorldStateScoreFrameClassText",
+ "WorldStateScoreFrameCloseButton",
+ "WorldStateScoreFrameDamageDone",
+ "WorldStateScoreFrameDamageDoneText",
+ "WorldStateScoreFrameDeaths",
+ "WorldStateScoreFrameDeathsText",
+ "WorldStateScoreFrameHK",
+ "WorldStateScoreFrameHKText",
+ "WorldStateScoreFrameHealingDone",
+ "WorldStateScoreFrameHealingDoneText",
+ "WorldStateScoreFrameHonorGained",
+ "WorldStateScoreFrameHonorGainedText",
+ "WorldStateScoreFrameKB",
+ "WorldStateScoreFrameKBText",
+ "WorldStateScoreFrameLabel",
+ "WorldStateScoreFrameLeaveButton",
+ "WorldStateScoreFrameLeaveButtonText",
+ "WorldStateScoreFrameName",
+ "WorldStateScoreFrameNameText",
+ "WorldStateScoreFrameTab1",
+ "WorldStateScoreFrameTab1HighlightTexture",
+ "WorldStateScoreFrameTab1Left",
+ "WorldStateScoreFrameTab1LeftDisabled",
+ "WorldStateScoreFrameTab1Middle",
+ "WorldStateScoreFrameTab1MiddleDisabled",
+ "WorldStateScoreFrameTab1Right",
+ "WorldStateScoreFrameTab1RightDisabled",
+ "WorldStateScoreFrameTab1Text",
+ "WorldStateScoreFrameTab2",
+ "WorldStateScoreFrameTab2HighlightTexture",
+ "WorldStateScoreFrameTab2Left",
+ "WorldStateScoreFrameTab2LeftDisabled",
+ "WorldStateScoreFrameTab2Middle",
+ "WorldStateScoreFrameTab2MiddleDisabled",
+ "WorldStateScoreFrameTab2Right",
+ "WorldStateScoreFrameTab2RightDisabled",
+ "WorldStateScoreFrameTab2Text",
+ "WorldStateScoreFrameTab3",
+ "WorldStateScoreFrameTab3HighlightTexture",
+ "WorldStateScoreFrameTab3Left",
+ "WorldStateScoreFrameTab3LeftDisabled",
+ "WorldStateScoreFrameTab3Middle",
+ "WorldStateScoreFrameTab3MiddleDisabled",
+ "WorldStateScoreFrameTab3Right",
+ "WorldStateScoreFrameTab3RightDisabled",
+ "WorldStateScoreFrameTab3Text",
+ "WorldStateScoreFrameTab_OnClick",
+ "WorldStateScoreFrameTeam",
+ "WorldStateScoreFrameTeamSkill",
+ "WorldStateScoreFrameTeamSkillText",
+ "WorldStateScoreFrameTeamText",
+ "WorldStateScoreFrameTimer",
+ "WorldStateScoreFrameTimerLabel",
+ "WorldStateScoreFrameTop",
+ "WorldStateScoreFrameTopBackground",
+ "WorldStateScoreFrameTopLeft",
+ "WorldStateScoreFrameTopRight",
+ "WorldStateScoreFrame_OnLoad",
+ "WorldStateScoreFrame_Resize",
+ "WorldStateScoreFrame_Update",
+ "WorldStateScorePlayerCount",
+ "WorldStateScoreScrollFrame",
+ "WorldStateScoreScrollFrameScrollBar",
+ "WorldStateScoreScrollFrameScrollBarScrollDownButton",
+ "WorldStateScoreScrollFrameScrollBarScrollUpButton",
+ "WorldStateScoreScrollFrameScrollBarThumbTexture",
+ "WorldStateScoreScrollFrameScrollBarTop",
+ "WorldStateScoreScrollFrameScrollChildFrame",
+ "WorldStateScoreWinnerFrame",
+ "WorldStateScoreWinnerFrameLeft",
+ "WorldStateScoreWinnerFrameRight",
+ "WorldStateScoreWinnerFrameText",
+ "YELLOW_FONT_COLOR",
+ "ZoneTextFont",
+ "ZoneTextFrame",
+ "ZoneTextString",
+ "ZoneText_OnEvent",
+ "ZoneText_OnLoad",
+ "ZoomOut",
+ "_ERRORMESSAGE",
+ "_G",
+ "_GetPlayerDifficultyMenuOptions",
+ "abs",
+ "achievementFunctions",
+ "acos",
+ "asin",
+ "assert",
+ "atan",
+ "atan2",
+ "aura_env",
+ "bit",
+ "bit.arshift",
+ "bit.band",
+ "bit.bnot",
+ "bit.bor",
+ "bit.bxor",
+ "bit.lshift",
+ "bit.mod",
+ "bit.rshift",
+ "ceil",
+ "collectgarbage",
+ "coroutine.create",
+ "coroutine.resume",
+ "coroutine.running",
+ "coroutine.status",
+ "coroutine.wrap",
+ "coroutine.yield",
+ "cos",
+ "date",
+ "debugbreak",
+ "debugdump",
+ "debughook",
+ "debuginfo",
+ "debugload",
+ "debuglocals",
+ "debugprint",
+ "debugprofilestart",
+ "debugprofilestop",
+ "debugstack",
+ "debugtimestamp",
+ "deg",
+ "difftime",
+ "error",
+ "exp",
+ "floor",
+ "forceinsecure",
+ "foreach",
+ "foreachi",
+ "format",
+ "frexp",
+ "gcinfo",
+ "geterrorhandler",
+ "getfenv",
+ "getglobal",
+ "getmetatable",
+ "getn",
+ "getprinthandler",
+ "gmatch",
+ "gsub",
+ "hash_ChatTypeInfoList",
+ "hash_EmoteTokenList",
+ "hash_SlashCmdList",
+ "hooksecurefunc",
+ "ipairs",
+ "issecure",
+ "issecurevariable",
+ "ldexp",
+ "loadstring",
+ "log",
+ "log10",
+ "math.abs",
+ "math.acos",
+ "math.asin",
+ "math.atan",
+ "math.atan2",
+ "math.ceil",
+ "math.cos",
+ "math.cosh",
+ "math.deg",
+ "math.exp",
+ "math.floor",
+ "math.fmod",
+ "math.frexp",
+ "math.ldexp",
+ "math.log",
+ "math.log10",
+ "math.max",
+ "math.min",
+ "math.modf",
+ "math.pow",
+ "math.rad",
+ "math.random",
+ "math.sin",
+ "math.sinh",
+ "math.sqrt",
+ "math.tan",
+ "math.tanh",
+ "max",
+ "message",
+ "min",
+ "mod",
+ "newproxy",
+ "next",
+ "nop",
+ "pairs",
+ "pcall",
+ "poiWorldMapQuestScrollChildFrame1_0",
+ "poiWorldMapQuestScrollChildFrame1_0IconNumber",
+ "poiWorldMapQuestScrollChildFrame1_0IconTurnin",
+ "print",
+ "rad",
+ "random",
+ "rawequal",
+ "rawget",
+ "rawset",
+ "rtable.concat",
+ "rtable.insert",
+ "rtable.ipairs",
+ "rtable.maxn",
+ "rtable.newtable",
+ "rtable.next",
+ "rtable.pairs",
+ "rtable.remove",
+ "rtable.sort",
+ "rtable.type",
+ "rtable.unpack",
+ "rtable.wipe",
+ "runeMapping",
+ "scrub",
+ "securecall",
+ "select",
+ "seterrorhandler",
+ "setfenv",
+ "setglobal",
+ "setmetatable",
+ "setprinthandler",
+ "shineGet",
+ "sin",
+ "sort",
+ "sqrt",
+ "strbyte",
+ "strchar",
+ "strconcat",
+ "strfind",
+ "string.byte",
+ "string.char",
+ "string.dump",
+ "string.find",
+ "string.format",
+ "string.gfind",
+ "string.gmatch",
+ "string.gsub",
+ "string.join",
+ "string.len",
+ "string.lower",
+ "string.match",
+ "string.rep",
+ "string.replace",
+ "string.reverse",
+ "string.rtgsub",
+ "string.split",
+ "string.sub",
+ "string.trim",
+ "string.upper",
+ "strjoin",
+ "strlen",
+ "strlenutf8",
+ "strlower",
+ "strmatch",
+ "strrep",
+ "strreplace",
+ "strrev",
+ "strsplit",
+ "strsub",
+ "strtrim",
+ "strupper",
+ "tContains",
+ "tDeleteItem",
+ "tIndexOf",
+ "tInvert",
+ "table.concat",
+ "table.foreach",
+ "table.foreachi",
+ "table.getn",
+ "table.insert",
+ "table.maxn",
+ "table.remove",
+ "table.removemulti",
+ "table.setn",
+ "table.sort",
+ "table.wipe",
+ "tan",
+ "this",
+ "time",
+ "tinsert",
+ "tomtest",
+ "tonumber",
+ "tostring",
+ "tostringall",
+ "tremove",
+ "type",
+ "unpack",
+ "updateContainerFrameAnchors",
+ "uvarInfo",
+ "wipe",
+ "xpcall",
+}
\ No newline at end of file
diff --git a/CITATION.cff b/CITATION.cff
new file mode 100644
index 0000000..c0d40fc
--- /dev/null
+++ b/CITATION.cff
@@ -0,0 +1,10 @@
+cff-version: 1.2.0
+message: "If you use this addon, please cite it as below."
+authors:
+ - given-names: "Kader"
+ family-names: "Bouyakoub"
+ orcid: "https://orcid.org/0000-0002-1184-8061"
+title: "Skada BfA (Revisited)"
+version: 1.8.78
+date-released: 2022-03-01
+url: "https://github.com/bkader/Skada-BfA"
\ No newline at end of file
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..fc2e125
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 Kader Bouyakoub
+
+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/README.md b/README.md
new file mode 100644
index 0000000..144355f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,76 @@
+# Skada for Legion `7.3.5` (_Revisited - v1.8.86_)
+
+![Discord](https://img.shields.io/discord/795698054371868743?label=discord)
+![GitHub last commit](https://img.shields.io/github/last-commit/bkader/Skada-Legion)
+![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/bkader/Skada-Legion?label=version)
+
+Skada is a modular damage meter with various viewing modes, segmented fights and customizable windows. It aims to be highly efficient with memory and CPU.
+
+
![Skada Damage Meter](https://github.com/bkader/Skada-Legion/assets/4732702/cc1e3f3c-a4f1-4604-a297-0fbdb83ba631)
+
+_**FOR PRIVATE SERVERS**_:
+* _[Wrath of the Lich King](https://github.com/bkader/Skada-WoTLK)_
+* _[Cataclysm](https://github.com/bkader/Skada-Cata)_
+* _[Mists of Pandaria](https://github.com/bkader/Skada-MoP)_
+* _[Warlords of Draenor](https://github.com/bkader/Skada-WoD)_
+
+_**FOR OFFICIAL SERVERS**_:
+* _[Retail/Classic Wrath](https://github.com/bkader/Skada-Damage-Meter)_
+
+> ***Is this a backported version?***
+> **No**! This is total **rewrite** of the original addon, it all started from version `r301` for `3.3.5`and built up to the current state.
+
+## IMPORTANT: How to install
+
+1. If you used the default on **Skada** before, please make sure to delete all its files from `Interface\AddOns` folder as well as all its _SavedVariables_ from `WTF` folder (_just delete all `Skada.lua` and `Skada.lua.bak` for this folder. Use the search box for quick delete_). If you are new, skip this step.
+2. [Download the package](https://github.com/bkader/Skada-Legion/archive/refs/heads/main.zip).
+3. Open the Zip package inside which you will find a single folder named `Skada-Legion-main`.
+4. Extract or drag and drop the unique folder `Skada` into your `Interface\AddOns` folder.
+5. If you want to use `SkadaImprovement` and/or `SkadaStorage` modules, drop them there as well.
+
+## Show Love & Support
+
+Though it's not required, **PayPal**/**Paysera** donations are most welcome at **bkader[at]mail.com**.
+
+## Special Credits
+
+* Original author: **Zarnivoop**
+* Localization: **meatgaga** (CN), **Ícar** & **Septimun** (ES), **Kader** (FR), **NGL** (RU)
+* Direct and indirect contributors: **Abel**, **Iqui**, **Jeb**, **Shoggoth**, **Havi** & **Ganrod**, **WotLK Community**.
+* The man behind the wheel: **[Nomadra](https://github.com/ridepad)**
+
+## Early Access
+
+If like some you cannot wait for updates to be pushed and releases to be published, visit [this link](https://mega.nz/folder/3gZFXa5T#nO6nqnv6gj1IYpCu4CJWaQ) and download the version (_expansion_) you want to use. Every time a progress is done and a milestone is reached, packages are updated, so you might want to check the date files were updated so you don't download the same package again (_compare date added to the in-game Skada date_).
+_Note that **3.4.x.zip** is for both **Retail** and **Classic Wrath**._
+
+## OTHER ADDONS (Private Servers)
+
+* **!ElvinCDs**: [https://github.com/bkader/ElvinCDs](https://github.com/bkader/ElvinCDs)
+* **!KTracker**: [https://github.com/bkader/KTracker](https://github.com/bkader/KTracker)
+* **BigWigs**: [https://github.com/bkader/BigWigs-WoTLK](https://github.com/bkader/BigWigs-WoTLK)
+* **BloodyMask**: [https://github.com/bkader/BloodyMask](https://github.com/bkader/BloodyMask)
+* **ButtonFacade**: [https://github.com/bkader/ButtonFacade](https://github.com/bkader/ButtonFacade)
+* **Comix**: [https://github.com/bkader/Comix-WoTLK](https://github.com/bkader/Comix-WoTLK)
+* **Crosshairs**: [https://github.com/bkader/Crosshairs-WotLK](https://github.com/bkader/Crosshairs-WotLK)
+* **Dominos**: [https://github.com/bkader/Dominos](https://github.com/bkader/Dominos)
+* **EclipseBar**: [https://github.com/bkader/EclipseBar-WotLK](https://github.com/bkader/EclipseBar-WotLK)
+* **FixGroups**: [https://github.com/bkader/FixGroups-WoTLK](https://github.com/bkader/FixGroups-WoTLK)
+* **GarbageProtector**: [https://github.com/bkader/GarbageProtector](https://github.com/bkader/GarbageProtector)
+* **Grid2**: [https://github.com/bkader/Grid2-WoTLK](https://github.com/bkader/Grid2-WoTLK)
+* **HalionHelper**: [https://github.com/bkader/HalionHelper-WoTLK](https://github.com/bkader/HalionHelper-WoTLK)
+* **Hermes**: [https://github.com/bkader/Hermes-WotLK](https://github.com/bkader/Hermes-WotLK)
+* **KPack**: [https://github.com/bkader/KPack](https://github.com/bkader/KPack)
+* **KRaidTools**: [https://github.com/bkader/KRT](https://github.com/bkader/KRT)
+* **KRaidUtilities**: [https://github.com/bkader/KRU-WoTLK](https://github.com/bkader/KRU-WoTLK)
+* **KuiNameplates**: [https://github.com/bkader/KuiNameplates-WoTLK](https://github.com/bkader/KuiNameplates-WoTLK)
+* **Masque**: [https://github.com/bkader/Masque-WoTLK](https://github.com/bkader/Masque-WoTLK)
+* **NameplateSCT**: [https://github.com/bkader/NameplateSCT_WoTLK](https://github.com/bkader/NameplateSCT_WoTLK)
+* **PlateBuffs**: [https://github.com/bkader/PlateBuffs_WoTLK](https://github.com/bkader/PlateBuffs_WoTLK)
+* **RUF**: [https://github.com/bkader/RUF-WoTLK](https://github.com/bkader/RUF-WoTLK)
+* **Raven**: [https://github.com/bkader/Raven-WotLK](https://github.com/bkader/Raven-WotLK)
+* **SharedMedia**: [https://github.com/bkader/SharedMedia](https://github.com/bkader/SharedMedia)
+* **Talented**: [https://github.com/bkader/Talented_WoTLK](https://github.com/bkader/Talented_WoTLK)
+* **TellMeWhen**: [https://github.com/bkader/TellMeWhen_3.3.5](https://github.com/bkader/TellMeWhen_3.3.5)
+* **TheClassicRace**: [https://github.com/bkader/TheClassicRace-WotLK](https://github.com/bkader/TheClassicRace-WotLK)
+* **TidyPlates & ThreatPlates**: [https://github.com/bkader/TidyPlates_WoTLK](https://github.com/bkader/TidyPlates_WoTLK)
\ No newline at end of file
diff --git a/Skada/Bindings.xml b/Skada/Bindings.xml
new file mode 100644
index 0000000..0292de7
--- /dev/null
+++ b/Skada/Bindings.xml
@@ -0,0 +1,16 @@
+
+ Skada:ToggleWindow()
+ Skada:ShowHide()
+ Skada:ShowPopup()
+ Skada:NewSegment()
+ Skada:NewPhase()
+
+ if Skada.current and Skada.current.stopped then
+ Skada:ResumeSegment()
+ elseif Skada.current then
+ Skada:StopSegment()
+ end
+
+ Skada:Scroll(true)
+ Skada:Scroll(false)
+
diff --git a/Skada/Core/Core.lua b/Skada/Core/Core.lua
new file mode 100644
index 0000000..561b4d3
--- /dev/null
+++ b/Skada/Core/Core.lua
@@ -0,0 +1,3174 @@
+local folder, ns = ...
+local Skada = LibStub("AceAddon-3.0"):NewAddon(ns, folder, "AceEvent-3.0", "AceTimer-3.0", "AceBucket-3.0", "AceHook-3.0", "AceConsole-3.0", "AceComm-3.0", "LibCompat-1.0-Skada")
+_G[folder] = ns
+
+local ACD = LibStub("AceConfigDialog-3.0")
+local ACR = LibStub("AceConfigRegistry-3.0")
+local DBI = LibStub("LibDBIcon-1.0", true)
+
+-- cache frequently used globals
+local _G = _G
+local next, pairs, type, tonumber, tostring, min, max = next, pairs, type, tonumber, tostring, math.min, math.max
+local strmatch, format, gsub, strlower, strfind = strmatch, string.format, string.gsub, string.lower, string.find
+local Private, GetCreatureId = ns.Private, Skada.GetCreatureId
+local tsort, tremove, wipe, setmetatable = table.sort, Private.tremove, wipe, setmetatable
+local TempTable, new, del, copy = Private.TempTable, Private.newTable, Private.delTable, Private.tCopy
+local InCombatLockdown, IsGroupInCombat, IsGroupDead = InCombatLockdown, Skada.IsGroupInCombat, Skada.IsGroupDead
+local UnitGUID, GameTooltip, ReloadUI = UnitGUID, GameTooltip, ReloadUI
+local IsShiftKeyDown, IsControlKeyDown = IsShiftKeyDown, IsControlKeyDown
+local SecondsToTime, time, GetTime = SecondsToTime, time, GetTime
+local IsInGroup, IsInRaid, IsInPvP = IsInGroup, IsInRaid, Skada.IsInPvP
+local CheckDuplicate = Private.CheckDuplicate
+local L, callbacks, O = Skada.Locale, Skada.callbacks, Skada.options.args
+local P, G, _
+
+local LDB = LibStub("LibDataBroker-1.1")
+local dataobj = LDB:NewDataObject(folder, {
+ label = folder,
+ type = "data source",
+ icon = Skada.logo,
+ text = "n/a"
+})
+
+-- Keybindings
+BINDING_HEADER_SKADA = folder
+BINDING_NAME_SKADA_TOGGLE = L["Toggle Windows"]
+BINDING_NAME_SKADA_SHOWHIDE = L["Show/Hide Windows"]
+BINDING_NAME_SKADA_RESET = L["Reset"]
+BINDING_NAME_SKADA_NEWSEGMENT = L["New Segment"]
+BINDING_NAME_SKADA_NEWPHASE = L["New Phase"]
+BINDING_NAME_SKADA_STOP = L["Stop"]
+
+-- things we need
+local userGUID = Skada.userGUID
+local userName = Skada.userName
+local userClass = Skada.userClass
+
+-- available display types
+local displays = ns.displays or {}
+ns.displays = displays
+
+-- displays that show totals
+local display_with_totals = ns.display_with_totals or {}
+ns.display_with_totals = display_with_totals
+
+-- update & tick timers
+local update_timer, tick_timer, toggle_timer, version_timer
+local roster_timer, bossdefeat_timer
+local check_version, convert_version
+local check_for_join_and_leave
+
+-- list of players, pets and vehicles
+local guidToUnit = Private.guidToUnit
+local guidToClass = Private.guidToClass
+local guidToName = Private.guidToName
+local guidToOwner = Private.guidToOwner
+local vehicles = {}
+
+-- targets table used when detecting boss fights.
+local _targets = nil
+
+-- list of feeds & selected feed
+local feeds, selected_feed = {}, nil
+
+-- window prototype
+local Window = ns.Window
+
+-- lists of modules and windows
+local windows = ns.windows or {}
+ns.windows = windows
+local modes = ns.modes or {}
+ns.modes = modes
+
+-- flags for party, instance and ovo
+local was_in_party = nil
+
+-- prototypes and references
+local setPrototype = ns.setPrototype
+local classcolors = ns.classcolors
+
+-------------------------------------------------------------------------------
+-- local functions.
+
+local StartWatching = Private.StartWatching
+local StopWatching = Private.StopWatching
+local set_active, add_window_options
+local set_window_child, set_window_mode_title
+local restore_view, restore_window_view
+local check_group, combat_end, combat_start
+
+-- verifies a set
+local function verify_set(mode, set)
+ if not mode or not set then return end
+
+ if mode.AddSetAttributes then
+ mode:AddSetAttributes(set)
+ end
+
+ if mode.AddPlayerAttributes or mode.AddEnemyAttributes then
+ local actors = set.actors
+ if not actors then return end
+ for _, actor in pairs(actors) do
+ if actor.enemy and mode.AddEnemyAttributes then
+ mode:AddEnemyAttributes(actor, set)
+ elseif not actor.enemy and mode.mode.AddPlayerAttributes then
+ mode:AddPlayerAttributes(actor, set)
+ end
+ end
+ end
+end
+
+local create_set
+local delete_set
+do
+ -- recycle sets
+ local recycle_bin = {}
+
+ -- cleans a set before reusing or deleting
+ local clear = Private.clearTable
+ local function clean_set(set)
+ if set then
+ local actors = set.actors
+ wipe(set)
+ setmetatable(set, nil)
+ if actors then
+ for k, v in pairs(actors) do
+ actors[k] = clear(v)
+ setmetatable(v, nil)
+ end
+ set.actors = actors
+ end
+ end
+ return set
+ end
+
+ -- creates a new set
+ -- @param setname the segment name
+ -- @param set the set to override/reuse
+ function create_set(setname, set)
+ if set then
+ set = clean_set(set)
+ else
+ set = next(recycle_bin)
+ if set then
+ recycle_bin[set] = nil
+ else
+ set = {}
+ end
+ end
+
+ -- add stuff.
+ set.name = setname
+ set.starttime = time()
+ set.time = 0
+ set.actors = wipe(set.actors or {})
+
+ -- last alterations before returning.
+ for i = 1, #modes do
+ verify_set(modes[i], set)
+ end
+
+ callbacks:Fire("Skada_SetCreated", set)
+ return setPrototype:Bind(set)
+ end
+
+ -- deletes a set
+ function delete_set(set)
+ if set then
+ recycle_bin[clean_set(set)] = true
+ end
+ return nil
+ end
+end
+
+-- prepares the given set name.
+local function check_set_name(set)
+ local setname = set.mobname or L["Unknown"]
+
+ if set.phase then
+ setname = format(L["%s - Phase %s"], setname, set.phase)
+ set.phase = nil
+ end
+
+ if P.setnumber then
+ -- remove old data
+ if Skada.sets.version then
+ Skada.sets.sets, Skada.sets.version = nil, nil
+ end
+ setname = CheckDuplicate(setname, Skada.sets, "name")
+ end
+
+ set.name = setname
+ return setname -- return reference.
+end
+
+-- process the given set and stores into sv.
+local tinsert = table.insert
+local function process_set(set, curtime, mobname)
+ if not set then
+ set = delete_set(set) -- just in case
+ return
+ end
+
+ curtime = curtime or time()
+
+ -- remove any additional keys.
+ set.started, set.stopped = nil, nil
+ set.gotboss = set.gotboss or nil -- remove false
+
+ if not P.onlykeepbosses or set.gotboss then
+ set.mobname = mobname or set.mobname -- override name
+ if set.mobname ~= nil and (P.inCombat or curtime - set.starttime >= (P.minsetlength or 5)) then
+ set.endtime = set.endtime and set.endtime > set.starttime and set.endtime or curtime
+ set.time = max(1, set.endtime - set.starttime)
+ set.name = check_set_name(set)
+
+ -- always keep boss fights
+ if set.gotboss and P.alwayskeepbosses then
+ set.keep = true
+ end
+
+ for i = 1, #modes do
+ local mode = modes[i]
+ if mode and mode.SetComplete then
+ mode:SetComplete(set)
+ end
+ end
+
+ -- do you want to do something?
+ callbacks:Fire("Skada_SetComplete", set, curtime)
+
+ tinsert(Skada.sets, 1, set)
+ Skada:Debug(format("Segment Saved: \124cffffbb00%s\124r", set.name))
+ else
+ set = delete_set(set)
+ end
+ end
+
+ -- the segment didn't have the chance to get saved
+ if set and set.endtime == nil then
+ set.endtime = curtime
+ set.time = max(1, set.endtime - set.starttime)
+ end
+end
+
+local function clean_sets(force)
+ local numsets = 0
+ local maxsets = 0
+ local sets = Skada.sets
+
+ for i = 1, #sets do
+ local set = sets[i]
+ if set then
+ maxsets = maxsets + 1
+ if not set.keep then
+ numsets = numsets + 1
+ end
+ end
+ end
+
+ -- we trim segments without touching persistent ones.
+ for i = #sets, 1, -1 do
+ if (force or numsets > P.setstokeep) and not sets[i].keep then
+ delete_set(tremove(sets, i))
+ numsets = numsets - 1
+ maxsets = maxsets - 1
+ end
+ end
+
+ -- because some players may enable the "always keep boss fights" option,
+ -- the amount of segments kept can grow big, so we make sure to keep
+ -- the player reasonable, otherwise they'll encounter memory issues.
+ while maxsets > Skada.maxsets and sets[maxsets] do
+ delete_set(tremove(Skada.sets, maxsets))
+ maxsets = maxsets - 1
+ end
+end
+
+-- finds a mode
+local function find_mode(name)
+ for i = 1, #modes do
+ local mode = modes[i]
+ if mode and (mode.moduleName == name or mode.localeName == name) then
+ return mode
+ end
+ end
+end
+
+-- returns a formmatted set time
+local function formatted_set_time(set)
+ return Skada:FormatTime(Skada:GetSetTime(set))
+end
+
+local function summon_pet(petGUID, ownerGUID)
+ local guidOrClass = guidToClass[ownerGUID]
+ ownerGUID = guidToClass[guidOrClass] and guidOrClass or ownerGUID
+ guidToOwner[petGUID] = ownerGUID
+end
+
+local dismiss_pet
+do
+ local dismiss_timers = nil
+ local function dismiss_handler(guid)
+ guidToOwner[guid] = nil
+ guidToClass[guid] = nil
+
+ if dismiss_timers and dismiss_timers[guid] then
+ Skada:CancelTimer(dismiss_timers[guid], true)
+ dismiss_timers[guid] = nil
+
+ if not next(dismiss_timers) then
+ dismiss_timers[guid] = del(dismiss_timers[guid])
+ end
+ end
+ end
+ function dismiss_pet(guid, delay)
+ if guid and guidToClass[guid] and not guidToName[guid] then
+ dismiss_timers = dismiss_timers or new()
+ dismiss_timers[guid] = Skada:ScheduleTimer(dismiss_handler, delay or 0.1, guid)
+ end
+ end
+end
+
+local function debug_pets()
+ check_group()
+ Skada:Print(L["Pets"])
+ for guid, guidOrClass in pairs(guidToClass) do
+ if guidToName[guidOrClass] then
+ Skada:Printf("%s > %s", guid, classcolors.format(guidToClass[guidOrClass], guidToName[guidOrClass]))
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- Windo functions
+
+do
+ local copywindow = nil
+
+ -- add window options
+ function add_window_options(self)
+ local templist = {}
+ local db = self.db
+
+ local opt = {
+ type = "group",
+ name = function() return db.name end,
+ desc = function() return format(L["Options for %s."], db.name) end,
+ get = function(i) return db[i[#i]] end,
+ set = function(i, val)
+ db[i[#i]] = val
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ name = {
+ type = "input",
+ name = L["Rename Window"],
+ desc = L["Enter the name for the window."],
+ order = 1,
+ width = "double",
+ set = function(_, val)
+ val = val:trim()
+ if val ~= db.name and val ~= "" then
+ local oldname = db.name
+ db.name = CheckDuplicate(val, windows, "name")
+ if db.name ~= oldname then
+ -- move options table
+ O.windows.args[db.name] = O.windows.args[oldname]
+ O.windows.args[oldname] = nil
+
+ -- rename window frame
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.name == oldname then
+ win.name = db.name
+ break -- stop
+ end
+ end
+ end
+
+ Skada:ApplySettings(db.name)
+ end
+ end
+ },
+ display = {
+ type = "select",
+ name = L["Display System"],
+ desc = L["Choose the system to be used for displaying data in this window."],
+ order = 2,
+ width = "double",
+ values = function()
+ local list = wipe(templist)
+ for name, display in pairs(displays) do
+ list[name] = display.localeName
+ end
+ return list
+ end,
+ set = function(_, display)
+ db.display = display
+ Private.ReloadSettings()
+ end
+ },
+ separator1 = {
+ type = "description",
+ name = " ",
+ order = 9,
+ width = "full"
+ },
+ copywin = {
+ type = "select",
+ name = L["Copy Settings"],
+ desc = L["Choose the window from which you want to copy the settings."],
+ order = 10,
+ hidden = true,
+ values = function()
+ local list = {[""] = L["None"]}
+ for i = 1, #windows do
+ local _db = windows[i] and windows[i].db
+ if _db and _db.name ~= db.name and _db.display == db.display then
+ list[_db.name] = _db.name
+ end
+ end
+ return list
+ end,
+ get = function() return copywindow or "" end,
+ set = function(_, val) copywindow = (val == "") and nil or val end
+ },
+ copyexec = {
+ type = "execute",
+ name = L["Copy Settings"],
+ order = 11,
+ hidden = true,
+ disabled = function()
+ return (copywindow == nil)
+ end,
+ func = function()
+ wipe(templist)
+ if copywindow then
+ for i = 1, #windows do
+ local _db = windows[i] and windows[i].db
+ if _db and _db.name == copywindow and _db.display == db.display then
+ copy(templist, _db, "name", "sticked", "x", "y", "point", "snapped", "child", "childmode")
+ break
+ end
+ end
+ end
+ for k, v in pairs(templist) do
+ db[k] = v
+ end
+ wipe(templist)
+ Skada:ApplySettings(db.name)
+ copywindow = nil
+ end
+ },
+ separator2 = {
+ type = "description",
+ name = " ",
+ order = 98,
+ hidden = true,
+ width = "full"
+ },
+ delete = {
+ type = "execute",
+ name = L["Delete Window"],
+ desc = L["Choose the window to be deleted."],
+ order = 998,
+ width = "double",
+ confirm = function() return L["Are you sure you want to delete this window?"] end,
+ func = function() Skada:DeleteWindow(db.name, true) end
+ },
+ testmode = {
+ type = "execute",
+ name = L["Test Mode"],
+ desc = L["Creates fake data to help you configure your windows."],
+ order = 999,
+ hidden = true,
+ disabled = function() return (InCombatLockdown() or IsGroupInCombat()) end,
+ func = function() Skada:TestMode() end
+ }
+ }
+ }
+
+ if self.display and self.display.AddDisplayOptions then
+ opt.args.copywin.hidden = nil
+ opt.args.copyexec.hidden = nil
+ opt.args.separator2.hidden = nil
+ opt.args.delete.width = nil
+ opt.args.testmode.hidden = nil
+
+ self.display:AddDisplayOptions(self, opt.args)
+ else
+ opt.name = function()
+ return format("\124cffff0000%s\124r - %s", db.name, L["ERROR"])
+ end
+ opt.args.display.name = format("%s - \124cffff0000%s\124r", L["Display System"], L["ERROR"])
+ end
+
+ O.windows.args[db.name] = opt
+ end
+end
+
+-- sets the selected window as a child to the current window
+function set_window_child(self, win)
+ if not win then
+ return
+ elseif type(win) == "table" then
+ self.child = win
+ elseif type(win) == "string" and win:trim() ~= "" then
+ for i = 1, #windows do
+ local w = windows[i]
+ if w and w.db and w.db.name == win then
+ self.child = w
+ return
+ end
+ end
+ end
+end
+
+-- destroy a window
+function Window:Destroy()
+ if self.display and self.display.Destroy then
+ self.display:Destroy(self)
+ end
+
+ self.name = nil
+ self.display = nil
+ self.parentmode = nil
+ self.selectedset = nil
+ self.selectedmode = nil
+
+ local name = self.db.name or Skada.windowdefaults.name
+ O.windows.args[name] = del(O.windows.args[name], true)
+
+ Window.del(self)
+end
+
+-- change window display
+function Window:SetDisplay(name, isnew)
+ if name ~= self.db.display or self.display == nil then
+ if self.display and self.display.Destroy then
+ self.display:Destroy(self)
+ end
+
+ if isnew then -- don't use unexisting display!
+ name = displays[name] and name or "legacy"
+ name = displays[name] and name or "inline"
+ name = displays[name] and name or "broker"
+ end
+
+ self.db.display = name
+ self.display = displays[self.db.display]
+ add_window_options(self)
+ end
+end
+
+-- checks if the window can show total bar/text
+local function can_show_total(db, mode, set)
+ -- totals aren't show if:
+ -- [1] disabled globally or for the window
+ -- [2] the display doesn't support totals
+ -- [3] then mode doesn't show totals (missing GetSetSummary function)
+ -- [4] not a group segment or a total segment.
+ if
+ (not P.showtotals and not db.showtotals) -- [1]
+ or (not display_with_totals[db.display]) -- [2]
+ or (not mode or not mode.GetSetSummary) -- [3]
+ or (not set.type or set.type == "none" and set.name ~= L["Total"]) -- [4]
+ then
+ return false
+ end
+
+ return true
+end
+
+-- tell window to update the display of its dataset, using its display provider.
+function Window:UpdateDisplay()
+ -- hidden window? nothing to do.
+ if not self:IsShown() then
+ return
+ elseif self.selectedmode then
+ local set = self:GetSelectedSet()
+ if set then
+ if self.selectedmode.Update then
+ self.selectedmode:Update(self, set)
+ else
+ Skada:Printf("Mode \124cffffbb00%s\124r does not have an Update function!", self.selectedmode.localeName or self.selectedmode.moduleName)
+ end
+
+ if can_show_total(self.db, self.selectedmode, set) then
+ local value, valuetext = self.selectedmode:GetSetSummary(set, self)
+ if value or valuetext then
+ if not value then
+ value = 0
+ for i = 1, #self.dataset do
+ local data = self.dataset[i]
+ if data and data.id then
+ value = value + data.value
+ end
+ end
+ end
+
+ local d = self:nr(0)
+ d.id = "total"
+ d.label = L["Total"]
+ d.text = self.class and format("%s (%s)", d.label, L[self.class]) or nil
+ d.ignore = true
+ d.value = value + 1 -- to be always first
+ d.valuetext = valuetext or tostring(value)
+ d.icon = P.moduleicons and self.selectedmode.metadata and self.selectedmode.metadata.icon or Skada.logo
+ end
+ end
+ end
+ elseif self.selectedset then
+ local set = self:GetSelectedSet()
+
+ for i = 1, #modes do
+ local mode = modes[i]
+ if mode then
+ local d = self:nr(i)
+
+ d.id = mode.moduleName
+ d.label = mode.localeName
+ d.icon = P.moduleicons and mode.metadata and mode.metadata.icon or nil
+ d.value = 1
+
+ if set and mode.GetSetSummary then
+ local value, valuetext = mode:GetSetSummary(set, self)
+ d.valuetext = valuetext or tostring(value)
+ end
+ end
+ end
+
+ self.metadata.ordersort = true
+ self.metadata.is_modelist = set and true or nil
+ self.metadata.is_setlist = nil
+ else
+ local nr = 1
+ local d = self:nr(nr)
+
+ d.id = "total"
+ d.label = L["Total"]
+ d.value = 1
+
+ nr = nr + 1
+ d = self:nr(nr)
+
+ d.id = "current"
+ d.label = L["Current"]
+ d.value = 1
+
+ local sets = Skada.sets
+ for i = 1, #sets do
+ local set = sets[i]
+ if set then
+ nr = nr + 1
+ d = self:nr(nr)
+
+ d.id = tostring(set.starttime)
+ _, d.label, d.valuetext = Skada:GetSetLabel(set)
+ d.value = 1
+ d.emphathize = set.keep
+ end
+ end
+
+ self.metadata.ordersort = true
+ self.metadata.is_setlist = true
+ end
+
+ if not self.metadata.maxvalue then
+ self.metadata.maxvalue = 0
+ if self.dataset then
+ for i = 1, #self.dataset do
+ local data = self.dataset[i]
+ if data and data.id and data.value and data.value > self.metadata.maxvalue then
+ self.metadata.maxvalue = data.value
+ end
+ end
+ end
+ end
+
+ self.changed = nil
+ self.display:Update(self)
+ set_window_mode_title(self)
+end
+
+function Window:IsShown()
+ return self.display:IsShown(self)
+end
+
+function Window:Show()
+ self.display:Show(self)
+ if self.changed then
+ self:UpdateDisplay()
+ end
+end
+
+function Window:Hide()
+ self.display:Hide(self)
+end
+
+-- toggles window visibility
+function Window:Toggle()
+ if
+ P.hidden or -- all windows are hidden
+ self.db.hidden or -- this window is hidden
+ ((P.hidesolo or self.db.hideauto == 4) and not IsInGroup()) or -- hide when solo & not in a group
+ ((P.hidepvp or self.db.hideauto == 7) and IsInPvP()) or -- hide in pvp & not in pvp
+ ((P.showcombat or self.db.hideauto == 3) and not IsGroupInCombat()) or -- show in combat & not in combat
+ ((P.hidecombat or self.db.hideauto == 2) and IsGroupInCombat()) or -- hide in combat & in combat
+ (self.db.hideauto == 5 and (Skada.insType == "raid" or Skada.insType == "party")) or -- hide in instance & in instance
+ (self.db.hideauto == 6 and Skada.insType ~= "raid" and Skada.insType ~= "party") -- hide out of instance and not in instance
+ then
+ self:Hide()
+ else
+ self:Show()
+ end
+end
+
+function Window:Wipe(changed)
+ self:reset()
+ if self.display and self.display.Wipe then
+ self.display:Wipe(self)
+ end
+
+ self.changed = changed or self.changed
+ if self.child and self.db.childmode == 1 then
+ self.child:Wipe(changed)
+ end
+end
+
+function Window:GetSelectedSet()
+ return Skada:GetSet(self.selectedset)
+end
+
+function Window:SetSelectedSet(set, step)
+ if step ~= nil then
+ local count = #Skada.sets
+ if count > 0 then
+ if type(self.selectedset) == "number" then
+ set = self.selectedset + step
+ if set < 1 then
+ set = "current"
+ elseif set > count then
+ set = "total"
+ end
+ elseif self.selectedset == "current" then
+ set = (step == 1) and 1 or "total"
+ elseif self.selectedset == "total" then
+ set = (step == 1) and "current" or count
+ end
+ elseif self.selectedset == "total" then
+ set = "current"
+ elseif self.selectedset == "current" then
+ set = "total"
+ end
+ end
+
+ if set and self.selectedset ~= set then
+ self.selectedset = set
+ restore_window_view(self)
+ if self.child and (self.db.childmode == 1 or self.db.childmode == 2) then
+ self.child:SetSelectedSet(set)
+ end
+ end
+end
+
+function Window:DisplayMode(mode)
+ if type(mode) ~= "table" then return end
+
+ self:Wipe()
+ self.selectedset = self.selectedset or "current"
+ self.selectedmode = mode
+ wipe(self.metadata)
+
+ if mode.isParent then
+ self.parentmode = self.parentmode ~= mode and mode or self.parentmode
+ self:clean()
+ elseif not self.parentmode then
+ self.parentmode = mode
+ end
+
+ if mode.metadata then
+ for key, value in pairs(mode.metadata) do
+ self.metadata[key] = value
+ end
+ end
+
+ self.changed = true
+
+ if self.child and (self.db.childmode == 1 or self.db.childmode == 3) then
+ if self.db.childmode == 1 and self.child.selectedset ~= self.selectedset then
+ self.child.selectedset = self.selectedset
+ self.child.changed = true
+ end
+ self.child:DisplayMode(mode)
+ end
+
+ Skada:UpdateDisplay()
+end
+
+function Window:FilterClass(class)
+ if self.class then
+ self.class = nil
+ else
+ self.class = class
+ end
+
+ self:Wipe()
+ self:UpdateDisplay()
+end
+
+local user_sort_func
+do
+ local function default_sort_func(a, b)
+ return a.localeName < b.localeName
+ end
+
+ function user_sort_func(a, b)
+ if P.sortmodesbyusage and P.modeclicks then
+ return (P.modeclicks[a.moduleName] or 0) > (P.modeclicks[b.moduleName] or 0)
+ end
+ return a.localeName < b.localeName
+ end
+
+ local function click_on_mode(win, id, _, button)
+ if button == "LeftButton" then
+ local mode = find_mode(id)
+ if mode then
+ if P.sortmodesbyusage then
+ P.modeclicks = P.modeclicks or {}
+ P.modeclicks[id] = (P.modeclicks[id] or 0) + 1
+ end
+ win:DisplayMode(mode)
+ end
+ tsort(modes, default_sort_func)
+ elseif button == "RightButton" then
+ win:RightClick()
+ end
+ end
+
+ function Window:DisplayModes(settime)
+ wipe(self.metadata)
+ wipe(self.history)
+ self:Wipe()
+
+ self.selectedmode = nil
+ self.metadata.title = L["Skada: Modes"]
+
+ self.db.set = settime
+
+ if settime == "current" or settime == "total" then
+ self.selectedset = settime
+ else
+ local sets = Skada.sets
+ for i = 1, #sets do
+ local set = sets[i]
+ if set and tostring(set.starttime) == settime then
+ if set.name == L["Current"] then
+ self.selectedset = "current"
+ elseif set.name == L["Total"] then
+ self.selectedset = "total"
+ else
+ self.selectedset = i
+ end
+ end
+ end
+ end
+
+ tsort(modes, user_sort_func)
+ self.metadata.click = click_on_mode
+ self.metadata.maxvalue = 1
+ self.changed = true
+
+ if self.display.SetTitle then
+ self.display:SetTitle(self, self.metadata.title)
+ end
+
+ if self.child then
+ if self.db.childmode == 1 or self.db.childmode == 3 then
+ self.child:DisplayModes(settime)
+ elseif self.db.childmode == 2 then
+ self.child:SetSelectedSet(self.selectedset)
+ end
+ end
+
+ Skada:UpdateDisplay()
+ end
+end
+
+do
+ local function click_on_set(win, id, _, button)
+ if button == "LeftButton" then
+ local mode = find_mode(id)
+ if mode then -- fix odd behavior
+ win:DisplayMode(mode)
+ else
+ win:DisplayModes(id)
+ end
+ elseif button == "RightButton" then
+ win:RightClick()
+ end
+ end
+
+ function Window:DisplaySets()
+ wipe(self.metadata)
+ wipe(self.history)
+ self:Wipe()
+
+ self.selectedmode = nil
+ self.selectedset = nil
+
+ self.metadata.title = L["Skada: Fights"]
+ if self.display.SetTitle then
+ self.display:SetTitle(self, self.metadata.title)
+ end
+
+ self.metadata.click = click_on_set
+ self.metadata.maxvalue = 1
+ self.changed = true
+
+ if self.child and self.db.childmode == 1 then
+ self.child:DisplaySets()
+ end
+
+ Skada:UpdateDisplay()
+ end
+end
+
+function Window:RightClick(bar, button)
+ if self.selectedmode then
+ -- only remove class filter on parent mode.
+ if self.class and self.selectedmode == self.parentmode then
+ self.class = nil
+ self:Wipe()
+ self:UpdateDisplay()
+ elseif #self.history > 0 then
+ local prev_mode = tremove(self.history)
+ while prev_mode == self.selectedmode and #self.history > 0 do
+ prev_mode = tremove(self.history)
+ end
+ self:DisplayMode(prev_mode)
+ else
+ self.class = nil
+ self:DisplayModes(self.selectedset)
+ end
+ elseif self.selectedset then
+ self.class = nil
+ self:DisplaySets()
+ end
+ Skada:CloseMenus()
+end
+
+-------------------------------------------------------------------------------
+-- windows and misc
+
+function Skada:CreateWindow(name, db, display)
+ name = name and name:trim() or db.name or self.windowdefaults.name
+ if not name or name == "" then
+ name = self.windowdefaults.name -- default
+ else
+ name = gsub(name, "^%l", strupper, 1)
+ end
+
+ local isnew = false
+ if not db then
+ db, isnew = new(), true
+ copy(db, self.windowdefaults)
+
+ local wins = P.windows
+ wins[#wins + 1] = db
+ end
+
+ if display then
+ db.display = display
+ end
+
+ db.barbgcolor = db.barbgcolor or self.windowdefaults.barbgcolor
+ db.buttons = db.buttons or self.windowdefaults.buttons
+ db.scale = db.scale or self.windowdefaults.scale or 1
+
+ -- child window mode
+ db.tooltippos = db.tooltippos or self.windowdefaults.tooltippos or "NONE"
+
+ local window = Window.new()
+ window.db = db
+
+ name = CheckDuplicate(name, windows, "name")
+ window.db.name = name
+ window.name = name
+ if G.reinstall then
+ G.reinstall = nil
+ window.db.mode = "Damage"
+ end
+
+ window:SetDisplay(db.display, isnew)
+ if db.display and displays[db.display] then
+ window.display:Create(window, isnew)
+ windows[#windows + 1] = window
+ window:DisplaySets()
+
+ if isnew and find_mode("Damage") then
+ restore_view(window, "current", "Damage")
+ elseif window.db.set or window.db.mode then
+ restore_view(window, window.db.set, window.db.mode)
+ end
+ else
+ self:Printf("Window \"\124cffffbb00%s\124r\" was not loaded because its display module, \"\124cff00ff00%s\124r\" was not found.", name, db.display or L["Unknown"])
+ end
+
+ self:NotifyChange()
+ self:ApplySettings()
+ return window
+end
+
+-- window deletion
+do
+ local function delete_window(name)
+ Skada:CloseMenus()
+
+ for i = 1, #windows do
+ local win = windows[i]
+ local db = win and win.db
+ if db and db.name == name then
+ win:Destroy()
+ tremove(windows, i)
+ elseif db and db.child == name then
+ db.child, db.childmode, win.child = nil, nil, nil
+ end
+ end
+
+ local wins = P.windows
+ for i = 1, #wins do
+ local win = wins[i]
+ if win and win.name == name then
+ O.windows.args[name] = del(O.windows.args[name], true)
+ tremove(wins, i)
+ elseif win and win.sticked and win.sticked[name] then
+ win.sticked[name] = nil
+ end
+ end
+ end
+
+ function Skada:DeleteWindow(name, internal)
+ if internal then
+ delete_window(name)
+ Skada:NotifyChange()
+ return
+ end
+
+ if not StaticPopupDialogs["SkadaDeleteWindowDialog"] then
+ StaticPopupDialogs["SkadaDeleteWindowDialog"] = {
+ text = L["Are you sure you want to delete this window?"],
+ button1 = L["Yes"],
+ button2 = L["No"],
+ timeout = 30,
+ whileDead = 0,
+ hideOnEscape = 1,
+ OnAccept = function(self, data)
+ Skada:NotifyChange()
+ return delete_window(data)
+ end
+ }
+ end
+ StaticPopup_Show("SkadaDeleteWindowDialog", nil, nil, name)
+ end
+end
+
+-- toggles windows visiblity
+function Skada:Toggle()
+ for i = 1, #windows do
+ local win = windows[i]
+ if win then
+ win:Toggle()
+ end
+ end
+
+ if toggle_timer then
+ self:CancelTimer(toggle_timer, true)
+ toggle_timer = nil
+ end
+end
+
+-- toggles windows visibility
+function Skada:ToggleWindow()
+ if P.hidden then
+ P.hidden = false
+ self:ApplySettings()
+ else
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win:IsShown() then
+ win.db.hidden = (P.showcombat ~= true)
+ win:Hide()
+ elseif win then
+ win.db.hidden = false
+ win:Show()
+ end
+ end
+ end
+end
+
+-- global show/hide windows
+function Skada:ShowHide()
+ P.hidden = not P.hidden
+ self:ApplySettings()
+end
+
+-- restores a view for the selected window
+function restore_view(self, set, mode)
+ self.selectedset = (set == "current" or set == "total" or set == "last" or (type(set) == "number" and set <= #Skada.sets)) and set or "current"
+ self.changed = true
+
+ if mode then
+ self:DisplayMode(find_mode(mode) or self.selectedset)
+ else
+ self:DisplayModes(self.selectedset)
+ end
+end
+
+-- wipes all windows
+function Skada:Wipe(changed)
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.Wipe then
+ win:Wipe(changed)
+ end
+ end
+
+ -- reset windows mode swap.
+ self.modes_set = false
+end
+
+function set_active(enable)
+ if enable and P.hidden then
+ enable = false
+ end
+
+ for i = 1, #windows do
+ local win = windows[i]
+ local db = win and win.db
+ if db and enable and not db.hidden and not win:IsShown() then
+ win:Show()
+ elseif db and not enable or not db.hidden and win:IsShown() then
+ win:Hide()
+ end
+ end
+
+ if not enable and P.hidedisables then
+ if not Skada.disabled then
+ Skada:Debug(format("%s \124cffff0000%s\124r", L["Data Collection"], L["DISABLED"]))
+ end
+ Skada.disabled = true
+ StopWatching(Skada)
+ else
+ if Skada.disabled then
+ Skada:Debug(format("%s \124cff00ff00%s\124r", L["Data Collection"], L["ENABLED"]))
+ end
+ Skada.disabled = nil
+ StartWatching(Skada)
+ end
+
+ Skada:UpdateDisplay(true)
+end
+
+-------------------------------------------------------------------------------
+-- mode functions
+
+do
+ -- scane modes to add column options
+ local function scan_for_columns(mode)
+ if type(mode) ~= "table" or mode.scanned then return end
+ mode.scanned = true
+
+ if not mode.metadata then return end
+
+ -- add columns if available
+ if mode.metadata.columns then
+ Skada:AddColumnOptions(mode)
+ end
+
+ -- scan for click modes
+ if mode.metadata.click1 then -- any click
+ scan_for_columns(mode.metadata.click1)
+ end
+ if mode.metadata.click2 then -- shift-click
+ scan_for_columns(mode.metadata.click2)
+ end
+ if mode.metadata.click3 then -- ctrl-click
+ scan_for_columns(mode.metadata.click3)
+ end
+ end
+
+ local function reload_mode(self)
+ if not self.metadata then return end
+
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.selectedmode == self and win.metadata then
+ for key, value in pairs(self.metadata) do
+ win.metadata[key] = value
+ end
+ end
+ end
+ end
+
+ function Skada:AddMode(mode, category)
+ if self.total then
+ verify_set(mode, self.total)
+ end
+
+ if self.current then
+ verify_set(mode, self.current)
+ end
+
+ local sets = self.sets
+ for i = 1, #sets do
+ verify_set(mode, sets[i])
+ end
+
+ mode.Reload = mode.Reload or reload_mode
+ mode.category = category or "Other"
+ modes[#modes + 1] = mode
+
+ if selected_feed == nil and P.feed ~= "" then
+ self:SetFeed(P.feed)
+ end
+
+ scan_for_columns(mode)
+
+ local modename = mode.moduleName
+ for i = 1, #windows do
+ local win = windows[i]
+ if win then
+ if win.db and modename == win.db.mode then
+ restore_view(win, win.db.set, modename)
+ end
+ if win.Wipe then
+ win:Wipe()
+ end
+ end
+ end
+
+ self.changed = true
+ end
+end
+
+function Skada:RemoveMode(mode)
+ for i = 1, #modes do
+ if modes[i] == mode then
+ tremove(modes, i)
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- set functions
+
+-- deletes a set
+function Skada:DeleteSet(set, index)
+ local sets = index ~= "current" and index ~= "total" and self.sets
+ if not sets then return end
+
+ if not (set and index) then
+ for i = 1, #sets do
+ local s = sets[i]
+ if s and ((i == index) or (set == s)) then
+ set = set or s
+ index = index or i
+ break
+ end
+ end
+ end
+
+ if set and index then
+ local s = tremove(sets, index)
+ callbacks:Fire("Skada_SetDeleted", index, s)
+ s = delete_set(s)
+
+ if set == self.last then
+ self.last = nil
+ end
+
+ -- Don't leave windows pointing to a deleted sets
+ for i = 1, #windows do
+ local win = windows[i]
+ if win then
+ if win.selectedset == index or win:GetSelectedSet() == set then
+ win.selectedset = "current"
+ win.changed = true
+ elseif (tonumber(win.selectedset) or 0) > index then
+ win.selectedset = win.selectedset - 1
+ win.changed = true
+ end
+ restore_window_view(win)
+ end
+ end
+
+ self:Wipe()
+ self:UpdateDisplay(true)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- tooltip functions
+
+-- sets the tooltip position
+local GetScreenWidth = GetScreenWidth
+function Skada:SetTooltipPosition(tooltip, frame, display, win)
+ local db = win and win.db
+ if db and db.tooltippos and db.tooltippos ~= "NONE" then
+ tooltip:SetOwner(UIParent, "ANCHOR_NONE")
+
+ local anchor = strfind(db.tooltippos, "TOP") and "TOP" or "BOTTOM"
+ if strfind(db.tooltippos, "LEFT") or strfind(db.tooltippos, "RIGHT") then
+ anchor = format("%s%s", anchor, strfind(db.tooltippos, "LEFT") and "RIGHT" or "LEFT")
+ tooltip:SetPoint(anchor, frame, db.tooltippos)
+ elseif anchor == "TOP" then
+ tooltip:SetPoint("BOTTOM", frame, anchor)
+ else
+ tooltip:SetPoint("TOP", frame, anchor)
+ end
+ elseif P.tooltippos == "default" then
+ tooltip:SetOwner(UIParent, "ANCHOR_NONE")
+ tooltip:SetPoint("BOTTOMRIGHT", "UIParent", "BOTTOMRIGHT", -40, 40)
+ elseif P.tooltippos == "cursor" then
+ tooltip:SetOwner(frame, "ANCHOR_CURSOR")
+ elseif P.tooltippos == "smart" and frame then
+ if display == "inline" then
+ tooltip:SetOwner(frame, "ANCHOR_CURSOR")
+ return
+ end
+
+ -- use effective scale so the tooltip doesn't become dumb
+ -- if the window is scaled up.
+ local s = frame:GetEffectiveScale() + 0.5
+ local top = frame:GetTop() * s -- frame top
+
+ tooltip:SetOwner(frame, "ANCHOR_PRESERVE")
+ tooltip:ClearAllPoints()
+
+ if (frame:GetLeft() * s) < (GetScreenWidth() * 0.5) then
+ tooltip:SetPoint("TOPLEFT", frame, "TOPRIGHT")
+ else
+ tooltip:SetPoint("TOPRIGHT", frame, "TOPLEFT")
+ end
+ elseif frame then
+ local anchor = strfind(P.tooltippos, "top") and "TOP" or "BOTTOM"
+ anchor = format("%s%s", anchor, strfind(P.tooltippos, "left") and "RIGHT" or "LEFT")
+ tooltip:SetOwner(frame, "ANCHOR_NONE")
+ tooltip:SetPoint(anchor, frame, P.tooltippos)
+ end
+end
+
+do
+ local function value_sort(a, b)
+ if not a or a.value == nil then
+ return false
+ elseif not b or b.value == nil then
+ return true
+ elseif a.value < b.value then
+ return false
+ elseif a.value > b.value then
+ return true
+ elseif not a.label then
+ return false
+ elseif not b.label then
+ return true
+ else
+ return a.label > b.label
+ end
+ end
+
+ local white = HIGHLIGHT_FONT_COLOR
+ local function add_subview_lines(tooltip, win, mode, id, label, class)
+ if not (type(mode) == "table" and mode.Update) then return end
+
+ local set = win and win:GetSelectedSet()
+ if not set then return end
+
+ -- windows should have separate tooltip tables in order
+ -- to display different numbers for same spells for example.
+ win.ttwin = win.ttwin or Window.new(win)
+ win.ttwin:reset()
+
+ if mode.Enter then
+ mode:Enter(win.ttwin, id, label, class)
+ end
+
+ -- tooltip title
+ tooltip:AddLine(win.ttwin.title or mode.title or mode.localeName)
+
+ -- mode:Update(win, set, info1)
+ if mode.Tooltip then
+ mode:Update(win.ttwin, set, mode:Tooltip(win.ttwin, set, id, label, tooltip, class))
+ else
+ mode:Update(win.ttwin, set)
+ end
+
+ local dataset = win.ttwin.dataset
+ local num_dataset = dataset and #dataset
+ if not num_dataset or num_dataset == 0 then
+ return
+ elseif not mode.metadata or not mode.metadata.ordersort then
+ tsort(dataset, value_sort)
+ end
+
+ local maxnr, nr = IsShiftKeyDown() and 10 or P.tooltiprows, 0
+ for i = 1, num_dataset do
+ local data = dataset[i]
+ if data and data.id and not data.ignore and nr < maxnr then
+ nr = nr + 1
+ local color = white
+
+ if data.color then
+ color = data.color
+ elseif Skada.validclass[data.class] then
+ color = classcolors(data.class)
+ end
+
+ local title = data.text or data.label
+ if mode.metadata and mode.metadata.showspots then
+ title = format("\124cffffffff%d.\124r %s", nr, title)
+ end
+ tooltip:AddDoubleLine(title, data.valuetext, color.r, color.g, color.b)
+ elseif nr >= maxnr then
+ break -- no need to continue
+ end
+ end
+
+ if mode.Enter then
+ tooltip:AddLine(" ")
+ end
+ end
+
+ local total_noclick = Private.total_noclick
+
+ local function add_submode_lines(mode, win, id, label, tooltip, class)
+ if mode and not total_noclick(win.selectedset, mode) then
+ add_subview_lines(tooltip, win, mode, id, label, class)
+ end
+ end
+
+ local uformat = Private.uformat
+ local function add_click_lines(mode, label, win, t, fmt)
+ if type(mode) == "function" then
+ t:AddLine(uformat(fmt, label))
+ elseif not total_noclick(win.selectedset, mode) then
+ t:AddLine(format(fmt, label or mode.localeName))
+ end
+ end
+
+ local date = date
+ local segment_types = Skada.segment_types
+
+ local function show_set_info(set, t)
+ if not set then return end
+
+ t:AddLine(set.name)
+
+ if set.diff then
+ t:AddDoubleLine(L["Type"], format("%s (%s)", segment_types[set.type] or set.type, set.diff), nil, nil, nil, 1, 1, 1)
+ else
+ t:AddDoubleLine(L["Type"], segment_types[set.type] or set.type, nil, nil, nil, 1, 1, 1)
+ end
+
+ if set.gotboss and set.success then
+ t:AddDoubleLine(L["BOSS"], set.mobname, nil, nil, nil, 0, 1, 0)
+ elseif set.gotboss then
+ t:AddDoubleLine(L["BOSS"], set.mobname, nil, nil, nil, 1, 0, 0)
+ elseif set.type == "pvp" or set.type == "arena" then
+ t:AddDoubleLine(L["Zone"], set.mobname, nil, nil, nil, 1, 1, 0)
+ else
+ t:AddDoubleLine(L["ENEMY"], set.mobname, nil, nil, nil, 1, 1, 1)
+ end
+
+ t:AddLine(" ")
+ t:AddDoubleLine(L["Start"], date("%x %X", set.starttime), nil, nil, nil, 1, 1, 1)
+ t:AddDoubleLine(L["End"], set.endtime and date("%x %X", set.endtime) or "??", nil, nil, nil, 1, 1, 1)
+ t:AddDoubleLine(L["Duration"], Skada:FormatTime(set.time, true), nil, nil, nil, 1, 1, 1)
+ end
+
+ function Skada:ShowTooltip(win, id, label, bar, class)
+ if self.testMode or not P.tooltips or (bar and bar.ignore) then return end
+
+ local md = win and win.metadata
+ local t = md and GameTooltip
+ if not t then return end
+
+ if P.informativetooltips and (md.is_setlist or md.is_modelist) then
+ if md.is_modelist then
+ t:ClearLines()
+ add_subview_lines(t, win, find_mode(id), id, label)
+ t:Show()
+ elseif id ~= "total" and id ~= "current" then
+ t:ClearLines()
+ show_set_info(self:GetSet(id, true), t)
+ t:Show()
+ end
+ return
+ end
+
+ local hasClick = md.click1 or md.click2 or md.click3 or md.filterclass
+ if not hasClick and not md.tooltip then return end
+
+ t:ClearLines()
+
+ if md.tooltip then
+ local numLines = t:NumLines()
+ md.tooltip(win, id, label, t)
+
+ if t:NumLines() ~= numLines and hasClick then
+ t:AddLine(" ")
+ end
+ end
+
+ if P.informativetooltips then
+ add_submode_lines(md.click1, win, id, label, t, class)
+ add_submode_lines(md.click2, win, id, label, t, class)
+ add_submode_lines(md.click3, win, id, label, t, class)
+ end
+
+ if md.post_tooltip then
+ local numLines = t:NumLines()
+ md.post_tooltip(win, id, label, t)
+
+ if numLines > 0 and t:NumLines() ~= numLines and hasClick then
+ t:AddLine(" ")
+ end
+ end
+
+ if md.click1 then
+ add_click_lines(md.click1, md.click1_label, win, t, L["Click for \124cff00ff00%s\124r"])
+ end
+ if md.click2 then
+ add_click_lines(md.click2, md.click2_label, win, t, L["Shift-Click for \124cff00ff00%s\124r"])
+ end
+ if md.click3 then
+ add_click_lines(md.click3, md.click3_label, win, t, L["Control-Click for \124cff00ff00%s\124r"])
+ end
+ if md.filterclass then
+ t:AddLine(format(L["Alt-Click for \124cff00ff00%s\124r"], L["Toggle Class Filter"]))
+ end
+
+ t:Show()
+ end
+end
+
+-------------------------------------------------------------------------------
+-- slash commands
+
+local function generate_total()
+ local sets = Skada.sets
+ if not sets or #sets == 0 then return end
+
+ Skada.sets[0] = create_set(L["Total"], Skada.sets[0])
+ Skada.total = Skada.sets[0]
+
+ local total = Skada.total
+ total.starttime = nil
+ total.endtime = nil
+
+ for i = 1, #sets do
+ local set = sets[i]
+ for k, v in pairs(set) do
+ if k == "starttime" and (not total.starttime or v < total.starttime) then
+ total.starttime = v
+ elseif k == "endtime" and (not total.endtime or v > total.endtime) then
+ total.endtime = v
+ elseif type(v) == "number" and k ~= "starttime" and k ~= "endtime" then
+ total[k] = (total[k] or 0) + v
+ end
+ end
+
+ local set_actors = set.actors
+ local total_actors = total.actors
+
+ for name, p in pairs(set_actors) do
+ if not p.enemy then
+ local actor = total_actors[name] or new()
+
+ for k, v in pairs(p) do
+ if (type(v) == "string" or k == "spec" or k == "flag") then
+ actor[k] = actor[k] or v
+ elseif type(v) == "number" then
+ actor[k] = (actor[k] or 0) + v
+ end
+ end
+
+ total_actors[name] = actor
+ end
+ end
+ end
+
+ ReloadUI()
+end
+
+local Print = Private.Print
+local report_channels, report_help
+local UnitExists, UnitName = UnitExists, UnitName
+local function slash_command(param)
+ local cmd, arg1, arg2, arg3 = Skada:GetArgs(param, 4)
+ cmd = (cmd and cmd ~= "") and strlower(cmd) or cmd
+
+ if cmd == "pets" or cmd == "pet" then
+ debug_pets()
+ elseif cmd == "reset" then
+ Skada:Reset(IsShiftKeyDown())
+ elseif cmd == "reinstall" then
+ Skada:Reinstall()
+ elseif cmd == "newsegment" or cmd == "new" then
+ Skada:NewSegment()
+ elseif cmd == "newphase" or cmd == "phase" then
+ Skada:NewPhase()
+ elseif cmd == "stopsegment" or cmd == "stop" then
+ Skada:StopSegment(nil, arg1)
+ elseif cmd == "resumesegment" or cmd == "resume" then
+ Skada:ResumeSegment(nil, arg1)
+ elseif cmd == "toggle" then
+ Skada:ToggleWindow()
+ elseif cmd == "show" then
+ if P.hidden then
+ P.hidden = false
+ Skada:ApplySettings()
+ end
+ elseif cmd == "hide" then
+ if not P.hidden then
+ P.hidden = true
+ Skada:ApplySettings()
+ end
+ elseif cmd == "debug" then
+ P.debug = not P.debug
+ Skada:Print("Debug mode " .. (P.debug and ("\124cff00ff00" .. L["ENABLED"] .. "\124r") or ("\124cffff0000" .. L["DISABLED"] .. "\124r")))
+ elseif cmd == "config" or cmd == "options" then
+ Private.OpenOptions()
+ elseif cmd == "memorycheck" or cmd == "memory" or cmd == "ram" then
+ Skada:CheckMemory()
+ elseif cmd == "import" and Skada.ProfileImport then
+ Skada:ProfileImport()
+ elseif cmd == "export" and Skada.ProfileExport then
+ Skada:ProfileExport()
+ elseif cmd == "about" or cmd == "info" then
+ InterfaceOptionsFrame_OpenToCategory(folder)
+ elseif cmd == "version" or cmd == "ver" or cmd == "checkversion" then
+ Skada:Printf("\124cffffbb00%s\124r: %s - \124cffffbb00%s\124r: %s", L["Version"], Skada.version, L["Date"], Skada.date)
+ check_version()
+ elseif cmd == "website" or cmd == "github" then
+ Skada:Printf("\124cffffbb00%s\124r", Skada.website)
+ elseif (cmd == "target" or cmd == "cid") and UnitExists("target") then
+ local guid = UnitGUID("target")
+ Skada:Printf("[\124cffffbb00%s\124r] %s (%s)", GetCreatureId(guid), UnitName("target"), guid)
+ elseif cmd == "timemesure" or cmd == "measure" then
+ if P.timemesure == 2 then
+ P.timemesure = 1
+ Skada:Printf("%s: %s", L["Time Measure"], L["Activity Time"])
+ Skada:ApplySettings()
+ elseif P.timemesure == 1 then
+ P.timemesure = 2
+ Skada:Printf("%s: %s", L["Time Measure"], L["Effective Time"])
+ Skada:ApplySettings()
+ end
+ elseif cmd == "numformat" then
+ P.numberformat = P.numberformat + 1
+ if P.numberformat > 3 then
+ P.numberformat = 1
+ end
+ Skada:ApplySettings()
+ elseif cmd == "total" or cmd == "generate" then
+ generate_total()
+ elseif cmd == "report" then
+ if not Skada:CanReset() then
+ Skada:Print(L["There is nothing to report."])
+ return
+ end
+
+ local chan = arg1 and arg1:trim()
+ local report_mode_name = arg2 or "Damage"
+ local num = tonumber(arg3) or 10
+
+ -- automatic
+ if chan == "auto" and IsInGroup() then
+ chan = IsInRaid() and "raid" or "party"
+ end
+
+ -- Sanity checks.
+ report_channels = report_channels or {self = true, say = true, yell = true, guild = true, officer = true, party = true, raid = true, auto = true}
+ if chan and report_channels[strlower(chan)] and report_mode_name then
+ Skada:Report(chan, "preset", report_mode_name, "current", num)
+ else
+ Skada:Print(L["Usage:"])
+ Skada:Printf("%-20s", "/skada report [\124cffffff33channel\124r] [\124cffffff33mode\124r] [\124cffffff33numlines\124r]")
+ if not report_help then
+ local temp = new()
+ for name in next, report_channels do
+ temp[#temp + 1] = name
+ end
+ report_help = format("\124cffffff33channel\124r: %s", table.concat(temp, ", "))
+ temp = del(temp)
+ end
+ Skada:Printf(report_help)
+ end
+ else
+ Skada:Print(L["Commands:"])
+ Print("\124cffffaeae/skada\124r \124cffffff33report\124r [channel] [mode] [lines]")
+ Print("\124cffffaeae/skada\124r \124cffffff33toggle\124r / \124cffffff33show\124r / \124cffffff33hide\124r")
+ Print("\124cffffaeae/skada\124r \124cffffff33newsegment\124r / \124cffffff33newphase\124r")
+ Print("\124cffffaeae/skada\124r \124cffffff33numformat\124r / \124cffffff33measure\124r")
+ Print("\124cffffaeae/skada\124r \124cffffff33import\124r / \124cffffff33export\124r")
+ Print("\124cffffaeae/skada\124r \124cffffff33about\124r / \124cffffff33version\124r / \124cffffff33website\124r")
+ Print("\124cffffaeae/skada\124r \124cffffff33reset\124r / \124cffffff33reinstall\124r")
+ Print("\124cffffaeae/skada\124r \124cffffff33config\124r / \124cffffff33debug\124r")
+ end
+end
+
+-------------------------------------------------------------------------------
+-- feed functions
+
+function Skada:SetFeed(name)
+ if name and feeds[name] then
+ selected_feed = feeds[name]
+ self:UpdateDisplay()
+ end
+end
+
+function Skada:AddFeed(name, func)
+ feeds[name] = func
+end
+
+function Skada:RemoveFeed(name)
+ feeds[name] = nil
+end
+
+-------------------------------------------------------------------------------
+
+function Skada:PLAYER_ENTERING_WORLD()
+ userGUID = self.userGUID or UnitGUID("player")
+ self.userGUID = userGUID
+
+ self:CheckZone()
+ if was_in_party == nil then
+ roster_timer = self:ScheduleTimer("UpdateRoster", 1)
+ end
+
+ -- force reset for old structure
+ if self.sets.sets then
+ self:Reset(true)
+ end
+
+ tsort(modes, user_sort_func)
+ self:ApplySettings()
+end
+
+function Skada:PLAYER_LEAVING_WORLD()
+ if not self.inCombat then return end
+ P.inCombat = true
+ combat_end()
+end
+
+do
+ local UnitIterator = Skada.UnitIterator
+ local AddCombatant = Private.AddCombatant
+ local last_check_group = nil
+
+ function check_group()
+ -- throttle group check.
+ local checkTime = GetTime()
+ if not last_check_group or (checkTime - last_check_group) > 0.5 then
+ last_check_group = checkTime -- update cooldown
+
+ -- wipe tables
+ wipe(guidToUnit)
+ wipe(guidToClass)
+ wipe(guidToName)
+
+ -- put back summoned pets
+ for petGUID, ownerGUID in pairs(guidToOwner) do
+ guidToClass[petGUID] = ownerGUID
+ end
+
+ -- add combatants
+ for unit, owner in UnitIterator() do
+ AddCombatant(unit, owner)
+ end
+
+ -- remove pet if the owner is gone
+ for petGUID, ownerGUID in pairs(guidToOwner) do
+ if not guidToClass[ownerGUID] then
+ guidToOwner[petGUID] = nil
+ guidToClass[petGUID] = nil
+ guidToUnit[petGUID] = nil
+ end
+ end
+ end
+ end
+end
+
+do
+ local IsInInstance = IsInInstance
+ local was_in_instance, was_in_pvp
+
+ function Skada:CheckZone()
+ local inInstance, instanceType = IsInInstance()
+ local isininstance = inInstance and (instanceType == "party" or instanceType == "raid") or false
+ local isinpvp = IsInPvP()
+
+ if isininstance and was_in_instance ~= nil and not was_in_instance and P.reset.instance ~= 1 and self:CanReset() then
+ if P.reset.instance == 3 then
+ self:ShowPopup(nil, true)
+ else
+ self:Reset()
+ end
+ end
+
+ if P.hidepvp then
+ if isinpvp then
+ set_active(false)
+ elseif was_in_pvp then
+ set_active(true)
+ end
+ end
+
+ if self.insType == "arena" and instanceType ~= "arena" then
+ self:SendMessage("COMBAT_ARENA_END")
+ elseif self.insType ~= instanceType then
+ self:SendMessage("ZONE_TYPE_CHANGED", instanceType, self.insType)
+ end
+
+ self.insDiff = isininstance and self:GetInstanceDiff() or nil
+ self.insType = instanceType
+
+ was_in_instance = (isininstance == true)
+ was_in_pvp = (isinpvp == true)
+ self:Toggle()
+ end
+end
+
+do
+ local version_count = 0
+
+ function check_version()
+ Skada:SendComm(nil, nil, "VersionCheck", Skada.version)
+ if version_timer then
+ Skada:CancelTimer(version_timer, true)
+ version_timer = nil
+ end
+ end
+
+ function convert_version(ver)
+ return tonumber(type(ver) == "string" and gsub(ver, "%.", "", 2) or ver) or 0
+ end
+
+ function Skada:VersionCheck(sender, version)
+ if sender and version then
+ version = convert_version(version)
+ local ver = self.version_num or convert_version(self.version)
+ self.version_num = ver
+ if not (version and ver) or self.versionChecked then
+ return
+ elseif version > ver then
+ self:Printf(L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"], self.website)
+ elseif version < ver then
+ self:SendComm("WHISPER", sender, "VersionCheck", self.version)
+ end
+
+ self.versionChecked = true
+ end
+ end
+
+ function check_for_join_and_leave()
+ if not IsInGroup() and was_in_party then
+ if P.reset.leave == 3 and Skada:CanReset() then
+ Skada:ShowPopup(nil, true)
+ elseif P.reset.leave == 2 and Skada:CanReset() then
+ Skada:Reset()
+ end
+
+ if P.hidesolo then
+ set_active(false)
+ end
+ end
+
+ if IsInGroup() and not was_in_party then
+ if P.reset.join == 3 and Skada:CanReset() then
+ Skada:ShowPopup(nil, true)
+ elseif P.reset.join == 2 and Skada:CanReset() then
+ Skada:Reset()
+ end
+
+ if P.hidesolo and not (P.hidepvp and IsInPvP()) then
+ set_active(true)
+ end
+ end
+
+ was_in_party = IsInGroup()
+ end
+
+ local GetGroupTypeAndCount = Skada.GetGroupTypeAndCount
+ function Skada:UpdateRoster()
+ check_for_join_and_leave()
+ check_group()
+
+ -- version check
+ local t, _, count = GetGroupTypeAndCount()
+ if t == "party" then
+ count = count + 1
+ end
+
+ if count ~= version_count then
+ if count > 1 and count > version_count then
+ version_timer = version_timer or Skada:ScheduleTimer(check_version, 10)
+ end
+ version_count = count
+ end
+
+ Skada:SendMessage("GROUP_ROSTER_UPDATE")
+
+ if roster_timer then
+ Skada:CancelTimer(roster_timer, true)
+ roster_timer = nil
+ end
+ end
+end
+
+do
+ local UnitHasVehicleUI = UnitHasVehicleUI
+ local groupUnits = Skada.Units.group
+
+ function Skada:UNIT_PET(owners)
+ for owner in pairs(owners) do
+ local unit = groupUnits[owner] and format("%spet", owner)
+ local guid = unit and UnitGUID(unit)
+ if guid then
+ guidToOwner[guid] = UnitGUID(owner)
+ end
+ end
+ end
+
+ local function CheckVehicle(unit)
+ local guid = unit and UnitGUID(unit)
+ if not guid or not guidToName[guid] then
+ return
+ elseif UnitHasVehicleUI(unit) then
+ local prefix, id, suffix = strmatch(unit, "([^%d]+)([%d]*)(.*)")
+ local vUnitId = format("%spet%s%s", prefix, id, suffix)
+ if UnitExists(vUnitId) then
+ guidToOwner[UnitGUID(vUnitId)] = guid
+ vehicles[guid] = UnitGUID(vUnitId)
+ end
+ elseif vehicles[guid] then
+ -- delayed for a reason (2 x MAINMENU_SLIDETIME).
+ dismiss_pet(vehicles[guid], 0.6)
+ end
+ end
+
+ function Skada:CheckVehicle(units)
+ for unit in pairs(units) do
+ if groupUnits[unit] then
+ CheckVehicle(unit)
+ end
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+
+function Skada:CanReset()
+ local total_actors = self.total and self.total.actors
+ if total_actors and next(total_actors) then
+ return true
+ end
+
+ local sets = self.sets
+
+ if not sets then
+ return false
+ end
+
+ for i = 1, #sets do
+ local set = sets[i]
+ if set and not set.keep then
+ return true
+ end
+ end
+
+ return false
+end
+
+function Skada:Reset(force)
+ if self.testMode then return end
+
+ if force then
+ local n = #self.sets
+ for i = n, 1, -1 do
+ delete_set(tremove(self.sets, i))
+ end
+ elseif not self:CanReset() then
+ self:Wipe()
+ self:UpdateDisplay(true)
+ self:Print(L["There is no data to reset."])
+ return
+ end
+
+ self:Wipe()
+ check_group()
+
+ if self.current ~= nil then
+ self.current = create_set(L["Current"], self.current)
+ end
+
+ if self.total ~= nil then
+ self.total = create_set(L["Total"], self.total)
+ self.sets[0] = self.total
+ end
+
+ self.last = nil
+
+ clean_sets(true)
+
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.selectedset ~= "total" then
+ win.selectedset = "current"
+ win.changed = true
+ restore_window_view(win)
+ end
+ end
+
+ dataobj.text = "n/a"
+ self:UpdateDisplay(true)
+ self:Notify(L["All data has been reset."])
+ callbacks:Fire("Skada_DataReset")
+ StaticPopup_Hide("SkadaCommonConfirmDialog")
+ self:CloseMenus()
+end
+
+function Skada:UpdateDisplay(force)
+ self.changed = self.changed or force
+
+ if type(selected_feed) == "function" then
+ local feedtext = selected_feed()
+ if feedtext then
+ dataobj.text = feedtext
+ end
+ end
+
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and (self.changed or win.changed or (self.current and (win.selectedset == "current" or win.selectedset == "total"))) then
+ win:UpdateDisplay()
+ end
+ end
+
+ self.changed = nil
+end
+
+-------------------------------------------------------------------------------
+-- format functions
+
+do
+ local date = date
+ local function set_label_format(name, starttime, endtime, fmt, dye)
+ fmt = max(1, min(8, fmt or P.setformat or 3))
+
+ local namelabel, timelabel = name or L["Unknown"], ""
+ if starttime and endtime and fmt > 1 then
+ local duration = SecondsToTime(endtime - starttime, false, false, 2)
+
+ if fmt == 2 then
+ timelabel = dye and format("\124cffffff00%s\124r", duration) or duration
+ elseif fmt == 3 then
+ timelabel = format(dye and "%s \124cffffff00(%s)\124r" or "%s (%s)", date("%H:%M", starttime), duration)
+ elseif fmt == 4 then
+ timelabel = format(dye and "%s \124cffffff00(%s)\124r" or "%s (%s)", date("%I:%M %p", starttime), duration)
+ elseif fmt == 5 then
+ timelabel = format(dye and "\124cffffff00%s - %s\124r" or "%s - %s", date("%H:%M", starttime), date("%H:%M", endtime))
+ elseif fmt == 6 then
+ timelabel = format(dye and "\124cffffff00%s - %s\124r" or "%s - %s", date("%I:%M %p", starttime), date("%I:%M %p", endtime))
+ elseif fmt == 7 then
+ timelabel = format(dye and "\124cffffff00%s - %s\124r" or "%s - %s", date("%H:%M:%S", starttime), date("%H:%M:%S", endtime))
+ elseif fmt == 8 then
+ timelabel = format(dye and "\124cffffff00%s - %s\124r \124cffffff00(%s)\124r" or "%s - %s (%s)", date("%H:%M", starttime), date("%H:%M", endtime), duration)
+ end
+ end
+
+ if #namelabel == 0 or #timelabel == 0 then
+ return format("%s%s", namelabel, timelabel), namelabel, timelabel
+ elseif strmatch(timelabel, "^%p") then
+ return format("%s %s", namelabel, timelabel), namelabel, timelabel
+ else
+ return format("%s: %s", namelabel, timelabel), namelabel, timelabel
+ end
+ end
+
+ function Skada:SetLabelFormats()
+ local ret, start = {}, 1631547006
+ for i = 1, 8 do
+ ret[i] = set_label_format(L["Hogger"], start, start + 380, i)
+ end
+ return ret
+ end
+
+ function Skada:GetSetLabel(set, dye)
+ if not set then return "" end
+ return set_label_format(set.name, set.starttime, set.endtime or time(), nil, dye)
+ end
+
+ function set_window_mode_title(self)
+ if
+ not self.db.enabletitle or -- title bar disabled
+ not self.selectedmode or -- window has no selected mode
+ not self.selectedmode.moduleName or -- selected mode isn't a valid mode
+ not self.selectedset -- window has no selected set
+ then
+ return
+ end
+
+ local name = self.selectedmode.title or self.selectedmode.localeName
+ local savemode = self.selectedmode.moduleName
+
+ if self.parentmode then
+ name = self.selectedmode.localeName or name
+ savemode = self.parentmode.moduleName or savemode
+ end
+
+ self.db.set = self.selectedset
+ self.db.mode = savemode
+
+ if self.changed and self.title then
+ self.title = nil
+ elseif self.title and self.title ~= name then
+ name = self.title
+ end
+
+ if self.db.display == "bar" then
+ -- title set enabled?
+ if self.db.titleset and self.selectedmode.metadata and not self.selectedmode.metadata.notitleset then
+ if self.selectedset == "current" then
+ name = format("%s%s %s", name, strfind(name, ":") and " -" or ":", L["Current"])
+ elseif self.selectedset == "total" then
+ name = format("%s%s %s", name, strfind(name, ":") and " -" or ":", L["Total"])
+ else
+ local set = self:GetSelectedSet()
+ if set then
+ name = format("%s%s %s", name, strfind(name, ":") and " -" or ":", Skada:GetSetLabel(set))
+ end
+ end
+ end
+ -- combat timer enabled?
+ if self.db.combattimer and (self.selectedset == "current" or self.selectedset == "last") and (Skada.current or Skada.last) then
+ name = format("[%s] %s", formatted_set_time(Skada.current or Skada.last), name)
+ end
+ end
+
+ self.metadata.title = name
+ if self.display.SetTitle then
+ self.display:SetTitle(self, name)
+ end
+ end
+end
+
+function restore_window_view(self, set, mode)
+ if self.history[1] then
+ wipe(self.history)
+ self.title = nil
+ self:clean()
+ end
+
+ -- force menu to close and let Skada handle the rest
+ Skada:CloseMenus()
+ restore_view(self, set or self.selectedset, mode or self.db.mode)
+end
+
+-------------------------------------------------------------------------------
+
+function dataobj:OnEnter()
+ self.tooltip = self.tooltip or GameTooltip
+ self.tooltip:SetOwner(self, "ANCHOR_NONE")
+ self.tooltip:SetPoint("TOPRIGHT", self, "BOTTOMRIGHT")
+ self.tooltip:ClearLines()
+
+ local set = Skada:GetSet("current")
+ if set then
+ self.tooltip:AddDoubleLine(L["Skada Summary"], Skada.version)
+ self.tooltip:AddLine(" ")
+ self.tooltip:AddDoubleLine(L["Segment Time"], formatted_set_time(set), 1, 1, 1)
+ for i = 1, #modes do
+ local mode = modes[i]
+ if mode and mode.AddToTooltip then
+ mode:AddToTooltip(set, self.tooltip)
+ end
+ end
+ self.tooltip:AddLine(" ")
+ else
+ self.tooltip:AddDoubleLine(folder, Skada.version, nil, nil, nil, 0, 1, 0)
+ end
+
+ self.tooltip:AddLine(L["\124cff00ff00Left-Click\124r to toggle windows."], 1, 1, 1)
+ self.tooltip:AddLine(L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."], 1, 1, 1)
+ self.tooltip:AddLine(L["\124cff00ff00Shift+Left-Click\124r to reset."], 1, 1, 1)
+ self.tooltip:AddLine(L["\124cff00ff00Right-Click\124r to open menu."], 1, 1, 1)
+
+ self.tooltip:Show()
+end
+
+function dataobj:OnLeave()
+ (self.tooltip or GameTooltip):Hide()
+end
+
+function dataobj:OnClick(button)
+ if button == "LeftButton" and IsControlKeyDown() then
+ P.hidden = not P.hidden
+ Skada:ApplySettings()
+ elseif button == "LeftButton" and IsShiftKeyDown() then
+ Skada:ShowPopup()
+ elseif button == "LeftButton" then
+ Skada:ToggleWindow()
+ elseif button == "RightButton" then
+ Skada:OpenMenu()
+ end
+end
+
+function Private.RefreshButton()
+ if not DBI then return end
+
+ DBI:Refresh(folder, Skada.data.profile.icon)
+ if Skada.data.profile.icon.hide then
+ DBI:Hide(folder)
+ else
+ DBI:Show(folder)
+ end
+end
+
+function Skada:NotifyChange()
+ ACR:NotifyChange(folder)
+end
+
+function Skada:ApplySettings(name, hidemenu)
+ if type(name) == "table" and name.db and name.db.name then
+ name = name.db.name
+ elseif type(name) == "boolean" then
+ hidemenu = name
+ name = nil
+ end
+
+ -- close dropdown menus?
+ if hidemenu == true then
+ Skada:CloseMenus()
+ end
+
+ -- fire callback in case modules need it
+ callbacks:Fire("Skada_ApplySettings")
+
+ for i = 1, #windows do
+ local win = windows[i]
+ local db = win and win.db
+ if db and name and db.name == name then
+ set_window_child(win, db.child)
+ win.display:ApplySettings(win)
+ win:Toggle()
+ Skada:UpdateDisplay(true)
+ return
+ elseif db then
+ set_window_child(win, db.child)
+ win.display:ApplySettings(win)
+ end
+ end
+
+ if (P.hidesolo and not IsInGroup()) or (P.hidepvp and IsInPvP()) then
+ set_active(false)
+ else
+ set_active(true)
+
+ for i = 1, #windows do
+ local win = windows[i]
+ if win then
+ win:Toggle()
+ end
+ end
+ end
+
+ Private.SetNumberFormat(P.numbersystem)
+ Private.SetValueFormat(P.brackets, P.separator)
+
+ -- the player wasn't in combat?
+ if not P.inCombat then
+ Skada:UpdateDisplay(true)
+ return
+ end
+
+ -- reset the flag...
+ P.inCombat = false
+
+ -- no longer in combat?
+ if not InCombatLockdown() and not IsGroupInCombat() then
+ Skada:UpdateDisplay(true)
+ return
+ end
+
+ local set = Skada.sets[1] -- last fight
+ -- unexistent/old fight? nothing to do... (imho 15 sec is fair)
+ if not set or not set.endtime or Skada._time - set.endtime >= 15 then
+ Skada:UpdateDisplay(true)
+ return
+ end
+
+ -- reuse set and start combat.
+ set = tremove(Skada.sets, 1)
+ set.time, set.endtime = 0, nil
+ Skada.current = setPrototype:Bind(set)
+ Skada.total = setPrototype:Bind(Skada.sets[0])
+ combat_start()
+ Skada:UpdateDisplay(true)
+end
+
+function Private.ReloadSettings()
+ for i = #windows, 1, -1 do
+ local win = windows[i]
+ if win and win.Destroy then
+ win:Destroy()
+ end
+ tremove(windows, i)
+ end
+
+ -- refresh refrences
+ P = Skada.data.profile
+ G = Skada.data.global
+
+ -- global references
+ Skada.profile = Skada.data.profile
+ Skada.global = Skada.data.global
+
+ local wins = P.windows
+ for i = 1, #wins do
+ local win = wins[i]
+ if win then
+ Skada:CreateWindow(win.name, win)
+ end
+ end
+
+ if DBI and not DBI:IsRegistered(folder) then
+ DBI:Register(folder, dataobj, P.icon)
+ end
+
+ Private.RefreshButton()
+ Skada.total = Skada.sets[0]
+ Skada:ApplySettings()
+end
+
+-------------------------------------------------------------------------------
+
+function Skada:OnInitialize()
+ self.data = LibStub("AceDB-3.0"):New("SkadaDB", self.defaults, true)
+
+ if type(SkadaCharDB) ~= "table" then
+ SkadaCharDB = {}
+ end
+
+ -- Profiles
+ local AceDBOptions = LibStub("AceDBOptions-3.0", true)
+ if AceDBOptions then
+ local LDS = LibStub("LibDualSpec-1.0", true)
+ if LDS then LDS:EnhanceDatabase(self.data, folder) end
+
+ O.profiles.args.general = AceDBOptions:GetOptionsTable(self.data)
+ O.profiles.args.general.order = 0
+
+ if LDS then LDS:EnhanceOptions(O.profiles.args.general, self.data) end
+
+ -- import/export profile if found.
+ if Private.AdvancedProfile then
+ Private.AdvancedProfile(O.profiles.args)
+ end
+ end
+
+ -- global references
+ self.profile = self.data.profile
+ self.global = self.data.global
+
+ -- backwards compatibility.
+ self.db = self.data
+
+ -- local references
+ P = self.data.profile
+ G = self.data.global
+
+ self:RegisterChatCommand("skada", slash_command, true) -- force flag set
+ self.data.RegisterCallback(self, "OnProfileChanged", Private.ReloadSettings)
+ self.data.RegisterCallback(self, "OnProfileCopied", Private.ReloadSettings)
+ self.data.RegisterCallback(self, "OnProfileReset", Private.ReloadSettings)
+
+ Private.InitOptions()
+ Private.RegisterMedias()
+ Private.RegisterClasses()
+ Private.RegisterSchools()
+ Private.RegisterToast()
+ self:RegisterComms(not P.syncoff)
+
+ -- fix things and remove others
+ P.setstokeep = min(25, max(0, P.setstokeep or 0))
+ P.setslimit = min(25, max(0, P.setslimit or 0))
+ P.timemesure = min(2, max(1, P.timemesure or 0))
+ P.totalflag = P.totalflag or 0x10
+ G.version, G.revision, G.inCombat = nil, nil, nil
+
+ -- sets limit
+ self.maxsets = P.setstokeep + P.setslimit
+ self.maxmeme = min(60, max(30, self.maxsets + 10))
+
+ -- update references
+ classcolors = self.classcolors
+
+ -- assign times before loading modules.
+ self._Time = GetTime()
+ self._time = time()
+
+ -- early loading of modules
+ self:LoadModules()
+end
+
+function Skada:SetupStorage()
+ self.sets = self.sets or _G.SkadaCharDB
+end
+
+function Skada:OnEnable()
+ self:RegisterEvent("PLAYER_ENTERING_WORLD")
+ self:RegisterEvent("PLAYER_LEAVING_WORLD")
+ self:RegisterEvent("PLAYER_REGEN_DISABLED")
+ self:RegisterEvent("ZONE_CHANGED_NEW_AREA", "CheckZone")
+ self:RegisterBucketEvent("UNIT_PET", 0.2)
+ self:RegisterBucketEvent("UNIT_ENTERED_VEHICLE", 0.1, "CheckVehicle")
+ self:RegisterBucketEvent("UNIT_EXITED_VEHICLE", 0.1, "CheckVehicle")
+ self:RegisterBucketEvent("GROUP_ROSTER_UPDATE", 0.2, "UpdateRoster")
+ StartWatching(self)
+
+ -- late loading of modules
+ self:LoadModules(true)
+
+ if _G.BigWigs then
+ self:RegisterMessage("BigWigs_Message", "BigWigs")
+ self.bossmod = "BigWigs"
+ elseif _G.DBM and _G.DBM.EndCombat then
+ self:SecureHook(_G.DBM, "EndCombat", "DBM")
+ self.bossmod = "DBM"
+ elseif self.bossmod then
+ self.bossmod = nil
+ end
+
+ self:SetupStorage()
+
+ -- deprecated table structure.
+ if self.sets.version or self.sets.sets then
+ self.sets.sets, self.sets.version = nil, nil
+ self:Debug("Fixed deprecated table structure!")
+ end
+
+ Private.ReloadSettings()
+ self.__memory_timer = self:ScheduleTimer("CheckMemory", 3)
+ self.__garbage_timer = self:ScheduleTimer("CleanGarbage", 4)
+end
+
+-- called on boss defeat
+local function BossDefeated()
+ if bossdefeat_timer then
+ Skada:CancelTimer(bossdefeat_timer, true)
+ bossdefeat_timer = nil
+ end
+
+ local set = Skada.current
+ if not set or set.success then return end
+
+ set.success = true
+
+ -- phase segments.
+ if Skada.tempsets then
+ for i = 1, #Skada.tempsets do
+ local s = Skada.tempsets[i]
+ if s and not s.success then
+ s.success = true
+ end
+ end
+ end
+
+ Skada:Debug("\124cffffbb00COMBAT_BOSS_DEFEATED\124r: Skada")
+ Skada:SendMessage("COMBAT_BOSS_DEFEATED", set)
+ Skada:SmartStop(set)
+end
+
+-------------------------------------------------------------------------------
+-- Getters & Iterators
+
+function Skada:GetWindows()
+ return windows
+end
+
+function Skada:GetModes()
+ return modes
+end
+
+function Skada:GetFeeds()
+ return feeds
+end
+
+function Skada:GetSet(id, unbound)
+ if id == "current" then
+ local set = self.current or self.last or self.sets[1]
+ return unbound and set or setPrototype:Bind(set)
+ elseif id == "total" then
+ return unbound and self.total or setPrototype:Bind(self.total)
+ elseif type(id) == "number" then
+ local set = self.sets[id]
+ return unbound and set or setPrototype:Bind(set)
+ end
+
+ for i = 1, #self.sets do
+ local set = self.sets[i]
+ if set and (tostring(set.starttime) == id or set.name == id) then
+ return unbound and set or setPrototype:Bind(set)
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+
+-- never initially registered.
+function Skada:PLAYER_REGEN_ENABLED()
+ self:UnregisterEvent("PLAYER_REGEN_ENABLED")
+ if not self.current then return end
+
+ -- we make sure to end the segment only if:
+ -- 1. the segment was previously stopped.
+ -- 2. the player and the group aren't in combat
+ if self.current.stopped or (not InCombatLockdown() and not IsGroupInCombat()) then
+ self:Debug("\124cffffbb00EndSegment\124r: PLAYER_REGEN_ENABLED")
+ combat_end()
+ end
+end
+
+function Skada:PLAYER_REGEN_DISABLED()
+ if not self.disabled and not self.current then
+ self:Debug("\124cffffbb00StartCombat\124r: PLAYER_REGEN_DISABLED")
+ combat_start()
+ end
+end
+
+function Skada:NewSegment()
+ if self.current then
+ combat_end()
+ combat_start()
+ end
+end
+
+function Skada:NewPhase()
+ if not self.current then return end
+ self.tempsets = self.tempsets or new()
+
+ local set = create_set(L["Current"])
+ set.mobname = self.current.mobname
+ set.gotboss = self.current.gotboss
+ set.started = self.current.started
+ set.phase = 2 + #self.tempsets
+
+ self.tempsets[#self.tempsets + 1] = set
+
+ self:Printf(L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."], set.mobname or L["Unknown"], set.phase)
+end
+
+function combat_end()
+ if not Skada.current then return end
+ Private.ClearTempUnits()
+ wipe(GetCreatureId) -- wipe cached creature IDs
+
+ -- trigger events.
+ local curtime = time()
+ Skada:SendMessage("COMBAT_PLAYER_LEAVE", Skada.current, curtime)
+ if Skada.current.gotboss then
+ Skada:SendMessage("COMBAT_ENCOUNTER_END", Skada.current, curtime)
+ Skada:ClearFirstHit()
+ elseif Skada.current.type == "pvp" then
+ Skada:SendMessage("COMBAT_PVP_END", nil, Skada.insType)
+ end
+
+ -- process segment
+ process_set(Skada.current, curtime)
+
+ -- process phase segments
+ if Skada.tempsets then
+ local setname = Skada.current.name
+ for i = 1, #Skada.tempsets do
+ local set = Skada.tempsets[i]
+ process_set(set, curtime, setname)
+ end
+ Skada.tempsets = del(Skada.tempsets)
+ end
+
+ -- clear total semgnt
+ if P.totalidc then
+ for i = 1, #modes do
+ local mode = modes[i]
+ if mode and mode.SetComplete then
+ mode:SetComplete(Skada.total)
+ end
+ end
+ end
+
+ -- remove players ".last" key from total segment.
+ local actors = Skada.total and Skada.total.actors
+ if actors then
+ for _, actor in pairs(actors) do
+ if actor.last then
+ actor.last = nil
+ end
+ end
+ end
+
+ if Skada.current.time and (P.inCombat or Skada.current.time >= P.minsetlength) then
+ Skada.total.time = (Skada.total.time or 0) + Skada.current.time
+ end
+
+ Skada.last = Skada.current
+ Skada.current = nil
+ Skada.inCombat = false
+ _targets = del(_targets)
+
+ clean_sets()
+ wipe(vehicles)
+
+ Skada:SetModes()
+
+ if update_timer then
+ Skada:CancelTimer(update_timer, true)
+ update_timer = nil
+ end
+
+ if tick_timer then
+ Skada:CancelTimer(tick_timer, true)
+ tick_timer = nil
+ end
+
+ if toggle_timer then
+ Skada:CancelTimer(toggle_timer, true)
+ toggle_timer = nil
+ end
+
+ Skada._Time = GetTime()
+ Skada._time = time()
+end
+
+function Skada:StopSegment(msg, phase)
+ local curtime = self.current and time()
+ if not curtime then return end
+
+ -- stop phase segment?
+ if phase then
+ phase = self.tempsets and (tonumber(phase) or #self.tempsets)
+ local set = phase and self.tempsets[phase]
+ if set and not set.stopped then
+ set.stopped = true
+ set.endtime = curtime
+ set.time = max(1, set.endtime - set.starttime)
+ self:Printf(L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."], set.mobname or L["Unknown"], set.phase)
+ end
+ return
+ end
+
+ if self.current.stopped then return end
+
+ -- stop current segment?
+ self.current.stopped = true
+ self.current.endtime = curtime
+ self.current.time = max(1, self.current.endtime - self.current.starttime)
+
+ -- stop phase segments?
+ if self.tempsets then
+ for i = 1, #self.tempsets do
+ local set = self.tempsets[i]
+ if set and not set.stopped then
+ set.stopped = true
+ set.endtime = curtime
+ set.time = max(1, set.endtime - set.starttime)
+ end
+ end
+ end
+
+ self:Print(msg or L["Segment Stopped."])
+ self:RegisterEvent("PLAYER_REGEN_ENABLED")
+end
+
+function Skada:ResumeSegment(msg, index)
+ if not self.current then return end
+
+ -- resume phase segment?
+ if index then
+ index = self.tempsets and (tonumber(index) or #self.tempsets)
+ local set = index and self.tempsets[index]
+ if set and set.stopped then
+ set.stopped = nil
+ set.endtime = nil
+ set.time = 0
+ self:Printf(L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."], set.mobname or L["Unknown"], set.phase)
+ end
+ return
+ end
+ if not self.current.stopped then return end
+
+ -- resume current segment?
+ self.current.stopped = nil
+ self.current.endtime = nil
+ self.current.time = 0
+
+ -- resume phase segments?
+ if self.tempsets then
+ for i = 1, #self.tempsets do
+ local set = self.tempsets[i]
+ if set and set.stopped then
+ set.stopped = nil
+ set.endtime = nil
+ set.time = 0
+ end
+ end
+ end
+
+ self:Print(msg or L["Segment Resumed."])
+end
+
+function Skada:SetModes()
+ if self.modes_set then return end
+ self.modes_set = true
+
+ for i = 1, #windows do
+ local win = windows[i]
+ if win then
+ if win.selectedset ~= "current" and win.selectedset ~= "total" then
+ win:SetSelectedSet(nil, 1) -- move to next set
+ end
+
+ win:Wipe()
+ Skada.changed = true
+
+ if win.db.wipemode ~= "" and IsGroupDead() then
+ restore_window_view(win, "current", win.db.wipemode)
+ elseif win.db.returnaftercombat and win.restore_mode and win.restore_set then
+ if win.restore_set ~= win.selectedset or win.restore_mode ~= win.selectedmode then
+ restore_window_view(win, win.restore_set, win.restore_mode)
+ win.restore_mode, win.restore_set = nil, nil
+ end
+ end
+
+ win:Toggle()
+ end
+ end
+
+ Skada:UpdateDisplay(true)
+end
+
+-------------------------------------------------------------------------------
+
+function Skada:ENCOUNTER_START(_, encounter_id, encounter_name)
+ if self.disabled then
+ return
+ elseif self.current then
+ self.current.gotboss = encounter_id
+ self.current.mobname = encounter_name
+ self:SendMessage("COMBAT_ENCOUNTER_START", self.current)
+ else
+ self._encounter_id = encounter_id
+ self._encounter_name = encounter_name
+ self._encounter_time = GetTime()
+ end
+end
+
+function Skada:ENCOUNTER_END(_, encounter_id, encounter_name)
+ if not self.disabled and self.current then
+ if not self.current.gotboss then
+ self.current.mobname = encounter_name
+ self.current.gotboss = encounter_id
+ end
+ end
+end
+
+do
+ local tentative, tentative_set, tentative_timer
+ local death_counter, starting_members = 0, 0
+
+ -- Edit Skada\Core\Tables.lua
+ local ignored_events = Skada.ignored_events
+ local trigger_events = Skada.trigger_events
+
+ -- events used to count spell casts.
+ local spellcast_events = {
+ SPELL_CAST_START = true,
+ SPELL_CAST_SUCCESS = true
+ }
+
+ -- events used to trigger deaths
+ local death_events = {
+ UNIT_DIED = true,
+ UNIT_DESTROYED = true,
+ UNIT_DISSIPATES = true
+ }
+
+ -- list of registered combat log event functions.
+ local combatlog_events = {}
+
+ -- register a func to cleu event(s).
+ function Skada:RegisterForCL(func, flags, ...)
+ if type(func) ~= "function" then return end
+ flags = flags or self.dummyTable -- allow empty flags
+
+ local index = 1
+ local event = select(index, ...)
+ while event do
+ combatlog_events[event] = combatlog_events[event] or {}
+ combatlog_events[event][func] = flags
+
+ index = index + 1
+ event = select(index, ...)
+ end
+ end
+
+ -- unregisters a func from cleu event(s)
+ function Skada:UnregisterFromCL(func)
+ if type(func) ~= "function" then return end
+ for _, funcs in pairs(combatlog_events) do
+ if funcs[func] then
+ funcs[func] = nil
+ break
+ end
+ end
+ end
+
+ local function combat_tick()
+ Skada._time = time()
+ if not Skada.disabled and Skada.current and not InCombatLockdown() and not IsGroupInCombat() and Skada.insType ~= "pvp" and Skada.insType ~= "arena" then
+ Skada:Debug("\124cffffbb00EndSegment\124r: Combat Tick")
+ combat_end()
+ end
+ end
+
+ local GetNumGroupMembers = GetNumGroupMembers
+ function combat_start()
+ Skada._time = time()
+
+ death_counter = 0
+ starting_members = GetNumGroupMembers()
+
+ if tentative_timer then
+ Skada:CancelTimer(tentative_timer, true)
+ tentative_timer = nil
+ end
+
+ if update_timer then
+ Skada:Debug("\124cffffbb00EndSegment\124r: StartCombat")
+ combat_end()
+ end
+
+ if Skada.current == nil then
+ Skada:Debug("\124cffffbb00StartCombat\124r: Segment Created!")
+ Skada.current = create_set(L["Current"], tentative_set)
+ end
+ tentative_set = nil
+
+ if Skada._encounter_name and GetTime() < (Skada._encounter_time or 0) + 15 then
+ Skada.current.mobname = Skada._encounter_name
+ Skada.current.gotboss = Skada._encounter_id or true
+ Skada:SendMessage("COMBAT_ENCOUNTER_START", Skada.current)
+ end
+
+ Skada._encounter_id = nil
+ Skada._encounter_name = nil
+ Skada._encounter_time = nil
+
+ if Skada.total == nil then
+ Skada.total = create_set(L["Total"], Skada.sets[0])
+ Skada.sets[0] = Skada.total
+ end
+
+ -- not yet flagged as started?
+ if not Skada.current.started then
+ Skada.current.started = true
+ local t = Skada.LastEvent
+ Skada:ScanGroupBuffs(t and t.timestamp)
+ Skada:SendMessage("COMBAT_PLAYER_ENTER", Skada.current, t)
+ end
+
+ Skada.inCombat = true
+ Skada:Wipe()
+
+ for i = 1, #windows do
+ local win = windows[i]
+ local db = win and win.db
+ if db then
+ -- combat mode switch
+ local mymode = find_mode(db.modeincombat)
+ if mymode then
+ if db.returnaftercombat then
+ if win.selectedset then
+ win.restore_set = win.selectedset
+ end
+ if win.selectedmode then
+ win.restore_mode = win.selectedmode.moduleName
+ end
+ end
+
+ win.selectedset = "current"
+ else
+ mymode = find_mode(db.mode)
+ end
+
+ if mymode then
+ win:DisplayMode(mymode)
+ end
+
+ -- combat switch to current
+ if db.autocurrent and win.selectedset ~= "current" then
+ win:SetSelectedSet("current")
+ end
+ end
+
+ if win and not P.tentativecombatstart then
+ win:Toggle()
+ end
+ end
+
+ Skada:UpdateDisplay(true)
+
+ if update_timer then
+ Skada:CancelTimer(update_timer, true)
+ update_timer = nil
+ end
+ update_timer = Skada:ScheduleRepeatingTimer("UpdateDisplay", P.updatefrequency or 0.5)
+
+ if tick_timer then
+ Skada:CancelTimer(tick_timer, true)
+ tick_timer = nil
+ end
+ tick_timer = Skada:ScheduleRepeatingTimer(combat_tick, 1)
+
+ if P.tentativecombatstart then
+ if toggle_timer then
+ Skada:CancelTimer(toggle_timer, true)
+ toggle_timer = nil
+ end
+ toggle_timer = Skada:ScheduleTimer("Toggle", 0.1)
+ elseif toggle_timer then
+ Skada:CancelTimer(toggle_timer, true)
+ toggle_timer = nil
+ end
+ end
+
+ local bit_band = bit.band
+ local GetInstanceInfo = GetInstanceInfo
+ local GetBattlefieldArenaFaction = GetBattlefieldArenaFaction
+ local BITMASK_CONTROL_PLAYER = COMBATLOG_OBJECT_CONTROL_PLAYER or 0x00000100
+
+ local function check_boss_fight(set, t, src_is_interesting, dst_is_interesting)
+ -- set mobname
+ if not set.mobname then
+ if Skada.insType == "pvp" or Skada.insType == "arena" then
+ set.type = Skada.insType
+ set.gotboss = false -- skip boss check
+ set.mobname = GetInstanceInfo()
+ set.faction = GetBattlefieldArenaFaction()
+ if set.type == "arena" then
+ Skada:SendMessage("COMBAT_ARENA_START", set, set.mobname)
+ end
+ elseif src_is_interesting and not t:DestIsFriendly() then
+ set.mobname = t.dstName
+ if bit_band(t.dstFlags or 0, BITMASK_CONTROL_PLAYER) ~= 0 then
+ set.type = "pvp"
+ set.gotboss = false
+ Skada:SendMessage("COMBAT_PVP_START", "pvp", Skada.insType)
+ end
+ elseif dst_is_interesting and not t:SourceIsFriendly() then
+ set.mobname = t.srcName
+ if bit_band(t.srcFlags or 0, BITMASK_CONTROL_PLAYER) ~= 0 then
+ set.type = "pvp"
+ set.gotboss = false
+ Skada:SendMessage("COMBAT_PVP_START", "pvp", Skada.insType)
+ end
+ end
+ end
+
+ -- set type
+ if not set.type then
+ if Skada.insType == nil then Skada:CheckZone() end
+ set.type = (Skada.insType == "none" and IsInGroup()) and "group" or Skada.insType
+ set.diff = (set.type == "party" or set.type == "raid") and Skada.insDiff
+ end
+
+ -- don't go further for arena/pvp
+ if set.type == "pvp" or set.type == "arena" then
+ return
+ end
+
+ -- boss already detected?
+ if set.gotboss then
+ -- default boss defeated event? (no DBM/BigWigs)
+ if not Skada.bossmod and death_events[t.event] and set.gotboss == GetCreatureId(t.dstGUID) then
+ bossdefeat_timer = bossdefeat_timer or Skada:ScheduleTimer(BossDefeated, 0.1)
+ end
+ return
+ end
+
+ -- marking set as boss fights relies only on src_is_interesting
+ if trigger_events[t.event] and src_is_interesting and not t:DestIsFriendly() then
+ if set.gotboss == nil then
+ if not _targets or not _targets[t.dstName] then
+ local isboss, bossid, bossname = Skada:IsEncounter(t.dstGUID, t.dstName)
+ if isboss then -- found?
+ set.mobname = bossname or set.mobname or t.dstName
+ set.gotboss = bossid or true
+ Skada:SendMessage("COMBAT_ENCOUNTER_START", set)
+ Skada:PrintFirstHit()
+ _targets = del(_targets)
+ else
+ _targets = _targets or new()
+ _targets[t.dstName] = true
+ set.gotboss = false
+ end
+ end
+ elseif _targets and not _targets[t.dstName] then
+ _targets[t.dstName] = true
+ set.gotboss = nil
+ end
+ end
+ end
+
+ local function check_autostop(set, event, src_is_interesting_nopets)
+ if event == "UNIT_DIED" and src_is_interesting_nopets then
+ death_counter = death_counter + 1
+ -- If we reached the treshold for stopping the segment, do so.
+ if death_counter >= starting_members * 0.5 and not set.stopped then
+ Skada:SendMessage("COMBAT_PLAYER_WIPE", set)
+ Skada:StopSegment(L["Stopping for wipe."])
+ end
+ elseif event == "SPELL_RESURRECT" and src_is_interesting_nopets then
+ death_counter = death_counter - 1
+ end
+ end
+
+ local function check_cached_names(t)
+ t.srcName = t.srcName and t.srcGUID and guidToName[t.srcGUID] or t.srcName
+ t.dstName = t.dstName and t.dstGUID and guidToName[t.dstGUID] or t.dstName
+ end
+
+ local function tentative_handler()
+ tentative_set = Skada.current
+ Skada.current = nil
+ tentative = nil
+ if tentative_timer then
+ Skada:CancelTimer(tentative_timer, true)
+ tentative_timer = nil
+ end
+ end
+
+ local GetTempUnit = Private.GetTempUnit
+ local src_is_interesting = false
+ local dst_is_interesting = false
+
+ function Skada:OnCombatEvent(t)
+ -- ignored combat event?
+ if (not t.event or ignored_events[t.event]) and not (spellcast_events[t.event] and self.current) then return end
+
+ src_is_interesting = false
+ dst_is_interesting = false
+
+ if not self.current and trigger_events[t.event] and t.srcName and t.dstName and t.srcGUID ~= t.dstGUID then
+ src_is_interesting = t:SourceInGroup() or t:SourceIsPet(true)
+
+ if t.event ~= "SPELL_PERIODIC_DAMAGE" then
+ dst_is_interesting = t:DestInGroup() or t:DestIsPet(true)
+ end
+
+ if src_is_interesting or dst_is_interesting then
+ self.current = create_set(L["Current"], tentative_set)
+ self.total = self.total or create_set(L["Total"])
+
+ if tentative_timer then
+ self:CancelTimer(tentative_timer, true)
+ tentative_timer = nil
+ end
+
+ tentative_timer = self:ScheduleTimer(tentative_handler, 1)
+ tentative = P.tentativecombatstart and 4 or 0
+
+ check_boss_fight(self.current, t, src_is_interesting, dst_is_interesting)
+ end
+ end
+
+ -- pet summons.
+ if t.event == "SPELL_SUMMON" and t:SourceInGroup() and t:DestIsPet() then
+ summon_pet(t.dstGUID, t.srcGUID)
+ -- pet died?
+ elseif death_events[t.event] and guidToOwner[t.dstGUID] then
+ dismiss_pet(t.dstGUID, 1)
+ end
+
+ -- current segment not created?
+ if not self.current then return end
+
+ -- autostop on wipe enabled?
+ if P.autostop and (t.event == "UNIT_DIED" or t.event == "SPELL_RESURRECT") then
+ check_autostop(self.current, t.event, t:SourceInGroup(true))
+ end
+
+ -- stopped or invalid events?
+ if self.current.stopped or not combatlog_events[t.event] then return end
+
+ self._Time = GetTime()
+ check_cached_names(t)
+
+ for func, flags in next, combatlog_events[t.event] do
+ local fail = false
+
+ if flags.src_is_interesting_nopets then
+ if t:SourceInGroup(true) then
+ src_is_interesting = true
+ else
+ fail = true
+ end
+ end
+
+ if not fail and flags.dst_is_interesting_nopets then
+ if t:DestInGroup(true) then
+ dst_is_interesting = true
+ else
+ fail = true
+ end
+ end
+
+ if not fail and (flags.src_is_interesting or flags.src_is_not_interesting) then
+ src_is_interesting = t:SourceInGroup() or t:SourceIsPet(true) or GetTempUnit(t.srcGUID)
+ if (flags.src_is_interesting and not src_is_interesting) or (flags.src_is_not_interesting and src_is_interesting) then
+ fail = true
+ end
+ end
+
+ if not fail and (flags.dst_is_interesting or flags.dst_is_not_interesting) then
+ dst_is_interesting = t:DestInGroup() or t:DestIsPet(true)
+ if (flags.dst_is_interesting and not dst_is_interesting) or (flags.dst_is_not_interesting and dst_is_interesting) then
+ fail = true
+ end
+ end
+
+ if not fail then
+ if tentative ~= nil then
+ tentative = tentative + 1
+ self:Debug(format("\124cffffbb00Tentative\124r: %s (%d)", t.event, tentative))
+ if tentative >= 5 then
+ self:CancelTimer(tentative_timer, true)
+ tentative_timer = nil
+ tentative = nil
+ self:Debug("\124cffffbb00StartCombat\124r: tentative combat")
+ combat_start()
+ end
+ end
+
+ -- avoid the rest of the code out of combat
+ if not self.inCombat then return end
+ func(t)
+ end
+ end
+
+ check_boss_fight(self.current, t, src_is_interesting, dst_is_interesting)
+ end
+end
diff --git a/Skada/Core/Display/Bar.lua b/Skada/Core/Display/Bar.lua
new file mode 100644
index 0000000..236a7ce
--- /dev/null
+++ b/Skada/Core/Display/Bar.lua
@@ -0,0 +1,2579 @@
+local folder, Skada = ...
+local Private = Skada.Private
+Skada:RegisterDisplay("Bar Display", "mod_bar_desc", function(L, P, G, _, _, O)
+ local mod = Skada:NewModule("Bar Display", Skada.displayPrototype, "SpecializedLibBars-1.0")
+ local LEFT_TO_RIGHT = mod.LEFT_TO_RIGHT or 1
+ local RIGHT_TO_LEFT = mod.RIGHT_TO_LEFT or 2
+ local callbacks = mod.callbacks
+
+ local pairs, tsort, format = pairs, table.sort, string.format
+ local max, min, abs = math.max, math.min, math.abs
+ local GameTooltip, GameTooltip_Hide = GameTooltip, GameTooltip_Hide
+ local SpellLink = Private.SpellLink or GetSpellLink
+ local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
+ local IsShiftKeyDown = IsShiftKeyDown
+ local IsAltKeyDown = IsAltKeyDown
+ local IsControlKeyDown = IsControlKeyDown
+ local IsModifierKeyDown = IsModifierKeyDown
+ local SavePosition = Private.SavePosition
+ local RestorePosition = Private.RestorePosition
+ local CheckDuplicate = Private.CheckDuplicate
+ local new, del, copy = Private.newTable, Private.delTable, Private.tCopy
+ local _
+
+ -- references
+ local validclass = Skada.validclass
+ local classcolors = Skada.classcolors
+ local classicons = Skada.classicons
+ local classcoords = Skada.classcoords
+ local roleicons = Skada.roleicons
+ local rolecoords = Skada.rolecoords
+ local specicons = Skada.specicons
+ local speccoords = Skada.speccoords
+ local spellschools = Skada.spellschools
+ local windows = Skada.windows
+
+ local WINDOW_DEFAULTS = Skada.windowdefaults
+ local COLOR_WHITE = HIGHLIGHT_FONT_COLOR
+ local FONT_FLAGS = Skada.fontFlags
+ if not FONT_FLAGS then
+ FONT_FLAGS = {
+ [""] = L["None"],
+ ["OUTLINE"] = L["Outline"],
+ ["THICK"] = L["Thick"],
+ ["THICKOUTLINE"] = L["Thick outline"],
+ ["MONOCHROME"] = L["Monochrome"],
+ ["OUTLINEMONOCHROME"] = L["Outlined monochrome"]
+ }
+ Skada.fontFlags = FONT_FLAGS
+ end
+
+ local function listOnMouseDown(self, button)
+ if button == "LeftButton" then
+ return
+ elseif IsShiftKeyDown() then
+ Skada:OpenMenu(self.win)
+ elseif IsControlKeyDown() then
+ Skada:SegmentMenu(self.win)
+ elseif IsAltKeyDown() then
+ Skada:ModeMenu(self.win, self)
+ elseif not self.clickthrough then
+ self.win:RightClick(nil, button)
+ end
+ end
+
+ local function anchorOnClick(self, button)
+ local bargroup = self:GetParent()
+ -- other buttons are reserved for other actions
+ if bargroup and button == "RightButton" then
+ if IsShiftKeyDown() then
+ Skada:OpenMenu(bargroup.win)
+ elseif IsControlKeyDown() then
+ Skada:SegmentMenu(bargroup.win)
+ elseif IsAltKeyDown() then
+ Skada:ModeMenu(bargroup.win, self, true)
+ elseif not bargroup.clickthrough and not Skada.testMode then
+ bargroup.win:RightClick(nil, button)
+ end
+ end
+ end
+
+ local buttonsTexPath = format([[%s\Textures\toolbar%%s\%%s]], Skada.mediapath)
+ do
+ local function AddWindowButton(win, style, index, title, description, func)
+ if win and win.AddButton and index then
+ return win:AddButton(index, title, description, format(buttonsTexPath, style or 1, index), nil, func)
+ end
+ end
+
+ local OpenOptions = Private.OpenOptions
+ local function configOnClick(self, button)
+ if button == "RightButton" then
+ OpenOptions(self.list.win)
+ elseif button == "LeftButton" then
+ Skada:OpenMenu(self.list.win)
+ end
+ end
+
+ local function resetOnClick(self, button)
+ if button == "LeftButton" and IsShiftKeyDown() then
+ Skada:DeleteSet(nil, self.list.win.selectedset)
+ elseif button == "LeftButton" then
+ Skada:ShowPopup(self.list.win)
+ end
+ end
+
+ local function segmentOnClick(self, button)
+ if IsModifierKeyDown() then
+ self.list.win:SetSelectedSet(nil, button == "RightButton" and 1 or -1)
+ elseif button == "MiddleButton" or button == "RightButton" then
+ self.list.win:SetSelectedSet("current")
+ elseif button == "LeftButton" then
+ Skada:SegmentMenu(self.list.win)
+ end
+ end
+
+ local function modeOnClick(self, button)
+ if button == "LeftButton" or button == "RightButton" then
+ Skada:ModeMenu(self.list.win, self, button == "RightButton")
+ end
+ end
+
+ local OpenReport = Private.OpenReport
+ local function reportOnClick(self, button)
+ if button == "LeftButton" then
+ OpenReport(self.list.win)
+ end
+ end
+
+ local function splitOnClick(self, button)
+ if button == "LeftButton" then
+ return Skada:NewSegment()
+ end
+ end
+
+ local function phaseOnClick(self, button)
+ if button == "LeftButton" then
+ return Skada:NewPhase()
+ end
+ end
+
+ local function stopOnClick(self, button)
+ if not Skada.current then
+ return
+ elseif Skada.tempsets and #Skada.tempsets > 0 then
+ if (IsShiftKeyDown() or button == "RightButton") and Skada.current.stopped then
+ Skada:ResumeSegment()
+ elseif IsShiftKeyDown() or button == "RightButton" then
+ Skada:StopSegment()
+ else
+ Skada:PhaseMenu(self.list.win)
+ end
+ elseif button == "LeftButton" and Skada.current.stopped then
+ Skada:ResumeSegment()
+ elseif button == "LeftButton" and Skada.current then
+ Skada:StopSegment()
+ end
+ end
+
+ function mod:Create(window, isnew)
+ -- Re-use bargroup if it exists.
+ local p = window.db
+ local bargroup = mod:GetBarGroup(p.name)
+
+ -- fix old oriantation & buttons texture
+ p.barorientation = max(LEFT_TO_RIGHT, min(RIGHT_TO_LEFT, p.barorientation or LEFT_TO_RIGHT))
+ p.title.toolbar = max(1, min(2, p.title.toolbar or 2))
+
+ if not bargroup then
+ bargroup = mod:NewBarGroup(
+ p.name, -- window name
+ p.barorientation, -- bars orientation
+ p.background.height, -- window height
+ p.barwidth, -- window width
+ p.barheight, -- bars height
+ format("%sBarWindow%s", folder, p.name) -- frame name
+ )
+
+ -- Add window buttons.
+ AddWindowButton(bargroup, p.title.toolbar, "config", L["Configure"], L["btn_config_desc"], configOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "reset", L["Reset"], L["btn_reset_desc"], resetOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "segment", L["Segment"], L["btn_segment_desc"], segmentOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "mode", L["Mode"], L["Jump to a specific mode."], modeOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "split", L["New Segment"], L["Starts a new segment."], splitOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "phase", L["New Phase"], L["Starts a new phase."], phaseOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "report", L["Report"], L["btn_report_desc"], reportOnClick)
+ AddWindowButton(bargroup, p.title.toolbar, "stop", L["Stop"], L["btn_stop_desc"], stopOnClick)
+ end
+
+ bargroup.win = window
+ bargroup:EnableMouse(true)
+ bargroup:HookScript("OnMouseDown", listOnMouseDown)
+ bargroup:HideBarIcons()
+
+ bargroup.button:SetScript("OnClick", anchorOnClick)
+ bargroup.button:SetHeight(p.title.height or 15)
+ bargroup:SetAnchorMouseover(p.title.hovermode)
+
+ if isnew then -- save position if new
+ SavePosition(bargroup, p)
+ else -- restore position if not
+ RestorePosition(bargroup, p)
+ end
+
+ window.bargroup = bargroup
+ end
+ end
+
+ function mod:SetTitle(win, title)
+ local bargroup = win and win.bargroup
+ if not bargroup then return end
+
+ bargroup.button:SetText(title or win.title or win.metadata.title)
+
+ -- module icon
+ if not win.db.moduleicons then
+ bargroup:HideAnchorIcon()
+ elseif win.selectedmode and win.selectedmode.metadata and win.selectedmode.metadata.icon then
+ bargroup:ShowAnchorIcon(win.selectedmode.metadata.icon)
+ elseif win.parentmode and win.parentmode.metadata and win.parentmode.metadata.icon then
+ bargroup:ShowAnchorIcon(win.parentmode.metadata.icon)
+ end
+ end
+
+ do
+ local ttactive = false
+
+ function mod:BarEnter(_, bar, motion)
+ local win = bar and bar.win
+ if not win then return end
+
+ local id, label, class = bar.id, bar.text, bar.class
+ Skada:SetTooltipPosition(GameTooltip, win.bargroup, "bar", win)
+ Skada:ShowTooltip(win, id, label, bar, class)
+ ttactive = true
+ end
+
+ function mod:BarLeave(_, bar, motion)
+ if not ttactive then return end
+ GameTooltip:Hide()
+ ttactive = false
+ end
+ end
+
+ function mod:BarReleased(_, bar)
+ if not bar then return end
+
+ bar.changed = nil
+ bar.fixed = nil
+ bar.order = nil
+ bar.text = nil
+ bar.win = nil
+
+ bar.iconFrame:SetScript("OnEnter", nil)
+ bar.iconFrame:SetScript("OnLeave", nil)
+ bar.iconFrame:SetScript("OnMouseDown", nil)
+ bar.iconFrame:EnableMouse(false)
+ end
+
+ do
+ local function stop_move(group, children, deep)
+ local p = group and group.win and group.win.db
+ if not p then return end
+
+ -- the window wasn't sticked to any? remove just incase
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.name ~= p.name and win.db.display == "bar" then
+ if win.db.sticked and win.db.sticked[p.name] and not deep then
+ win.db.sticked[p.name] = nil
+ -- remove table if empty
+ if next(win.db.sticked) == nil then
+ win.db.sticked = del(win.db.sticked)
+ end
+ SavePosition(win.bargroup, win.db)
+ end
+
+ -- save other window posotions if sticked to this!
+ if children and children[win.db.name] then
+ SavePosition(win.bargroup, win.db)
+ stop_move(win.bargroup, win.db.sticked, true)
+ end
+ end
+ end
+ end
+
+ function mod:WindowMoveStop(_, group)
+ SavePosition(group, group.win.db) -- save window position
+
+ -- handle sticked windows
+ if group.win.db.sticky and not group.locked then
+ local p = group.win.db
+
+ -- attempt to stick to the closest frame.
+ local offset = p.background.borderthickness
+ local _, _, frame = group:StickToClosestFrameInGroup(folder, nil, offset, offset)
+
+ -- found a frame to stick it to?
+ if frame then
+ -- nothing to do
+ SavePosition(group, p)
+ else
+ stop_move(group, p.sticked)
+ end
+ end
+
+ Skada:CloseMenus()
+ Skada:NotifyChange()
+ end
+ end
+
+ do
+ local function start_move(group, children, offset)
+ if not children then return end
+ for i = 1, #windows do
+ local win = windows[i]
+ local p = win and win.db
+ if p and p.display == "bar" and children[win.name] then
+ win.bargroup:Stick(group, nil, offset, offset)
+ start_move(win.bargroup, p.sticked, p.background.borderthickness)
+ end
+ end
+ end
+
+ function mod:WindowMoveStart(_, group)
+ local p = group and group.win and group.win.db
+ if p and p.sticky and not p.hidden then
+ local offset = p.background.borderthickness
+ start_move(group, p.sticked, offset)
+ end
+ end
+ end
+
+ function mod:WindowResized(_, group)
+ local p = group.win.db
+ local width, height = group:GetSize()
+
+ -- Snap to best fit
+ if p.snapto then
+ local maxbars = group:GetMaxBars()
+ local sheight = height
+
+ if p.enabletitle then
+ sheight = p.title.height + p.baroffset + ((p.barheight + p.barspacing) * maxbars) - p.barspacing
+ else
+ sheight = ((p.barheight + p.barspacing) * maxbars) - p.barspacing
+ end
+
+ height = sheight
+ end
+
+ p.barwidth = width
+ p.background.height = height
+
+ -- resize sticked windows as well.
+ if p.sticky then
+ local offset = p.background.borderthickness
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.display == "bar" and win.bargroup:IsShown() and p.sticked and p.sticked[win.db.name] then
+ callbacks:Fire("WindowMoveStop", win.bargroup)
+ end
+ end
+ end
+
+ SavePosition(group, p)
+ Skada:ApplySettings(p.name)
+ Skada:NotifyChange()
+ end
+
+ function mod:WindowLocked(_, group, locked)
+ if group and group.win and group.win.db then
+ group.win.db.barslocked = locked
+ end
+ end
+
+ function mod:WindowStretching(_, group)
+ if group and group.backdropA and group.backdropA < 0.85 then
+ group.backdropA = min(0.85, max(0, group.backdropA + 0.015))
+ group:SetBackdropColor(group.backdropR, group.backdropG, group.backdropB, group.backdropA)
+ end
+ end
+
+ function mod:WindowStretchStart(_, group)
+ if group then
+ group.backdropR, group.backdropG, group.backdropB, group.backdropA = group:GetBackdropColor()
+ group:SetBackdropColor(0, 0, 0, group.backdropA)
+ group:SetFrameStrata("TOOLTIP")
+ end
+ Skada:CloseMenus()
+ end
+
+ function mod:WindowStretchStop(_, group)
+ if group and group.win and group.win.db then
+ -- not longer needed
+ group.backdropR = nil
+ group.backdropG = nil
+ group.backdropB = nil
+ group.backdropA = nil
+
+ local p = group.win.db
+ group:SetBackdropColor(p.background.color.r, p.background.color.g, p.background.color.b, p.background.color.a or 1)
+ group:SetFrameStrata(p.strata)
+ end
+ end
+
+ function mod:CreateBar(win, name, label, value, maxvalue, icon)
+ local bar, isnew = win.bargroup:NewBar(name, label, value, maxvalue, icon)
+ bar.win = win
+ return bar, isnew
+ end
+
+ -- ======================================================= --
+
+ do
+ -- these anchors are used to correctly position the windows due
+ -- to the title bar overlapping.
+ local Xanchors = {LT = true, LB = true, LC = true, RT = true, RB = true, RC = true}
+ local Yanchors = {TL = true, TR = true, TC = true, BL = true, BR = true, BC = true}
+
+ function mod:OnAnchorFrame(_, group, frame, anchor, x, y)
+ local p = group and group.win and group.win.db
+ local q = frame and frame.win and frame.win.db
+ if not p or not q then return end
+
+ -- change the window it is sticked to.
+ q.sticked = q.sticked or new()
+ q.sticked[p.name] = true
+
+ -- if the window that we are sticking this one to was
+ -- sticked to it, we make sure to remove it from table.
+ if p.sticked then
+ p.sticked[q.name] = nil
+ end
+
+ -- bar spacing first
+ p.barspacing = q.barspacing
+ group:SetSpacing(p.barspacing)
+
+ -- change the width of the window accordingly
+ if Yanchors[anchor] then
+ -- we change things related to height
+ p.barwidth = q.barwidth
+ group:SetLength(p.barwidth)
+ elseif Xanchors[anchor] then
+ -- window height
+ p.background.height = q.background.height
+ group:SetHeight(p.background.height)
+
+ -- title bar height
+ p.title.height = q.title.height
+ group.button:SetHeight(p.title.height)
+ group:AdjustButtons()
+
+ -- bars height
+ p.barheight = q.barheight
+ group:SetBarHeight(p.barheight)
+
+ group:SortBars()
+ end
+
+ SavePosition(group, p)
+ end
+
+ -- remove all windows that were sticked to this!
+ function mod:OnRemoveFrame(_, group, _, name)
+ local p = group and group.win and group.win.db
+ if p and p.sticked then
+ p.sticked = del(p.sticked)
+ end
+ end
+ end
+
+ -- ======================================================= --
+
+ do
+ local function inserthistory(win)
+ if win.selectedmode and win.history[#win.history] ~= win.selectedmode then
+ win.history[#win.history + 1] = win.selectedmode
+ if win.child and (win.db.childmode == 1 or win.db.childmode == 3) then
+ inserthistory(win.child)
+ end
+ end
+ end
+
+ local function onEnter(win, id, label, class, mode)
+ mode:Enter(win, id, label, class)
+ if win.child and (win.db.childmode == 1 or win.db.childmode == 3) then
+ onEnter(win.child, id, label, class, mode)
+ end
+ end
+
+ local total_noclick = Private.total_noclick
+ local function showmode(win, id, label, class, mode)
+ if total_noclick(win.selectedset, mode) then
+ return
+ end
+
+ inserthistory(win)
+
+ if type(mode) == "function" then
+ mode(win, id, label, class)
+ else
+ if mode.Enter then
+ onEnter(win, id, label, class, mode)
+ end
+ win:DisplayMode(mode)
+ end
+
+ Skada:CloseMenus()
+ GameTooltip:Hide()
+ end
+
+ local function BarClickIgnore(bar, button)
+ if not bar.win then
+ return
+ elseif IsShiftKeyDown() and button == "RightButton" then
+ Skada:OpenMenu(bar.win)
+ elseif IsControlKeyDown() and button == "RightButton" then
+ Skada:SegmentMenu(bar.win)
+ elseif IsAltKeyDown() and button == "RightButton" then
+ Skada:ModeMenu(bar.win, bar)
+ elseif button == "RightButton" then
+ bar.win:RightClick(bar, button)
+ elseif IsAltKeyDown() and bar.win.class then
+ bar.win.class = nil
+ bar.win:UpdateDisplay()
+ end
+ end
+
+ function mod:BarClick(_, bar, button)
+ local win = not Skada.testMode and bar and bar.win
+ if not win then return end
+
+ local id, label, class = bar.id, bar.text, bar.class
+
+ if button == self.db.button then
+ self:ScrollStart(win)
+ elseif button == "RightButton" and IsShiftKeyDown() then
+ Skada:OpenMenu(win)
+ elseif button == "RightButton" and IsAltKeyDown() then
+ Skada:ModeMenu(win, bar)
+ elseif button == "RightButton" and IsControlKeyDown() then
+ Skada:SegmentMenu(win)
+ elseif win.metadata.click then
+ win.metadata.click(win, id, label, button, class)
+ elseif button == "RightButton" and not IsModifierKeyDown() then
+ win:RightClick(bar, button)
+ elseif button == "LeftButton" and win.metadata.click2 and IsShiftKeyDown() then
+ showmode(win, id, label, class, win.metadata.click2)
+ elseif button == "LeftButton" and win.metadata.filterclass and IsAltKeyDown() then
+ win:FilterClass(class)
+ elseif button == "LeftButton" and win.metadata.click3 and IsControlKeyDown() then
+ showmode(win, id, label, class, win.metadata.click3)
+ elseif button == "LeftButton" and win.metadata.click1 and not IsModifierKeyDown() then
+ showmode(win, id, label, class, win.metadata.click1)
+ end
+ end
+
+ local function barOnSizeChanged(bar)
+ if bar.bgwidth then
+ bar.bg:SetWidth(bar.bgwidth * bar:GetWidth())
+ else
+ bar:SetScript("OnSizeChanged", bar.OnSizeChanged)
+ end
+ bar:OnSizeChanged()
+ end
+
+ local function iconOnEnter(icon)
+ local bar = icon.bar
+ local win = bar.win
+ if bar.link and win and win.bargroup then
+ Skada:SetTooltipPosition(GameTooltip, win.bargroup, "bar", win)
+ GameTooltip:SetHyperlink(bar.link)
+ GameTooltip:Show()
+ end
+ end
+
+ local function iconOnMouseDown(icon)
+ local bar = icon.bar
+ if not IsShiftKeyDown() or not bar.link then
+ return
+ end
+ local activeEditBox = ChatEdit_GetActiveWindow()
+ if activeEditBox then
+ ChatEdit_InsertLink(bar.link)
+ else
+ ChatFrame_OpenChat(bar.link, DEFAULT_CHAT_FRAME)
+ end
+ end
+
+ local function value_sort(a, b)
+ if not a or a.value == nil then
+ return false
+ elseif not b or b.value == nil then
+ return true
+ elseif a.value < b.value then
+ return false
+ elseif a.value > b.value then
+ return true
+ elseif not a.label then
+ return false
+ elseif not b.label then
+ return true
+ else
+ return a.label > b.label
+ end
+ end
+
+ local function bar_order_sort(a, b)
+ if not a or a.order == nil then
+ return true
+ elseif not b or b.order == nil then
+ return false
+ elseif a.order < b.order then
+ return true
+ elseif a.order > b.order then
+ return false
+ elseif not a.GetLabel then
+ return true
+ elseif not b.GetLabel then
+ return false
+ else
+ return a:GetLabel() < b:GetLabel()
+ end
+ end
+
+ local function bar_order_reverse_sort(a, b)
+ if not a or a.order == nil then
+ return false
+ elseif not b or b.order == nil then
+ return true
+ elseif a.order < b.order then
+ return false
+ elseif a.order > b.order then
+ return true
+ elseif not a.GetLabel then
+ return false
+ elseif not b.GetLabel then
+ return true
+ else
+ return a:GetLabel() > b:GetLabel()
+ end
+ end
+
+ local function bar_seticon(bar, db, data, icon)
+ if icon then
+ bar:SetIcon(icon)
+ bar:ShowIcon()
+ elseif db.specicons and data.spec and speccoords[data.spec] then
+ bar:SetIcon(specicons, speccoords(data.spec))
+ bar:ShowIcon()
+ elseif db.roleicons and data.role then
+ bar:SetIcon(roleicons, rolecoords(data.role))
+ bar:ShowIcon()
+ elseif db.classicons and data.class and data.icon == nil then
+ bar:SetIcon(classicons, classcoords(data.class))
+ bar:ShowIcon()
+ elseif data.icon and not data.ignore and not data.spellid and not data.hyperlink then
+ bar:SetIcon(data.icon)
+ bar:ShowIcon()
+ end
+ end
+
+ local function bar_setcolor(bar, db, data, color)
+ local default = db.barcolor or WINDOW_DEFAULTS.barcolor
+ if not color and data.color then
+ color = data.color
+ elseif not color and db.spellschoolcolors and data.spellschool and spellschools[data.spellschool] then
+ color = spellschools[data.spellschool]
+ elseif not color and db.useselfcolor and db.selfcolor and data.id == Skada.userGUID then
+ color = db.selfcolor
+ elseif not color and db.classcolorbars and data.class then
+ color = classcolors(data.class)
+ end
+ if color then
+ bar:SetColor(color.r, color.g, color.b, color.a or default.a or 1, true)
+ else
+ bar:SetColor(default.r, default.g, default.b, default.a or 1)
+ end
+ end
+
+ function mod:Update(win)
+ local bargroup = win and win.bargroup
+ if not bargroup then return end
+ bargroup.button:SetText(win.metadata.title)
+
+ local metadata = win.metadata
+ local dataset = win.dataset
+
+ if metadata.showspots or metadata.valueorder then
+ tsort(dataset, value_sort)
+ end
+
+ local db = win.db
+ local hasicon = nil
+ for i = 0, #dataset do
+ local data = dataset[i]
+ if
+ (data and data.icon and not data.ignore) or
+ (data and db.classicons and data.class) or
+ (data and db.roleicons and data.role) or
+ (data and db.specicons and data.spec)
+ then
+ hasicon = true
+ break
+ end
+ end
+
+ if hasicon and not bargroup.showIcon then
+ bargroup:ShowBarIcons()
+ end
+ if not hasicon and bargroup.showIcon then
+ bargroup:HideBarIcons()
+ end
+
+ if metadata.wipestale then
+ for _, bar in pairs(bargroup:GetBars()) do
+ bar.checked = nil
+ end
+ end
+
+ local nr = 1
+ for i = 0, #dataset do
+ local data = dataset[i]
+ if data and data.id then
+ local bar = bargroup:GetBar(data.id)
+
+ -- bar generated before class info? remove it...
+ if bar and bar.missingclass and data.class and not data.ignore then
+ bar:Hide()
+ bargroup:RemoveBar(bar)
+ bar.missingclass = nil
+ bar = nil
+ end
+
+ if bar then
+ bar.class = data.class
+ bar:SetValue(data.value)
+ bar:SetMaxValue(metadata.maxvalue or 1)
+
+ if data.changed and not bar.changed then
+ bar.changed = true
+ bar_seticon(bar, db, data, data.icon)
+ bar_setcolor(bar, db, data, data.color)
+ elseif not data.changed and bar.changed then
+ bar.changed = nil
+ bar_seticon(bar, db, data)
+ bar_setcolor(bar, db, data)
+ end
+ else
+ -- Initialization of bars.
+ bar = mod:CreateBar(win, data.id, data.label, data.value, metadata.maxvalue or 1, data.icon)
+ bar.id = data.id
+ bar.text = data.label
+ bar.class = data.class
+ bar.fixed = nil
+
+ if not data.ignore then
+ if data.icon then
+ bar:ShowIcon()
+
+ bar.link = nil
+ if data.spellid then
+ bar.link = SpellLink(abs(data.spellid))
+ elseif data.hyperlink then
+ bar.link = data.hyperlink
+ end
+
+ if bar.link then
+ bar.iconFrame:EnableMouse(true)
+ bar.iconFrame:SetScript("OnEnter", iconOnEnter)
+ bar.iconFrame:SetScript("OnLeave", GameTooltip_Hide)
+ bar.iconFrame:SetScript("OnMouseDown", iconOnMouseDown)
+ end
+ end
+
+ bar:EnableMouse(not db.clickthrough)
+ else
+ bar:SetScript("OnEnter", nil)
+ bar:SetScript("OnLeave", nil)
+ bar:SetScript("OnMouseDown", BarClickIgnore)
+ end
+
+ bar:SetValue(data.value)
+
+ if not data.class and (db.classicons or db.classcolorbars or db.classcolortext) then
+ bar.missingclass = true
+ else
+ bar.missingclass = nil
+ end
+
+ -- set bar icon and color
+ bar_seticon(bar, db, data)
+ bar_setcolor(bar, db, data)
+
+ if validclass[data.class] and (db.classcolortext or db.classcolorleft or db.classcolorright) then
+ local c = classcolors(data.class)
+ if db.classcolortext or db.classcolorleft then
+ bar.label:SetTextColor(c.r, c.g, c.b, c.a or 1)
+ end
+ if db.classcolortext or db.classcolorright then
+ bar.timerLabel:SetTextColor(c.r, c.g, c.b, c.a or 1)
+ end
+ else
+ local c = db.textcolor or COLOR_WHITE
+ bar.label:SetTextColor(c.r, c.g, c.b, c.a or 1)
+ bar.timerLabel:SetTextColor(c.r, c.g, c.b, c.a or 1)
+ end
+
+ if bargroup.showself and data.id == Skada.userGUID then
+ bar.fixed = true
+ end
+ end
+
+ if metadata.ordersort or metadata.reversesort then
+ bar.order = i
+ end
+
+ if metadata.showspots and P.showranks and not data.ignore then
+ if db.barorientation == 1 then
+ bar:SetLabel(format("%d. %s", nr, data.text or data.label or L["Unknown"]))
+ else
+ bar:SetLabel(format("%s .%d", data.text or data.label or L["Unknown"], nr))
+ end
+ else
+ bar:SetLabel(data.text or data.label or L["Unknown"])
+ end
+ bar:SetTimerLabel(data.valuetext)
+
+ if metadata.wipestale then
+ bar.checked = true
+ end
+
+ if data.emphathize and bar.emphathize_set ~= true then
+ bar:SetFont(nil, nil, "OUTLINE", nil, nil, "OUTLINE")
+ bar.emphathize_set = true
+ elseif not data.emphathize and bar.emphathize_set ~= false then
+ bar:SetFont(nil, nil, db.barfontflags, nil, nil, db.numfontflags)
+ bar.emphathize_set = false
+ end
+
+ if data.backgroundcolor then
+ bar.bg:SetVertexColor(
+ data.backgroundcolor.r,
+ data.backgroundcolor.g,
+ data.backgroundcolor.b,
+ data.backgroundcolor.a or 1
+ )
+ end
+
+ if data.backgroundwidth then
+ bar.bg:ClearAllPoints()
+ bar.bg:SetPoint("BOTTOMLEFT")
+ bar.bg:SetPoint("TOPLEFT")
+ bar.bgwidth = data.backgroundwidth
+ bar:SetScript("OnSizeChanged", barOnSizeChanged)
+ barOnSizeChanged(bar)
+ else
+ bar.bgwidth = nil
+ end
+
+ if not data.ignore then
+ nr = nr + 1
+ end
+ end
+ end
+
+ if metadata.wipestale then
+ for _, bar in pairs(bargroup:GetBars()) do
+ if not bar.checked then
+ bargroup:RemoveBar(bar)
+ end
+ end
+ end
+
+ if metadata.reversesort then
+ bargroup:SetSortFunction(bar_order_reverse_sort)
+ elseif metadata.ordersort then
+ bargroup:SetSortFunction(db.reversegrowth and bar_order_reverse_sort or bar_order_sort)
+ else
+ bargroup:SetSortFunction(nil)
+ end
+
+ bargroup:SortBars()
+ end
+ end
+
+ -- ======================================================= --
+
+ do
+ local math_abs = math.abs
+ local CreateFrame = CreateFrame
+ local SetCursor = SetCursor
+ local ResetCursor = ResetCursor
+ local GetCursorPosition = GetCursorPosition
+ local IsMouseButtonDown = IsMouseButtonDown
+
+ local f = CreateFrame("Frame")
+ local scrollWin = nil
+ local cursorYPos = nil
+ local lastUpdated = 0
+ local start_scroll = nil
+ local stop_scroll = nil
+
+ local function ShowCursor(win)
+ if not mod.db.icon then return end
+
+ SetCursor("")
+ local icon = win.scroll_icon
+ if not icon then
+ icon = CreateFrame("Frame", nil, win.bargroup)
+ icon:SetWidth(32)
+ icon:SetHeight(32)
+ icon:SetPoint("CENTER")
+ icon:SetFrameLevel(win.bargroup:GetFrameLevel() + 6)
+
+ local t = icon:CreateTexture(nil, "OVERLAY")
+ t:SetTexture(format([[%s\Textures\icon-scroll]], Skada.mediapath))
+ t:SetAllPoints(icon)
+
+ win.scroll_icon = icon
+ end
+ icon:Show()
+ end
+
+ local function HideCursor(win)
+ local icon = win and win.scroll_icon
+ if not icon then return end
+ ResetCursor()
+ icon:Hide()
+ end
+
+ local function OnMouseWheel(win, direction)
+ win.OnMouseWheel = win.OnMouseWheel or win:GetScript("OnMouseWheel")
+ win.OnMouseWheel(win, direction)
+ end
+
+ local function OnUpdate(self, elapsed)
+ -- no scrolled window
+ if not scrollWin then
+ stop_scroll()
+ return
+ end
+
+ -- db button isn't used
+ if not IsMouseButtonDown(mod.db.button) then
+ mod:EndScroll(scrollWin)
+ return
+ end
+
+ ShowCursor(scrollWin)
+ lastUpdated = lastUpdated + elapsed
+ if lastUpdated <= 0.1 then return end
+ lastUpdated = 0
+
+ local _, newpos = GetCursorPosition()
+ local step = (scrollWin.db.barheight + scrollWin.db.barspacing) / (scrollWin.bargroup:GetEffectiveScale() * mod.db.speed)
+ while math_abs(newpos - cursorYPos) > step do
+ if newpos > cursorYPos then
+ OnMouseWheel(scrollWin.bargroup, 1)
+ cursorYPos = cursorYPos + step
+ else
+ OnMouseWheel(scrollWin.bargroup, -1)
+ cursorYPos = cursorYPos - step
+ end
+ end
+ end
+
+ function start_scroll()
+ f:SetScript("OnUpdate", OnUpdate)
+ f:Show()
+ end
+
+ function stop_scroll()
+ f:SetScript("OnUpdate", nil)
+ f:Hide()
+ end
+
+ function mod:ScrollStart(win)
+ _, cursorYPos = GetCursorPosition()
+ scrollWin = win
+ ShowCursor(win)
+ start_scroll()
+ end
+
+ function mod:EndScroll(win)
+ scrollWin = nil
+ HideCursor(win)
+ stop_scroll()
+ end
+
+ function Skada:Scroll(up)
+ for _, win in pairs(mod:GetBarGroups()) do
+ OnMouseWheel(win, up and 1 or -1)
+ end
+ end
+ end
+
+ -- ======================================================= --
+
+ do
+ local backdrop = {insets = {left = 0, right = 0, top = 0, bottom = 0}}
+
+ -- Called by Skada windows when window settings have changed.
+ function mod:ApplySettings(win)
+ if not win or not win.bargroup then return end
+
+ local g = win.bargroup
+ local p = win.db
+
+ g.name = p.name -- update name
+ g:SetReverseGrowth(p.reversegrowth)
+ g:SetOrientation(p.barorientation)
+ g:SetBarHeight(p.barheight)
+ g:SetHeight(p.background.height)
+ g:SetLength(p.barwidth)
+ g:SetTexture(Skada:MediaFetch("statusbar", p.bartexture))
+ g:SetDisableHighlight(p.disablehighlight)
+ g:SetBarBackgroundColor(p.barbgcolor.r, p.barbgcolor.g, p.barbgcolor.b, p.barbgcolor.a or 0.6)
+ g:SetAnchorMouseover(p.title.hovermode)
+ g:SetButtonsOpacity(p.title.toolbaropacity or 0.25)
+ g:SetButtonsSpacing(p.title.spacing or 1)
+ g:SetUseSpark(p.spark)
+ g:SetDisableResize(p.noresize)
+ g:SetDisableStretch(p.nostrech)
+ g:SetReverseStretch(p.botstretch)
+ g:SetFont(Skada:MediaFetch("font", p.barfont), p.barfontsize, p.barfontflags, Skada:MediaFetch("font", p.numfont), p.numfontsize, p.numfontflags)
+ g:SetSpacing(p.barspacing)
+ g:SetColor(p.barcolor.r, p.barcolor.g, p.barcolor.b, p.barcolor.a)
+ g:SetLocked(p.barslocked)
+ g:SetDisplacement(p.baroffset or 0)
+
+ if p.strata then
+ g:SetFrameStrata(p.strata)
+ end
+
+ -- Header
+ local fo = g.TitleFont or CreateFont(format("%s%sTitleFont", folder, win.db.name))
+ g.TitleFont = fo
+ fo:SetFont(p.title.fontpath or Skada:MediaFetch("font", p.title.font), p.title.fontsize, p.title.fontflags)
+ if p.title.textcolor then
+ fo:SetTextColor(p.title.textcolor.r, p.title.textcolor.g, p.title.textcolor.b, p.title.textcolor.a)
+ end
+ g.button:SetNormalFontObject(fo)
+ g.button:SetHeight(p.title.height or 15)
+
+ backdrop.bgFile = p.title.texturepath or Skada:MediaFetch("statusbar", p.title.texture)
+ backdrop.tile = false
+ backdrop.tileSize = 0
+ backdrop.edgeSize = p.title.borderthickness
+ backdrop.insets.left, backdrop.insets.right = 0, 0
+ backdrop.insets.top, backdrop.insets.bottom = 0, 0
+ g.button:SetBackdrop(backdrop)
+
+ local color = p.title.color
+ g.button:SetBackdropColor(color.r, color.g, color.b, color.a or 1)
+ Skada:ApplyBorder(g.button, p.title.bordertexture, p.title.bordercolor, p.title.borderthickness, p.title.borderinsets)
+
+ if g.stretcher then
+ g.stretcher.bg:SetTexture(backdrop.bgFile)
+ g.stretcher.bg:SetVertexColor(color.r, color.g, color.b, color.a or 1)
+ end
+
+ g.button.toolbar = g.button.toolbar or p.title.toolbar or 1
+ if g.button.toolbar ~= p.title.toolbar then
+ g.button.toolbar = p.title.toolbar or 1
+ for i = 1, #g.buttons do
+ local b = g.buttons[i]
+ b.normalTex:SetTexture(format(buttonsTexPath, g.button.toolbar, b.index))
+ b.highlightTex:SetTexture(format(buttonsTexPath, g.button.toolbar, b.index), 1.0)
+ end
+ end
+
+ if p.enabletitle then
+ g:ShowAnchor()
+
+ g:ShowButton(L["Configure"], p.buttons.menu)
+ g:ShowButton(L["Reset"], p.buttons.reset)
+ g:ShowButton(L["Segment"], p.buttons.segment)
+ g:ShowButton(L["Mode"], p.buttons.mode)
+ g:ShowButton(L["New Phase"], p.buttons.phase)
+ g:ShowButton(L["New Segment"], p.buttons.split)
+ g:ShowButton(L["Report"], p.buttons.report)
+ g:ShowButton(L["Stop"], p.buttons.stop)
+ else
+ g:HideAnchor()
+ end
+
+ backdrop.bgFile = p.background.texturepath or Skada:MediaFetch("background", p.background.texture)
+ backdrop.tile = p.background.tile
+ backdrop.tileSize = p.background.tilesize
+ backdrop.insets.left, backdrop.insets.right = 0, 0
+ backdrop.insets.top, backdrop.insets.bottom = 0, 0
+ if p.enabletitle and p.reversegrowth then
+ backdrop.insets.top = 0
+ backdrop.insets.bottom = p.title.height
+ elseif p.enabletitle then
+ backdrop.insets.top = p.title.height
+ backdrop.insets.bottom = 0
+ end
+ g:SetBackdrop(backdrop)
+
+ color = p.background.color
+ g:SetBackdropColor(color.r, color.g, color.b, color.a or 1)
+ Skada:ApplyBorder(g, p.background.bordertexture, p.background.bordercolor, p.background.borderthickness, p.background.borderinsets)
+
+ color = p.textcolor or COLOR_WHITE
+ g:SetTextColor(color.r, color.g, color.b, color.a or 1)
+ g:SetSticky(p.sticky, folder)
+
+ -- make player's bar fixed.
+ g.showself = P.showself or p.showself
+
+ g:SetClickthrough(p.clickthrough)
+ g:SetClampedToScreen(p.clamped == true)
+ g:SetSmoothing(p.smoothing)
+ g:SetShown(not p.hidden)
+ g:SetScale(p.scale or 1)
+ g:SortBars()
+
+ -- restore position
+ RestorePosition(g, p)
+ end
+
+ function mod:WindowResizing(_, group)
+ if group and not group.isStretching and group.win and group.win.db and group.win.db.sticky then
+ local offset = group.win.db.background.borderthickness
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.display == "bar" and win.bargroup:IsShown() and group.win.db.sticked and group.win.db.sticked[win.db.name] then
+ win.bargroup:Stick(group, nil, offset, offset)
+ end
+ end
+ end
+ end
+ end
+
+ local optionsValues = {
+ ORIENTATION = {
+ [LEFT_TO_RIGHT] = L["Left to right"],
+ [RIGHT_TO_LEFT] = L["Right to left"]
+ },
+ TITLEBTNS = {
+ [1] = format("\124T%s:22:88\124t", format(buttonsTexPath, 1, "_prev")),
+ [2] = format("\124T%s:22:88\124t", format(buttonsTexPath, 2, "_prev"))
+ }
+ }
+
+ local FrameOptions = Private.FrameOptions
+
+ function mod:AddDisplayOptions(win, options)
+ local db = win.db
+
+ options.baroptions = {
+ type = "group",
+ name = L["Bars"],
+ desc = format(L["Options for %s."], L["Bars"]),
+ childGroups = "tab",
+ order = 10,
+ get = function(i)
+ return db[i[#i]]
+ end,
+ set = function(i, val)
+ local key = i[#i]
+ db[key] = (type(val) == "boolean" and val or nil) or val
+ if key == "showtotals" or key == "classcolortext" or key == "classcolorleft" or key == "classcolorright" then
+ win:Wipe(true)
+ end
+ Skada:ApplySettings(win)
+ end,
+ args = {
+ general = {
+ type = "group",
+ name = L["General"],
+ desc = format(L["General options for %s."], L["Bars"]),
+ order = 10,
+ args = {
+ bartexture = {
+ type = "select",
+ name = L["Bar Texture"],
+ desc = L["The texture used by all bars."],
+ order = 10,
+ width = "double",
+ dialogControl = "LSM30_Statusbar",
+ values = Skada:MediaList("statusbar")
+ },
+ barheight = {
+ type = "range",
+ name = L["Height"],
+ desc = format(L["The height of %s."], L["Bars"]),
+ order = 20,
+ min = 10,
+ max = 40,
+ step = 0.01,
+ bigStep = 1
+ },
+ barwidth = {
+ type = "range",
+ name = L["Width"],
+ desc = format(L["The width of %s."], L["Bars"]),
+ order = 30,
+ min = 80,
+ max = 400,
+ step = 0.01,
+ bigStep = 1
+ },
+ barspacing = {
+ type = "range",
+ name = L["Spacing"],
+ desc = format(L["Distance between %s."], L["Bars"]),
+ order = 40,
+ min = 0,
+ max = 10,
+ step = 0.01,
+ bigStep = 1
+ },
+ baroffset = {
+ type = "range",
+ name = L["Displacement"],
+ desc = L["The distance between the edge of the window and the first bar."],
+ order = 50,
+ min = 0,
+ max = 40,
+ step = 0.01,
+ bigStep = 1
+ },
+ barorientation = {
+ type = "select",
+ name = L["Bar Orientation"],
+ desc = L["The direction the bars are drawn in."],
+ order = 60,
+ width = "double",
+ values = optionsValues.ORIENTATION
+ },
+ reversegrowth = {
+ type = "toggle",
+ name = L["Reverse bar growth"],
+ desc = L["Bars will grow up instead of down."],
+ order = 70,
+ width = "double"
+ },
+ color = {
+ type = "color",
+ name = L["Bar Color"],
+ desc = L["Choose the default color of the bars."],
+ order = 80,
+ hasAlpha = true,
+ get = function()
+ local c = db.barcolor or WINDOW_DEFAULTS.barcolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.barcolor = db.barcolor or {}
+ db.barcolor.r, db.barcolor.g, db.barcolor.b, db.barcolor.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end
+ },
+ bgcolor = {
+ type = "color",
+ name = L["Background Color"],
+ desc = L["The color of the background."],
+ order = 90,
+ hasAlpha = true,
+ get = function()
+ local c = db.barbgcolor or WINDOW_DEFAULTS.barbgcolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.barbgcolor = db.barbgcolor or {}
+ db.barbgcolor.r, db.barbgcolor.g, db.barbgcolor.b, db.barbgcolor.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end
+ },
+ useselfcolor = {
+ type = "toggle",
+ name = L["Custom Color"],
+ desc = L["Use a different color for my bar."],
+ order = 100
+ },
+ selfcolor = {
+ type = "color",
+ name = L["My Color"],
+ order = 110,
+ hasAlpha = true,
+ get = function()
+ local c = db.selfcolor or WINDOW_DEFAULTS.barcolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.selfcolor = db.selfcolor or {}
+ db.selfcolor.r, db.selfcolor.g, db.selfcolor.b, db.selfcolor.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end,
+ disabled = function()
+ return not db.useselfcolor
+ end
+ },
+ classcolorbars = {
+ type = "toggle",
+ name = L["Class Colors"],
+ desc = L["When possible, bars will be colored according to player class."],
+ order = 120
+ },
+ spellschoolcolors = {
+ type = "toggle",
+ name = L["Spell school colors"],
+ desc = L["Use spell school colors where applicable."],
+ order = 130
+ },
+ classicons = {
+ type = "toggle",
+ name = L["Class Icons"],
+ desc = L["Use class icons where applicable."],
+ order = 140,
+ disabled = function()
+ return (db.specicons or db.roleicons)
+ end
+ },
+ roleicons = {
+ type = "toggle",
+ name = L["Role Icons"],
+ desc = L["Use role icons where applicable."],
+ order = 150,
+ set = function()
+ db.roleicons = not db.roleicons
+ if db.roleicons and not db.classicons then
+ db.classicons = true
+ end
+ win:Wipe(true)
+ Skada:ApplySettings(win)
+ end
+ },
+ specicons = {
+ type = "toggle",
+ name = L["Spec Icons"],
+ desc = L["Use specialization icons where applicable."],
+ order = 160,
+ set = function()
+ db.specicons = not db.specicons
+ if db.specicons and not db.classicons then
+ db.classicons = true
+ end
+ win:Wipe(true)
+ Skada:ApplySettings(win)
+ end
+ },
+ spark = {
+ type = "toggle",
+ name = L["Show Spark Effect"],
+ order = 170
+ }
+ }
+ },
+ text = {
+ type = "group",
+ name = L["Text"],
+ desc = format(L["Text options for %s."], L["Bars"]),
+ order = 20,
+ args = {
+ classcolortext = {
+ type = "toggle",
+ name = L["Class Colors"],
+ desc = L["When possible, bar text will be colored according to player class."],
+ order = 10
+ },
+ textcolor = {
+ type = "color",
+ name = L["Text Color"],
+ desc = format(L["The text color of %s."], L["Bars"]),
+ order = 20,
+ hasAlpha = true,
+ disabled = function() return db.classcolortext end,
+ get = function()
+ local c = db.textcolor or COLOR_WHITE
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.textcolor = db.textcolor or {}
+ db.textcolor.r, db.textcolor.g, db.textcolor.b, db.textcolor.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 20.9
+ },
+ lefttext = {
+ type = "group",
+ name = L["Left Text"],
+ desc = format(L["Text options for %s."], L["Left Text"]),
+ inline = true,
+ order = 30,
+ args = {
+ barfont = {
+ type = "select",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Left Text"]),
+ order = 10,
+ values = Skada:MediaList("font"),
+ dialogControl = "LSM30_Font"
+ },
+ barfontflags = {
+ type = "select",
+ name = L["Font Outline"],
+ desc = L["Sets the font outline."],
+ order = 20,
+ values = FONT_FLAGS
+ },
+ barfontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Left Text"]),
+ order = 30,
+ min = 5,
+ max = 32,
+ step = 1
+ },
+ classcolorleft = {
+ type = "toggle",
+ name = L["Class Colors"],
+ desc = format(L["Use class colors for %s."], L["Left Text"]),
+ disabled = function() return db.classcolortext end,
+ order = 40
+ }
+ }
+ },
+ righttext = {
+ type = "group",
+ name = L["Right Text"],
+ desc = format(L["Text options for %s."], L["Right Text"]),
+ inline = true,
+ order = 40,
+ args = {
+ numfont = {
+ type = "select",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Right Text"]),
+ order = 10,
+ values = Skada:MediaList("font"),
+ dialogControl = "LSM30_Font"
+ },
+ numfontflags = {
+ type = "select",
+ name = L["Font Outline"],
+ desc = L["Sets the font outline."],
+ order = 20,
+ values = FONT_FLAGS
+ },
+ numfontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Right Text"]),
+ order = 30,
+ min = 5,
+ max = 32,
+ step = 1
+ },
+ classcolorright = {
+ type = "toggle",
+ name = L["Class Colors"],
+ desc = format(L["Use class colors for %s."], L["Right Text"]),
+ disabled = function() return db.classcolortext end,
+ order = 40
+ }
+ }
+ }
+ }
+ },
+ advanced = {
+ type = "group",
+ name = L["Advanced"],
+ desc = format(L["Advanced options for %s."], L["Bars"]),
+ order = 30,
+ args = {
+ showself = {
+ type = "toggle",
+ name = L["Always show self"],
+ desc = L["opt_showself_desc"],
+ descStyle = "inline",
+ width = "double",
+ disabled = function() return P.showself end,
+ hidden = function() return P.showself end,
+ order = 10
+ },
+ showtotals = {
+ type = "toggle",
+ name = L["Show totals"],
+ desc = L["Shows a extra row with a summary in certain modes."],
+ descStyle = "inline",
+ width = "double",
+ disabled = function() return P.showtotals end,
+ hidden = function() return P.showtotals end,
+ order = 20
+ },
+ disablehighlight = {
+ type = "toggle",
+ name = L["Disable bar highlight"],
+ desc = L["Hovering a bar won't make it brighter."],
+ descStyle = "inline",
+ width = "double",
+ order = 30
+ },
+ clickthrough = {
+ type = "toggle",
+ name = L["Click Through"],
+ desc = L["Disables mouse clicks on bars."],
+ descStyle = "inline",
+ width = "double",
+ order = 40
+ },
+ smoothing = {
+ type = "toggle",
+ name = L["Smooth Bars"],
+ desc = L["Animate bar changes smoothly rather than immediately."],
+ descStyle = "inline",
+ width = "double",
+ order = 50
+ }
+ }
+ }
+ }
+ }
+
+ options.titleoptions = {
+ type = "group",
+ name = L["Title Bar"],
+ desc = format(L["Options for %s."], L["Title Bar"]),
+ childGroups = "tab",
+ order = 20,
+ get = function(i)
+ return db.title[i[#i]]
+ end,
+ set = function(i, val)
+ db.title[i[#i]] = val
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ general = {
+ type = "group",
+ name = L["General"],
+ desc = format(L["General options for %s."], L["Title Bar"]),
+ order = 10,
+ args = {
+ enable = {
+ type = "toggle",
+ name = L["Enable"],
+ desc = L["Enables the title bar."],
+ order = 10,
+ get = function()
+ return db.enabletitle
+ end,
+ set = function()
+ db.enabletitle = not db.enabletitle
+ Skada:ApplySettings(db.name)
+ end
+ },
+ titleset = {
+ type = "toggle",
+ name = L["Include set"],
+ desc = L["Include set name in title bar"],
+ order = 20,
+ get = function()
+ return db.titleset
+ end,
+ set = function()
+ db.titleset = not db.titleset
+ Skada:ApplySettings(db.name)
+ end
+ },
+ combattimer = {
+ type = "toggle",
+ name = L["Encounter Timer"],
+ desc = L["When enabled, a stopwatch is shown on the left side of the text."],
+ order = 30,
+ get = function()
+ return db.combattimer
+ end,
+ set = function()
+ db.combattimer = not db.combattimer
+ Skada:ApplySettings(db.name)
+ end
+ },
+ moduleicons = {
+ type = "toggle",
+ name = L["Mode Icon"],
+ desc = L["Shows mode's icon in the title bar."],
+ order = 40,
+ get = function()
+ return db.moduleicons
+ end,
+ set = function()
+ db.moduleicons = not db.moduleicons
+ Skada:ApplySettings(db.name)
+ end
+ },
+ height = {
+ type = "range",
+ name = L["Height"],
+ desc = format(L["The height of %s."], L["Title Bar"]),
+ width = "double",
+ order = 50,
+ min = 10,
+ max = 50,
+ step = 1
+ },
+ background = {
+ type = "group",
+ name = L["Background"],
+ inline = true,
+ order = 60,
+ args = {
+ texture = {
+ type = "select",
+ dialogControl = "LSM30_Statusbar",
+ name = L["Background Texture"],
+ desc = L["The texture used as the background of the title."],
+ order = 10,
+ values = Skada:MediaList("statusbar")
+ },
+ color = {
+ type = "color",
+ name = L["Background Color"],
+ desc = L["The color of the background."],
+ order = 20,
+ hasAlpha = true,
+ get = function()
+ local c = db.title.color or WINDOW_DEFAULTS.title.color
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.title.color = db.title.color or {}
+ db.title.color.r, db.title.color.g, db.title.color.b, db.title.color.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end
+ }
+ }
+ },
+ border = {
+ type = "group",
+ name = L["Border"],
+ inline = true,
+ order = 70,
+ args = {
+ bordertexture = {
+ type = "select",
+ dialogControl = "LSM30_Border",
+ name = L["Border texture"],
+ desc = L["The texture used for the borders."],
+ order = 10,
+ values = Skada:MediaList("border")
+ },
+ bordercolor = {
+ type = "color",
+ name = L["Border Color"],
+ desc = L["The color used for the border."],
+ hasAlpha = true,
+ order = 20,
+ get = function()
+ local c = db.title.bordercolor or WINDOW_DEFAULTS.title.bordercolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.title.bordercolor = db.title.bordercolor or {}
+ db.title.bordercolor.r = r
+ db.title.bordercolor.g = g
+ db.title.bordercolor.b = b
+ db.title.bordercolor.a = a
+ Skada:ApplySettings(db.name)
+ end
+ },
+ borderthickness = {
+ type = "range",
+ name = L["Border Thickness"],
+ desc = L["The thickness of the borders."],
+ order = 30,
+ min = 0,
+ max = 50,
+ step = 0.01,
+ bigStep = 0.1
+ },
+ borderinsets = {
+ type = "range",
+ name = L["Border Insets"],
+ desc = L["The distance between the window and its border."],
+ order = 40,
+ min = -32,
+ max = 32,
+ step = 0.01,
+ bigStep = 1
+ }
+ }
+ }
+ }
+ },
+ text = {
+ type = "group",
+ name = L["Text"],
+ desc = format(L["Text options for %s."], L["Title Bar"]),
+ order = 20,
+ args = {
+ font = {
+ type = "select",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Title Bar"]),
+ dialogControl = "LSM30_Font",
+ values = Skada:MediaList("font"),
+ order = 10
+ },
+ fontflags = {
+ type = "select",
+ name = L["Font Outline"],
+ desc = L["Sets the font outline."],
+ order = 20,
+ values = FONT_FLAGS
+ },
+ fontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Title Bar"]),
+ order = 30,
+ min = 5,
+ max = 32,
+ step = 1
+ },
+ textcolor = {
+ type = "color",
+ name = L["Text Color"],
+ desc = format(L["The text color of %s."], L["Title Bar"]),
+ order = 40,
+ hasAlpha = true,
+ get = function()
+ local c = db.title.textcolor or WINDOW_DEFAULTS.title.textcolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(_, r, g, b, a)
+ db.title.textcolor = db.title.textcolor or {}
+ db.title.textcolor.r = r
+ db.title.textcolor.g = g
+ db.title.textcolor.b = b
+ db.title.textcolor.a = a
+ Skada:ApplySettings(db.name)
+ end
+ }
+ }
+ },
+ buttons = {
+ type = "group",
+ name = L["Buttons"],
+ desc = format(L["Options for %s."], L["Buttons"]),
+ order = 30,
+ width = "double",
+ args = {
+ buttons = {
+ type = "group",
+ name = L["Buttons"],
+ inline = true,
+ order = 10,
+ get = function(i)
+ return db.buttons[i[#i]]
+ end,
+ set = function(i, val)
+ db.buttons[i[#i]] = val
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ menu = {
+ type = "toggle",
+ name = L["Configure"],
+ desc = L["btn_config_desc"],
+ order = 10
+ },
+ reset = {
+ type = "toggle",
+ name = L["Reset"],
+ desc = L["btn_reset_desc"],
+ order = 20
+ },
+ segment = {
+ type = "toggle",
+ name = L["Segment"],
+ desc = L["btn_segment_desc"],
+ order = 30
+ },
+ mode = {
+ type = "toggle",
+ name = L["Mode"],
+ desc = L["Jump to a specific mode."],
+ order = 40
+ },
+ report = {
+ type = "toggle",
+ name = L["Report"],
+ desc = L["btn_report_desc"],
+ order = 50
+ },
+ stop = {
+ type = "toggle",
+ name = L["Stop"],
+ desc = L["btn_stop_desc"],
+ order = 60
+ },
+ split = {
+ type = "toggle",
+ name = L["New Segment"],
+ desc = L["Starts a new segment."],
+ order = 70
+ },
+ phase = {
+ type = "toggle",
+ name = L["New Phase"],
+ desc = L["Starts a new phase."],
+ order = 80
+ }
+ }
+ },
+ style = {
+ type = "multiselect",
+ name = L["Buttons Style"],
+ order = 20,
+ get = function(_, key)
+ return (db.title.toolbar == key)
+ end,
+ set = function(_, val)
+ db.title.toolbar = val
+ Skada:ApplySettings(db.name)
+ end,
+ values = optionsValues.TITLEBTNS
+ },
+ sep1 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 30
+ },
+ opacity = {
+ type = "range",
+ name = L["Opacity"],
+ get = function()
+ return db.title.toolbaropacity or 0.25
+ end,
+ set = function(_, val)
+ db.title.toolbaropacity = val
+ Skada:ApplySettings(db.name)
+ end,
+ min = 0,
+ max = 1,
+ step = 0.01,
+ isPercent = true,
+ order = 40
+ },
+ spacing = {
+ type = "range",
+ name = L["Spacing"],
+ desc = format(L["Distance between %s."], L["Buttons"]),
+ get = function()
+ return db.title.spacing or 1
+ end,
+ set = function(_, val)
+ db.title.spacing = val
+ Skada:ApplySettings(db.name)
+ end,
+ min = 0,
+ max = 10,
+ step = 0.01,
+ bigStep = 1,
+ order = 50
+ },
+ hovermode = {
+ type = "toggle",
+ name = L["Auto Hide Buttons"],
+ desc = L["Show window buttons only if the cursor is over the title bar."],
+ width = "double",
+ order = 90,
+ get = function()
+ return db.title.hovermode
+ end,
+ set = function()
+ db.title.hovermode = not db.title.hovermode
+ Skada:ApplySettings(db.name)
+ end
+ }
+ }
+ }
+ }
+ }
+
+ options.windowoptions = FrameOptions(db)
+
+ options.windowoptions.args.position.args.barwidth = {
+ type = "range",
+ name = L["Width"],
+ order = 70,
+ min = 80,
+ max = 500,
+ step = 0.01,
+ bigStep = 1
+ }
+ options.windowoptions.args.position.args.height = {
+ type = "range",
+ name = L["Height"],
+ order = 80,
+ min = 60,
+ max = 500,
+ step = 0.01,
+ bigStep = 1,
+ get = function()
+ return db.background.height
+ end,
+ set = function(_, val)
+ db.background.height = val
+ Skada:ApplySettings(db.name)
+ end
+ }
+
+ local x, y = floor(GetScreenWidth() * 0.025) * 20, floor(GetScreenHeight() * 0.025) * 20
+ options.windowoptions.args.position.args.x = {
+ type = "range",
+ name = L["X Offset"],
+ order = 90,
+ min = -x,
+ max = x,
+ step = 0.01,
+ bigStep = 1,
+ set = function(_, val)
+ local window = mod:GetBarGroup(db.name)
+ if window then
+ db.x = val
+ RestorePosition(window, db)
+ end
+ end
+ }
+ options.windowoptions.args.position.args.y = {
+ type = "range",
+ name = L["Y Offset"],
+ order = 100,
+ min = -y,
+ max = y,
+ step = 0.01,
+ bigStep = 1,
+ set = function(_, val)
+ local window = mod:GetBarGroup(db.name)
+ if window then
+ db.y = val
+ RestorePosition(window, db)
+ end
+ end
+ }
+ end
+
+ -- ======================================================= --
+
+ do
+ local tremove = table.remove
+ local strmatch = strmatch or string.match
+ local GetBindingKey = GetBindingKey
+ local SetBinding = SetBinding
+ local SaveBindings = SaveBindings
+ local GetCurrentBindingSet = GetCurrentBindingSet
+
+ local opt_themes
+ local function GetThemeOptions()
+ GetThemeOptions = nil
+ if opt_themes then
+ return opt_themes
+ end
+
+ local applytheme, applywindow = nil, nil
+ local savetheme, savewindow = nil, nil
+ local skipped = {"name", "x", "y", "sticked", "set", "modeincombat", "wipemode", "returnaftercombat"}
+ local list = {}
+
+ local themes = {
+ ["All glowy 'n stuff"] = {
+ barspacing = 0,
+ bartexture = "LiteStep",
+ barfont = "ABF",
+ barfontflags = "",
+ barfontsize = 12,
+ barheight = 16,
+ barwidth = 240,
+ baroffset = 0,
+ barorientation = 1,
+ barcolor = {r = 0.3, g = 0.3, b = 0.8, a = 1},
+ barbgcolor = {r = 0.3, g = 0.3, b = 0.3, a = 0.6},
+ classcolorbars = true,
+ classicons = true,
+ buttons = {menu = true, reset = true, report = true, mode = true, segment = true},
+ title = {
+ textcolor = {r = 0.9, g = 0.9, b = 0.9, a = 1},
+ height = 20,
+ font = "ABF",
+ fontsize = 12,
+ texture = "Aluminium",
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "None",
+ borderthickness = 0,
+ borderinsets = 0,
+ color = {r = 0.6, g = 0.6, b = 0.8, a = 1},
+ fontflags = ""
+ },
+ background = {
+ height = 195,
+ texture = "None",
+ bordercolor = {r = 0.9, g = 0.9, b = 0.5, a = 0.6},
+ bordertexture = "Glow",
+ borderthickness = 5,
+ borderinsets = 0,
+ color = {r = 0, g = 0, b = 0, a = 0.4},
+ tilesize = 0
+ },
+ strata = "LOW",
+ scale = 1,
+ enabletitle = true,
+ titleset = true,
+ display = "bar",
+ snapto = true
+ },
+ ["Minimalistic"] = {
+ barspacing = 0,
+ bartexture = "Armory",
+ barfont = "Accidental Presidency",
+ barfontflags = "",
+ barfontsize = 12,
+ barheight = 16,
+ barwidth = 240,
+ baroffset = 0,
+ barorientation = 1,
+ barcolor = {r = 0.3, g = 0.3, b = 0.8, a = 1},
+ barbgcolor = {r = 0.3, g = 0.3, b = 0.3, a = 0.6},
+ classcolorbars = true,
+ classicons = true,
+ buttons = {menu = true, reset = true, report = true, mode = true, segment = true},
+ title = {
+ textcolor = {r = 0.9, g = 0.9, b = 0.9, a = 1},
+ height = 18,
+ font = "Accidental Presidency",
+ fontsize = 12,
+ texture = "Armory",
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "None",
+ borderthickness = 0,
+ borderinsets = 0,
+ color = {r = 0.6, g = 0.6, b = 0.8, a = 1},
+ fontflags = ""
+ },
+ background = {
+ height = 195,
+ texture = "None",
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "Blizzard Party",
+ borderthickness = 0,
+ borderinsets = 0,
+ color = {r = 0, g = 0, b = 0, a = 0.4},
+ tilesize = 0
+ },
+ strata = "LOW",
+ scale = 1,
+ enabletitle = true,
+ titleset = true,
+ display = "bar",
+ snapto = true
+ },
+ ["Omen Threat Meter"] = {
+ barspacing = 1,
+ bartexture = "Blizzard",
+ barfont = "Friz Quadrata TT",
+ barfontflags = "",
+ barfontsize = 10,
+ numfont = "Friz Quadrata TT",
+ numfontflags = "",
+ numfontsize = 10,
+ barheight = 14,
+ barwidth = 200,
+ baroffset = 0,
+ barorientation = 1,
+ barcolor = {r = 0.8, g = 0.05, b = 0, a = 1},
+ barbgcolor = {r = 0.3, g = 0.01, b = 0, a = 0.6},
+ classcolorbars = true,
+ smoothing = true,
+ buttons = {menu = true, reset = true, mode = true},
+ title = {
+ textcolor = {r = 1, g = 1, b = 1, a = 1},
+ height = 16,
+ font = "Friz Quadrata TT",
+ fontsize = 10,
+ texture = "Blizzard",
+ bordercolor = {r = 1, g = 0.75, b = 0, a = 1},
+ bordertexture = "Blizzard Dialog",
+ borderthickness = 0,
+ borderinsets = 0,
+ color = {r = 0.2, g = 0.2, b = 0.2, a = 0},
+ fontflags = ""
+ },
+ background = {
+ height = 108,
+ texture = "Blizzard Parchment",
+ bordercolor = {r = 1, g = 1, b = 1, a = 1},
+ bordertexture = "Blizzard Dialog",
+ borderthickness = 0,
+ borderinsets = 0,
+ color = {r = 1, g = 1, b = 1, a = 1},
+ tilesize = 0
+ },
+ strata = "LOW",
+ scale = 1,
+ enabletitle = true,
+ display = "bar"
+ },
+ ["Recount"] = {
+ barspacing = 0,
+ bartexture = "BantoBar",
+ barfont = "Arial Narrow",
+ barfontflags = "",
+ barfontsize = 12,
+ barheight = 18,
+ barwidth = 240,
+ baroffset = 0,
+ barorientation = 1,
+ barcolor = {r = 0.3, g = 0.3, b = 0.8, a = 1},
+ barbgcolor = {r = 0.3, g = 0.3, b = 0.3, a = 0.6},
+ classcolorbars = true,
+ buttons = {menu = true, reset = true, report = true, mode = true, segment = true},
+ title = {
+ textcolor = {r = 1, g = 1, b = 1, a = 1},
+ height = 18,
+ font = "Arial Narrow",
+ fontsize = 12,
+ texture = "Gloss",
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "None",
+ borderthickness = 0,
+ borderinsets = 0,
+ color = {r = 1, g = 0, b = 0, a = 0.75},
+ fontflags = ""
+ },
+ background = {
+ height = 150,
+ texture = "Solid",
+ bordercolor = {r = 0.9, g = 0.9, b = 0.5, a = 0.6},
+ bordertexture = "None",
+ borderthickness = 5,
+ borderinsets = 0,
+ color = {r = 0, g = 0, b = 0, a = 0.4},
+ tilesize = 0
+ },
+ strata = "LOW",
+ scale = 1,
+ enabletitle = true,
+ titleset = true,
+ display = "bar",
+ snapto = true
+ },
+ ["Skada default (Legion)"] = {
+ barspacing = 0,
+ bartexture = "BantoBar",
+ barfont = "Accidental Presidency",
+ barfontflags = "",
+ barfontsize = 13,
+ barheight = 18,
+ barwidth = 240,
+ baroffset = 0,
+ barorientation = 1,
+ barcolor = {r = 0.3, g = 0.3, b = 0.8, a = 1},
+ barbgcolor = {r = 0.3, g = 0.3, b = 0.3, a = 0.6},
+ classcolorbars = true,
+ classicons = true,
+ buttons = {menu = true, reset = true, report = true, mode = true, segment = true},
+ title = {
+ textcolor = {r = 0.9, g = 0.9, b = 0.9, a = 1},
+ height = 20,
+ font = "Accidental Presidency",
+ fontsize = 13,
+ texture = "Armory",
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "None",
+ borderthickness = 2,
+ borderinsets = 0,
+ color = {r = 0.3, g = 0.3, b = 0.3, a = 1},
+ fontflags = ""
+ },
+ background = {
+ height = 200,
+ texture = "Solid",
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "Blizzard Party",
+ borderthickness = 2,
+ borderinsets = 0,
+ color = {r = 0, g = 0, b = 0, a = 0.4},
+ tilesize = 0
+ },
+ strata = "LOW",
+ scale = 1,
+ enabletitle = true,
+ titleset = true,
+ display = "bar",
+ snapto = true
+ }
+ }
+
+ local function theme_locked()
+ return (applytheme == nil or themes[applytheme])
+ end
+
+ local function check_theme_name(name)
+ return CheckDuplicate(CheckDuplicate(name, themes), G.themes)
+ end
+
+ local ImportExport = Private.ImportExport
+ local serialize, deserialize = Private.serialize, Private.deserialize
+ local temp = {}
+
+ local function theme_export()
+ local theme = not theme_locked() and G.themes and G.themes[applytheme]
+ if not theme then return end
+
+ wipe(temp)
+ copy(temp, theme)
+ temp.__name = applytheme
+ return ImportExport(L["This is your current theme in text format."], serialize(false, temp))
+ end
+
+ local function theme_import(data)
+ if type(data) ~= "string" then
+ Skada:Print("Import theme failed, data supplied must be a string.")
+ return false
+ end
+
+ local success, theme = deserialize(data)
+ if not success or theme.bartexture == nil then -- sanity check!
+ Skada:Print("Import theme failed!")
+ return false
+ end
+
+ local name = check_theme_name(theme.__name)
+ theme.__name = nil
+ G.themes = G.themes or {}
+ G.themes[name] = theme
+ Skada:NotifyChange()
+ end
+
+ opt_themes = {
+ type = "group",
+ name = L["Themes"],
+ desc = format(L["Options for %s."], L["Themes"]),
+ args = {
+ manage = {
+ type = "group",
+ name = L["Manage Themes"],
+ inline = true,
+ order = 10,
+ args = {
+ theme = {
+ type = "select",
+ name = L["Theme"],
+ order = 10,
+ get = function() return applytheme end,
+ set = function(_, val) applytheme = val end,
+ values = function()
+ wipe(list)
+ for name in pairs(themes) do
+ list[name] = name
+ end
+ if G.themes then
+ for name in pairs(G.themes) do
+ list[name] = name
+ end
+ end
+ return list
+ end
+ },
+ window = {
+ type = "select",
+ name = L["Window"],
+ order = 20,
+ get = function() return applywindow end,
+ set = function(_, val) applywindow = val end,
+ disabled = function() return (applytheme == nil) end,
+ values = function()
+ wipe(list)
+ list["**"] = L["All Windows"]
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.display == "bar" then
+ list[win.db.name] = win.db.name
+ end
+ end
+ return list
+ end
+ },
+ export = {
+ type = "execute",
+ name = L["Export"],
+ order = 30,
+ disabled = theme_locked,
+ func = theme_export
+ },
+ apply = {
+ type = "execute",
+ name = L["Apply"],
+ desc = L["Apply Theme"],
+ order = 40,
+ disabled = function()
+ return (applytheme == nil or applywindow == nil)
+ end,
+ func = function()
+ if applywindow and applytheme then
+ local theme = themes[applytheme] or G.themes and G.themes[applytheme]
+ if theme then
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and (applywindow == "**" or win.db.name == applywindow) then
+ copy(win.db, theme, skipped)
+ Skada:ApplySettings()
+ applytheme = nil
+ -- single window? no need to go further..
+ if win.db.name == applywindow then break end
+ end
+ end
+ if not applytheme then
+ Skada:Print(L["Theme applied!"])
+ end
+ end
+ end
+ applytheme, applywindow = nil, nil
+ end
+ },
+ import = {
+ type = "execute",
+ name = L["Import"],
+ order = 50,
+ func = function()
+ return ImportExport(L["Paste here a theme in text format."], theme_import)
+ end
+ },
+ delete = {
+ type = "execute",
+ name = L["Delete"],
+ desc = L["Delete Theme"],
+ order = 60,
+ disabled = theme_locked,
+ confirm = function() return L["Are you sure you want to delete this theme?"] end,
+ func = function()
+ G.themes[applytheme] = del(G.themes[applytheme], true)
+ applytheme = nil
+ end
+ }
+ }
+ },
+ save = {
+ type = "group",
+ name = L["Save Theme"],
+ inline = true,
+ order = 20,
+ args = {
+ window = {
+ type = "select",
+ name = L["Window"],
+ order = 10,
+ get = function() return savewindow end,
+ set = function(_, val) savewindow = val end,
+ values = function()
+ wipe(list)
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.display == "bar" then
+ list[win.db.name] = win.db.name
+ end
+ end
+ return list
+ end
+ },
+ theme = {
+ type = "input",
+ name = L["Name"],
+ desc = L["Name of your new theme."],
+ order = 20,
+ get = function() return savetheme end,
+ set = function(_, val) savetheme = val end,
+ disabled = function() return (savewindow == nil) end
+ },
+ exec = {
+ type = "execute",
+ name = L["Save"],
+ width = "double",
+ order = 30,
+ disabled = function() return (savewindow == nil or savetheme == nil or savetheme:trim() == "") end,
+ func = function()
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.name == savewindow then
+ G.themes = G.themes or {}
+ local theme = {}
+ copy(theme, win.db, skipped)
+ local name = check_theme_name(savetheme or win.db.name)
+ G.themes[name] = theme
+ break -- stop
+ end
+ end
+ savetheme, savewindow = nil, nil
+ end
+ }
+ }
+ }
+ }
+ }
+
+ return opt_themes
+ end
+
+ local opt_scroll
+ local function GetScrollOptions()
+ if not opt_scroll then
+ opt_scroll = {
+ type = "group",
+ name = L["Scroll"],
+ desc = format(L["Options for %s."], L["Scroll"]),
+ order = 10,
+ get = function(info) return mod.db[info[#info]] end,
+ set = function(info, val) mod.db[info[#info]] = val end,
+ args = {
+ mouse = {
+ type = "group",
+ name = L["Mouse"],
+ inline = true,
+ order = 10,
+ args = {
+ speed = {
+ type = "range",
+ name = L["Wheel Speed"],
+ desc = L["opt_wheelspeed_desc"],
+ set = function(_, val)
+ mod.db.speed = val
+ mod:SetScrollSpeed(val)
+ end,
+ min = 1,
+ max = 10,
+ step = 1,
+ width = "double",
+ order = 10
+ },
+ button = {
+ type = "select",
+ name = L["Scroll mouse button"],
+ values = {
+ MiddleButton = L["Middle Button"],
+ Button4 = L["Mouse Button 4"],
+ Button5 = L["Mouse Button 5"]
+ },
+ order = 20
+ },
+ icon = {
+ type = "toggle",
+ name = L["Scroll Icon"],
+ order = 30
+ }
+ }
+ },
+ binding = {
+ type = "group",
+ name = L["Keybinding"],
+ inline = true,
+ order = 20,
+ args = {
+ upkey = {
+ type = "keybinding",
+ name = L["Scroll Up"],
+ set = function(info, val)
+ local b1, b2 = GetBindingKey("SKADA_SCROLLUP")
+ if b1 then
+ SetBinding(b1)
+ end
+ if b2 then
+ SetBinding(b2)
+ end
+ SetBinding(val, "SKADA_SCROLLUP")
+ SaveBindings(GetCurrentBindingSet())
+ end,
+ get = function(info)
+ return GetBindingKey("SKADA_SCROLLUP")
+ end,
+ order = 10
+ },
+ downkey = {
+ type = "keybinding",
+ name = L["Scroll Down"],
+ set = function(info, val)
+ local b1, b2 = GetBindingKey("SKADA_SCROLLDOWN")
+ if b1 then
+ SetBinding(b1)
+ end
+ if b2 then
+ SetBinding(b2)
+ end
+ SetBinding(val, "SKADA_SCROLLDOWN")
+ SaveBindings(GetCurrentBindingSet())
+ end,
+ get = function(info)
+ return GetBindingKey("SKADA_SCROLLDOWN")
+ end,
+ order = 20
+ }
+ }
+ }
+ }
+ }
+ end
+
+ GetScrollOptions = nil
+ return opt_scroll
+ end
+
+ function mod:OnEnable()
+ self:RegisterCallback("OnRemoveFrame")
+ self:RegisterCallback("OnAnchorFrame")
+ self:RegisterCallback("BarClick")
+ self:RegisterCallback("BarEnter")
+ self:RegisterCallback("BarLeave")
+ self:RegisterCallback("BarReleased")
+ self:RegisterCallback("WindowMoveStart")
+ self:RegisterCallback("WindowMoveStop")
+ self:RegisterCallback("WindowResized")
+ self:RegisterCallback("WindowLocked")
+ self:RegisterCallback("WindowResizing")
+ self:RegisterCallback("WindowStretching")
+ self:RegisterCallback("WindowStretchStart")
+ self:RegisterCallback("WindowStretchStop")
+ end
+
+ function mod:OnInitialize()
+ self.description = L["mod_bar_desc"]
+ Skada:AddDisplaySystem("bar", self, true)
+
+ self.db = P.scroll
+ if not self.db then
+ self.db = {speed = 2, icon = true, button = "MiddleButton"}
+ P.scroll = self.db
+ end
+
+ O.themeoptions = GetThemeOptions()
+ O.themeoptions.order = 960
+
+ O.tweaks.args.advanced.args.scroll = GetScrollOptions()
+ O.tweaks.args.advanced.args.scroll.order = 980
+
+ self:SetScrollSpeed(self.db.speed)
+
+ validclass = validclass or Skada.validclass
+ classcolors = classcolors or Skada.classcolors
+ classicons = classicons or Skada.classicons
+ classcoords = classcoords or Skada.classcoords
+ roleicons = roleicons or Skada.roleicons
+ rolecoords = rolecoords or Skada.rolecoords
+ specicons = specicons or Skada.specicons
+ speccoords = speccoords or Skada.speccoords
+ spellschools = spellschools or Skada.spellschools
+ windows = windows or Skada.windows
+
+ -- fix old saved themes!
+ if G.themes and #G.themes > 0 then
+ local i = 1
+ local theme = G.themes[i]
+ while theme do
+ local name = theme.name or format("%s (%d)", L["Unknown"], i)
+ theme.name = nil
+ G.themes[name] = theme
+ tremove(G.themes, i)
+
+ i = i + 1
+ theme = G.themes[i]
+ end
+ end
+ end
+ end
+
+ _G.BINDING_NAME_SKADA_SCROLLUP = L["Scroll Up"]
+ _G.BINDING_NAME_SKADA_SCROLLDOWN = L["Scroll Down"]
+end)
diff --git a/Skada/Core/Display/Broker.lua b/Skada/Core/Display/Broker.lua
new file mode 100644
index 0000000..11858c5
--- /dev/null
+++ b/Skada/Core/Display/Broker.lua
@@ -0,0 +1,327 @@
+local folder, Skada = ...
+local Private = Skada.Private
+Skada:RegisterDisplay("Data Text", "mod_broker_desc", function(L, P)
+ local mod = Skada:NewModule("Data Text", Skada.displayPrototype)
+ local LDB = LibStub:GetLibrary("LibDataBroker-1.1")
+
+ mod.SetTitle = Skada.EmptyFunc
+
+ local wipe, tsort, format = wipe, table.sort, string.format
+ local GameTooltip = GameTooltip
+ local GameTooltip_Hide = GameTooltip_Hide
+ local SavePosition = Private.SavePosition
+ local RestorePosition = Private.RestorePosition
+ local WrapTextInColorCode = Private.WrapTextInColorCode
+ local RGBPercToHex = Private.RGBPercToHex
+ local classcolors = Skada.classcolors
+
+ local FONT_FLAGS = Skada.fontFlags
+ if not FONT_FLAGS then
+ FONT_FLAGS = {
+ [""] = L["None"],
+ ["OUTLINE"] = L["Outline"],
+ ["THICK"] = L["Thick"],
+ ["THICKOUTLINE"] = L["Thick outline"],
+ ["MONOCHROME"] = L["Monochrome"],
+ ["OUTLINEMONOCHROME"] = L["Outlined monochrome"]
+ }
+ Skada.fontFlags = FONT_FLAGS
+ end
+
+ local function sortFunc(a, b)
+ if not a or a.value == nil then
+ return false
+ elseif not b or b.value == nil then
+ return true
+ elseif a.value < b.value then
+ return false
+ elseif a.value > b.value then
+ return true
+ elseif not a.label then
+ return false
+ elseif not b.label then
+ return true
+ else
+ return a.label > b.label
+ end
+ end
+
+ local function sortDataset(win)
+ tsort(win.dataset, sortFunc)
+ return win.dataset
+ end
+
+ local function formatLabel(win, data)
+ if win.db.isusingclasscolors and data.class then
+ return classcolors.format(data.class, data.text or data.label or L["Unknown"])
+ elseif data.color and data.color.colorStr then
+ return format("\124c%s%s\124r", data.color.colorStr, data.text or data.label or L["Unknown"])
+ elseif data.color then
+ return WrapTextInColorCode(data.text or data.label or L["Unknown"], RGBPercToHex(data.color.r or 1, data.color.g or 1, data.color.b or 1, true))
+ else
+ return data.text or data.label or L["Unknown"]
+ end
+ end
+
+ local function formatValue(win, data)
+ return data.valuetext
+ end
+
+ local function clickHandler(win, frame, button)
+ if not win.obj then return end
+
+ if button == "LeftButton" and IsShiftKeyDown() then
+ Skada:OpenMenu(win)
+ elseif button == "LeftButton" then
+ Skada:ModeMenu(win, frame)
+ elseif button == "RightButton" then
+ Skada:SegmentMenu(win)
+ end
+ end
+
+ local function tooltipHandler(win, tooltip)
+ if win.db.useframe then
+ Skada:SetTooltipPosition(tooltip, win.frame, "broker", win)
+ end
+
+ -- Default color.
+ local color = win.db.textcolor or {r = 1, g = 1, b = 1}
+
+ tooltip:AddLine(win.metadata.title)
+
+ local dataset = sortDataset(win)
+ if #dataset > 0 then
+ tooltip:AddLine(" ")
+ local n = 0 -- used to fix spots starting from 2
+ for i = 1, #dataset do
+ local data = dataset[i]
+ if data and data.id and not data.ignore and i < 30 then
+ n = n + 1
+ local label = formatLabel(win, data)
+ local value = formatValue(win, data)
+
+ if win.metadata.showspots and P.showranks then
+ label = format("%s. %s", n, label)
+ end
+
+ tooltip:AddDoubleLine(label or "", value or "", color.r, color.g, color.b, color.r, color.g, color.b)
+ elseif i >= 30 then
+ break
+ end
+ end
+ end
+
+ tooltip:AddLine(" ")
+ tooltip:AddLine(L["Hint: Left-Click to set active mode."], 0, 1, 0)
+ tooltip:AddLine(L["Right-Click to set active set."], 0, 1, 0)
+ tooltip:AddLine(L["Shift+Left-Click to open menu."], 0, 1, 0)
+
+ tooltip:Show()
+ end
+
+ local ttactive = false
+
+ function mod:Create(win, isnew)
+ local p = win.db
+ local frame = win.frame
+
+ -- Optional internal frame
+ if not frame then
+ frame = CreateFrame("Frame", format("%sBrokerWindow%s", folder, p.name), UIParent)
+ frame:SetHeight(p.height or 30)
+ frame:SetWidth(p.width or 200)
+ frame:SetPoint("CENTER", 0, 0)
+
+ local title = frame:CreateFontString("frameTitle", 6)
+ title:SetPoint("CENTER", 0, 0)
+ frame.title = title
+
+ frame:EnableMouse(true)
+ frame:SetMovable(true)
+ frame:RegisterForDrag("LeftButton")
+ frame:SetScript("OnMouseUp", function(frame, button) clickHandler(win, frame, button) end)
+ frame:SetScript("OnEnter", function(frame) tooltipHandler(win, GameTooltip) end)
+ frame:SetScript("OnLeave", GameTooltip_Hide)
+ frame:SetScript("OnDragStart", function(self)
+ if not p.barslocked then
+ GameTooltip:Hide()
+ self.isDragging = true
+ self:StartMoving()
+ end
+ end)
+ frame:SetScript("OnDragStop", function(self)
+ self:StopMovingOrSizing()
+ self.isDragging = false
+ SavePosition(self, p)
+ end)
+ end
+
+ -- Restore window position.
+ if isnew then
+ SavePosition(frame, p)
+ else
+ RestorePosition(frame, p)
+ end
+
+ win.frame = frame
+
+ -- LDB object
+ if not win.obj then
+ win.obj = LDB:NewDataObject(format("%s: %s", folder, p.name), {
+ type = "data source",
+ text = "",
+ OnTooltipShow = function(tooltip) tooltipHandler(win, tooltip) end,
+ OnClick = function(frame, button) clickHandler(win, frame, button) end
+ })
+ end
+
+ mod:ApplySettings(win)
+ end
+
+ function mod:Update(win)
+ if win.obj then
+ win.obj.text = ""
+ end
+
+ local dataset = sortDataset(win)
+ local data = (#dataset > 0) and dataset[1]
+ if not data or not data.id then return end
+
+ local label = format("%s - %s", formatLabel(win, data) or "", formatValue(win, data) or "")
+
+ if win.obj then
+ win.obj.text = label
+ end
+ if win.db.useframe then
+ win.frame.title:SetText(label)
+ end
+ end
+
+ local fbackdrop = {}
+ function mod:ApplySettings(win)
+ if win.db.useframe then
+ local title = win.frame.title
+ local db = win.db
+
+ win.frame:SetMovable(not db.barslocked)
+ win.frame:SetHeight(db.height or 30)
+ win.frame:SetWidth(db.width or 200)
+ win.frame:SetScale(db.scale)
+ win.frame:SetFrameStrata(db.strata)
+
+ wipe(fbackdrop)
+ fbackdrop.bgFile = Skada:MediaFetch("background", db.background.texture)
+ fbackdrop.tile = db.background.tile
+ fbackdrop.tileSize = db.background.tilesize
+ win.frame:SetBackdrop(fbackdrop)
+ win.frame:SetBackdropColor(db.background.color.r, db.background.color.g, db.background.color.b, db.background.color.a)
+
+ Skada:ApplyBorder(win.frame, db.background.bordertexture, db.background.bordercolor, db.background.borderthickness, db.background.borderinsets)
+
+ local color = db.textcolor or {r = 1, g = 1, b = 1, a = 1}
+ title:SetTextColor(color.r, color.g, color.b, color.a)
+ title:SetFont(Skada:MediaFetch("font", db.barfont), db.barfontsize, db.barfontflags)
+ title:SetWordWrap(false)
+ title:SetJustifyH("CENTER")
+ title:SetJustifyV("MIDDLE")
+ title:SetHeight(db.height or 30)
+ title:SetText(win.metadata.title or folder)
+
+ -- restore position
+ RestorePosition(win.frame, db)
+
+ if db.hidden and win.frame:IsShown() then
+ win.frame:Hide()
+ elseif not db.hidden and not win.frame:IsShown() then
+ win.frame:Show()
+ end
+ else
+ win.frame:Hide()
+ end
+
+ self:Update(win)
+ end
+
+ function mod:AddDisplayOptions(win, options)
+ local db = win.db
+
+ options.main = {
+ type = "group",
+ name = L["Data Text"],
+ desc = format(L["Options for %s."], L["Data Text"]),
+ order = 10,
+ get = function(i)
+ return db[i[#i]]
+ end,
+ set = function(i, val)
+ db[i[#i]] = val
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ useframe = {
+ type = "toggle",
+ name = L["Use frame"],
+ desc = L["opt_useframe_desc"],
+ order = 10,
+ width = "double"
+ },
+ barfont = {
+ type = "select",
+ dialogControl = "LSM30_Font",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Bars"]),
+ values = Skada:MediaList("font"),
+ order = 20
+ },
+ barfontflags = {
+ type = "select",
+ name = L["Font Outline"],
+ desc = L["Sets the font outline."],
+ values = FONT_FLAGS,
+ order = 30
+ },
+ barfontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Bars"]),
+ min = 5,
+ max = 32,
+ step = 1,
+ order = 40,
+ width = "double"
+ },
+ color = {
+ type = "color",
+ name = L["Text Color"],
+ desc = L["Choose the default color."],
+ hasAlpha = true,
+ get = function()
+ local c = db.textcolor or Skada.windowdefaults.textcolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(i, r, g, b, a)
+ db.textcolor = db.textcolor or {}
+ db.textcolor.r, db.textcolor.g, db.textcolor.b, db.textcolor.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end,
+ disabled = function() return db.isusingclasscolors end,
+ order = 50,
+ },
+ isusingclasscolors = {
+ type = "toggle",
+ name = L["Class Colors"],
+ desc = L["When possible, bar text will be colored according to player class."],
+ order = 60
+ },
+ }
+ }
+
+ options.windowoptions = Private.FrameOptions(db, true)
+ end
+
+ function mod:OnInitialize()
+ classcolors = classcolors or Skada.classcolors
+ self.description = L["mod_broker_desc"]
+ Skada:AddDisplaySystem("broker", self)
+ end
+end)
diff --git a/Skada/Core/Display/Inline.lua b/Skada/Core/Display/Inline.lua
new file mode 100644
index 0000000..8759ce3
--- /dev/null
+++ b/Skada/Core/Display/Inline.lua
@@ -0,0 +1,673 @@
+local folder, Skada = ...
+local Private = Skada.Private
+Skada:RegisterDisplay("Inline Bar Display", "mod_inline_desc", function(L)
+ local mod = Skada:NewModule("Inline Bar Display", Skada.displayPrototype)
+
+ local pairs, tostring, type = pairs, tostring, type
+ local format, strmatch = string.format, string.match
+ local tinsert, tremove, tsort = table.insert, table.remove, table.sort
+ local GameTooltip = GameTooltip
+ local GetScreenWidth = GetScreenWidth
+ local GetScreenHeight = GetScreenHeight
+ local SavePosition = Private.SavePosition
+ local RestorePosition = Private.RestorePosition
+
+ local mybars = {}
+ local barlibrary = {bars = {}, nextuuid = 1}
+ local leftmargin = 40
+ local ttactive = false
+
+ local WrapTextInColorCode = Private.WrapTextInColorCode
+ local RGBPercToHex = Private.RGBPercToHex
+ local classcolors = Skada.classcolors
+ local ElvUI = _G.ElvUI
+
+ local FONT_FLAGS = Skada.fontFlags
+ if not FONT_FLAGS then
+ FONT_FLAGS = {
+ [""] = L["None"],
+ ["OUTLINE"] = L["Outline"],
+ ["THICK"] = L["Thick"],
+ ["THICKOUTLINE"] = L["Thick outline"],
+ ["MONOCHROME"] = L["Monochrome"],
+ ["OUTLINEMONOCHROME"] = L["Outlined monochrome"]
+ }
+ Skada.fontFlags = FONT_FLAGS
+ end
+
+ local buttonTexture = format([[%s\Textures\toolbar%%s\config]], Skada.mediapath)
+
+ local function BarLeave(bar)
+ if ttactive then
+ GameTooltip:Hide()
+ ttactive = false
+ end
+ end
+
+ local function inserthistory(win)
+ if win.selectedmode and win.history[#win.history] ~= win.selectedmode then
+ win.history[#win.history + 1] = win.selectedmode
+ if win.child and (win.db.childmode == 1 or win.db.childmode == 3) then
+ inserthistory(win.child)
+ end
+ end
+ end
+
+ local function onEnter(win, id, label, class, mode)
+ mode:Enter(win, id, label, class)
+ if win.child and (win.db.childmode == 1 or win.db.childmode == 3) then
+ onEnter(win.child, id, label, class, mode)
+ end
+ end
+
+ local function showmode(win, id, label, class, mode)
+ if Private.total_noclick(win.selectedset, mode) then return end
+
+ inserthistory(win)
+
+ if type(mode) == "function" then
+ mode(win, id, label, class)
+ else
+ if mode.Enter then
+ onEnter(win, id, label, class, mode)
+ end
+ win:DisplayMode(mode)
+ end
+
+ Skada:CloseMenus()
+ GameTooltip:Hide()
+ end
+
+ local function BarClick(win, bar, button)
+ if Skada.testMode or bar.ignore then return end
+
+ local id, label, class = bar.valueid, bar.valuetext, bar.class
+
+ if button == "RightButton" and IsShiftKeyDown() then
+ Skada:OpenMenu(win)
+ elseif win.metadata.click then
+ win.metadata.click(win, id, label, button)
+ elseif button == "RightButton" then
+ win:RightClick(bar, button)
+ elseif button == "LeftButton" and win.metadata.click2 and IsShiftKeyDown() then
+ showmode(win, id, label, class, win.metadata.click2)
+ elseif button == "LeftButton" and win.metadata.filterclass and IsAltKeyDown() then
+ win:FilterClass(class)
+ elseif button == "LeftButton" and win.metadata.click3 and IsControlKeyDown() then
+ showmode(win, id, label, class, win.metadata.click3)
+ elseif button == "LeftButton" and win.metadata.click1 then
+ showmode(win, id, label, class, win.metadata.click1)
+ end
+ end
+
+ local function frameOnMouseDown(self, button)
+ if button == "RightButton" and not Skada.testMode then
+ self.win:RightClick(nil, button)
+ end
+ end
+
+ local function frameOnDragStart(self)
+ if not self.win.db.barslocked then
+ GameTooltip:Hide()
+ self.isDragging = true
+ self:StartMoving()
+ end
+ end
+
+ local function frameOnDragStop(self)
+ self:StopMovingOrSizing()
+ self.isDragging = false
+ SavePosition(self, self.win.db)
+ end
+
+ local function titleOnMouseDown(self, button)
+ if button == "RightButton" then
+ Skada:SegmentMenu(self.win)
+ elseif button == "LeftButton" then
+ Skada:ModeMenu(self.win, self)
+ end
+ end
+
+ local function menuOnClick(self, button)
+ if button == "RightButton" then
+ Private.OpenOptions(self.win)
+ else
+ Skada:OpenMenu(self.win)
+ end
+ end
+
+ function mod:Create(window, isnew)
+ local p = window.db
+ local frame = window.frame
+
+ if not frame then
+ frame = CreateFrame("Frame", format("%sInlineWindow%s", folder, p.name), UIParent)
+ frame:SetFrameLevel(1)
+
+ if p.height == 15 then
+ p.height = 23
+ end
+
+ frame:SetHeight(p.height)
+ frame:SetWidth(p.width or GetScreenWidth())
+ frame:ClearAllPoints()
+ frame:SetPoint("BOTTOM", -1)
+ frame:SetPoint("LEFT", -1)
+ if p.background.color.a == 0.2 then
+ p.background.color = {r = 1, b = 0.98, g = 0.98, a = 1}
+ end
+ end
+
+ if isnew then
+ SavePosition(frame, p)
+ else
+ RestorePosition(frame, p)
+ end
+
+ frame:SetClampedToScreen(true)
+ frame:EnableMouse(true)
+ frame:SetMovable(true)
+ frame:RegisterForDrag("LeftButton")
+ frame:SetScript("OnMouseDown", frameOnMouseDown)
+ frame:SetScript("OnDragStart", frameOnDragStart)
+ frame:SetScript("OnDragStop", frameOnDragStop)
+
+ local titlebg = CreateFrame("Frame", "$parentTitleBackground", frame)
+ titlebg.win = window
+
+ local title = frame:CreateFontString("frameTitle", 6)
+ title:SetTextColor(self:GetFontColor(p))
+ title:SetFont(self:GetFont(p))
+ title:SetText(window.metadata.title or folder)
+ title:SetWordWrap(false)
+ title:SetJustifyH("LEFT")
+ title:SetPoint("LEFT", leftmargin, -1)
+ title:SetPoint("CENTER", 0, 0)
+ title:SetHeight(p.height or 23)
+ frame.fstitle = title
+ frame.titlebg = titlebg
+
+ titlebg:SetAllPoints(title)
+ titlebg:EnableMouse(true)
+ titlebg:SetScript("OnMouseDown", titleOnMouseDown)
+
+ local menu = CreateFrame("Button", "$parentMenuButton", frame)
+ menu:ClearAllPoints()
+ menu:SetWidth(12)
+ menu:SetHeight(12)
+ menu:SetNormalTexture(format(buttonTexture, p.title.toolbar or 1))
+ menu:SetHighlightTexture(format(buttonTexture, p.title.toolbar or 1), "ADD")
+ menu:SetAlpha(0.5)
+ menu:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+ menu:SetPoint("LEFT", frame, "LEFT", 6, 0)
+ menu:SetFrameLevel(frame:GetFrameLevel() + 5)
+ menu.win = window
+ menu:SetScript("OnClick", menuOnClick)
+
+ frame.menu = menu
+ frame.skadamenubutton = title
+ frame.barstartx = leftmargin + frame.fstitle:GetStringWidth()
+
+ frame.win = window
+ window.frame = frame
+
+ --create 20 barframes
+ local temp = 20
+ repeat
+ local bar = barlibrary:CreateBar(nil, window)
+ barlibrary.bars[temp] = bar
+ temp = temp - 1
+ until (temp < 1)
+ self:Update(window)
+ end
+
+ function mod:SetTitle(win, title)
+ local frame = win and win.frame
+ if not win then return end
+ frame.fstitle:SetText(title or win.title or win.metadata.title)
+ frame.barstartx = leftmargin + frame.fstitle:GetStringWidth() + 20
+ end
+
+ local function barOnMouseDown(self, button)
+ local bar = self.bar
+ local win = bar and bar.win
+ if not win then return end
+ BarClick(win, bar, button)
+ end
+
+ local function barOnEnter(self, motion)
+ local bar = self.bar
+ local win = bar and bar.win
+ if not win then return end
+ ttactive = true
+ Skada:SetTooltipPosition(GameTooltip, win.frame, "inline", win)
+ Skada:ShowTooltip(win, bar.valueid, bar.valuetext, bar, bar.class)
+ end
+
+ function barlibrary:CreateBar(uuid, win)
+ local bar = {}
+ bar.uuid = uuid or self.nextuuid
+ bar.inuse = false
+ bar.value = 0
+ bar.win = win
+
+ bar.bg = CreateFrame("Frame", format("$parentBackground%d", bar.uuid), win.frame)
+ bar.bg:SetFrameLevel(win.frame:GetFrameLevel() + 6)
+ bar.bg.bar = bar
+
+ bar.label = win.frame:CreateFontString(format("$parentLabel%d", bar.uuid))
+ bar.label:SetFont(mod:GetFont(win.db))
+ bar.label:SetTextColor(mod:GetFontColor(win.db))
+ bar.label:SetJustifyH("LEFT")
+ bar.label:SetJustifyV("MIDDLE")
+ bar.bg:EnableMouse(true)
+ bar.bg:SetScript("OnMouseDown", barOnMouseDown)
+ bar.bg:SetScript("OnEnter", barOnEnter)
+ bar.bg:SetScript("OnLeave", BarLeave)
+
+ if uuid then
+ self.nextuuid = self.nextuuid + 1
+ end
+ return bar
+ end
+
+ function barlibrary:Deposit(bar)
+ --strip the bar of variables
+ bar.inuse = false
+ bar.bg:Hide()
+ bar.value = 0
+ bar.label:Hide()
+
+ --place it at the front of the queue
+ tinsert(barlibrary.bars, 1, bar)
+ end
+
+ local Print = Private.Print
+ function barlibrary:Withdraw(win)
+ local db = win.db
+
+ if #barlibrary.bars < 2 then
+ local replacement = {}
+ local uuid = 1
+ if #barlibrary.bars == 0 then
+ uuid = 1
+ elseif #barlibrary.bars < 2 then
+ uuid = barlibrary.bars[#barlibrary.bars].uuid + 1
+ else
+ uuid = 1
+ Print("\124c0033ff99SkadaInline\124r: THIS SHOULD NEVER HAPPEN")
+ end
+ replacement = self:CreateBar(uuid, win)
+ barlibrary.bars[#barlibrary.bars + 1] = replacement
+ end
+
+ barlibrary.bars[1].inuse = false
+ barlibrary.bars[1].value = 0
+ barlibrary.bars[1].label:SetJustifyH("LEFT")
+ mod:ApplySettings(win)
+ return tremove(barlibrary.bars, 1)
+ end
+
+ function mod:RecycleBar(bar)
+ bar.value = 0
+ bar.label:Hide()
+ bar.bg:Hide()
+ barlibrary:Deposit(bar)
+ end
+
+ function mod:GetBar(win)
+ return barlibrary:Withdraw(win)
+ end
+
+ function mod:UpdateBar(bar, bardata, db)
+ local label = bardata.text or bardata.label or L["Unknown"]
+ if db.isusingclasscolors and bardata.class then
+ label = classcolors.format(bardata.class, bardata.text or bardata.label or L["Unknown"])
+ elseif bardata.color and bardata.color.colorStr then
+ label = format("\124c%s%s\124r", bardata.color.colorStr, bardata.text or bardata.label or L["Unknown"])
+ elseif bardata.color then
+ label = WrapTextInColorCode(bardata.text or bardata.label or L["Unknown"], RGBPercToHex(bardata.color.r or 1, bardata.color.g or 1, bardata.color.b or 1, true))
+ else
+ label = bardata.text or bardata.label or L["Unknown"]
+ end
+
+ if bardata.valuetext then
+ label = format("%s%s%s", label, (db.isonnewline and db.barfontsize * 2 < db.height) and "\n" or " - ", bardata.valuetext)
+ end
+
+ bar.label:SetFont(mod:GetFont(db))
+ bar.label:SetText(label)
+ bar.label:SetTextColor(mod:GetFontColor(db))
+ bar.class = bardata.class
+ bar.value = bardata.value
+ if bardata.ignore then
+ bar.ignore = true
+ else
+ bar.class = bardata.class
+ bar.spec = bardata.spec
+ bar.role = bardata.role
+ end
+
+ bar.valueid = bardata.id
+ bar.valuetext = bardata.text or bardata.label or L["Unknown"]
+ return bar
+ end
+
+ local function sortFunc(a, b)
+ if not a or a.value == nil then
+ return false
+ elseif not b or b.value == nil then
+ return true
+ elseif a.value < b.value then
+ return false
+ elseif a.value > b.value then
+ return true
+ elseif not a.label then
+ return false
+ elseif not b.label then
+ return true
+ else
+ return a.label:GetText() > b.label:GetText()
+ end
+ end
+
+ function mod:Update(win)
+ if not win or not win.frame then return end
+
+ local wd = win.dataset
+ for i = #wd, 1, -1 do
+ if wd[i] and wd[i].label == nil then
+ tremove(wd, i)
+ end
+ end
+
+ local i = #mybars
+ while i > 0 do
+ mod:RecycleBar(tremove(mybars, i))
+ i = i - 1
+ end
+
+ for k, bardata in pairs(wd) do
+ if bardata.id then
+ mybars[#mybars + 1] = mod:UpdateBar(mod:GetBar(win), bardata, win.db)
+ end
+ end
+
+ tsort(mybars, sortFunc)
+
+ local yoffset = (win.db.height - win.db.barfontsize) * 0.5
+ local left = win.frame.barstartx + 40
+
+ for key, bar in pairs(mybars) do
+ bar.bg:SetHeight(win.db.height)
+ bar.bg:SetPoint("BOTTOMLEFT", win.frame, "BOTTOMLEFT", left, 0)
+ bar.bg:SetWidth(bar.label:GetStringWidth())
+ bar.label:SetHeight(win.db.height)
+ bar.label:SetPoint("BOTTOMLEFT", win.frame, "BOTTOMLEFT", left, 0)
+
+ if win.db.fixedbarwidth then
+ left = left + win.db.barwidth
+ else
+ left = left + bar.label:GetStringWidth()
+ left = left + 15
+ end
+
+ if (left + win.frame:GetLeft()) < win.frame:GetRight() then
+ bar.bg:Show()
+ bar.label:Show()
+ else
+ bar.bg:Hide()
+ bar.label:Hide()
+ end
+ end
+ end
+
+ function mod:OnMouseWheel(win, frame, direction)
+ end
+
+ function mod:CreateBar(win, name, label, maxValue, icon, o)
+ local bar = {}
+ bar.win = win
+
+ return bar
+ end
+
+ function mod:GetFont(db)
+ if db.isusingelvuiskin and ElvUI then
+ if ElvUI then
+ return ElvUI[1]["media"].normFont, db.barfontsize, nil
+ else
+ return nil
+ end
+ else
+ return Skada:MediaFetch("font", db.barfont), db.barfontsize, db.barfontflags
+ end
+ end
+
+ function mod:GetFontColor(db)
+ if db.isusingelvuiskin and ElvUI then
+ return 255, 255, 255, 1
+ else
+ return db.title.textcolor.r, db.title.textcolor.g, db.title.textcolor.b, db.title.textcolor.a
+ end
+ end
+
+ function mod:ApplySettings(win)
+ if not win or not win.frame then return end
+
+ local f = win.frame
+ local p = win.db
+
+ f:SetHeight(p.height)
+ f:SetWidth(p.width or GetScreenWidth())
+ f.fstitle:SetTextColor(self:GetFontColor(p))
+ f.fstitle:SetFont(self:GetFont(p))
+
+ for k, bar in pairs(mybars) do
+ bar.label:SetFont(self:GetFont(p))
+ bar.label:SetTextColor(self:GetFontColor(p))
+ bar.bg:EnableMouse(not p.clickthrough)
+ end
+ f.menu:SetPoint("BOTTOMLEFT", f, "BOTTOMLEFT", 6, p.height * 0.5 - 8)
+
+ f:SetClampedToScreen(p.clamped == true)
+ f:EnableMouse(not p.clickthrough)
+ f:SetScale(p.scale)
+
+ -- restore position
+ RestorePosition(f, p)
+
+ --ElvUI
+ if p.isusingelvuiskin and ElvUI then
+ f:SetHeight(p.height)
+ f.fstitle:SetTextColor(255, 255, 255, 1)
+ f.fstitle:SetFont(ElvUI[1]["media"].normFont, p.barfontsize, nil)
+ for k, bar in pairs(mybars) do
+ bar.label:SetFont(ElvUI[1]["media"].normFont, p.barfontsize, nil)
+ bar.label:SetTextColor(255, 255, 255, 1)
+ end
+
+ --background
+ local fbackdrop = {}
+ local borderR, borderG, borderB = ElvUI[1]["media"].bordercolor[1], ElvUI[1]["media"].bordercolor[2], ElvUI[1]["media"].bordercolor[3]
+ local backdropR, backdropG, backdropB = ElvUI[1]["media"].backdropcolor[1], ElvUI[1]["media"].backdropcolor[2], ElvUI[1]["media"].backdropcolor[3]
+ local backdropA = 0
+ if p.issolidbackdrop then
+ backdropA = 1.0
+ else
+ backdropA = 0.8
+ end
+ local resolution = ({GetScreenResolutions()})[GetCurrentResolution()]
+ local mult = 768 / strmatch(resolution, "%d+x(%d+)") / (max(0.64, min(1.15, 768 / GetScreenHeight() or UIParent:GetScale())))
+
+ fbackdrop.bgFile = ElvUI[1]["media"].blankTex
+ fbackdrop.edgeFile = ElvUI[1]["media"].blankTex
+ fbackdrop.tile = false
+ fbackdrop.tileSize = 0
+ fbackdrop.edgeSize = mult
+ fbackdrop.insets = {left = 0, right = 0, top = 0, bottom = 0}
+ f:SetBackdrop(fbackdrop)
+ f:SetBackdropColor(backdropR, backdropG, backdropB, backdropA)
+ f:SetBackdropBorderColor(borderR, borderG, borderB, 1.0)
+ else
+ --background
+ local fbackdrop = {}
+ fbackdrop.bgFile = Skada:MediaFetch("background", p.background.texture)
+ fbackdrop.tile = p.background.tile
+ fbackdrop.tileSize = p.background.tilesize
+ f:SetBackdrop(fbackdrop)
+ f:SetBackdropColor(p.background.color.r, p.background.color.g, p.background.color.b, p.background.color.a)
+ f:SetFrameStrata(p.strata)
+ Skada:ApplyBorder(f, p.background.bordertexture, p.background.bordercolor, p.background.borderthickness, p.background.borderinsets)
+ end
+
+ if p.hidden and win.frame:IsShown() then
+ win.frame:Hide()
+ elseif not p.hidden and not win.frame:IsShown() then
+ win.frame:Show()
+ end
+ end
+
+ function mod:AddDisplayOptions(win, options)
+ local db = win.db
+
+ options.baroptions = {
+ type = "group",
+ name = L["Text"],
+ desc = format(L["Options for %s."], L["Text"]),
+ order = 1,
+ get = function(i)
+ return db[i[#i]]
+ end,
+ set = function(i, val)
+ db[i[#i]] = val
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ barfont = {
+ type = "select",
+ dialogControl = "LSM30_Font",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Bars"]),
+ values = Skada:MediaList("font"),
+ order = 10
+ },
+ barfontflags = {
+ type = "select",
+ name = L["Font Outline"],
+ desc = L["Sets the font outline."],
+ values = FONT_FLAGS,
+ order = 20
+ },
+ barfontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Bars"]),
+ min = 5,
+ max = 32,
+ step = 1,
+ order = 30,
+ width = "double"
+ },
+ color = {
+ type = "color",
+ name = L["Font Color"],
+ desc = L["Font Color.\nClick \"Class Colors\" to begin."],
+ hasAlpha = true,
+ get = function()
+ local c = db.title.textcolor or Skada.windowdefaults.title.textcolor
+ return c.r, c.g, c.b, c.a or 1
+ end,
+ set = function(win, r, g, b, a)
+ db.title.textcolor = db.title.textcolor or {}
+ db.title.textcolor.r, db.title.textcolor.g, db.title.textcolor.b, db.title.textcolor.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end,
+ order = 40,
+ width = "double"
+ },
+ barwidth = {
+ type = "range",
+ name = L["Width"],
+ desc = L["opt_barwidth_desc"],
+ min = 100,
+ max = 300,
+ step = 1.0,
+ order = 50,
+ width = "double"
+ },
+ separator = {
+ type = "description",
+ name = "\n",
+ order = 60,
+ width = "full"
+ },
+ fixedbarwidth = {
+ type = "toggle",
+ name = L["Fixed bar width"],
+ desc = L["opt_fixedbarwidth_desc"],
+ order = 70
+ },
+ isusingclasscolors = {
+ type = "toggle",
+ name = L["Class Colors"],
+ desc = format(L["opt_isusingclasscolors_desc"], classcolors.format(Skada.userClass, Skada.userName), Skada.userName),
+ order = 80,
+ },
+ isonnewline = {
+ type = "toggle",
+ name = L["Put values on new line."],
+ desc = format(L["opt_isonnewline_desc"], Skada.userName),
+ order = 90
+ },
+ clickthrough = {
+ type = "toggle",
+ name = L["Click Through"],
+ desc = L["Disables mouse clicks on bars."],
+ order = 100
+ }
+ }
+ }
+
+ options.elvuioptions = {
+ type = "group",
+ name = "ElvUI",
+ desc = format(L["Options for %s."], "ElvUI"),
+ order = 2,
+ get = function(i)
+ return db[i[#i]]
+ end,
+ set = function(i, val)
+ db[i[#i]] = val
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ isusingelvuiskin = {
+ type = "toggle",
+ name = L["Use ElvUI skin if avaliable."],
+ desc = L["opt_isusingelvuiskin_desc"],
+ descStyle = "inline",
+ order = 10,
+ width = "full"
+ },
+ issolidbackdrop = {
+ type = "toggle",
+ name = L["Use solid background."],
+ desc = L["Un-check this for an opaque background."],
+ descStyle = "inline",
+ order = 20,
+ width = "full"
+ }
+ }
+ }
+
+ options.windowoptions = Private.FrameOptions(db, true)
+ end
+
+ function mod:OnInitialize()
+ classcolors = classcolors or Skada.classcolors
+ self.name = L["Inline Bar Display"]
+ self.description = L["mod_inline_desc"]
+ Skada:AddDisplaySystem("inline", self, true)
+ end
+end)
diff --git a/Skada/Core/Display/Legacy.lua b/Skada/Core/Display/Legacy.lua
new file mode 100644
index 0000000..e5ba8e2
--- /dev/null
+++ b/Skada/Core/Display/Legacy.lua
@@ -0,0 +1,2068 @@
+local folder, Skada = ...
+local Private = Skada.Private
+Skada:RegisterDisplay("Legacy Bar Display", "mod_bar_desc", function(L, P)
+
+ -- common stuff
+ local pairs, type, tsort, format = pairs, type, table.sort, string.format
+ local lib = {} -- LegacyLibBars-1.0
+ local _
+
+ ----------------------------------------------------------------
+ -- LegacyLibBars-1.0 -- stripped down to minimum
+ ----------------------------------------------------------------
+ do
+ local GetTime = GetTime
+ local cos, abs, min, max, floor = math.cos, math.abs, math.min, math.max, math.floor
+ local wipe, tremove, tconcat = wipe, tremove, table.concat
+ local next, error = next, error
+
+ local CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0")
+ lib.callbacks = lib.callbacks or CallbackHandler:New(lib)
+ local callbacks = lib.callbacks
+
+ local dummyFrame, barPrototype, barPrototype_mt, barListPrototype
+ local barListPrototype_mt
+
+ lib.dummyFrame = lib.dummyFrame or CreateFrame("Frame")
+ lib.barFrameMT = lib.barFrameMT or {__index = lib.dummyFrame}
+ lib.barPrototype = lib.barPrototype or setmetatable({}, lib.barFrameMT)
+ lib.barPrototype_mt = lib.barPrototype_mt or {__index = lib.barPrototype}
+ lib.barListPrototype = lib.barListPrototype or setmetatable({}, lib.barFrameMT)
+ lib.barListPrototype_mt = lib.barListPrototype_mt or {__index = lib.barListPrototype}
+
+ dummyFrame = lib.dummyFrame
+ barPrototype = lib.barPrototype
+ barPrototype_mt = lib.barPrototype_mt
+ barListPrototype = lib.barListPrototype
+ barListPrototype_mt = lib.barListPrototype_mt
+
+ barPrototype.prototype = barPrototype
+ barPrototype.metatable = barPrototype_mt
+ barPrototype.super = dummyFrame
+
+ barListPrototype.prototype = barListPrototype
+ barListPrototype.metatable = barListPrototype_mt
+ barListPrototype.super = dummyFrame
+
+ lib.bars = lib.bars or {}
+ lib.barLists = lib.barLists or {}
+ lib.recycledBars = lib.recycledBars or {}
+ lib.embeds = lib.embeds or {}
+ local bars = lib.bars
+ local barLists = lib.barLists
+ local recycledBars = lib.recycledBars
+
+ local frame_defaults = {
+ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
+ edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
+ inset = 4,
+ edgeSize = 8,
+ tile = true,
+ insets = {left = 2, right = 2, top = 2, bottom = 2}
+ }
+ local CONFIG_ICON = format([[%s\Textures\toolbar1\config]], Skada.mediapath)
+
+ function lib:GetBar(name)
+ return bars[self] and bars[self][name]
+ end
+
+ function lib:GetBars(name)
+ return bars[self]
+ end
+
+ function lib:NewBarFromPrototype(prototype, name, ...)
+ if self == lib then
+ error("You may only call :NewBar as an embedded function")
+ end
+ if type(prototype) ~= "table" or type(prototype.metatable) ~= "table" then
+ error("Invalid bar prototype")
+ end
+
+ bars[self] = bars[self] or {}
+ local bar = bars[self][name]
+ local isNew = false
+ if not bar then
+ isNew = true
+ bar = tremove(recycledBars)
+ if not bar then
+ bar = CreateFrame("Frame")
+ else
+ bar:Show()
+ end
+ end
+ bar = setmetatable(bar, prototype.metatable)
+ bar.name = name
+ bar:Create(...)
+ bar:SetFont(self.font, self.fontSize, self.fontFlags)
+
+ bars[self][name] = bar
+
+ return bar, isNew
+ end
+
+ function lib:NewCounterBar(name, text, value, maxVal, icon, orientation, length, thickness, isTimer)
+ return self:NewBarFromPrototype(barPrototype, name, text, value, maxVal, icon, orientation, length, thickness, isTimer)
+ end
+
+ function lib:ReleaseBar(name)
+ if not bars[self] then return end
+
+ local bar
+ if type(name) == "string" then
+ bar = bars[self][name]
+ elseif type(name) == "table" then
+ if name.name and bars[self][name.name] == name then
+ bar = name
+ end
+ end
+
+ if bar then
+ bar:OnBarReleased()
+ bars[self][bar.name] = nil
+ recycledBars[#recycledBars + 1] = bar
+ end
+ end
+
+ do
+ local function move(self)
+ local p = self:GetParent()
+ if p and not p.locked then
+ self.startX = p:GetLeft()
+ self.startY = p:GetTop()
+ p:StartMoving()
+ end
+ end
+ local function stopMove(self)
+ local p = self:GetParent()
+ if p and not p.locked then
+ p:StopMovingOrSizing()
+ local endX = p:GetLeft()
+ local endY = p:GetTop()
+ if self.startX ~= endX or self.startY ~= endY then
+ callbacks:Fire("AnchorMoved", p, endX, endY)
+ end
+ end
+ end
+ local function buttonClick(self, button)
+ callbacks:Fire("AnchorClicked", self:GetParent(), button)
+ end
+ local function configClick(self, button)
+ callbacks:Fire("ConfigClicked", self:GetParent(), button)
+ end
+
+ local DEFAULT_TEXTURE = [[Interface\TARGETINGFRAME\UI-StatusBar]]
+ function lib:NewBarGroup(name, orientation, length, thickness, frameName)
+ if self == lib then
+ error("You may only call :NewBarGroup as an embedded function")
+ end
+
+ barLists[self] = barLists[self] or {}
+ if barLists[self][name] then
+ error(format("A bar list named %s already exists.", name))
+ end
+
+ orientation = orientation or 1
+ orientation = orientation == "LEFT" and 1 or orientation
+ orientation = orientation == "RIGHT" and 2 or orientation
+
+ local list = setmetatable(CreateFrame("Frame", frameName, UIParent), barListPrototype_mt)
+ list:SetMovable(true)
+ list:SetClampedToScreen(true)
+
+ barLists[self][name] = list
+ list.name = name
+
+ local myfont = lib.defaultFont or _G["SkadaRevTitleFont"]
+ if not myfont then
+ myfont = CreateFont("SkadaRevTitleFont")
+ myfont:CopyFontObject(ChatFontSmall)
+ lib.defaultFont = myfont
+ end
+
+ list.button = CreateFrame("Button", nil, list)
+ list.button:SetBackdrop(frame_defaults)
+ list.button:SetText(name)
+ list.button:SetNormalFontObject(myfont)
+ list.button.text = list.button:GetFontString(nil, "ARTWORK")
+ list.button.text:SetWordWrap(false)
+ list.button.text:SetAllPoints(true)
+
+ list.length = length or 200
+ list.thickness = thickness or 15
+ list:SetOrientation(orientation)
+
+ list:UpdateOrientationLayout()
+
+ list.button:SetScript("OnMouseDown", move)
+ list.button:SetScript("OnMouseUp", stopMove)
+ list.button:SetBackdropColor(0, 0, 0, 1)
+ list.button:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
+ list.button:SetScript("OnClick", buttonClick)
+
+ list.optbutton = CreateFrame("Button", nil, list)
+ list.optbutton:SetFrameLevel(10)
+ list.optbutton:ClearAllPoints()
+ list.optbutton:SetHeight(16)
+ list.optbutton:SetWidth(16)
+ list.optbutton:SetNormalTexture(CONFIG_ICON)
+ list.optbutton:SetHighlightTexture(CONFIG_ICON, "ADD")
+ list.optbutton:SetAlpha(0.3)
+ list.optbutton:SetPoint("TOPRIGHT", list.button, "TOPRIGHT", -5, 0 - (max(list.button:GetHeight() - list.optbutton:GetHeight(), 2) / 2))
+ list.optbutton:Show()
+ list.optbutton:RegisterForClicks("LeftButtonUp", "RightButtonUp")
+ list.optbutton:SetScript("OnClick", configClick)
+
+ list:SetPoint("TOPLEFT", UIParent, "CENTER")
+ list:ReverseGrowth(false)
+
+ list.showIcon = true
+ list.showLabel = true
+ list.showTimerLabel = true
+
+ list.lastBar = list
+ list.locked = false
+
+ list.texture = DEFAULT_TEXTURE
+ list.spacing = 0
+ list.offset = 0
+
+ return list
+ end
+ end
+
+ function lib:GetBarGroup(name)
+ return barLists[self] and barLists[self][name]
+ end
+
+ function barListPrototype:NewBarFromPrototype(prototype, ...)
+ local bar, isNew = lib.NewBarFromPrototype(self, prototype, ...)
+ bar:SetTexture(self.texture)
+ bar:SetFill(self.fill)
+
+ if self.showIcon then
+ bar:ShowIcon()
+ else
+ bar:HideIcon(bar)
+ end
+ if self.showLabel then
+ bar:ShowLabel()
+ else
+ bar:HideLabel(bar)
+ end
+ if self.showTimerLabel then
+ bar:ShowTimerLabel()
+ else
+ bar:HideTimerLabel(bar)
+ end
+ self:SortBars()
+ bar.ownerGroup = self
+ bar:SetParent(self)
+ return bar, isNew
+ end
+
+ barListPrototype.SetWidth = barListPrototype.SetLength
+ barListPrototype.SetHeight = barListPrototype.SetThickness
+
+ function barListPrototype:NewCounterBar(name, text, value, maxVal, icon, isTimer)
+ return self:NewBarFromPrototype(barPrototype, name, text, value, maxVal, icon, self.orientation, self.length, self.thickness, isTimer)
+ end
+
+ function barListPrototype:SetLocked(lock)
+ if lock then
+ self:Lock()
+ else
+ self:Unlock()
+ end
+ end
+
+ function barListPrototype:Lock()
+ self.locked = true
+ end
+
+ function barListPrototype:Unlock()
+ self.locked = false
+ end
+
+ -- Max number of bars to display. nil to display all.
+ function barListPrototype:SetMaxBars(num)
+ self.maxBars = num
+ end
+
+ function barListPrototype:SetTexture(tex)
+ self.texture = tex
+ if not bars[self] then return end
+ for k, v in pairs(bars[self]) do
+ v:SetTexture(tex)
+ end
+ end
+
+ function barListPrototype:SetFont(f, s, m)
+ self.font, self.fontSize, self.fontFlags = f, s, m
+ if not bars[self] then return end
+ for k, v in pairs(bars[self]) do
+ v:SetFont(f, s, m)
+ end
+ end
+
+ function barListPrototype:SetFill(fill)
+ self.fill = fill
+ if not bars[self] then return end
+ for k, v in pairs(bars[self]) do
+ v:SetFill(fill)
+ end
+ end
+
+ function barListPrototype:ShowIcon()
+ self.showIcon = true
+ if not bars[self] then return end
+ for name, bar in pairs(bars[self]) do
+ bar:ShowIcon()
+ end
+ end
+
+ function barListPrototype:HideIcon()
+ self.showIcon = false
+ if not bars[self] then return end
+ for name, bar in pairs(bars[self]) do
+ bar:HideIcon()
+ end
+ end
+
+ function barListPrototype:ShowLabel()
+ self.showLabel = true
+ for name, bar in pairs(bars[self]) do
+ bar:ShowLabel()
+ end
+ end
+
+ function barListPrototype:HideLabel()
+ self.showLabel = false
+ for name, bar in pairs(bars[self]) do
+ bar:HideLabel()
+ end
+ end
+
+ function barListPrototype:ShowTimerLabel()
+ self.showTimerLabel = true
+ for name, bar in pairs(bars[self]) do
+ bar:ShowTimerLabel()
+ end
+ end
+
+ function barListPrototype:HideTimerLabel()
+ self.showTimerLabel = false
+ for name, bar in pairs(bars[self]) do
+ bar:HideTimerLabel()
+ end
+ end
+
+ function barListPrototype:SetSpacing(spacing)
+ self.spacing = spacing
+ self:SortBars()
+ end
+
+ barListPrototype.GetBar = lib.GetBar
+ barListPrototype.GetBars = lib.GetBars
+
+ function barListPrototype:RemoveBar(bar)
+ lib.ReleaseBar(self, bar)
+ end
+
+ function barListPrototype:SetDisplayMax(val)
+ self.displayMax = val
+ end
+
+ function barListPrototype:SetColor(r, g, b, a)
+ self.colors = self.colors or {}
+ self.colors[1] = r
+ self.colors[2] = g
+ self.colors[3] = b
+ self.colors[4] = a
+ self:UpdateColors()
+ end
+
+ function barListPrototype:UnsetColor()
+ if not self.colors then return end
+ wipe(self.colors)
+ end
+ barListPrototype.UnsetAllColors = barListPrototype.UnsetColor
+
+ function barListPrototype:UpdateColors()
+ if not bars[self] then return end
+ for k, v in pairs(bars[self]) do
+ v:UpdateColor()
+ end
+ end
+
+ function barListPrototype:TimerFinished(evt, bar, name)
+ callbacks:Fire("TimerFinished", bar.ownerGroup, bar, name)
+ end
+
+ function barListPrototype:ShowAnchor()
+ self.button:Show()
+ self:SortBars()
+ end
+
+ function barListPrototype:HideAnchor()
+ self.button:Hide()
+ self:SortBars()
+ end
+
+ function barListPrototype:ReverseGrowth(reverse)
+ self.growup = reverse
+ self.button:ClearAllPoints()
+ if reverse then
+ self.button:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT")
+ self.button:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
+ else
+ self.button:SetPoint("TOPLEFT", self, "TOPLEFT")
+ self.button:SetPoint("TOPRIGHT", self, "TOPRIGHT")
+ end
+ self:SortBars()
+ end
+
+ function barListPrototype:SetClickthrough(clickthrough)
+ if self.clickthrough ~= clickthrough then
+ self.clickthrough = clickthrough or nil
+ if bars[self] then
+ for _, bar in pairs(bars[self]) do
+ bar:EnableMouse(not self.clickthrough)
+ end
+ end
+ end
+ end
+
+ function barListPrototype:UpdateOrientationLayout()
+ local length, thickness = self.length, self.thickness
+ barListPrototype.super.SetWidth(self, length)
+ barListPrototype.super.SetHeight(self, thickness)
+ self.button:SetWidth(length)
+ self.button:SetHeight(thickness)
+
+ self.button:SetText(self.name)
+ self:ReverseGrowth(self.growup)
+ end
+
+ function barListPrototype:SetLength(length)
+ self.length = length
+ if bars[self] then
+ for k, v in pairs(bars[self]) do
+ v:SetLength(length)
+ end
+ end
+ self:UpdateOrientationLayout()
+ end
+
+ function barListPrototype:GetLength()
+ return self.length
+ end
+
+ function barListPrototype:SetThickness(thickness)
+ self.thickness = thickness
+ if bars[self] then
+ for k, v in pairs(bars[self]) do
+ v:SetThickness(thickness)
+ end
+ end
+ self:UpdateOrientationLayout()
+ end
+
+ function barListPrototype:GetThickness()
+ return self.thickness
+ end
+
+ function barListPrototype:SetOrientation(orientation)
+ self.orientation = orientation
+ if bars[self] then
+ for k, v in pairs(bars[self]) do
+ v:SetOrientation(orientation)
+ end
+ end
+ self:UpdateOrientationLayout()
+ end
+
+ -- Allows nil sort function.
+ function barListPrototype:SetSortFunction(func)
+ if func and type(func) ~= "function" then
+ error(":SetSortFunction requires a valid function.")
+ end
+ self.sortFunc = func
+ end
+
+ function barListPrototype:SetBarOffset(offset)
+ self.offset = offset
+ self:SortBars()
+ end
+
+ function barListPrototype:SetUseSpark(use)
+ self.usespark = use
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ if self.usespark and not bar.spark:IsShown() then
+ bar.spark:Show()
+ elseif not self.usespark and bar.spark:IsShown() then
+ bar.spark:Hide()
+ end
+ end
+ end
+
+ do
+ local values = {}
+ local function sortFuncReverse(a, b)
+ if a.isTimer ~= b.isTimer then
+ return a.isTimer
+ end
+
+ local apct, bpct = a.value / a.maxValue, b.value / b.maxValue
+ if apct == bpct then
+ if a.maxValue == b.maxValue then
+ return a.name < b.name
+ else
+ return a.maxValue < b.maxValue
+ end
+ else
+ return apct < bpct
+ end
+ end
+ local function sortFunc(a, b)
+ if a.isTimer ~= b.isTimer then
+ return a.isTimer
+ end
+
+ local apct, bpct = a.value / a.maxValue, b.value / b.maxValue
+ if apct == bpct then
+ if a.maxValue == b.maxValue then
+ return a.name > b.name
+ else
+ return a.maxValue > b.maxValue
+ end
+ else
+ return apct > bpct
+ end
+ end
+ function barListPrototype:SortBars()
+ local lastBar = self.button:IsVisible() and self.button or self
+ local ct = 0
+ if not bars[self] then return end
+
+ for k, v in pairs(bars[self]) do
+ ct = ct + 1
+ values[ct] = v
+ end
+ for i = ct + 1, #values do
+ values[i] = nil
+ end
+
+ if self.growup then
+ tsort(values, self.sortFunc or sortFuncReverse)
+ else
+ tsort(values, self.sortFunc or sortFunc)
+ end
+
+ local orientation = self.orientation
+ local growup = self.growup
+ local spacing = self.spacing
+
+ local from, to
+ local thickness, showIcon = self.thickness, self.showIcon
+ local x1, y1, x2, y2 = 0, 0, 0, 0
+ if growup then
+ from = "BOTTOM"
+ to = "TOP"
+ y1, y2 = spacing, spacing
+ else
+ from = "TOP"
+ to = "BOTTOM"
+ y1, y2 = -spacing, -spacing
+ end
+ local totalHeight = 0
+
+ local shown = 0
+ for i = 1, #values do
+ local origTo = to
+ local v = values[i]
+ if lastBar == self or lastBar == self.button then
+ if lastBar == self then
+ to = from
+ end
+ if orientation == 1 then
+ x1, x2 = (v.showIcon and thickness or 0), 0
+ else
+ x1, x2 = 0, (v.showIcon and -thickness or 0)
+ end
+ else
+ x1, x2 = 0, 0
+ end
+
+ v:ClearAllPoints()
+ if (self.maxBars and shown >= self.maxBars) or (i < self.offset + 1) then
+ v:Hide()
+ else
+ v:Show()
+ shown = shown + 1
+ totalHeight = totalHeight + v:GetHeight() + y1
+ v:SetPoint(format("%sLEFT", from), lastBar, format("%sLEFT", to), x1, y1)
+ v:SetPoint(format("%sRIGHT", from), lastBar, format("%sRIGHT", to), x2, y2)
+ lastBar = v
+ end
+ to = origTo
+ end
+ self.lastBar = lastBar
+ end
+ end
+
+ -- ****************************************************************
+ -- *** Bar methods
+ -- ****************************************************************
+
+ --[[ Bar Prototype ]]
+ do
+ local function barClick(self, button)
+ callbacks:Fire("BarClick", self:GetParent(), button)
+ end
+ local function barEnter(self, button)
+ callbacks:Fire("BarEnter", self:GetParent(), button)
+ end
+ local function barLeave(self, button)
+ callbacks:Fire("BarLeave", self:GetParent(), button)
+ end
+
+ local DEFAULT_ICON = [[Interface\ICONS\INV_Misc_QuestionMark]]
+ function barPrototype:Create(text, value, maxVal, icon, orientation, length, thickness, isTimer)
+ self:SetScript("OnSizeChanged", self.OnSizeChanged)
+
+ self.texture = self.texture or self:CreateTexture(nil, "ARTWORK")
+
+ if self.timeLeftTriggers then
+ for k, v in pairs(self.timeLeftTriggers) do
+ self.timeLeftTriggers[k] = false
+ end
+ end
+
+ if not self.spark then
+ self.spark = self:CreateTexture(nil, "OVERLAY")
+ self.spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
+ self.spark:SetWidth(10)
+ self.spark:SetHeight(10)
+ self.spark:SetBlendMode("ADD")
+ end
+
+ self.bgtexture = self.bgtexture or self:CreateTexture(nil, "BACKGROUND")
+ self.bgtexture:SetAllPoints()
+ self.bgtexture:SetVertexColor(0.3, 0.3, 0.3, 0.6)
+
+ self.icon = self.icon or self:CreateTexture(nil, "OVERLAY")
+ self.icon:SetPoint("LEFT", self, "LEFT", 0, 0)
+ self:SetIcon(icon or DEFAULT_ICON)
+ if icon then
+ self:ShowIcon()
+ end
+ self.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)
+
+ self.label = self.label or self:CreateFontString(nil, "OVERLAY", "ChatFontNormal")
+ self.label:SetText(text)
+ self.label:ClearAllPoints()
+ self.label:SetPoint("LEFT", self, "LEFT", 3, 0)
+ self:ShowLabel()
+
+ local f, s, m = self.label:GetFont()
+ self.label:SetFont(f, s or 10, m)
+
+ self.timerLabel = self.timerLabel or self:CreateFontString(nil, "OVERLAY", "ChatFontNormal")
+ self:SetTimerLabel("")
+ self.timerLabel:ClearAllPoints()
+ self.timerLabel:SetPoint("RIGHT", self, "RIGHT", -6, 0)
+ self:HideTimerLabel()
+
+ f, s, m = self.timerLabel:GetFont()
+ self.timerLabel:SetFont(f, s or 10, m)
+
+ self.timerFuncs = wipe(self.timerFuncs or {})
+
+ self:SetScale(1)
+ self:SetAlpha(1)
+
+ self.length = length or 200
+ self.thickness = thickness or 15
+ self:SetOrientation(orientation or 1)
+
+ value = value or 1
+ maxVal = maxVal or value
+ self.value = value
+ self.maxValue = maxVal
+ self.isTimer = isTimer
+
+ if not isTimer then
+ self:SetMaxValue(maxVal)
+ else
+ self:SetTimer(value, maxVal)
+ end
+ self:SetValue(value)
+ end
+ end
+
+ barPrototype.SetWidth = barListPrototype.SetWidth
+ barPrototype.SetHeight = barListPrototype.SetHeight
+
+ function barPrototype:OnBarReleased()
+ self:StopTimer()
+
+ callbacks:Fire("BarReleased", self, self.name)
+
+ -- Reset our attributes
+ self.isTimer = false
+ self.ownerGroup = nil
+ self.fill = false
+ if self.colors then
+ wipe(self.colors)
+ end
+ if self.timeLeftTriggers then
+ wipe(self.timeLeftTriggers)
+ end
+
+ -- Reset widget
+ self.texture:SetVertexColor(1, 1, 1, 0)
+ self:SetScript("OnUpdate", nil)
+ self:SetParent(UIParent)
+ self:ClearAllPoints()
+ self:Hide()
+ local f, s, m = ChatFontNormal:GetFont()
+ self.label:SetFont(f, s or 10, m)
+ self.timerLabel:SetFont(f, s or 10, m)
+ end
+
+ function barPrototype:GetGroup()
+ return self.ownerGroup
+ end
+
+ function barPrototype:OnSizeChanged()
+ self:SetValue(self.value)
+ end
+
+ function barPrototype:SetFont(newFont, newSize, newFlags)
+ local t, font, size, flags
+ t = self.label
+ font, size, flags = t:GetFont()
+ t:SetFont(newFont or font, newSize or size, newFlags or flags)
+
+ t = self.timerLabel
+ font, size, flags = t:GetFont()
+ t:SetFont(newFont or font, newSize or size, newFlags or flags)
+ end
+
+ function barPrototype:AddOnUpdate(f)
+ self.timerFuncs[#self.timerFuncs + 1] = f
+ self:SetScript("OnUpdate", self.OnUpdate)
+ end
+
+ function barPrototype:RemoveOnUpdate(f)
+ local timerFuncs = self.timerFuncs
+ for i = 1, #timerFuncs do
+ if f == timerFuncs[i] then
+ tremove(timerFuncs, i)
+ if #timerFuncs == 0 then
+ self:SetScript("OnUpdate", nil)
+ end
+ return
+ end
+ end
+ end
+
+ function barPrototype.OnUpdate(f, t)
+ local timerFuncs = f.timerFuncs
+ for i = 1, #timerFuncs do
+ local func = timerFuncs[i]
+ if func then
+ func(f, t)
+ end
+ end
+ end
+
+ function barPrototype:SetIcon(icon, ...)
+ if icon then
+ self.icon:SetTexture(icon)
+ if self.showIcon then
+ self.icon:Show()
+ end
+ if ... then
+ self.icon:SetTexCoord(...)
+ end
+ else
+ self.icon:Hide()
+ end
+ self.iconTexture = icon or nil
+ end
+
+ function barPrototype:ShowIcon()
+ self.showIcon = true
+ if self.iconTexture then
+ self.icon:Show()
+ end
+ end
+
+ function barPrototype:HideIcon()
+ self.showIcon = false
+ self.icon:Hide()
+ end
+
+ function barPrototype:SetLabel(text)
+ self.label:SetText(text)
+ end
+
+ function barPrototype:GetLabel(text)
+ return self.label:GetText(text)
+ end
+
+ barPrototype.SetText = barPrototype.SetLabel -- for API compatibility
+ barPrototype.GetText = barPrototype.GetLabel -- for API compatibility
+
+ function barPrototype:ShowLabel()
+ self.showLabel = true
+ self.label:Show()
+ end
+
+ function barPrototype:HideLabel()
+ self.showLabel = false
+ self.label:Hide()
+ end
+
+ function barPrototype:SetTimerLabel(text)
+ self.timerLabel:SetText(text)
+ end
+
+ function barPrototype:GetTimerLabel(text)
+ return self.timerLabel:GetText(text)
+ end
+
+ function barPrototype:ShowTimerLabel()
+ self.showTimerLabel = true
+ self.timerLabel:Show()
+ end
+
+ function barPrototype:HideTimerLabel()
+ self.showTimerLabel = false
+ self.timerLabel:Hide()
+ end
+
+ function barPrototype:SetTexture(texture)
+ self.texture:SetTexture(texture)
+ self.bgtexture:SetTexture(texture)
+ end
+
+ -- Allows for the setting of background colors for a specific bar
+ -- Someday I'll figure out to do it at the group level
+ function barPrototype:SetBackgroundColor(r, g, b, a)
+ if r and g and b then
+ self.bgtexture:SetVertexColor(r, g, b, a or 0.6)
+ end
+ end
+
+ function barPrototype:SetColor(r, g, b, a)
+ self.colors = self.colors or {}
+ self.colors[1] = r
+ self.colors[2] = g
+ self.colors[3] = b
+ self.colors[4] = a
+ self:UpdateColor()
+ end
+
+ function barPrototype:UnsetColor()
+ if not self.colors then return end
+ wipe(self.colors)
+ end
+ barPrototype.UnsetAllColors = barPrototype.UnsetColor
+
+ do
+ function barPrototype:UpdateOrientationLayout()
+ local o = self.orientation
+ local t
+ if o == 1 then
+ self.icon:ClearAllPoints()
+ self.icon:SetPoint("RIGHT", self, "LEFT", 0, 0)
+
+ t = self.spark
+ t:ClearAllPoints()
+ t:SetPoint("TOP", self.texture, "TOPRIGHT", 0, 7)
+ t:SetPoint("BOTTOM", self.texture, "BOTTOMRIGHT", 0, -7)
+ t:SetTexCoord(0, 1, 0, 1)
+
+ t = self.texture
+ t.SetValue = t.SetWidth
+ t:ClearAllPoints()
+ t:SetPoint("TOPLEFT", self, "TOPLEFT")
+ t:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT")
+
+ t = self.timerLabel
+ t:ClearAllPoints()
+ t:SetPoint("RIGHT", self, "RIGHT", -6, 0)
+ t:SetJustifyH("RIGHT")
+ t:SetJustifyV("MIDDLE")
+
+ t = self.label
+ t:ClearAllPoints()
+ t:SetPoint("LEFT", self, "LEFT", 6, 0)
+ t:SetPoint("RIGHT", self.timerLabel, "LEFT", 0, 0)
+ t:SetJustifyH("LEFT")
+ t:SetJustifyV("MIDDLE")
+
+ self.bgtexture:SetTexCoord(0, 1, 0, 1)
+ elseif o == 2 then
+ self.icon:ClearAllPoints()
+ self.icon:SetPoint("LEFT", self, "RIGHT", 0, 0)
+
+ t = self.spark
+ t:ClearAllPoints()
+ t:SetPoint("TOP", self.texture, "TOPLEFT", 0, 7)
+ t:SetPoint("BOTTOM", self.texture, "BOTTOMLEFT", 0, -7)
+ t:SetTexCoord(0, 1, 0, 1)
+
+ t = self.texture
+ t.SetValue = t.SetWidth
+ t:ClearAllPoints()
+ t:SetPoint("TOPRIGHT", self, "TOPRIGHT")
+ t:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
+
+ t = self.timerLabel
+ t:ClearAllPoints()
+ t:SetPoint("LEFT", self, "LEFT", 6, 0)
+ t:SetJustifyH("LEFT")
+ t:SetJustifyV("MIDDLE")
+
+ t = self.label
+ t:ClearAllPoints()
+ t:SetPoint("RIGHT", self, "RIGHT", -6, 0)
+ t:SetPoint("LEFT", self.timerLabel, "RIGHT", 0, 0)
+ t:SetJustifyH("RIGHT")
+ t:SetJustifyV("MIDDLE")
+
+ self.bgtexture:SetTexCoord(0, 1, 0, 1)
+ end
+ self:SetValue(self.value or 0)
+ end
+ end
+
+ function barPrototype:GetLength()
+ return self.length
+ end
+
+ do
+ local function updateSize(self)
+ local thickness, length = self.thickness, self.length
+ local iconSize = self.showIcon and length or thickness
+ local width = max(0.0001, length - iconSize)
+ local height = thickness
+ barPrototype.super.SetWidth(self, width)
+ barPrototype.super.SetHeight(self, height)
+ self.icon:SetWidth(thickness)
+ self.icon:SetHeight(thickness)
+ end
+
+ function barPrototype:SetLength(length)
+ self.length = length
+ updateSize(self)
+ end
+
+ function barPrototype:SetThickness(thickness)
+ self.thickness = thickness
+ updateSize(self)
+ end
+ end
+
+ function barPrototype:GetThickness()
+ return self.thickness
+ end
+
+ function barPrototype:SetOrientation(orientation)
+ self.orientation = orientation
+ self:UpdateOrientationLayout()
+ self:SetThickness(self.thickness)
+ end
+
+ function barPrototype:SetValue(val)
+ if not val then
+ error("Value cannot be nil!")
+ end
+ self.value = val
+ if not self.maxValue or val > self.maxValue then
+ self.maxValue = val
+ end
+ local ownerGroup = self.ownerGroup
+ local displayMax = ownerGroup and ownerGroup.displayMax or self.displayMax
+ if displayMax then
+ displayMax = min(displayMax, self.maxValue)
+ else
+ displayMax = self.maxValue
+ end
+ local amt = max(0.000001, min(1, val / max(displayMax, 0.000001)))
+ if amt == 1 or amt <= 0.000001 then
+ self.spark:Hide()
+ else
+ self.spark:Show()
+ end
+ local dist = (ownerGroup and ownerGroup:GetLength()) or self.length
+ self:SetTextureValue(max(amt, 0.000001), dist)
+ self:UpdateColor()
+ end
+
+ function barPrototype:SetTextureValue(amt, dist)
+ dist = max(0.0001, dist - (self.showIcon and self.thickness or 0))
+ local t, o = self.texture, self.orientation
+ t:SetValue(amt * dist)
+
+ if o == 1 then
+ t:SetTexCoord(0, amt, 0, 1)
+ elseif o == 2 then
+ t:SetTexCoord(1 - amt, 1, 0, 1)
+ end
+ end
+
+ function barPrototype:SetDisplayMax(val)
+ self.displayMax = val
+ end
+
+ function barPrototype:SetMaxValue(val)
+ self.maxValue = val
+ self:SetValue(self.value)
+ end
+
+ function barPrototype:RegisterTimeLeftTrigger(time, func)
+ if time > 0 then
+ self.timeLeftTriggers = self.timeLeftTriggers or {}
+ self.timeLeftTriggerFuncs = self.timeLeftTriggerFuncs or {}
+ self.timeLeftTriggers[time] = false
+ self.timeLeftTriggerFuncs[time] = func
+ end
+ end
+
+ function barPrototype:OnTimerStarted()
+ callbacks:Fire("TimerStarted", self, self.name)
+ end
+
+ function barPrototype:OnTimerStopped()
+ callbacks:Fire("TimerStopped", self, self.name)
+ end
+
+ function barPrototype:OnTimerFinished()
+ callbacks:Fire("TimerFinished", self, self.name)
+ end
+
+ function barPrototype:SetTimer(remaining, maxVal)
+ if not self.isTimer then
+ return
+ end
+ self.maxValue = maxVal or self.maxValue
+ self:SetValue(self.fill and self.maxValue - remaining or remaining)
+
+ self.timerLabel:Show()
+ self.startTime = GetTime() - (self.maxValue - remaining)
+ self.lastElapsed = 0
+ self.updateDelay = min(max(self.maxValue, 1) / self.length, 0.05)
+ self:UpdateTimer()
+ if remaining > 0 then
+ self:RemoveOnUpdate(self.UpdateTimer)
+ self:AddOnUpdate(self.UpdateTimer)
+ if not self.isTimerRunning then
+ self.isTimerRunning = true
+ if self.OnTimerStarted then
+ self:OnTimerStarted()
+ end
+ end
+ end
+ end
+
+ function barPrototype:StopTimer()
+ if self.isTimer and self.isTimerRunning then
+ self:RemoveOnUpdate(self.UpdateTimer)
+ self.isTimerRunning = false
+ if self.OnTimerStopped then
+ self:OnTimerStopped()
+ end
+ end
+ end
+
+ function barPrototype:SetFill(fill)
+ self.fill = fill
+ end
+
+ function barPrototype:UpdateColor()
+ if not self.colors then return end
+ self.texture:SetVertexColor(self.colors[1], self.colors[2], self.colors[3], self.colors[4] or 1)
+ end
+
+ function barPrototype:UpdateTimer(t)
+ t = t or GetTime()
+ local elapsed, elapsedClamped = t - self.startTime, floor(t) - floor(self.startTime)
+ self.lastElapsed = self.lastElapsed or 0
+ if elapsed - self.lastElapsed <= self.updateDelay then
+ return
+ end
+ self.lastElapsed = elapsed
+
+ local maxvalue = self.maxValue
+ local value, valueClamped, remaining
+ if not self.fill then
+ value = maxvalue - elapsed
+ remaining = value
+ valueClamped = maxvalue - elapsedClamped
+ else
+ value = elapsed
+ remaining = maxvalue - value
+ valueClamped = elapsedClamped
+ end
+ if self.timeLeftTriggers then
+ for k, v in pairs(self.timeLeftTriggers) do
+ if not v and remaining < k then
+ self.timeLeftTriggers[k] = true
+ self.timeLeftTriggerFuncs[k](self, k, remaining)
+ end
+ end
+ end
+ if remaining <= 0 then
+ self:RemoveOnUpdate(self.UpdateTimer)
+ self.isTimerRunning = false
+ if self.OnTimerFinished then
+ self:OnTimerFinished()
+ end
+ end
+ if valueClamped >= 3600 then
+ local h, m, s
+ h = floor(valueClamped / 3600)
+ m = floor((valueClamped - (h * 3600)) / 60)
+ s = floor((valueClamped - (h * 3600)) - (m * 60))
+ self:SetTimerLabel(("%02.0f:%02.0f:%02.0f"):format(h, m, s))
+ elseif valueClamped >= 60 then
+ local m, s
+ m = floor(valueClamped / 60)
+ s = floor(valueClamped - (m * 60))
+ self:SetTimerLabel(("%02.0f:%02.0f"):format(m, s))
+ elseif valueClamped > 10 then
+ self:SetTimerLabel(("%02.0f"):format(valueClamped))
+ else
+ self:SetTimerLabel(("%02.1f"):format(abs(value)))
+ end
+ self:SetValue(value)
+
+ local o = self.orientation
+ if o == 1 then
+ self.texture:SetTexCoord(0, value / maxvalue, 0, 1)
+ elseif o == 2 then
+ self.texture:SetTexCoord(1 - (value / maxvalue), 1, 0, 1)
+ end
+ end
+
+ local function SetShown(self, show)
+ if show and not self:IsShown() then
+ self:Show()
+ elseif not show and self:IsShown() then
+ self:Hide()
+ end
+ end
+ barListPrototype.SetShown = SetShown
+ barPrototype.SetShown = SetShown
+
+ -- things to prevent errors.
+ barListPrototype.SetReverseGrowth = barListPrototype.ReverseGrowth
+ barListPrototype.SetBarHeight = Skada.EmptyFunc
+ barListPrototype.SetDisableHighlight = Skada.EmptyFunc
+ barListPrototype.SetBarBackgroundColor = Skada.EmptyFunc
+ barListPrototype.SetAnchorMouseover = Skada.EmptyFunc
+ barListPrototype.SetButtonsOpacity = Skada.EmptyFunc
+ barListPrototype.SetButtonsSpacing = Skada.EmptyFunc
+ barListPrototype.SetDisableResize = Skada.EmptyFunc
+ barListPrototype.SetDisableStretch = Skada.EmptyFunc
+ barListPrototype.SetReverseStretch = Skada.EmptyFunc
+ barListPrototype.SetDisplacement = Skada.EmptyFunc
+ barListPrototype.ShowButton = Skada.EmptyFunc
+ barListPrototype.SetTextColor = Skada.EmptyFunc
+ barListPrototype.SetSticky = Skada.EmptyFunc
+ barListPrototype.SetSmoothing = Skada.EmptyFunc
+ end
+
+ ----------------------------------------------------------------
+ -- Legacy Bar Display
+ ----------------------------------------------------------------
+ do
+ local mod = Skada:NewModule("Legacy Bar Display", Skada.displayPrototype)
+
+ local IsShiftKeyDown = IsShiftKeyDown
+ local IsAltKeyDown = IsAltKeyDown
+ local IsControlKeyDown = IsControlKeyDown
+
+ local SavePosition, RestorePosition = Private.SavePosition, Private.RestorePosition
+ local classcolors = Skada.classcolors
+ local white = {r = 1, g = 1, b = 1, a = 1}
+
+ -- Display implementation.
+ function mod:OnInitialize()
+ classcolors = classcolors or Skada.classcolors
+ self.description = L["mod_bar_desc"]
+ Skada:AddDisplaySystem("legacy", self, true)
+ end
+
+ function mod:OnEnable()
+ lib.RegisterCallback(self, "AnchorMoved")
+ lib.RegisterCallback(self, "AnchorClicked")
+ lib.RegisterCallback(self, "ConfigClicked")
+ lib.RegisterCallback(self, "BarReleased")
+ end
+
+ -- Called when a Skada window starts using this display provider.
+ function mod:Create(window)
+ -- Re-use bargroup if it exists.
+ local p = window.db
+ window.bargroup = lib.GetBarGroup(mod, p.name)
+ if not window.bargroup then
+ window.bargroup = lib.NewBarGroup(
+ mod,
+ p.name, -- window name
+ p.barorientation, -- bars orientation
+ p.barwidth, -- bars width
+ p.barheight, -- bars height
+ format("%sLegacyWindow%s", folder, p.name) -- frame name
+ )
+ end
+
+ window.bargroup.win = window
+ window.bargroup:EnableMouse(true)
+ window.bargroup:SetScript("OnMouseDown", function(win, button)
+ if button == "RightButton" then
+ window:RightClick()
+ end
+ end)
+ window.bargroup:HideIcon()
+
+ -- Restore window position.
+ RestorePosition(window.bargroup, p)
+ end
+
+ local function showmode(win, id, label, class, mode)
+ -- Add current mode to window traversal history.
+ if win.selectedmode then
+ win.history[#win.history + 1] = win.selectedmode
+ end
+
+ if type(mode) == "function" then
+ mode(win, id, label, class)
+ else
+ if mode.Enter then
+ mode:Enter(win, id, label, class, mode)
+ end
+ win:DisplayMode(mode)
+ end
+ end
+
+ local function BarClick(bar, button)
+ local win = not Skada.testMode and bar and bar.win
+ if not win then return end
+
+ local id, label, class = bar.id, bar.text, bar.class
+
+ local click1 = win.metadata.click1
+ local click2 = win.metadata.click2
+ local click3 = win.metadata.click3
+ local filterclass = win.metadata.filterclass
+
+ if button == "RightButton" and IsShiftKeyDown() then
+ Skada:OpenMenu(win)
+ elseif button == "RightButton" and IsAltKeyDown() then
+ Skada:ModeMenu(win, bar)
+ elseif button == "RightButton" and IsControlKeyDown() then
+ Skada:SegmentMenu(win)
+ elseif win.metadata.click then
+ win.metadata.click(win, id, label, button, class)
+ elseif button == "RightButton" and not IsModifierKeyDown() then
+ win:RightClick(bar, button)
+ elseif button == "LeftButton" and click2 and IsShiftKeyDown() then
+ showmode(win, id, label, class, click2)
+ elseif button == "LeftButton" and filterclass and IsAltKeyDown() then
+ win:FilterClass(class)
+ elseif button == "LeftButton" and click3 and IsControlKeyDown() then
+ showmode(win, id, label, class, click3)
+ elseif button == "LeftButton" and click1 and not IsModifierKeyDown() then
+ showmode(win, id, label, class, click1)
+ end
+ end
+
+ function mod:SetTitle(win, title)
+ local bargroup = win and win.bargroup
+ if not bargroup then return end
+
+ bargroup.button:SetText(title or win.title or win.metadata.title)
+ end
+
+ function mod:BarReleased(_, bar)
+ if not bar then return end
+ bar.order = nil
+ bar.text = nil
+ bar.win = nil
+ end
+
+ local ttactive = false
+
+ local function BarEnter(bar, motion)
+ local win = bar and bar.win
+ if not win then return end
+
+ local id, label, class = bar.id, bar.text, bar.class
+ Skada:SetTooltipPosition(GameTooltip, win.bargroup, "legacy", win)
+ Skada:ShowTooltip(win, id, label, bar, class)
+ ttactive = true
+ end
+
+ local function BarLeave(win, id, label)
+ if not ttactive then return end
+ GameTooltip:Hide()
+ ttactive = false
+ end
+
+ local function value_sort(a, b)
+ if not a or a.value == nil then
+ return false
+ elseif not b or b.value == nil then
+ return true
+ else
+ return a.value > b.value
+ end
+ end
+
+ local function bar_order_sort(a, b)
+ return a and b and a.order and b.order and a.order < b.order
+ end
+
+ local function bar_order_reverse_sort(a, b)
+ return a and b and a.order and b.order and a.order < b.order
+ end
+
+ local function bar_seticon(bar, db, data, icon)
+ if icon then
+ bar:SetIcon(icon)
+ bar:ShowIcon()
+ elseif data.icon and not data.ignore and not data.spellid and not data.hyperlink then
+ bar:SetIcon(data.icon)
+ bar:ShowIcon()
+ end
+ end
+
+ local function bar_setcolor(bar, db, data, color)
+ local default = db.barcolor or Skada.windowdefaults.barcolor
+ if not color and data.color then
+ color = data.color
+ elseif not color and db.classcolorbars and data.class then
+ color = classcolors(data.class)
+ end
+
+ color = color or default
+ bar:SetColor(color.r, color.g, color.b, color.a or 1)
+ end
+
+ -- Called by Skada windows when the display should be updated to match the dataset.
+ function mod:Update(win)
+ if not win or not win.bargroup then return end
+
+ -- Set title.
+ win.bargroup.button:SetText(win.metadata.title)
+
+ -- Sort if we are showing spots with "showspots".
+ local metadata = win.metadata
+ local dataset = win.dataset
+ if metadata.showspots or metadata.valueorder then
+ tsort(dataset, value_sort)
+ end
+
+ -- If we are using "wipestale", we may have removed data
+ -- and we need to remove unused bars.
+ -- The Threat module uses this.
+ -- For each bar, mark bar as unchecked.
+ if metadata.wipestale then
+ local bars = win.bargroup:GetBars()
+ if bars then
+ for name, bar in pairs(bars) do
+ bar.checked = nil
+ end
+ end
+ end
+
+ local nr = 1
+ for i = 0, #dataset do
+ local data = dataset[i]
+ if data and data.id then
+ local barid = data.id
+ local barlabel = data.label
+
+ local bar = win.bargroup:GetBar(barid)
+
+ if not bar then
+ -- Initialization of bars.
+ bar = mod:CreateBar(win, barid, barlabel, data.value, metadata.maxvalue or 1, data.icon, false)
+ if data.icon and not data.ignore then
+ bar:ShowIcon()
+ end
+ bar.id = data.id
+ bar.text = data.label
+
+ bar_seticon(bar, win.db, data)
+ bar_setcolor(bar, win.db, data)
+
+ local color = data.class and win.db.classcolortext and classcolors[data.class] or white
+ bar.label:SetTextColor(color.r, color.g, color.b, color.a or 1)
+ bar.timerLabel:SetTextColor(color.r, color.g, color.b, color.a or 1)
+
+ if not data.ignore then
+ bar:SetScript("OnEnter", BarEnter)
+ bar:SetScript("OnLeave", BarLeave)
+ bar:SetScript("OnMouseDown", BarClick)
+ bar:EnableMouse(not win.db.clickthrough)
+ else
+ bar:SetScript("OnEnter", nil)
+ bar:SetScript("OnLeave", nil)
+ bar:SetScript("OnMouseDown", nil)
+ bar:EnableMouse(false)
+ end
+ end
+
+ bar.class = data.class
+ bar:SetValue(data.value)
+ bar:SetMaxValue(metadata.maxvalue or 1)
+
+ if metadata.ordersort then
+ bar.order = i
+ end
+
+ if metadata.showspots and P.showranks and not data.ignore then
+ if win.db.barorientation == 2 then
+ bar:SetLabel(format("%s .%2u", data.text or data.label or L["Unknown"], nr))
+ else
+ bar:SetLabel(format("%2u. %s", nr, data.text or data.label or L["Unknown"]))
+ end
+ else
+ bar:SetLabel(data.text or data.label or L["Unknown"])
+ end
+ bar:SetTimerLabel(data.valuetext)
+
+ if metadata.wipestale then
+ bar.checked = true
+ end
+
+ -- Emphathized items - cache a flag saying it is done so it is not done again.
+ -- This is a little lame.
+ if data.emphathize and bar.emphathize_set ~= true then
+ bar:SetFont(nil, nil, "OUTLINE")
+ bar.emphathize_set = true
+ elseif not data.emphathize and bar.emphathize_set ~= false then
+ bar:SetFont(nil, nil, "PLAIN")
+ bar.emphathize_set = false
+ end
+
+ -- Background texture color.
+ if data.backgroundcolor then
+ bar.bgtexture:SetVertexColor(
+ data.backgroundcolor.r,
+ data.backgroundcolor.g,
+ data.backgroundcolor.b,
+ data.backgroundcolor.a or 1
+ )
+ end
+
+ -- Background texture size (in percent, as the mode has no idea on actual widths).
+ if data.backgroundwidth then
+ bar.bgtexture:ClearAllPoints()
+ bar.bgtexture:SetPoint("BOTTOMLEFT")
+ bar.bgtexture:SetPoint("TOPLEFT")
+ bar.bgtexture:SetWidth(data.backgroundwidth * bar:GetLength())
+ end
+
+ if not data.ignore then
+ nr = nr + 1
+
+ if data.changed and not bar.changed then
+ bar.changed = true
+ bar_seticon(bar, win.db, data, data.icon)
+ bar_setcolor(bar, win.db, data, data.color)
+ elseif not data.changed and bar.changed then
+ bar.changed = nil
+ bar_seticon(bar, win.db, data)
+ bar_setcolor(bar, win.db, data)
+ end
+ end
+ end
+ end
+
+ -- If we are using "wipestale", remove all unchecked bars.
+ if metadata.wipestale then
+ local bars = win.bargroup:GetBars()
+ for name, bar in pairs(bars) do
+ if not bar.checked then
+ win.bargroup:RemoveBar(bar)
+ end
+ end
+ end
+
+ -- Adjust our background frame if background height is dynamic.
+ if win.bargroup.bgframe and win.db.background.height == 0 then
+ self:AdjustBackgroundHeight(win)
+ end
+
+ -- Sort by the order in the data table if we are using "ordersort".
+ if metadata.reversesort then
+ win.bargroup:SetSortFunction(bar_order_reverse_sort)
+ elseif metadata.ordersort then
+ win.bargroup:SetSortFunction(win.db.reversegrowth and bar_order_reverse_sort or bar_order_sort)
+ else
+ win.bargroup:SetSortFunction(nil)
+ end
+
+ win.bargroup:SortBars()
+ end
+
+ function mod:AdjustBackgroundHeight(win)
+ local numbars = 0
+ if win.bargroup:GetBars() ~= nil then
+ for name, bar in pairs(win.bargroup:GetBars()) do
+ if bar:IsShown() then
+ numbars = numbars + 1
+ end
+ end
+ local height = numbars * (win.db.barheight + win.db.barspacing) + win.db.background.borderthickness
+ if win.bargroup.bgframe:GetHeight() ~= height then
+ win.bargroup.bgframe:SetHeight(height)
+ end
+ end
+ end
+
+ local OpenOptions = Private.OpenOptions
+ function mod:ConfigClicked(_, group, button)
+ if button == "RightButton" then
+ OpenOptions(group.win)
+ else
+ Skada:OpenMenu(group.win)
+ end
+ end
+
+ function mod:AnchorClicked(_, group, button)
+ if group and button == "RightButton" then
+ if IsShiftKeyDown() then
+ Skada:OpenMenu(group.win)
+ elseif IsControlKeyDown() then
+ Skada:SegmentMenu(group.win)
+ elseif IsAltKeyDown() then
+ Skada:ModeMenu(group.win, group, true)
+ elseif not group.clickthrough and not Skada.testMode then
+ group.win:RightClick(nil, button)
+ end
+ end
+ end
+
+ function mod:AnchorMoved(_, group, x, y)
+ SavePosition(group, group.win.db)
+ end
+
+ local function getNumberOfBars(win)
+ local bars = win.bargroup:GetBars()
+ local n = 0
+ for i, bar in pairs(bars) do
+ n = n + 1
+ end
+ return n
+ end
+
+ function mod:OnMouseWheel(win, frame, direction)
+ if direction == 1 and win.bargroup.offset > 0 then
+ win.bargroup:SetBarOffset(win.bargroup.offset - 1)
+ elseif direction == -1 and ((getNumberOfBars(win) - win.bargroup.maxBars - win.bargroup.offset) > 0) then
+ win.bargroup:SetBarOffset(win.bargroup.offset + 1)
+ end
+ end
+
+ function mod:CreateBar(win, name, label, value, maxvalue, icon, o)
+ local bar = win.bargroup:NewCounterBar(name, label, value, maxvalue, icon, o)
+ bar:EnableMouseWheel(true)
+ bar:SetScript("OnMouseWheel", function(f, d) mod:OnMouseWheel(win, f, d) end)
+ bar.win = win
+ return bar
+ end
+
+ local titlebackdrop = {}
+ local windowbackdrop = {}
+
+ -- Called by Skada windows when window settings have changed.
+ function mod:ApplySettings(win)
+ local g = win.bargroup
+ local p = win.db
+ g:ReverseGrowth(p.reversegrowth)
+ g:SetOrientation(p.barorientation)
+ g:SetHeight(p.barheight)
+ g:SetWidth(p.barwidth)
+ g:SetTexture(Skada:MediaFetch("statusbar", p.bartexture))
+ g:SetFont(Skada:MediaFetch("font", p.barfont), p.barfontsize)
+ g:SetSpacing(p.barspacing)
+ g:SetColor(p.barcolor.r, p.barcolor.g, p.barcolor.b, p.barcolor.a)
+ g:SetMaxBars(p.barmax)
+ g:SetUseSpark(p.spark)
+ g:SetLocked(p.barslocked)
+
+ -- Header
+ local fo = g.TitleFont or CreateFont(format("TitleFont%s", win.db.name))
+ g.TitleFont = fo
+ fo:SetFont(Skada:MediaFetch("font", p.title.font), p.title.fontsize)
+ g.button:SetNormalFontObject(fo)
+ local inset = p.title.borderinsets
+ titlebackdrop.bgFile = Skada:MediaFetch("statusbar", p.title.texture)
+ if p.title.borderthickness > 0 then
+ titlebackdrop.edgeFile = Skada:MediaFetch("border", p.title.bordertexture)
+ else
+ titlebackdrop.edgeFile = nil
+ end
+ titlebackdrop.tile = false
+ titlebackdrop.tileSize = 0
+ titlebackdrop.edgeSize = p.title.borderthickness
+ titlebackdrop.insets = {left = inset, right = inset, top = inset, bottom = inset}
+ g.button:SetBackdrop(titlebackdrop)
+ local color = p.title.color
+ g.button:SetBackdropColor(color.r, color.g, color.b, color.a or 1)
+
+ if p.enabletitle then
+ g:ShowAnchor()
+ else
+ g:HideAnchor()
+ end
+
+ -- Spark.
+ for i, bar in pairs(g:GetBars()) do
+ if p.spark then
+ bar.spark:Show()
+ else
+ bar.spark:Hide()
+ end
+ end
+
+ -- Header config button
+ g.optbutton:ClearAllPoints()
+ g.optbutton:SetPoint("TOPRIGHT", g.button, "TOPRIGHT", -5, 0 - (math.max(g.button:GetHeight() - g.optbutton:GetHeight(), 1) * 0.5))
+
+ -- Menu button - default on.
+ if p.title.menubutton == nil or p.title.menubutton then
+ g.optbutton:Show()
+ else
+ g.optbutton:Hide()
+ end
+
+ -- Window
+ if p.enablebackground then
+ if g.bgframe == nil then
+ g.bgframe = CreateFrame("Frame", "$parentBG", g)
+ g.bgframe:SetFrameStrata("BACKGROUND")
+ g.bgframe:EnableMouse()
+ g.bgframe:EnableMouseWheel()
+ g.bgframe:SetScript("OnMouseDown", function(frame, btn)
+ if IsShiftKeyDown() then
+ Skada:OpenMenu(win)
+ elseif btn == "RightButton" then
+ win:RightClick()
+ end
+ end)
+ g.bgframe:SetScript("OnMouseWheel", win.OnMouseWheel)
+ end
+
+ inset = p.background.borderinsets
+ windowbackdrop.bgFile = Skada:MediaFetch("background", p.background.texture)
+ if p.background.borderthickness > 0 then
+ windowbackdrop.edgeFile = Skada:MediaFetch("border", p.background.bordertexture)
+ else
+ windowbackdrop.edgeFile = nil
+ end
+ windowbackdrop.tile = false
+ windowbackdrop.tileSize = 0
+ windowbackdrop.edgeSize = p.background.borderthickness
+ windowbackdrop.insets = {left = inset, right = inset, top = inset, bottom = inset}
+ g.bgframe:SetBackdrop(windowbackdrop)
+ color = p.background.color
+ g.bgframe:SetBackdropColor(color.r, color.g, color.b, color.a or 1)
+ g.bgframe:SetWidth(g:GetWidth() + (p.background.borderthickness * 2))
+ g.bgframe:SetHeight(p.background.height)
+
+ g.bgframe:ClearAllPoints()
+ if p.reversegrowth then
+ g.bgframe:SetPoint("LEFT", g.button, "LEFT", -p.background.borderthickness, 0)
+ g.bgframe:SetPoint("RIGHT", g.button, "RIGHT", p.background.borderthickness, 0)
+ g.bgframe:SetPoint("BOTTOM", g.button, "TOP", 0, 0)
+ else
+ g.bgframe:SetPoint("LEFT", g.button, "LEFT", -p.background.borderthickness, 0)
+ g.bgframe:SetPoint("RIGHT", g.button, "RIGHT", p.background.borderthickness, 0)
+ g.bgframe:SetPoint("TOP", g.button, "BOTTOM", 0, 5)
+ end
+ g.bgframe:Show()
+
+ -- Calculate max number of bars to show if our height is not dynamic.
+ if p.background.height > 0 then
+ local maxbars = math.floor(p.background.height / math.max(1, p.barheight + p.barspacing))
+ g:SetMaxBars(maxbars)
+ else
+ -- Adjust background height according to current bars.
+ self:AdjustBackgroundHeight(win)
+ end
+ elseif g.bgframe then
+ g.bgframe:Hide()
+ end
+
+ g:SortBars()
+ end
+
+ --
+ -- Options.
+ --
+
+ local optionsValues = {
+ ORIENTATION = {
+ [1] = L["Left to right"],
+ [2] = L["Right to left"]
+ }
+ }
+
+ function mod:AddDisplayOptions(win, options)
+ local db = win.db
+
+ options.baroptions = {
+ type = "group",
+ name = L["Bars"],
+ order = 1,
+ get = function(info)
+ return db[info[#info]]
+ end,
+ set = function(info, value)
+ db[info[#info]] = value
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ barfont = {
+ type = "select",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Bars"]),
+ order = 10,
+ dialogControl = "LSM30_Font",
+ values = Skada:MediaList("font")
+ },
+ barfontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Bars"]),
+ min = 7,
+ max = 40,
+ step = 1,
+ order = 11
+ },
+ bartexture = {
+ type = "select",
+ name = L["Bar Texture"],
+ desc = L["The texture used by all bars."],
+ width = "double",
+ order = 12,
+ dialogControl = "LSM30_Statusbar",
+ values = Skada:MediaList("statusbar")
+ },
+ barspacing = {
+ type = "range",
+ name = L["Spacing"],
+ desc = format(L["Distance between %s."], L["Bars"]),
+ min = 0,
+ max = 10,
+ step = 1,
+ order = 13
+ },
+ barheight = {
+ type = "range",
+ name = L["Height"],
+ desc = format(L["The height of %s."], L["Bars"]),
+ min = 10,
+ max = 40,
+ step = 1,
+ order = 14
+ },
+ barwidth = {
+ type = "range",
+ name = L["Width"],
+ desc = format(L["The width of %s."], L["Bars"]),
+ min = 80,
+ max = 400,
+ step = 1,
+ order = 14
+ },
+ barmax = {
+ type = "range",
+ name = L["Max Bars"],
+ desc = L["The maximum number of bars shown."],
+ min = 0,
+ max = 100,
+ step = 1,
+ order = 15
+ },
+ barorientation = {
+ type = "select",
+ name = L["Bar Orientation"],
+ desc = L["The direction the bars are drawn in."],
+ values = optionsValues.ORIENTATION,
+ width = "double",
+ order = 17
+ },
+ reversegrowth = {
+ type = "toggle",
+ name = L["Reverse bar growth"],
+ desc = L["Bars will grow up instead of down."],
+ width = "double",
+ order = 19
+ },
+ barcolor = {
+ type = "color",
+ name = L["Bar Color"],
+ desc = L["Choose the default color of the bars."],
+ hasAlpha = true,
+ get = function(i)
+ local c = db.barcolor or Skada.windowdefaults.barcolor
+ return c.r, c.g, c.b, c.a
+ end,
+ set = function(i, r, g, b, a)
+ db.barcolor = db.barcolor or {}
+ db.barcolor.r, db.barcolor.g, db.barcolor.b, db.barcolor.a = r, g, b, a
+ Skada:ApplySettings(db.names)
+ end,
+ order = 20
+ },
+ baraltcolor = {
+ type = "color",
+ name = L["Background Color"],
+ desc = L["The color of the background."],
+ hasAlpha = true,
+ get = function(i)
+ local c = db.baraltcolor or Skada.windowdefaults.baraltcolor
+ return c.r, c.g, c.b, c.a
+ end,
+ set = function(i, r, g, b, a)
+ db.baraltcolor = db.baraltcolor or {}
+ db.baraltcolor.r = r
+ db.baraltcolor.g = g
+ db.baraltcolor.b = b
+ db.baraltcolor.a = a
+ Skada:ApplySettings(db.name)
+ end,
+ order = 21
+ },
+ classcolorbars = {
+ type = "toggle",
+ name = L["Class Color Bars"],
+ desc = L["When possible, bars will be colored according to player class."],
+ order = 30
+ },
+ classcolortext = {
+ type = "toggle",
+ name = L["Class Color Text"],
+ desc = L["When possible, bar text will be colored according to player class."],
+ order = 31
+ },
+ spark = {
+ type = "toggle",
+ name = L["Show Spark Effect"],
+ order = 32
+ },
+ clickthrough = {
+ type = "toggle",
+ name = L["Click Through"],
+ desc = L["Disables mouse clicks on bars."],
+ order = 33
+ }
+ }
+ }
+
+ options.titleoptions = {
+ type = "group",
+ name = L["Title Bar"],
+ order = 2,
+ get = function(info)
+ return db.title[info[#info]]
+ end,
+ set = function(info, value)
+ db.title[info[#info]] = value
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ enable = {
+ type = "toggle",
+ name = L["Enable"],
+ desc = L["Enables the title bar."],
+ width = "double",
+ order = 0,
+ get = function()
+ return db.enabletitle
+ end,
+ set = function()
+ db.enabletitle = not db.enabletitle
+ Skada:ApplySettings(db.name)
+ end
+ },
+ font = {
+ type = "select",
+ name = L["Font"],
+ desc = format(L["The font used by %s."], L["Title Bar"]),
+ dialogControl = "LSM30_Font",
+ values = Skada:MediaList("font"),
+ order = 1
+ },
+ fontsize = {
+ type = "range",
+ name = L["Font Size"],
+ desc = format(L["The font size of %s."], L["Title Bar"]),
+ min = 7,
+ max = 40,
+ step = 1,
+ order = 2
+ },
+ texture = {
+ type = "select",
+ dialogControl = "LSM30_Statusbar",
+ name = L["Background Texture"],
+ desc = L["The texture used as the background of the title."],
+ values = Skada:MediaList("statusbar"),
+ order = 3
+ },
+ color = {
+ type = "color",
+ name = L["Background Color"],
+ desc = L["The color of the background."],
+ hasAlpha = true,
+ get = function(i)
+ local c = db.title.color or Skada.windowdefaults.title.color
+ return c.r, c.g, c.b, c.a
+ end,
+ set = function(i, r, g, b, a)
+ db.title.color = db.title.color or {}
+ db.title.color.r, db.title.color.g, db.title.color.b, db.title.color.a = r, g, b, a
+ Skada:ApplySettings(db.name)
+ end,
+ order = 4
+ },
+ bordertexture = {
+ type = "select",
+ dialogControl = "LSM30_Border",
+ name = L["Border texture"],
+ desc = L["The texture used for the borders."],
+ values = Skada:MediaList("border"),
+ order = 5
+ },
+ borderthickness = {
+ type = "range",
+ name = L["Border Thickness"],
+ desc = L["The thickness of the borders."],
+ min = 0,
+ max = 50,
+ step = 0.5,
+ order = 6
+ },
+ borderinsets = {
+ type = "range",
+ name = L["Border Insets"],
+ desc = L["The distance between the window and its border."],
+ min = 0,
+ max = 50,
+ step = 0.5,
+ width = "double",
+ order = 7
+ },
+ menubutton = {
+ type = "toggle",
+ name = L["Show Menu Button"],
+ desc = L["Shows a button for opening the menu in the window title bar."],
+ order = 9
+ }
+ }
+ }
+
+ options.windowoptions = {
+ type = "group",
+ name = L["Background"],
+ order = 2,
+ get = function(info)
+ return db.background[info[#info]]
+ end,
+ set = function(info, value)
+ db.background[info[#info]] = value
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ enablebackground = {
+ type = "toggle",
+ name = L["Enable"],
+ width = "double",
+ order = 0,
+ get = function()
+ return db.enablebackground
+ end,
+ set = function(_, value)
+ db.enablebackground = value
+ Skada:ApplySettings(db.name)
+ end
+ },
+ texture = {
+ type = "select",
+ name = L["Background Texture"],
+ desc = L["The texture used as the background."],
+ dialogControl = "LSM30_Background",
+ values = Skada:MediaList("background"),
+ order = 1
+ },
+ color = {
+ type = "color",
+ name = L["Background Color"],
+ desc = L["The color of the background."],
+ hasAlpha = true,
+ get = function(i)
+ local c = db.background.color or Skada.windowdefaults.background.color
+ return c.r, c.g, c.b, c.a
+ end,
+ set = function(i, r, g, b, a)
+ db.background.color = db.background.color or {}
+ db.background.color.r = r
+ db.background.color.g = g
+ db.background.color.b = b
+ db.background.color.a = a
+ Skada:ApplySettings(db.name)
+ end,
+ order = 2
+ },
+ bordertexture = {
+ type = "select",
+ name = L["Border texture"],
+ desc = L["The texture used for the borders."],
+ dialogControl = "LSM30_Border",
+ values = Skada:MediaList("border"),
+ order = 3
+ },
+ borderthickness = {
+ type = "range",
+ name = L["Border Thickness"],
+ desc = L["The thickness of the borders."],
+ min = 0,
+ max = 50,
+ step = 0.5,
+ order = 4
+ },
+ borderinsets = {
+ type = "range",
+ name = L["Border Insets"],
+ desc = L["The distance between the window and its border."],
+ min = 0,
+ max = 50,
+ step = 0.5,
+ order = 5
+ },
+ height = {
+ type = "range",
+ name = L["Height"],
+ desc = format(L["The height of %s."], L["Window"]),
+ min = 0,
+ max = 600,
+ step = 1,
+ order = 6
+ }
+ }
+ }
+ end
+ end
+end)
diff --git a/Skada/Core/Functions.lua b/Skada/Core/Functions.lua
new file mode 100644
index 0000000..22a75b6
--- /dev/null
+++ b/Skada/Core/Functions.lua
@@ -0,0 +1,2322 @@
+local folder, Skada = ...
+local Private = Skada.Private
+
+local select, pairs, type = select, pairs, type
+local tonumber, format, gsub = tonumber, string.format, string.gsub
+local setmetatable, wipe = setmetatable, wipe
+local next, time, GetTime = next, time, GetTime
+local _
+
+local UnitGUID, UnitClass, UnitFullName = UnitGUID, UnitClass, Private.UnitFullName
+local IsInGroup, IsInRaid = IsInGroup, IsInRaid
+local tablePool, TempTable = Skada.tablePool, Private.TempTable
+local new, del = Private.newTable, Private.delTable
+local L, callbacks = Skada.Locale, Skada.callbacks
+local guidToName, guidToClass, guidToOwner = Private.guidToName, Private.guidToClass, Private.guidToOwner
+
+-------------------------------------------------------------------------------
+-- debug function
+
+do
+ local Print = Private.Print
+ local debug_str = format("\124cff33ff99%s Debug\124r:", folder)
+ function Skada:Debug(...)
+ if not self.profile.debug then return end
+ Print(debug_str, ...)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- modules and display functions
+
+do
+ local tconcat = table.concat
+ local function module_table(...)
+ local args = TempTable(...)
+ if #args >= 2 then
+ -- name must always be first
+ local name = args:remove(1)
+ if type(name) ~= "string" then
+ args:free()
+ return
+ end
+
+ -- second arg can be the desc or the callback
+ local func = nil
+ local desc = args:remove(1)
+ if type(desc) == "string" then
+ func = args:remove(1)
+ desc = L[desc]
+ elseif type(desc) == "function" then
+ func = desc
+ desc = nil
+ end
+
+ -- double check just in case
+ if type(func) ~= "function" then
+ args:free()
+ return
+ end
+
+ local module = new()
+ module.name = name
+ module.func = func
+
+ -- treat args left as dependencies
+ local args_rem = #args
+ if args_rem > 0 then
+ module.deps = {}
+ local localized_deps = new()
+ for i = 1, #args do
+ module.deps[i] = args[i]
+ localized_deps[i] = L[args[i]] -- localize
+ end
+
+ -- format module's description
+ if desc then
+ desc = format("%s\n%s", desc, format(L["\124cff00ff00Requires\124r: %s"], tconcat(localized_deps, ", ")))
+ else
+ desc = format(L["\124cff00ff00Requires\124r: %s"], tconcat(localized_deps, ", "))
+ end
+ del(localized_deps)
+ end
+ module.desc = desc
+ args:free()
+
+ return module
+ end
+
+ args:free()
+ end
+
+ -- adds a module to the loadable modules table.
+ local unpack = unpack
+ function Skada:RegisterModule(...)
+ local module = module_table(...)
+ if not module then return end
+
+ -- add to loadable modules table
+ self.LoadableModules = self.LoadableModules or new()
+ self.LoadableModules[#self.LoadableModules + 1] = module
+
+ -- add its check button
+ self.options.args.modules.args.blocked.args[module.name] = {
+ type = "toggle",
+ name = function()
+ if module.deps and self:IsDisabled(unpack(module.deps)) then
+ return format("\124cffff0000%s\124r", L[module.name])
+ end
+ return L[module.name]
+ end,
+ desc = module.desc
+ }
+
+ -- return it so that RegisterDisplay changes order
+ return self.options.args.modules.args.blocked.args[module.name]
+ end
+
+ -- when modules are created w make sure to save
+ -- their english "name" then localize "moduleName"
+ function Skada:OnModuleCreated(module)
+ module.localeName = L[module.moduleName]
+ module.OnModuleCreated = module.OnModuleCreated or self.OnModuleCreated
+ module.isParent = (self == Skada)
+ end
+
+ do
+ local cbxorder = 910
+
+ -- registers a loadable display system
+ function Skada:RegisterDisplay(...)
+ local args = self:RegisterModule(...)
+ if not args then return end
+ args.order = cbxorder
+ cbxorder = cbxorder + 10
+ end
+
+ local displays = Skada.displays
+ local display_with_totals = Skada.display_with_totals
+ local numorder = 80
+
+ -- adds a display system
+ function Skada:AddDisplaySystem(key, mod, has_totals)
+ displays[key] = mod
+ if mod.description then
+ self.options.args.windows.args[format("%sdesc", key)] = {
+ type = "description",
+ name = format("\n\124cffffd700%s\124r:\n%s", mod.localeName, mod.description),
+ fontSize = "small",
+ order = numorder
+ }
+ numorder = numorder + 10
+ end
+ display_with_totals[key] = (has_totals == true)
+ end
+ end
+
+ -- checks whether the select module(s) are disabled
+ function Skada:IsDisabled(...)
+ for i = 1, select("#", ...) do
+ if self.profile.modulesBlocked[select(i, ...)] == true then
+ return true
+ end
+ end
+ return false
+ end
+
+ -- loads registered modules
+ function Skada:LoadModules(release)
+ -- loadable modules
+ if self.LoadableModules then
+ local mod = tremove(self.LoadableModules, 1)
+ while mod do
+ if mod.name and mod.func and not self:IsDisabled(mod.name) and not (mod.deps and self:IsDisabled(unpack(mod.deps))) then
+ mod.func(L, self.profile, self.global, self.cacheTable, self.profile.modules, self.options.args)
+ end
+ mod = tremove(self.LoadableModules, 1)
+ end
+ end
+
+ if not release then return end
+ self.LoadableModules = del(self.LoadableModules)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- format functions
+
+do
+ local reverse = string.reverse
+ local numbersystem = nil
+ function Private.SetNumberFormat(system)
+ system = system or numbersystem
+ if numbersystem == system then return end
+ numbersystem = system
+
+ local ShortenValue = function(num)
+ if num >= 1e9 or num <= -1e9 then
+ return format("%.2fB", num * 1e-09)
+ elseif num >= 1e6 or num <= -1e6 then
+ return format("%.2fM", num * 1e-06)
+ elseif num >= 1e3 or num <= -1e3 then
+ return format("%.1fK", num * 0.001)
+ end
+ return format("%.0f", num)
+ end
+
+ if system == 3 or (system == 1 and (LOCALE_koKR or LOCALE_zhCN or LOCALE_zhTW)) then
+ -- default to chinese, even for western clients.
+ local symbol_1k, symbol_10k, symbol_1b = "千", "万", "亿"
+ if LOCALE_koKR then
+ symbol_1k, symbol_10k, symbol_1b = "천", "만", "억"
+ elseif LOCALE_zhTW then
+ symbol_1k, symbol_10k, symbol_1b = "千", "萬", "億"
+ end
+
+ ShortenValue = function(num)
+ if num >= 1e8 or num <= -1e8 then
+ return format("%.2f%s", num * 1e-08, symbol_1b)
+ elseif num >= 1e4 or num <= -1e4 then
+ return format("%.2f%s", num * 0.0001, symbol_10k)
+ elseif num >= 1e3 or num <= -1e3 then
+ return format("%.1f%s", num * 0.001, symbol_1k)
+ end
+ return format("%.0f", num)
+ end
+ end
+
+ Skada.FormatNumber = function(self, num, fmt)
+ if not num then return end
+ fmt = fmt or self.profile.numberformat or 1
+
+ if fmt == 1 and (num >= 1e3 or num <= -1e3) then
+ return ShortenValue(num)
+ elseif fmt == 2 and (num >= 1e3 or num <= -1e3) then
+ local left, mid, right = strmatch(tostring(floor(num)), "^([^%d]*%d)(%d*)(.-)$")
+ return format("%s%s%s", left, reverse(gsub(reverse(mid), "(%d%d%d)", "%1,")), right)
+ else
+ return format("%.0f", num)
+ end
+ end
+ end
+end
+
+function Skada:FormatPercent(value, total, dec)
+ dec = dec or self.profile.decimals or 1
+
+ -- no value? 0%
+ if not value then
+ return format(format("%%.%df%%%%", dec), 0)
+ end
+
+ -- correct values.
+ value, total = total and (100 * value) or value, max(1, total or 0)
+
+ -- below 0? clamp to -999
+ if value <= 0 then
+ return format(format("%%.%df%%%%", dec), max(-999, value / total))
+ -- otherwise, clamp to 999
+ else
+ return format(format("%%.%df%%%%", dec), min(999, value / total))
+ end
+end
+
+function Skada:FormatTime(sec, alt, ...)
+ if not sec then
+ return
+ elseif alt then
+ return SecondsToTime(sec, ...)
+ elseif sec >= 3600 then
+ local h = floor(sec / 3600)
+ local m = floor(sec / 60 - (h * 60))
+ local s = floor(sec - h * 3600 - m * 60)
+ return format("%02.f:%02.f:%02.f", h, m, s)
+ else
+ return format("%02.f:%02.f", floor(sec / 60), floor((sec % 60) + 0.5))
+ end
+end
+
+local Translit = LibStub("LibTranslit-1.0", true)
+function Skada:FormatName(name)
+ name = self.profile.realmless and gsub(name, ("%-.*"), "") or name
+ return self.profile.translit and Translit and Translit:Transliterate(name, "!") or name
+end
+
+do
+ -- brackets and separators
+ local brackets = {"(%s)", "{%s}", "[%s]", "<%s>", "%s"}
+ local separators = {"%s, %s", "%s. %s", "%s; %s", "%s - %s", "%s \124\124 %s", "%s / %s", "%s \\ %s", "%s ~ %s", "%s %s"}
+
+ -- formats default values
+ local format_2 = "%s (%s)"
+ local format_3 = "%s (%s, %s)"
+
+ function Private.SetValueFormat(bracket, separator)
+ format_2 = brackets[bracket or 1]
+ format_3 = format("%%s %s", format(format_2, separators[separator or 1]))
+ format_2 = format("%%s %s", format_2)
+ end
+
+ function Skada:FormatValueText(v1, b1, v2, b2, v3, b3)
+ if b1 and b2 and b3 then
+ return format(format_3, v1, v2, v3)
+ elseif b1 and b2 then
+ return format(format_2, v1, v2)
+ elseif b1 and b3 then
+ return format(format_2, v1, v3)
+ elseif b2 and b3 then
+ return format(format_2, v2, v3)
+ elseif b2 then
+ return v2
+ elseif b1 then
+ return v1
+ elseif b3 then
+ return v3
+ end
+ end
+
+ function Skada:FormatValueCols(col1, col2, col3)
+ if col1 and col2 and col3 then
+ return format(format_3, col1, col2, col3)
+ elseif col1 and col2 then
+ return format(format_2, col1, col2)
+ elseif col1 and col3 then
+ return format(format_2, col1, col3)
+ elseif col2 and col3 then
+ return format(format_2, col2, col3)
+ elseif col2 then
+ return col2
+ elseif col1 then
+ return col1
+ elseif col3 then
+ return col3
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- report function
+
+do
+ local tsort = table.sort
+ local SendChatMessage, BNSendWhisper = SendChatMessage, BNSendWhisper
+ local Window, windows = Skada.Window, Skada.windows
+ local EscapeStr = Private.EscapeStr
+
+ function Skada:SendChat(msg, chan, chantype, noescape)
+ if strlower(chan) == "self" or strlower(chantype) == "self" then
+ Skada:Print(msg)
+ return
+ end
+ if strlower(chan) == "auto" then
+ if not IsInGroup() then return end
+ chan = (Skada.insType == "pvp" or Skada.insType == "arena") and "battleground" or IsInRaid() and "raid" or "party"
+ end
+
+ if not noescape then
+ msg = EscapeStr(msg)
+ end
+
+ if chantype == "channel" then
+ SendChatMessage(msg, "CHANNEL", nil, chan)
+ elseif chantype == "preset" then
+ SendChatMessage(msg, chan:upper())
+ elseif chantype == "whisper" then
+ SendChatMessage(msg, "WHISPER", nil, chan)
+ elseif chantype == "bnet" then
+ BNSendWhisper(chan, msg)
+ end
+ end
+
+ local strrep = strrep or string.rep
+ local tinsert = table.insert
+ local SpellLink = Private.SpellLink
+
+ local function BuildReportTable(mode, firstline, dataset, maxlines, fmt, barid)
+ local temp = TempTable(EscapeStr(firstline))
+
+ local num = #dataset
+ local nr, max_length = 0, 0
+ for i = 1, num do
+ if nr >= maxlines then break end
+
+ local data = dataset[i]
+ if data and not data.ignore and ((barid and barid == data.id) or (data.id and not barid)) then
+ nr = nr + 1
+ local label = nil
+ if Skada.profile.reportlinks and (data.spellid or data.hyperlink) then
+ if data.reportlabel and data.spellid then
+ label = data.reportlabel:gsub(data.label, SpellLink(data.spellid))
+ else
+ label = data.hyperlink or SpellLink(data.spellid) or data.reportlabel or data.label
+ end
+ label = TempTable(EscapeStr(label), " ")
+ else
+ label = TempTable(EscapeStr(data.reportlabel or data.label), " ")
+ end
+
+ if label then
+ label[#label + 1] = EscapeStr(data.reportvalue or data.valuetext)
+ if mode.metadata and mode.metadata.showspots then
+ if fmt and maxlines >= 10 and num >= 10 and not barid then
+ label[1] = format(nr >= 10 and "%s. %s" or " %s. %s", nr, label[1])
+ else
+ label[1] = format("%s. %s", nr, label[1])
+ end
+ end
+ end
+
+ label.n = #label[1]
+ if label[3] then
+ label.n = label.n + #label[3]
+ end
+
+ if label.n > max_length then
+ max_length = label.n
+ end
+
+ temp[#temp + 1] = label
+
+ if barid then break end
+ end
+ end
+
+ for i = #temp, 2, -1 do
+ local label = tremove(temp, i)
+ if label[2] and fmt then
+ label[2] = strrep(" ", max_length - label.n + 3)
+ end
+ tinsert(temp, i, label:concat(""))
+ label = label:free()
+ end
+
+ return temp
+ end
+
+ local function value_id_sort(a, b)
+ if not a or a.value == nil or a.id == nil then
+ return false
+ elseif not b or b.value == nil or b.id == nil then
+ return true
+ else
+ return a.value > b.value
+ end
+ end
+
+ local strupper, strlower = string.upper, string.lower
+ local function camel_case(first, rest)
+ return format("%s%s", strupper(first), strlower(rest))
+ end
+
+ local GetChannelList = GetChannelList
+ local OpenExport = Private.ImportExport
+
+ function Skada:Report(channel, chantype, modename, setname, maxlines, window, barid)
+ if maxlines == 0 then return end
+
+ if chantype == "channel" then
+ local list = TempTable(GetChannelList())
+ for i = 1, #list * 0.5 do
+ if (self.profile.report.channel == list[i * 2]) then
+ channel = list[i * 2 - 1]
+ break
+ end
+ end
+ list:free()
+ end
+
+ chantype = chantype or "preset"
+ local set, mode = nil, nil
+
+ if window == nil then
+ set = self:GetSet(setname or "current")
+ if set == nil then
+ self:Print(L["No mode or segment selected for report."])
+ return
+ end
+
+ modename = modename and gsub(gsub(modename, "_", " "), "(%a)([%w_']*)", camel_case) or "Damage"
+ mode = self.modules[modename] or self.modules[strupper(modename)] or self.modules[strlower(modename)]
+ if not mode then return end
+ window = Window.new(true)
+ mode:Update(window, set)
+ elseif type(window) == "string" then
+ for i = 1, #windows do
+ local win = windows[i]
+ local db = win and win.db
+ if db and strlower(db.name) == strlower(window) then
+ window = win
+ set = win:GetSelectedSet()
+ mode = win.selectedmode
+ break
+ end
+ end
+ else
+ set = window:GetSelectedSet()
+ mode = window.selectedmode
+ end
+
+ if not set then
+ Skada:Print(L["There is nothing to report."])
+ return
+ end
+
+ local metadata = window.metadata
+ local dataset = window.dataset
+
+ if not metadata or not metadata.ordersort then
+ tsort(dataset, value_id_sort)
+ end
+
+ if not mode then
+ self:Print(L["No mode or segment selected for report."])
+ return
+ end
+
+ local title = (window and window.title) or mode.title or mode.localeName
+ if window.parentmode and title ~= window.parentmode.localeName then
+ title = format("%s - %s", window.parentmode.localeName, title)
+ end
+ local label = (modename == L["Improvement"]) and self.userName or Skada:GetSetLabel(set)
+ maxlines = maxlines or 10
+
+ local firstline = format(L["Skada: %s for %s:"], EscapeStr(title, true), label)
+ local temp = BuildReportTable(mode, firstline, dataset, maxlines, channel == "text", barid)
+
+ if channel == "text" then
+ tinsert(temp, 2, "") -- extra line
+ OpenExport(nil, temp:concat("\n"), nil, 12)
+ else
+ for i = 1, #temp do
+ self:SendChat(temp[i], channel, chantype)
+ end
+ end
+
+ temp = temp:free()
+ end
+end
+
+-------------------------------------------------------------------------------
+-- boss and creature functions
+
+do
+ local creature_to_fight = Skada.creature_to_fight or Skada.dummyTable
+ local creature_to_boss = Skada.creature_to_boss or Skada.dummyTable
+ local GetCreatureId = Skada.GetCreatureId
+
+ -- checks if the provided guid is a boss
+ function Skada:IsBoss(guid, strict)
+ local id = GetCreatureId(guid)
+ if creature_to_boss[id] and creature_to_boss[id] ~= true then
+ if strict then
+ return false
+ end
+ return true, id
+ elseif creature_to_boss[id] or creature_to_fight[id] then
+ return true, id
+ end
+ return false
+ end
+
+ function Skada:IsEncounter(guid, name)
+ local isboss, id = self:IsBoss(guid)
+ if isboss and id then
+ if creature_to_boss[id] and creature_to_boss[id] ~= true then
+ return true, creature_to_boss[id], creature_to_fight[id] or name
+ end
+
+ if creature_to_fight[id] then
+ return true, true, creature_to_fight[id] or name
+ end
+
+ return true, id, creature_to_fight[id] or name
+ end
+ return false
+ end
+end
+
+-------------------------------------------------------------------------------
+-- test mode
+
+do
+ local random = math.random
+ local IsGroupInCombat = Skada.IsGroupInCombat
+ local InCombatLockdown = InCombatLockdown
+ local setPrototype = Skada.setPrototype
+ local playerPrototype = Skada.playerPrototype
+
+ local fake_set, update_timer = nil, nil
+
+ -- there was no discrimination with classes and specs
+ -- the only reason this group composition was made is
+ -- to have all 10 classes displayed on windows.
+ local fake_actors
+ do
+ local actorsTable = nil
+ function fake_actors()
+ if not actorsTable then
+ actorsTable = {
+ -- Tanks & Healers
+ Deafknight = {"DEATHKNIGHT", "TANK", 250}, -- Blood Death Knight
+ Bubbleboy = {"PRIEST", "HEALER", 256}, -- Discipline Priest
+ Channingtotem = {"SHAMAN", "HEALER", 264}, -- Restoration Shaman
+ -- Damagers
+ Shiftycent = {"DRUID", "DAMAGER", 102}, -- Balance Druid
+ Beargrills = {"HUNTER", "DAMAGER", 254}, -- Marksmanship Hunter
+ Foodanddps = {"MAGE", "DAMAGER", 63}, -- Fire Mage
+ Retryhard = {"PALADIN", "DAMAGER", 70}, -- Retribution Paladin
+ Stabass = {"ROGUE", "DAMAGER", 260}, -- Combat Rogue
+ Summonbot = {"WARLOCK", "DAMAGER", 266}, -- Demonology Warlock
+ Chuggernaut = {"WARRIOR", "DAMAGER", 72} -- Fury Warrior
+ }
+ end
+
+ return actorsTable
+ end
+ end
+
+ local function generate_fake_data()
+ fake_set = tablePool.acquireHash(
+ "name", "Fake Fight",
+ "starttime", time() - 120,
+ "damage", 0,
+ "heal", 0,
+ "absorb", 0,
+ "type", "raid",
+ "actors", new()
+ )
+
+ local actors = fake_actors()
+ for name, info in pairs(actors) do
+ local class, role, spec = info[1], info[2], info[3]
+ local damage, heal, absorb = 0, 0, 0
+
+ if role == "TANK" then
+ damage = random(1e5, 1e5 * 2)
+ heal = random(10000, 20000)
+ absorb = random(5000, 100000)
+ elseif role == "HEALER" then
+ damage = random(1000, 3000)
+ if spec == 256 then -- Discipline Priest
+ heal = random(1e5, 1e5 * 2)
+ absorb = random(1e6, 1e6 * 2)
+ else -- Other healers
+ heal = random(1e6, 1e6 * 2)
+ absorb = random(1000, 5000)
+ end
+ else
+ damage = random(1e6, 1e6 * 2)
+ heal = random(250, 1500)
+ end
+
+ local actor = tablePool.acquireHash(
+ "id", name, "name", name, "class", class, "role", role, "spec", spec,
+ "damage", damage, "heal", heal, "absorb", absorb
+ )
+ fake_set.actors[name] = playerPrototype:Bind(actor)
+
+ fake_set.damage = fake_set.damage + damage
+ fake_set.heal = fake_set.heal + heal
+ fake_set.absorb = fake_set.absorb + absorb
+ end
+
+ return setPrototype:Bind(fake_set)
+ end
+
+ local function randomize_fake_data(set, coef)
+ set.time = time() - set.starttime
+
+ local actors = set.actors
+ for actorname, actor in pairs(actors) do
+ local damage, heal, absorb = 0, 0, 0
+
+ if actor.role == "HEALER" then
+ damage = coef * random(0, 1500)
+ if actor.spec == 256 then
+ heal = coef * random(500, 1500)
+ absorb = coef * random(2500, 20000)
+ else
+ heal = coef * random(2500, 15000)
+ absorb = coef * random(0, 150)
+ end
+ elseif actor.role == "TANK" then
+ damage = coef * random(1000, 10000)
+ heal = coef * random(500, 1500)
+ absorb = coef * random(1000, 1500)
+ else
+ damage = coef * random(8000, 18000)
+ heal = coef * random(150, 1500)
+ end
+
+ actor.damage = (actor.damage or 0) + damage
+ actor.heal = (actor.heal or 0) + heal
+ actor.absorb = (actor.absorb or 0) + absorb
+
+ set.damage = set.damage + damage
+ set.heal = set.heal + heal
+ set.absorb = set.absorb + absorb
+ end
+ end
+
+ local function update_fake_data(self)
+ randomize_fake_data(self.current, self.profile.updatefrequency or 0.25)
+ self:UpdateDisplay(true)
+ end
+
+ function Skada:TestMode()
+ if InCombatLockdown() or IsGroupInCombat() then
+ fake_set = del(fake_set, true)
+ self.testMode = nil
+ if update_timer then
+ self:CancelTimer(update_timer)
+ update_timer = nil
+ end
+ return
+ end
+ self.testMode = not self.testMode
+ if not self.testMode then
+ fake_set = del(fake_set, true)
+ if update_timer then
+ self:CancelTimer(update_timer)
+ update_timer = nil
+ end
+ self.current = del(self.current, true)
+ return
+ end
+
+ self:Wipe()
+ self.current = generate_fake_data()
+ update_timer = update_timer or self:ScheduleRepeatingTimer(update_fake_data, self.profile.updatefrequency or 0.25, self)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- frame borders
+
+function Skada:ApplyBorder(frame, texture, color, thickness, padtop, padbottom, padleft, padright)
+ if not frame.borderFrame then
+ frame.borderFrame = CreateFrame("Frame", "$parentBorder", frame)
+ frame.borderFrame:SetFrameLevel(frame:GetFrameLevel() - 1)
+ end
+
+ thickness = thickness or 0
+ padtop = padtop or 0
+ padbottom = padbottom or padtop
+ padleft = padleft or padtop
+ padright = padright or padtop
+
+ frame.borderFrame:SetPoint("TOPLEFT", frame, -thickness - padleft, thickness + padtop)
+ frame.borderFrame:SetPoint("BOTTOMRIGHT", frame, thickness + padright, -thickness - padbottom)
+
+ local borderbackdrop = new()
+ borderbackdrop.edgeFile = (texture and thickness > 0) and self:MediaFetch("border", texture) or nil
+ borderbackdrop.edgeSize = thickness
+ frame.borderFrame:SetBackdrop(borderbackdrop)
+ del(borderbackdrop)
+ if color then
+ frame.borderFrame:SetBackdropBorderColor(color.r, color.g, color.b, color.a)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- addon communication
+
+do
+ local UnitIsConnected = UnitIsConnected
+ local collectgarbage = collectgarbage
+
+ local function create_progress_window()
+ local frame = CreateFrame("Frame", "SkadaProgressWindow", UIParent)
+ frame:SetFrameStrata("TOOLTIP")
+
+ local elem = frame:CreateTexture(nil, "BORDER")
+ elem:SetTexture([[Interface\Buttons\WHITE8X8]])
+ elem:SetVertexColor(0, 0, 0, 1)
+ elem:SetPoint("TOPLEFT")
+ elem:SetPoint("RIGHT")
+ elem:SetHeight(25)
+ frame.head = elem
+
+ elem = frame:CreateFontString(nil, "ARTWORK", "GameFontNormal")
+ elem:SetJustifyH("CENTER")
+ elem:SetJustifyV("MIDDLE")
+ elem:SetPoint("TOPLEFT", frame.head, "TOPLEFT", 25, 0)
+ elem:SetPoint("BOTTOMRIGHT", frame.head, "BOTTOMRIGHT", -25, 0)
+ elem:SetText(L["Progress"])
+ frame.title = elem
+
+ elem = CreateFrame("Button", nil, frame, "UIPanelCloseButton")
+ elem:SetWidth(24)
+ elem:SetHeight(24)
+ elem:SetPoint("RIGHT", frame.head, "RIGHT", -4, 0)
+ frame.close = elem
+
+ elem = frame:CreateFontString(nil, "ARTWORK", "GameFontHighlight")
+ elem:SetJustifyH("CENTER")
+ elem:SetJustifyV("MIDDLE")
+ elem:SetPoint("TOPLEFT", frame.head, "BOTTOMLEFT", 0, -10)
+ elem:SetPoint("TOPRIGHT", frame.head, "BOTTOMRIGHT", 0, -10)
+ frame.text = elem
+
+ elem = CreateFrame("StatusBar", nil, frame)
+ elem:SetMinMaxValues(0, 100)
+ elem:SetPoint("TOPLEFT", frame.text, "BOTTOMLEFT", 20, -15)
+ elem:SetPoint("TOPRIGHT", frame.text, "BOTTOMRIGHT", -20, -15)
+ elem:SetHeight(5)
+ elem:SetStatusBarTexture(format([[%s\Statusbar\Flat.tga]], Skada.mediapath))
+ elem:SetStatusBarColor(0, 1, 0)
+ frame.bar = elem
+
+ elem = frame.bar:CreateTexture(nil, "BACKGROUND")
+ elem:SetTexture([[Interface\Buttons\WHITE8X8]])
+ elem:SetVertexColor(1, 1, 1, 0.2)
+ elem:SetAllPoints(true)
+
+ elem = frame:CreateFontString(nil, "ARTWORK", "GameFontNormalSmall")
+ elem:SetPoint("TOP", frame.bar, "BOTTOM", 0, -15)
+ frame.size = elem
+
+ frame:SetBackdrop {
+ bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
+ edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
+ edgeSize = 16,
+ insets = {left = 4, right = 4, top = 4, bottom = 4}
+ }
+ frame:SetBackdropColor(0, 0, 0, 0.6)
+ frame:SetBackdropBorderColor(0, 0, 0, 1)
+ frame:SetPoint("CENTER", 0, 0)
+ frame:SetWidth(360)
+ frame:SetHeight(110)
+
+ frame:SetScript("OnShow", function(self)
+ self.size:SetText(format(L["Data Size: \124cffffffff%.1f\124rKB"], self.total * 0.001))
+ end)
+
+ frame:SetScript("OnHide", function(self)
+ self.total = 0
+ self.text:SetText(self.fmt)
+ self.size:SetText("")
+ self.bar:SetValue(0)
+ collectgarbage()
+ end)
+
+ frame.fmt = L["Transmision Progress: %02.f%%"]
+ frame:Hide()
+ return frame
+ end
+
+ local function show_progress_window(self, sent, total)
+ local progress = self.ProgressWindow or create_progress_window()
+ self.ProgressWindow = progress
+ if not progress:IsShown() then
+ progress.total = total
+ progress:Show()
+ end
+
+ if sent < total then
+ local p = sent * (100 / total)
+ progress.text:SetText(format(progress.fmt, p))
+ progress.bar:SetValue(p)
+ else
+ progress.text:SetText(L["Transmission Completed"])
+ progress.bar:SetValue(100)
+ end
+ end
+
+ -- "PURR" is a special key to whisper with progress window.
+ local serialize = Private.serialize
+ local function send_comm_message(self, channel, target, ...)
+ if target == self.userName then
+ return -- to yourself? really...
+ elseif channel ~= "WHISPER" and channel ~= "PURR" and not IsInGroup() then
+ return -- only for group members!
+ elseif (channel == "WHISPER" or channel == "PURR") and not (target and UnitIsConnected(target)) then
+ return -- whisper target must be connected!
+ end
+
+ -- not channel provided?
+ if not channel then
+ channel = IsInRaid() and "RAID" or "PARTY" -- default
+
+ -- arena or battlegrounds?
+ if self.insType == "pvp" or self.insType == "arena" then
+ channel = "BATTLEGROUND"
+ end
+ end
+
+ if channel == "PURR" then
+ self:SendCommMessage(folder, serialize(true, ...), "WHISPER", target, "NORMAL", show_progress_window, self)
+ elseif channel then
+ self:SendCommMessage(folder, serialize(true, ...), channel, target)
+ end
+ end
+
+ local function dispatch_comm(sender, ok, const, ...)
+ if ok and Skada.comms and type(const) == "string" and Skada.comms[const] then
+ for self, funcs in pairs(Skada.comms[const]) do
+ for func in pairs(funcs) do
+ if type(self[func]) == "function" then
+ self[func](self, sender, ...)
+ elseif type(func) == "function" then
+ func(sender, ...)
+ end
+ end
+ end
+ end
+ end
+
+ local deserialize = Private.deserialize
+ local function on_comm_received(self, prefix, message, channel, sender)
+ if prefix == folder and channel and sender and sender ~= self.userName then
+ dispatch_comm(sender, deserialize(message, true))
+ end
+ end
+
+ function Skada:RegisterComms(enable)
+ if enable then
+ self.SendComm = send_comm_message
+ self.OnCommReceived = on_comm_received
+ self:RegisterComm(folder)
+ self:AddComm("VersionCheck")
+ else
+ self.SendComm = self.EmptyFunc
+ self.OnCommReceived = self.EmptyFunc
+ self:UnregisterAllComm()
+ self:RemoveAllComms()
+ end
+
+ callbacks:Fire("Skada_UpdateComms", enable)
+ end
+
+ function Skada.AddComm(self, const, func)
+ if not self or not const then return end
+
+ Skada.comms = Skada.comms or {}
+ Skada.comms[const] = Skada.comms[const] or {}
+ Skada.comms[const][self] = Skada.comms[const][self] or {}
+ Skada.comms[const][self][func or const] = true
+ end
+
+ function Skada.RemoveComm(self, func)
+ if not self or not Skada.comms then return end
+
+ for const, selfs in pairs(Skada.comms) do
+ if selfs[self] then
+ selfs[self][func] = nil
+
+ -- remove the table if empty
+ if next(selfs[self]) == nil then
+ selfs[self] = nil
+ end
+
+ break
+ end
+ end
+ end
+
+ function Skada.RemoveAllComms(self)
+ if not self or not Skada.comms then return end
+
+ for const, selfs in pairs(Skada.comms) do
+ for _self in pairs(selfs) do
+ if self == _self then
+ selfs[self] = nil
+ break
+ end
+ end
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- instance difficulty
+
+do
+ local GetRaidDifficultyID = GetRaidDifficultyID
+ local GetDungeonDifficulty = GetDungeonDifficulty
+
+ function Skada:GetInstanceDiff()
+ local _, insType, diff, _, count, dynDiff, isDynamic = GetInstanceInfo()
+ if insType == "none" then
+ return diff == 1 and "wb" or "NaN" -- World Boss
+ elseif insType == "raid" and isDynamic then
+ if diff == 1 or diff == 3 then
+ return (dynDiff == 0) and "10n" or (dynDiff == 1) and "10h" or "NaN"
+ elseif diff == 2 or diff == 4 then
+ return (dynDiff == 0) and "25n" or (dynDiff == 1) and "25h" or "NaN"
+ end
+ elseif insType == "raid" then
+ if diff == 1 then
+ local comp_diff = GetRaidDifficultyID()
+ if diff ~= comp_diff and (comp_diff == 2 or comp_diff == 4) then
+ return "tw" -- timewalker
+ else
+ return count and format("%dn", count) or "10n"
+ end
+ else
+ return diff == 2 and "25n" or diff == 3 and "10h" or diff == 4 and "25h" or "NaN"
+ end
+ elseif insType == "party" then
+ if diff == 1 then
+ return "5n"
+ elseif diff == 2 then
+ local comp_diff = GetDungeonDifficulty()
+ return comp_diff == 3 and "mc" or "5h" -- mythic or heroic 5man
+ end
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- Active / Effetive time functions
+
+-- returns the selected set time.
+function Skada:GetSetTime(set)
+ local settime = set and set.time
+ return not settime and 0 or (settime >= 1) and settime or max(1, time() - set.starttime)
+end
+
+-- returns the actor's active/effective time
+function Skada:GetActiveTime(set, actor, active)
+ -- force active for pvp/arena
+ active = active or (set and (set.type == "pvp" or set.type == "arena"))
+
+ -- use settime to clamp
+ local settime = self:GetSetTime(set)
+
+ -- active: actor's time.
+ if (self.profile.timemesure ~= 2 or active) and actor.time and actor.time > 0 then
+ return max(1, min(actor.time, settime))
+ end
+
+ -- effective: combat time.
+ return settime
+end
+
+-- updates the actor's active time
+function Skada:AddActiveTime(set, actor, target, override)
+ if not actor or not actor.last then return end
+
+ local curtime = Skada._Time or GetTime()
+ local delta = curtime - actor.last
+ actor.last = curtime
+
+ if override and override > 0 and override <= delta then
+ delta = override
+ elseif delta > 3.5 then
+ delta = 3.5
+ end
+
+ local adding = floor(100 * delta + 0.5) * 0.01
+ actor.time = (actor.time or 0) + adding
+
+ -- to save up memory, we only record the rest to the current set.
+ if (set == self.total and not self.profile.totalidc) or not target then return end
+
+ actor.timespent = actor.timespent or {}
+ actor.timespent[target] = (actor.timespent[target] or 0) + adding
+end
+
+-------------------------------------------------------------------------------
+-- popup dialogs
+
+-- skada reset dialog
+do
+ local ConfirmDialog = Private.ConfirmDialog
+
+ local t = {timeout = 30, whileDead = 0}
+ local f = function() Skada:Reset(IsShiftKeyDown()) end
+
+ function Skada:ShowPopup(win, popup)
+ if Skada.testMode then return end
+
+ if Skada.profile.skippopup and not popup then
+ Skada:Reset(IsShiftKeyDown())
+ return
+ end
+
+ ConfirmDialog(L["Do you want to reset Skada?\nHold SHIFT to reset all data."], f, t)
+ end
+end
+
+-- new window creation dialog
+local copy = Private.tCopy
+local dialog_name = nil
+function Skada:NewWindow(window)
+ dialog_name = dialog_name or format("%sCreateWindowDialog", folder)
+ if not StaticPopupDialogs[dialog_name] then
+ local function create_window(name, win)
+ name = name and name:trim()
+ if not name or name == "" then return end
+
+ local db = win and win.db
+ if db and IsShiftKeyDown() then
+ local w = Skada:CreateWindow(name, nil, db.display)
+ copy(w.db, db, "name", "sticked", "point", "snapped", "child", "childmode")
+ w.db.x, w.db.y = 0, 0
+ Skada:ApplySettings(name)
+ else
+ Skada:CreateWindow(name)
+ end
+ end
+
+ StaticPopupDialogs[dialog_name] = {
+ text = L["Enter the name for the new window."],
+ button1 = L["Create"],
+ button2 = L["Cancel"],
+ timeout = 30,
+ whileDead = 0,
+ hideOnEscape = 1,
+ hasEditBox = 1,
+ OnShow = function(self)
+ self.button1:Disable()
+ self.editBox:SetText("")
+ self.editBox:SetFocus()
+ end,
+ OnHide = function(self)
+ self.editBox:SetText("")
+ self.editBox:ClearFocus()
+ end,
+ EditBoxOnEscapePressed = function(self)
+ self:GetParent():Hide()
+ end,
+ EditBoxOnTextChanged = function(self)
+ local name = self:GetText()
+ if not name or name:trim() == "" then
+ self:GetParent().button1:Disable()
+ else
+ self:GetParent().button1:Enable()
+ end
+ end,
+ EditBoxOnEnterPressed = function(self, win)
+ create_window(self:GetText(), win)
+ self:GetParent():Hide()
+ end,
+ OnAccept = function(self, win)
+ create_window(self.editBox:GetText(), win)
+ self:Hide()
+ end
+ }
+ end
+ StaticPopup_Show(dialog_name, nil, nil, window)
+end
+
+-- reinstall the addon
+do
+ local ReloadUI = ReloadUI
+ local ConfirmDialog = Private.ConfirmDialog
+
+ local t = {timeout = 15, whileDead = 0}
+ local f = function()
+ if Skada.data.profiles then
+ wipe(Skada.data.profiles)
+ end
+ if Skada.data.profileKeys then
+ wipe(Skada.data.profileKeys)
+ end
+
+ Skada.global.reinstall = true
+ ReloadUI()
+ end
+
+ function Skada:Reinstall()
+ ConfirmDialog(L["Are you sure you want to reinstall Skada?"], f, t)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- bossmods callbacks
+
+local find, lower = string.find, string.lower
+
+function Skada:BigWigs(_, _, event, message)
+ if event == "bosskill" and message and self.current and self.current.gotboss then
+ if find(lower(message), lower(self.current.mobname)) ~= nil and not self.current.success then
+ self.current.success = true
+
+ if self.tempsets then -- phases
+ for i = 1, #self.tempsets do
+ local set = self.tempsets[i]
+ if set and not set.success then
+ set.success = true
+ end
+ end
+ end
+
+ self:Debug("\124cffffbb00COMBAT_BOSS_DEFEATED\124r: BigWigs")
+ self:SendMessage("COMBAT_BOSS_DEFEATED", self.current)
+
+ self:StopSegment(L["Smart Stop"])
+ self:SetModes()
+ end
+ end
+end
+
+function Skada:DBM(_, mod, wipe)
+ if not wipe and mod and mod.combatInfo then
+ local set = self.current or self.last -- just in case DBM was late.
+ if set and not set.success and mod.combatInfo.name and (not set.mobname or find(lower(set.mobname), lower(mod.combatInfo.name)) ~= nil) then
+ set.success = true
+ set.gotboss = set.gotboss or mod.combatInfo.creatureId or true
+ set.mobname = (not set.mobname or set.mobname == L["Unknown"]) and mod.combatInfo.name or set.mobname
+
+ if self.tempsets then -- phases
+ for i = 1, #self.tempsets do
+ local s = self.tempsets[i]
+ if s and not s.success then
+ s.success = true
+ s.gotboss = s.gotboss or mod.combatInfo.creatureId or true
+ s.mobname = (not s.mobname or s.mobname == L["Unknown"]) and mod.combatInfo.name or s.mobname
+ end
+ end
+ end
+
+ self:Debug("\124cffffbb00COMBAT_BOSS_DEFEATED\124r: DBM")
+ self:SendMessage("COMBAT_BOSS_DEFEATED", set)
+
+ self:StopSegment(L["Smart Stop"])
+ self:SetModes()
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- misc functions
+
+-- memory usage check
+function Skada:CheckMemory()
+ if self.__memory_timer then
+ self:CancelTimer(self.__memory_timer, true)
+ self.__memory_timer = nil
+ end
+
+ if not self.profile.memorycheck then return end
+ UpdateAddOnMemoryUsage()
+ local memory = GetAddOnMemoryUsage(folder)
+ if memory > (self.maxmeme * 1024) then
+ self:Notify(L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."], L["Memory Check"], nil, "emergency")
+ end
+end
+
+-- clean garbage
+do
+ local InCombatLockdown = InCombatLockdown
+ local collectgarbage = collectgarbage
+ function Skada:CleanGarbage()
+ if self.__garbage_timer then
+ self:CancelTimer(self.__garbage_timer, true)
+ self.__garbage_timer = nil
+ end
+
+ if InCombatLockdown() then return end
+ collectgarbage("collect")
+ self:Debug("Garbage \124cffffbb00Cleaned\124r!")
+ end
+end
+
+-------------------------------------------------------------------------------
+-- player & enemies functions
+
+do
+ local UnitLevel = UnitLevel
+ local GetUnitRole = Skada.GetUnitRole
+ local GetUnitSpec = Skada.GetUnitSpec
+ local GetUnitIdFromGUID = Skada.GetUnitIdFromGUID
+ local actorPrototype = Skada.actorPrototype
+ local playerPrototype = Skada.playerPrototype
+ local enemyPrototype = Skada.enemyPrototype
+ local modes = Skada.modes
+
+ local dummy_actor = {} -- used as fallback
+
+ -- attempts to find and actor
+ function Skada:FindActor(set, actorname, actorid, is_strict)
+ -- make sure we have all data
+ actorid = actorid or actorname
+ actorname = actorname or actorid
+
+ -- why? I don't know...
+ if actorid == "total" or actorname == L["Total"] then return end
+
+ -- no set/actors table?
+ if not set or not set.actors then return end
+
+ -- already cached?
+ local actor = set.actors[actorname]
+ if actor then
+ return (actor.enemy and enemyPrototype or playerPrototype):Bind(actor)
+ end
+
+ -- is_strict means we don't use our dummy_actor
+ if is_strict then return end
+
+ -- speed up things with pets
+ if strmatch(actorname, "%<(%a+)%>") then
+ dummy_actor.id = actorid
+ dummy_actor.class = "PET"
+ return actorPrototype:Bind(dummy_actor)
+ end
+
+ -- well.. our last hope!
+ dummy_actor.id = actorid
+ dummy_actor.class = (set.mobname == actorname) and "ENEMY" or "UNKNOWN" -- can be wrong
+ return actorPrototype:Bind(dummy_actor)
+ end
+
+ -- generic: finds a player/enemy or creates it.
+ function Skada:GetActor(set, actorname, actorid, actorflags)
+ -- no set/actors table, sorry!
+ if not set or not set.actors then return end
+
+ -- attempt to find the actor (true: no dummy_actor)
+ local actor = self:FindActor(set, actorname, actorid, true)
+
+ -- not found? try to creat it then
+ if not actor then
+ -- at least the name should be provided!
+ if not actorname then return end
+
+ -- make sure we have all data
+ actorid = actorid or actorname
+
+ -- create a new actor table...
+ actor = new()
+ actor.id = actorid
+ actor.__new = true
+
+ -- is it me? move on..
+ if actorid == self.userGUID then
+ actor.class = self.userClass
+ actor.spec = GetUnitSpec(self.userGUID)
+ actor.role = GetUnitRole(self.userGUID)
+ end
+
+ -- actorflags:true => fake actor
+ if not actor.class and actorflags == true then
+ actor.enemy = true
+ actor.class = "ENEMY"
+ actor.fake = true
+ end
+
+ -- a group member/pet?
+ if not actor.class and guidToClass[actorid] then
+ actor.class = guidToClass[actorid]
+ if guidToName[actor.class] then
+ actor.class = "PET"
+ else
+ actor.spec = GetUnitSpec(actorid)
+ actor.role = GetUnitRole(actorid)
+ end
+ end
+
+ -- was it a player? (pvp scenario)
+ if not actor.class and self:IsPlayer(actorflags) then
+ local unit = GetUnitIdFromGUID(actorid, true)
+ if unit then -- found a valid unit?
+ _, actor.class = UnitClass(unit)
+ else
+ actor.class = "PLAYER"
+ end
+ if not self:IsFriendly(actorflags) or not self:InGroup(actorflags) then
+ actor.enemy = true
+ end
+ end
+
+ -- avoid "nil" stuff
+ if not actor.class and not self:IsNone(actorflags) then
+ local unit = GetUnitIdFromGUID(actorid)
+ local level = unit and UnitLevel(unit)
+ if level == -1 or self:IsBoss(actorid, true) then
+ actor.class = "BOSS"
+ elseif self:IsPet(actorflags) then
+ actor.class = "PET"
+ elseif self:IsNeutral(actorflags) then
+ actor.class = "NEUTRAL"
+ else
+ actor.class = "MONSTER"
+ end
+ if not self:IsFriendly(actorflags) or not self:InGroup(actorflags) then
+ actor.enemy = true
+ end
+ end
+
+ -- last hope!
+ if not actor.class then
+ actor.enemy = true
+ actor.class = "UNKNOWN"
+ self:Debug(format("Unknown unit detected: \124cffffbb00%s\124r (%s)", actorname, actorid))
+ end
+
+ for _, mode in pairs(modes) do
+ -- common
+ if mode.AddActorAttributes then
+ mode:AddActorAttributes(actor, set)
+ end
+
+ if mode.AddEnemyAttributes and actor.enemy then
+ mode:AddEnemyAttributes(actor, set) -- enemies
+ elseif mode.AddPlayerAttributes and not actor.enemy then
+ mode:AddPlayerAttributes(actor, set) -- players
+ end
+ end
+
+ set.actors[actorname] = actor
+ end
+
+ -- add more details to the actor...
+ if guidToClass[actor.id] then
+ if self.validclass[actor.class] then
+ -- missing spec?
+ if actor.spec == nil then
+ actor.spec = GetUnitSpec(actor.id)
+ actor.__mod = true
+ end
+ -- missing role?
+ if actor.role == nil or actor.role == "NONE" then
+ actor.role = GetUnitRole(actor.id)
+ actor.__mod = true
+ end
+ end
+
+ -- total set has "last" always removed.
+ if not actor.last then
+ actor.last = Skada._Time or GetTime()
+ actor.__mod = true
+ end
+ end
+
+ -- pvp enabled
+ if self.validclass[actor.class] and self.forPVP and not actor.spec then
+ actor.__mod = true
+ end
+
+ -- remove __mod key and fire callbacks
+ if actor.__new or actor.__mod then
+ actor.__mod = nil
+ callbacks:Fire(actor.enemy and "Skada_GetEnemy" or "Skada_GetPlayer", actor, set)
+ end
+
+ -- trigger addon change status
+ self.changed = true
+
+ -- remove the __new key after binding the actor
+ if actor.__new then
+ actor.__new = nil
+ return (actor.enemy and enemyPrototype or playerPrototype):Bind(actor), true
+ end
+ return actor
+ end
+end
+
+-------------------------------------------------------------------------------
+-- pet functions
+
+do
+ do
+ local GetPetOwnerFromTooltip
+ do
+ local pettooltip = CreateFrame("GameTooltip", format("%sPetTooltip", folder), nil, "GameTooltipTemplate")
+
+ local ValidatePetOwner
+ do
+ local ownerPatterns = {}
+ do
+ local i = 1
+ local title = _G[format("UNITNAME_SUMMON_TITLE%s", i)]
+ while (title and title ~= "%s" and find(title, "%s")) do
+ ownerPatterns[#ownerPatterns + 1] = title
+ i = i + 1
+ title = _G[format("UNITNAME_SUMMON_TITLE%s", i)]
+ end
+ end
+
+ local EscapeStr = Private.EscapeStr
+ function ValidatePetOwner(text, name)
+ for i = 1, #ownerPatterns do
+ local pattern = ownerPatterns[i]
+ if pattern and EscapeStr(format(pattern, name)) == text then
+ return true
+ end
+ end
+ return false
+ end
+ end
+
+ -- attempts to find the player guid on Russian clients.
+ local GetNumDeclensionSets, DeclineName = GetNumDeclensionSets, DeclineName
+ local function FindNameDeclension(text, actorname)
+ for gender = 2, 3 do
+ for decset = 1, GetNumDeclensionSets(actorname, gender) do
+ local ownerName = DeclineName(actorname, gender, decset)
+ if ValidatePetOwner(text, ownerName) or find(text, ownerName) then
+ return true
+ end
+ end
+ end
+ return false
+ end
+
+ -- attempt to get the pet's owner from tooltip
+ function GetPetOwnerFromTooltip(guid)
+ local set = guid and Skada.current
+ local actors = set and set.actors
+ if not actors then return end
+
+ pettooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
+ pettooltip:ClearLines()
+ pettooltip:SetHyperlink(format("unit:%s", guid))
+
+ -- we only need to scan the 2nd line.
+ local text = _G["SkadaPetTooltipTextLeft2"] and _G["SkadaPetTooltipTextLeft2"]:GetText()
+ if not text or text == "" then return end
+
+ for actorname, actor in pairs(actors) do
+ local name = not actor.enemy and gsub(actorname, "%-.*", "")
+ if name and ((LOCALE_ruRU and FindNameDeclension(text, name)) or ValidatePetOwner(text, name)) then
+ return actor.id, actorname
+ end
+ end
+ end
+ end
+
+ local UnitIterator = Skada.UnitIterator
+ local function GetPetOwnerUnit(guid)
+ for unit, owner in UnitIterator() do
+ if owner ~= nil and UnitGUID(unit) == guid then
+ return owner
+ end
+ end
+ end
+
+ local function FixPetsHandler(guid, flag)
+ local guidOrClass = guid and guidToClass[guid]
+ if guidOrClass and guidToName[guidOrClass] then
+ return guidOrClass, guidToName[guidOrClass]
+ end
+
+ -- flag is provided and it is mine.
+ if guid and flag and Skada:IsMine(flag) then
+ guidToOwner[guid] = Skada.userGUID
+ return Skada.userGUID, Skada.userName
+ end
+
+ -- no owner yet?
+ if not guid then return end
+
+ -- guess the pet from roster.
+ local ownerUnit = GetPetOwnerUnit(guid)
+ if ownerUnit then
+ local ownerGUID = UnitGUID(ownerUnit)
+ guidToOwner[guid] = ownerGUID
+ return ownerGUID, UnitFullName(ownerUnit)
+ end
+
+ -- guess the pet from tooltip.
+ local ownerGUID, ownerName = GetPetOwnerFromTooltip(guid)
+ if ownerGUID and ownerName then
+ guidToOwner[guid] = ownerGUID
+ return ownerGUID, ownerName
+ end
+ end
+
+ local IsPlayer = Private.IsPlayer
+ function Skada:FixPets(action)
+ if not action then return end
+ action.petname = nil -- clear it
+
+ -- 1: group member / true: player / false: everything else
+ if IsPlayer(action.actorid, action.actorname, action.actorflags) ~= false then return end
+
+ local ownerGUID, ownerName = FixPetsHandler(action.actorid, action.actorflags)
+ if ownerGUID and ownerName then
+ if self.profile.mergepets then
+ action.petname = action.actorname
+ action.actorid = ownerGUID
+ action.actorname = ownerName
+
+ if action.actorflags then
+ action.actorflags = self:GetOwnerFlags(action.actorflags)
+ end
+ if action.spellid and action.petname then
+ action.spellid = format("%s.%s", action.spellid, action.petname)
+ end
+ if action.spellname and action.petname then
+ action.spellname = format("%s (%s)", action.spellname, action.petname)
+ end
+ else
+ action.actorname = format("%s <%s>", action.actorname, ownerName)
+ end
+ else
+ -- if for any reason we fail to find the pets, we simply
+ -- adds them separately as a single entry.
+ action.actorid = action.actorname
+ end
+ end
+
+ local IsPet = Private.IsPet
+ function Skada:FixMyPets(guid, name, flags)
+ if not IsPet(guid, flags) then
+ return guid, name, flags
+ end
+
+ local ownerGUID, ownerName = FixPetsHandler(guid, flags)
+ if ownerGUID and ownerName then
+ return ownerGUID, ownerName, self:GetOwnerFlags(flags)
+ end
+
+ return guid, name, flags
+ end
+
+ function Skada:FixPetsName(guid, name, flags)
+ local _, ownerName = self:FixMyPets(guid, name, flags)
+ return (name and ownerName and ownerName ~= name) and format("%s <%s>", name, ownerName) or name
+ end
+ end
+
+ function Skada:GetPetOwner(petGUID)
+ local guidOrClass = guidToClass[petGUID]
+ if guidOrClass and guidToName[guidOrClass] then
+ return guidOrClass, guidToName[guidOrClass], guidToClass[guidOrClass]
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- combat log parser
+
+do
+ local loadstring, rawset = loadstring, rawset
+ local strsub, strlen, strlower = string.sub, string.len, string.lower
+
+ -- args associated to each event name prefix
+ local PREFIXES = {
+ SWING = "",
+ RANGE = ", spellid, spellname, spellschool",
+ SPELL = ", spellid, spellname, spellschool",
+ SPELL_PERIODIC = ", spellid, spellname, spellschool",
+ SPELL_BUILDING = ", spellid, spellname, spellschool",
+ ENVIRONMENTAL = ", envtype"
+ }
+
+ -- args associated to each event name suffix
+ local SUFFIXES = {
+ DAMAGE = ", amount, overkill, school, resisted, blocked, absorbed, critical, glancing, crushing",
+ MISSED = ", misstype, offhand, amount, critical",
+ HEAL = ", amount, overheal, absorbed, critical",
+ ENERGIZE = ", amount, powertype",
+ DRAIN = ", amount, powertype, extraamount",
+ LEECH = ", amount, powertype, extraamount",
+ INTERRUPT = ", extraspellid, extraspellname, extraschool",
+ DISPEL = ", extraspellid, extraspellname, extraschool, auratype",
+ DISPEL_FAILED = ", extraspellid, extraspellname, extraschool",
+ STOLEN = ", extraspellid, extraspellname, extraschool, auratype",
+ EXTRA_ATTACKS = ", amount",
+ AURA_APPLIED = ", auratype, amount",
+ AURA_REMOVED = ", auratype, amount",
+ AURA_APPLIED_DOSE = ", auratype, amount",
+ AURA_REMOVED_DOSE = ", auratype, amount",
+ AURA_REFRESH = ", auratype, amount",
+ AURA_BROKEN = ", auratype",
+ AURA_BROKEN_SPELL = ", extraspellid, extraspellname, extraschool, auratype",
+ CAST_START = "",
+ CAST_SUCCESS = "",
+ CAST_FAILED = ", failtype",
+ INSTAKILL = "",
+ DURABILITY_DAMAGE = "",
+ DURABILITY_DAMAGE_ALL = "",
+ CREATE = "",
+ SUMMON = "",
+ RESURRECT = ""
+ }
+
+ -- aliases of events that don't follow prefix_suffix
+ local ALIASES = {
+ DAMAGE_SHIELD = "SPELL_DAMAGE",
+ DAMAGE_SPLIT = "SPELL_DAMAGE",
+ DAMAGE_SHIELD_MISSED = "SPELL_MISSED"
+ }
+
+ -- creates dispatchers
+ local code = [[local wipe = wipe; return function(e, %s) wipe(e); e.%s = %s; return e; end]]
+ local Dispatchers = setmetatable({}, {__index = function(self, args)
+ local dispatcher = loadstring(format(code, args, gsub(args, ", ", ", e."), args), args)()
+ rawset(self, args, dispatcher)
+ return dispatcher
+ end})
+
+ local DEFAULTS = "timestamp, event, hideCaster, srcGUID, srcName, srcFlags, srcRaidFlags, dstGUID, dstName, dstFlags, dstRaidFlags"
+ local Handlers = setmetatable({}, {__index = function(self, event)
+ local args = DEFAULTS -- default args first
+ event = ALIASES[event] or event
+
+ for prefix, prefix_args in pairs(PREFIXES) do
+ local len = strlen(prefix)
+ if strsub(event, 1, len) == prefix then
+ local suffix_args = SUFFIXES[strsub(event, len + 2)]
+ if suffix_args then
+ args = format("%s%s%s", args, prefix_args, suffix_args)
+ break
+ end
+ end
+ end
+
+ local handler = Dispatchers[args]
+ rawset(self, event, handler)
+ return handler
+ end})
+
+ -- environment fake spell ids
+ local environment_ids = {
+ falling = 3,
+ drowning = 4,
+ fatigue = 5,
+ fire = 6,
+ lava = 7,
+ slime = 8
+ }
+
+ -- environmental types/names
+ local environment_names = {
+ falling = L["Falling"],
+ drowning = L["Drowning"],
+ fatigue = L["Fatigue"],
+ fire = L["Fire"],
+ lava = L["Lava"],
+ slime = L["Slime"]
+ }
+
+ -- environmental fake spell schools
+ local environment_schools = {
+ falling = 0x01,
+ drowning = 0x01,
+ fatigue = 0x01,
+ fire = 0x04,
+ lava = 0x04,
+ slime = 0x08
+ }
+
+ local ext_attacks = {} -- extra attacks table
+
+ local function create_extra_attack(args)
+ if ext_attacks[args.srcName] then return end
+
+ ext_attacks[args.srcName] = tablePool.acquireHash(
+ "proc_id", args.spellid, "proc_name", args.spellname,
+ "proc_amount", args.amount, "proc_time", GetTime()
+ )
+ end
+
+ local function check_extra_attack(args)
+ -- no extra attack was recorded
+ if not ext_attacks[args.srcName] then
+ return
+
+ -- it was missing a spell?
+ elseif not ext_attacks[args.srcName].spellname then
+ ext_attacks[args.srcName].spellname = args.spellname
+
+ -- valid so fat?
+ elseif ext_attacks[args.srcName].spellname and args.spellid == 6603 then
+ -- expired proc?
+ if ext_attacks[args.srcName].proc_time < GetTime() - 5 then
+ ext_attacks[args.srcName] = del(ext_attacks[args.srcName])
+ return
+ end
+
+ local spellid = args.spellid -- to generate spellstring
+ args.spellid = ext_attacks[args.srcName].proc_id
+ args.spellname = format("%s (%s)", ext_attacks[args.srcName].spellname, ext_attacks[args.srcName].proc_name)
+ args.spellstring = format("%s.%s.%s", args.spellid, args.spellschool, spellid)
+
+ ext_attacks[args.srcName].proc_amount = ext_attacks[args.srcName].proc_amount - 1
+ if ext_attacks[args.srcName].proc_amount == 0 then
+ ext_attacks[args.srcName] = del(ext_attacks[args.srcName])
+ end
+ end
+ end
+
+ local ARGS = {} -- reusable args table
+ do
+ local bit_band = bit.band
+ local ARGS_MT = {}
+
+ do -- source or destination in the group
+ local BITMASK_GROUP = Private.BITMASK_GROUP
+ local BITMASK_PETS = Private.BITMASK_PETS
+
+ function ARGS_MT.SourceInGroup(args, nopets)
+ if args._srcInGroup == nil then
+ if guidToName[args.srcGUID] ~= nil then
+ args._srcInGroup = true
+ args._srcInGroupNopets = true
+ args._srcIsPet = false
+ args._srcIsGroupPet = false
+ else
+ args._srcInGroup = (bit_band(args.srcFlags, BITMASK_GROUP) ~= 0)
+ end
+ end
+
+ if args._srcInGroupNopets == nil then
+ if bit_band(args.srcFlags, BITMASK_PETS) == 0 then
+ args._srcInGroupNopets = args._srcInGroup
+ args._srcIsPet = false
+ args._srcIsGroupPet = false
+ else
+ args._srcInGroupNopets = false
+ args._srcIsPet = true
+ args._srcIsGroupPet = (guidToOwner[args.srcGUID] ~= nil)
+ end
+ end
+
+ if nopets then
+ return args._srcInGroupNopets
+ end
+ return args._srcInGroup
+ end
+
+ function ARGS_MT.DestInGroup(args, nopets)
+ if args._dstInGroup == nil then
+ if guidToName[args.dstGUID] ~= nil then
+ args._dstInGroup = true
+ args._dstInGroupNopets = true
+ args._dstIsPet = false
+ args._dstIsGroupPet = false
+ args._dstIsOwnedPet = false
+ else
+ args._dstInGroup = (bit_band(args.dstFlags, BITMASK_GROUP) ~= 0)
+ end
+ end
+
+ if args._dstInGroupNopets == nil then
+ if bit_band(args.dstFlags, BITMASK_PETS) == 0 then
+ args._dstInGroupNopets = args._dstInGroup
+ args._dstIsPet = false
+ args._dstIsGroupPet = false
+ args._dstIsOwnedPet = false
+ else
+ args._dstInGroupNopets = false
+ args._dstIsPet = true
+ args._dstIsGroupPet = (guidToOwner[args.dstGUID] ~= nil)
+ end
+ end
+
+ if nopets then
+ return args._dstInGroupNopets
+ end
+ return args._dstInGroup
+ end
+
+ function ARGS_MT.IsGroupEvent(args, nopets)
+ return args:SourceInGroup(nopets) or args:DestInGroup(nopets)
+ end
+
+ function ARGS_MT.SourceIsPet(args, ingroup)
+ if args._srcIsPet == nil then
+ args._srcIsPet = (bit_band(args.srcFlags, BITMASK_PETS) ~= 0)
+ end
+
+ if not args._srcIsPet then
+ return false
+ elseif args._srcIsGroupPet == nil then
+ args._srcIsGroupPet = (guidToOwner[args.srcGUID] ~= nil)
+ end
+
+ if ingroup then
+ return args._srcIsGroupPet
+ end
+ return args._srcIsPet
+ end
+
+ -- owner=true? acts like "ingroup" (SourceIsPet)
+ function ARGS_MT.DestIsPet(args, owner)
+ if args._dstIsPet == nil then
+ args._dstIsPet = (bit_band(args.dstFlags, BITMASK_PETS) ~= 0)
+ end
+
+ if not args._dstIsPet then
+ return false
+ elseif owner == true then
+ if args._dstIsGroupPet == nil then
+ args._dstIsGroupPet = (guidToOwner[args.dstGUID] ~= nil)
+ end
+ return args._dstIsGroupPet
+ elseif owner then
+ if args._dstIsOwnedPet == nil then
+ args._dstIsOwnedPet = (bit_band(args.srcFlags, BITMASK_GROUP) ~= 0) -- owner is a group member?
+ args._dstIsOwnedPet = args._dstIsOwnedPet or (bit_band(args.srcFlags, BITMASK_PETS) ~= 0) -- summoned by another pet?
+ args._dstIsOwnedPet = args._dstIsOwnedPet or (guidToClass[args.dstGUID] ~= nil) -- already known pet
+ end
+ return args._dstIsOwnedPet
+ else
+ return args._dstIsPet
+ end
+ end
+ end
+
+ do -- source or destination are players
+ local BITMASK_PLAYER = Private.BITMASK_PLAYER
+ function ARGS_MT.SourceIsPlayer(args)
+ if args._srcIsPlayer == nil then
+ args._srcIsPlayer = (guidToName[args.srcGUID] ~= nil) or (bit_band(args.srcFlags, BITMASK_PLAYER) == BITMASK_PLAYER)
+ end
+ return args._srcIsPlayer
+ end
+ function ARGS_MT.DestIsPlayer(args)
+ if args._dstIsPlayer == nil then
+ args._dstIsPlayer = (guidToName[args.dstGUID] ~= nil) or (bit_band(args.dstFlags, BITMASK_PLAYER) == BITMASK_PLAYER)
+ end
+ return args._dstIsPlayer
+ end
+ end
+
+ do -- source or destination are bosses
+ local BossIDs = Skada.BossIDs
+ local GetCreatureId = Skada.GetCreatureId
+
+ function ARGS_MT.SourceIsBoss(args)
+ if args._srcIsBoss == nil then
+ args._srcIsBoss = BossIDs[GetCreatureId(args.srcGUID)] or false
+ end
+ return args._srcIsBoss
+ end
+ function ARGS_MT.DestIsBoss(args)
+ if args._dstIsBoss == nil then
+ args._dstIsBoss = BossIDs[GetCreatureId(args.dstGUID)] or false
+ end
+ return args._dstIsBoss
+ end
+ function ARGS_MT.IsBossEvent(args)
+ return args:SourceIsBoss() or args:DestIsBoss()
+ end
+ end
+
+ do -- source and destination reactions
+ local BITMASK_FRIENDLY = Private.BITMASK_FRIENDLY
+ function ARGS_MT.SourceIsFriendly(args)
+ if args._srcIsFriendly == nil then
+ args._srcIsFriendly = (bit_band(args.srcFlags, BITMASK_FRIENDLY) ~= 0)
+ if args._srcIsFriendly then
+ args._srcIsNeutral = false
+ args._srcIsHostile = false
+ end
+ end
+ return args._srcIsFriendly
+ end
+ function ARGS_MT.DestIsFriendly(args)
+ if args._dstIsFriendly == nil then
+ args._dstIsFriendly = (bit_band(args.dstFlags, BITMASK_FRIENDLY) ~= 0)
+ if args._dstIsFriendly then
+ args._dstIsNeutral = false
+ args._dstIsHostile = false
+ end
+ end
+ return args._dstIsFriendly
+ end
+
+ local BITMASK_NEUTRAL = Private.BITMASK_NEUTRAL
+ function ARGS_MT.SourceIsNeutral(args)
+ if args._srcIsNeutral == nil then
+ args._srcIsNeutral = (bit_band(args.srcFlags, BITMASK_NEUTRAL) ~= 0)
+ if args._srcIsNeutral then
+ args._srcIsFriendly = false
+ args._srcIsHostile = false
+ end
+ end
+ return args._srcIsNeutral
+ end
+ function ARGS_MT.DestIsNeutral(args)
+ if args._dstIsNeutral == nil then
+ args._dstIsNeutral = (bit_band(args.dstFlags, BITMASK_NEUTRAL) ~= 0)
+ if args._dstIsNeutral then
+ args._dstIsFriendly = false
+ args._dstIsHostile = false
+ end
+ end
+ return args._dstIsNeutral
+ end
+
+ local BITMASK_HOSTILE = Private.BITMASK_HOSTILE
+ function ARGS_MT.SourceIsHostile(args)
+ if args._srcIsHostile == nil then
+ args._srcIsHostile = (bit_band(args.srcFlags, BITMASK_HOSTILE) ~= 0)
+ if args._srcIsHostile then
+ args._srcIsFriendly = false
+ args._srcIsNeutral = false
+ end
+ end
+ return args._srcIsHostile
+ end
+ function ARGS_MT.DestIsHostile(args)
+ if args._dstIsHostile == nil then
+ args._dstIsHostile = (bit_band(args.dstFlags, BITMASK_HOSTILE) ~= 0)
+ if args._dstIsHostile then
+ args._dstIsFriendly = false
+ args._dstIsNeutral = false
+ end
+ end
+ return args._dstIsHostile
+ end
+ end
+
+ setmetatable(ARGS, {__index = ARGS_MT})
+ ARGS_MT.__index = ARGS_MT
+ end
+
+ -- trigger events used for first hit check
+ -- Edit Skada\Core\Tables.lua
+ local TRIGGER_EVENTS = Skada.trigger_events
+
+ -- specific events used for specific reasons.
+ local SWING_EVENTS = {SWING_DAMAGE = true, SWING_MISSED = true}
+ local ENVIRONMENT_EVENTS = {ENVIRONMENTAL_DAMAGE = true, ENVIRONMENTAL_MISSED = true}
+ local DOT_EVENTS = {SPELL_PERIODIC_DAMAGE = true, SPELL_PERIODIC_MISSED = true}
+ local HOT_EVENTS = {SPELL_PERIODIC_HEAL = true--[[, SPELL_PERIODIC_ENERGIZE = true--]]}
+
+ -- combat log handler
+ function Skada:ParseCombatLog(_, timestamp, event, ...)
+ -- disabled or test mode?
+ if self.disabled or self.testMode then return end
+
+ local args = Handlers[event](ARGS, timestamp, event, ...)
+
+ if event == "SPELL_EXTRA_ATTACKS" then
+ create_extra_attack(args)
+ return -- queue for later!
+ end
+
+ if SWING_EVENTS[event] then
+ args.spellid = 6603
+ args.spellname = L["Melee"]
+ args.spellschool = 0x01
+ elseif ENVIRONMENT_EVENTS[event] and args.envtype then
+ local envtype = strlower(args.envtype)
+ args.spellid = environment_ids[envtype]
+ args.spellname = environment_names[envtype]
+ args.spellschool = environment_schools[envtype]
+ args.srcName = L["Environment"]
+ elseif DOT_EVENTS[event] or args.auratype == "DEBUFF" then
+ args.is_dot = true
+ elseif HOT_EVENTS[event] then
+ args.is_hot = true
+ end
+
+ -- check for extra attack
+ check_extra_attack(args)
+
+ -- process some miss types!
+ if args.misstype == "ABSORB" and args.amount then
+ args.absorbed = args.amount
+ args.amount = 0
+ elseif args.misstype == "BLOCK" and args.amount then
+ args.blocked = args.amount
+ args.amount = 0
+ elseif args.misstype == "RESIST" and args.amount then
+ args.resisted = args.amount
+ args.amount = 0
+ elseif args.misstype and not args.amount then
+ args.amount = 0
+ end
+
+ if args.spellid and args.spellschool and not args.spellstring then
+ args.spellstring = format((args.is_dot or args.is_hot) and "-%s.%s" or "%s.%s", args.spellid, args.spellschool)
+ end
+
+ if args.extraspellid and args.extraschool and not args.extrastring then
+ args.extrastring = format("%s.%s", args.extraspellid, args.extraschool)
+ end
+
+ -- the event happens within the group?
+ args.inside_event = args:IsGroupEvent()
+ self.LastEvent = args
+
+ -- not really? skip everything else...
+ if not args.inside_event then
+ return self:OnCombatEvent(args)
+ end
+
+ if args.spellstring then
+ callbacks:Fire("Skada_SpellString", args, args.spellid, args.spellstring)
+ end
+
+ if args.extrastring then
+ callbacks:Fire("Skada_SpellString", args, args.extraspellid, args.extrastring)
+ end
+
+ -- check first hit!
+ if self.profile.firsthit and not self.firsthit and TRIGGER_EVENTS[args.event] then
+ self:CheckFirstHit(args)
+ end
+
+ return self:OnCombatEvent(args)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- group buffs scanner
+
+do
+ local UnitIsDeadOrGhost, UnitBuff = UnitIsDeadOrGhost, UnitBuff
+ local UnitIterator = Skada.UnitIterator
+ local actorflags = Private.DEFAULT_FLAGS
+ local clear = Private.clearTable
+
+ local function ScanUnitBuffs(unit, owner, t)
+ if UnitIsDeadOrGhost(unit) then return end
+
+ t.dstGUID = UnitGUID(unit)
+ t.dstName = UnitFullName(unit, owner)
+ t.dstFlags = not owner and actorflags or nil
+
+ t.class = guidToClass[t.dstGUID]
+ if guidToName[t.class] then
+ t.class = "PET"
+ end
+
+ t.unit, t.owner = unit, owner
+ t.auras = clear(t.auras) or new()
+
+ for i = 1, 41 do
+ local name, _, icon, _, _, duration, expires, source, _, _, id = UnitBuff(unit, i)
+ if not id then
+ break -- nothing found
+ elseif source then
+ local aura = new()
+ aura.srcGUID = UnitGUID(source)
+ aura.srcName = UnitFullName(source)
+ aura.srcFlags = actorflags
+ aura.id = id
+ aura.name = name
+ aura.icon = icon
+ aura.duration = duration
+ aura.expires = expires
+ t.auras[#t.auras + 1] = aura
+ end
+ end
+
+ if next(t.auras) then
+ callbacks:Fire("Skada_UnitBuffs", t)
+ end
+ end
+
+
+ local function ScanGroupBuffs(self, timestamp)
+ if self.global.inCombat then return end
+
+ local t = new()
+ t.event = "SPELL_AURA_APPLIED"
+ t.timestamp = timestamp
+ t.time = self._time
+ t.Time = self._time
+
+ for unit, owner in UnitIterator() do
+ if not UnitIsDeadOrGhost(unit) then
+ ScanUnitBuffs(unit, owner, t)
+ end
+ end
+ t = del(t, true)
+ end
+
+ Skada.ScanGroupBuffs = Skada.EmptyFunc
+ function callbacks:OnUsed(_, event)
+ if event == "Skada_UnitBuffs" then
+ Skada.ScanGroupBuffs = ScanGroupBuffs
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- first hit check
+
+do
+ local UnitExists, SpellLink = UnitExists, Private.SpellLink or GetSpellLink
+ local IsPet, uformat = Private.IsPet, Private.uformat
+ local ignored_spells = Skada.ignored_spells.firsthit
+ local firsthit_fmt = {"%s (%s)", "%s (\124c%s%s\124r)", "\124c%s%s\124r", "\124c%s%s\124r (%s)"}
+
+ local boss_units = Skada.Units.boss
+ local function WhoPulled(hit_line)
+ hit_line = hit_line or L["\124cffffbb00First Hit\124r: *?*"] -- first hit
+
+ local target_table = nil
+ for _, unit in next, boss_units do
+ if not UnitExists(unit) then break end
+
+ local target_unit = format("%starget", unit)
+ local target = UnitFullName(target_unit)
+ if target then
+ local _, class = UnitClass(target_unit)
+ if class then
+ target = Skada.classcolors.format(class, target)
+ end
+
+ target_table = target_table or TempTable()
+ target_table:insert(uformat("%s > %s", UnitFullName(unit), target))
+ end
+ end
+
+ local target_line = nil
+ if target_table then
+ target_line = format(L["\124cffffbb00Boss First Target\124r: %s"], target_table:concat(" \124\124 "))
+ target_table = target_table:free()
+ end
+
+ return hit_line, target_line
+ end
+
+ function Skada:CheckFirstHit(t)
+ -- ignored spell?
+ if t.event ~= "SWING_DAMAGE" and t.spellid and ignored_spells[t.spellid] then return end
+
+ local output = nil -- initial ouptut
+
+ if self:IsBoss(t.srcGUID) then -- boss started?
+ if IsPet(t.dstGUID, t.dstFlags) then
+ output = uformat(firsthit_fmt[1], t.srcName, t.dstName)
+ elseif t.dstName then
+ local _, class = UnitClass(t.dstName)
+ if class then
+ output = uformat(firsthit_fmt[2], t.srcName, self.classcolors.str(class), t.dstName)
+ else
+ output = uformat(firsthit_fmt[1], t.srcName, t.dstName)
+ end
+ end
+ elseif self:IsBoss(t.dstGUID) then -- a player/pet started?
+ local _, ownerName, ownerClass = self:GetPetOwner(t.srcGUID)
+ if ownerName then
+ if ownerClass then
+ output = uformat(firsthit_fmt[4], self.classcolors.str(ownerClass), ownerName, L["PET"])
+ else
+ output = uformat(firsthit_fmt[1], ownerName, L["PET"])
+ end
+ elseif t.srcName then
+ local _, class = UnitClass(t.srcName)
+ if class and self.classcolors[class] then
+ output = uformat(firsthit_fmt[3], self.classcolors.str(class), t.srcName)
+ else
+ output = t.srcName
+ end
+ end
+ end
+
+ if output then
+ local spell = SpellLink(t.spellid) or t.spellname or L["Unknown"]
+ self.firsthit = self.firsthit or TempTable()
+ self.firsthit.hitline = WhoPulled(uformat(L["\124cffffff00First Hit\124r: %s from %s"], spell, output))
+ end
+ end
+
+ do
+ local firsthit_timer = nil
+ local function PrintFirstHit()
+ local t = Skada.firsthit
+ if t then
+ t.hitline, t.targetline = WhoPulled(t.hitline)
+ Skada:Print(t.hitline)
+ if t.targetline then
+ Skada:Print(t.targetline)
+ end
+ Skada:Debug("\124cffffbb00First Hit\124r: Printed!")
+ end
+ end
+
+ function Skada:PrintFirstHit()
+ if not self.profile.firsthit then
+ return self:ClearFirstHit()
+ end
+
+ firsthit_timer = firsthit_timer or self:ScheduleTimer(PrintFirstHit, 0.5)
+ end
+
+ function Skada:ClearFirstHit()
+ if self.firsthit then
+ self.firsthit = self.firsthit:free()
+ self:Debug("\124cffffbb00First Hit\124r: Cleared!")
+ end
+ if firsthit_timer then
+ self:CancelTimer(firsthit_timer, true)
+ firsthit_timer = nil
+ end
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- smart stop
+
+do
+ local smartstop_timer = nil
+ -- list of creature IDs to be ignored
+ local ignored_creature = {
+ [37217] = true, -- ICC: Precious
+ [37025] = true -- iCC: Stinky
+ }
+
+ local function SmartStop(set)
+ if smartstop_timer then
+ Skada:CancelTimer(smartstop_timer, true)
+ smartstop_timer = nil
+ end
+
+ if set.endtime then return end
+ Skada:StopSegment(L["Smart Stop"])
+ Skada:SetModes()
+ end
+
+ function Skada:SmartStop(set)
+ if
+ not self.profile.smartstop and -- feature disabled?
+ not set or set.stopped and -- no set or already stopped?
+ not set.gotboss and -- not a boss fight?
+ not ignored_creature[set.gotboss] -- an ignored boss fight?
+ then
+ return
+ end
+
+ -- (re)schedule smart stop.
+ if smartstop_timer then
+ Skada:CancelTimer(smartstop_timer, true)
+ smartstop_timer = nil
+ end
+ smartstop_timer = self:ScheduleTimer(SmartStop, self.profile.smartwait or 3, set)
+ end
+end
diff --git a/Skada/Core/Init.lua b/Skada/Core/Init.lua
new file mode 100644
index 0000000..bad1a8b
--- /dev/null
+++ b/Skada/Core/Init.lua
@@ -0,0 +1,2023 @@
+local folder, ns = ...
+
+local GetAddOnMetadata = GetAddOnMetadata
+ns.author = GetAddOnMetadata(folder, "Author")
+ns.version = GetAddOnMetadata(folder, "Version")
+ns.date = GetAddOnMetadata(folder, "X-Date")
+ns.website = "https://github.com/bkader/Skada-Legion"
+ns.logo = [[Interface\ICONS\spell_lightning_lightningbolt01]]
+ns.revisited = true -- Skada-Revisited flag
+ns.Private = {} -- holds private stuff
+ns.Locale = LibStub("AceLocale-3.0"):GetLocale(folder)
+ns.callbacks = LibStub("CallbackHandler-1.0"):New(ns)
+
+-- cache frequently used globals
+local pairs, ipairs = pairs, ipairs
+local select, next, max = select, next, math.max
+local band, tonumber, type = bit.band, tonumber, type
+local strsplit, format, strmatch, gsub = strsplit, string.format, string.match, string.gsub
+local setmetatable, rawset, wipe = setmetatable, rawset, wipe
+local EmptyFunc = Multibar_EmptyFunc
+local Private, L = ns.Private, ns.Locale
+local _
+
+-- location of media files (textures, fonts...)
+ns.mediapath = format([[Interface\AddOns\%s\Media]], folder)
+
+-- options table
+ns.options = {
+ type = "group",
+ name = format("%s \124cffffffff%s\124r", folder, ns.version),
+ get = true,
+ set = true,
+ args = {}
+}
+
+-- common weak table
+do
+ local weaktable = {__mode = "kv"}
+ function Private.WeakTable(t)
+ return setmetatable(t or {}, weaktable)
+ end
+end
+
+-- some tables we need
+ns.dummyTable = {} -- a dummy table used as fallback
+ns.cacheTable = {} -- primary cache table
+ns.cacheTable2 = {} -- secondary cache table
+
+-- table used to crop mode options images.
+ns.cropTable = {0.06, 0.94, 0.06, 0.94}
+
+-------------------------------------------------------------------------------
+-- flags/bitmasks
+
+do
+ local bit_bor = bit.bor
+
+ ------------------------------------------------------
+ -- generic flag check function
+ ------------------------------------------------------
+ local function HasFlag(flags, flag)
+ return (band(flags or 0, flag) ~= 0)
+ end
+ Private.HasFlag = HasFlag
+
+ ------------------------------------------------------
+ -- self-affilation
+ ------------------------------------------------------
+ local BITMASK_MINE = COMBATLOG_OBJECT_AFFILIATION_MINE or 0x00000001
+ Private.BITMASK_MINE = BITMASK_MINE
+
+ function ns:IsMine(flags)
+ return (band(flags or 0, BITMASK_MINE) ~= 0)
+ end
+
+ ------------------------------------------------------
+ -- group affilation
+ ------------------------------------------------------
+ local BITMASK_PARTY = COMBATLOG_OBJECT_AFFILIATION_PARTY or 0x00000002
+ local BITMASK_RAID = COMBATLOG_OBJECT_AFFILIATION_RAID or 0x00000004
+ local BITMASK_GROUP = bit_bor(BITMASK_MINE, BITMASK_PARTY, BITMASK_RAID)
+ Private.BITMASK_GROUP = BITMASK_GROUP
+
+ function ns:InGroup(flags)
+ return (band(flags or 0, BITMASK_GROUP) ~= 0)
+ end
+
+ ------------------------------------------------------
+ -- pets and guardiands
+ ------------------------------------------------------
+ local BITMASK_TYPE_PET = COMBATLOG_OBJECT_TYPE_PET or 0x00001000
+ local BITMASK_TYPE_GUARDIAN = COMBATLOG_OBJECT_TYPE_GUARDIAN or 0x00002000
+ local BITMASK_PETS = bit_bor(BITMASK_TYPE_PET, BITMASK_TYPE_GUARDIAN)
+ Private.BITMASK_PETS = BITMASK_PETS
+
+ function ns:IsPet(flags)
+ return (band(flags or 0, BITMASK_PETS) ~= 0)
+ end
+
+ ------------------------------------------------------
+ -- reactions: friendly, neutral and hostile
+ ------------------------------------------------------
+ local BITMASK_FRIENDLY = COMBATLOG_OBJECT_REACTION_FRIENDLY or 0x00000010
+ local BITMASK_NEUTRAL = COMBATLOG_OBJECT_REACTION_NEUTRAL or 0x00000020
+ local BITMASK_HOSTILE = COMBATLOG_OBJECT_REACTION_HOSTILE or 0x00000040
+ Private.BITMASK_FRIENDLY = BITMASK_FRIENDLY
+ Private.BITMASK_NEUTRAL = BITMASK_NEUTRAL
+ Private.BITMASK_HOSTILE = BITMASK_HOSTILE
+
+ function ns:IsFriendly(flags)
+ return (band(flags or 0, BITMASK_FRIENDLY) ~= 0)
+ end
+
+ function ns:IsNeutral(flags)
+ return (band(flags or 0, BITMASK_NEUTRAL) ~= 0)
+ end
+
+ function ns:IsHostile(flags)
+ return (band(flags or 0, BITMASK_HOSTILE) ~= 0)
+ end
+
+ ------------------------------------------------------
+ -- object type: player, npc and none
+ ------------------------------------------------------
+ local BITMASK_PLAYER = COMBATLOG_OBJECT_TYPE_PLAYER or 0x00000400
+ local BITMASK_NPC = COMBATLOG_OBJECT_TYPE_NPC or 0x00000800
+ local BITMASK_NONE = COMBATLOG_OBJECT_NONE or 0x80000000
+ Private.BITMASK_PLAYER = BITMASK_PLAYER
+ Private.BITMASK_NPC = BITMASK_NPC
+ Private.BITMASK_NONE = BITMASK_NONE
+
+ function ns:IsPlayer(flags)
+ return (band(flags or 0, BITMASK_PLAYER) == BITMASK_PLAYER)
+ end
+
+ function ns:IsNPC(flags)
+ return (band(flags or 0, BITMASK_NPC) ~= 0)
+ end
+
+ function ns:IsNone(flags)
+ return (band(flags or 0, BITMASK_NONE) ~= 0)
+ end
+
+ ------------------------------------------------------
+ -- masks used for ownership
+ ------------------------------------------------------
+ do
+ local BITMASK_AFFILIATION = COMBATLOG_OBJECT_AFFILIATION_MASK or 0x0000000F
+ local BITMASK_REACTION = COMBATLOG_OBJECT_REACTION_MASK or 0x000000F0
+ local BITMASK_CONTROL = COMBATLOG_OBJECT_CONTROL_MASK or 0x00000300
+ local BITMASK_OWNERSHIP = bit_bor(BITMASK_AFFILIATION, BITMASK_REACTION, BITMASK_CONTROL)
+ local BITMASK_CONTROL_PLAYER = COMBATLOG_OBJECT_CONTROL_PLAYER or 0x00000100
+
+ function ns:GetOwnerFlags(flags)
+ local ownerFlags = band(flags or 0, BITMASK_OWNERSHIP)
+ if band(ownerFlags, BITMASK_CONTROL_PLAYER) ~= 0 then
+ return bit_bor(ownerFlags, BITMASK_PLAYER)
+ end
+ return bit_bor(ownerFlags, BITMASK_NPC)
+ end
+ end
+
+ ------------------------------------------------------
+ -- default flags used mainly for scan
+ ------------------------------------------------------
+ Private.DEFAULT_FLAGS = 0x00000417
+end
+
+-------------------------------------------------------------------------------
+-- table pools
+
+-- creates a table pool
+function Private.TablePool()
+ local pool = {tables = Private.WeakTable()}
+
+ -- reuses or creates a table
+ pool.new = function()
+ local t = next(pool.tables)
+ if t then pool.tables[t] = nil end
+ return t or {}
+ end
+
+ -- deletes a table to be reused later
+ pool.del = function(t, deep)
+ if type(t) == "table" then
+ for k, v in pairs(t) do
+ if deep and type(v) == "table" then
+ pool.del(v)
+ end
+ t[k] = nil
+ end
+ t[""] = true
+ t[""] = nil
+ pool.tables[t] = true
+ end
+ return nil
+ end
+
+ -- clears/wipes the given table
+ pool.clear = function(t)
+ if type(t) == "table" then
+ for k, v in pairs(t) do
+ t[k] = pool.del(v, true)
+ end
+ end
+ return t
+ end
+
+ -- creates a table a fills it with args passed
+ pool.acquire = function(...)
+ local t, n = pool.new(), select("#", ...)
+ for i = 1, n do t[i] = select(i, ...) end
+ return t
+ end
+
+ -- creates a table and fills it with key-value args
+ pool.acquireHash = function(...)
+ local t, n = pool.new(), select("#", ...)
+ for i = 1, n, 2 do
+ local k, v = select(i, ...)
+ t[k] = v
+ end
+ return t
+ end
+
+ -- populates the given table with args passed
+ pool.populate = function(t, ...)
+ if type(t) == "table" then
+ for i = 1, select("#", ...) do
+ t[#t + 1] = select(i, ...)
+ end
+ end
+ return t
+ end
+
+ -- populates the given table with key-value args
+ pool.populateHash = function(t, ...)
+ if type(t) == "table" then
+ for i = 1, select("#", ...), 2 do
+ local k, v = select(i, ...)
+ t[k] = v
+ end
+ end
+ return t
+ end
+
+ -- deep copies a table.
+ pool.copy = function(orig)
+ local orig_type, copy = type(orig), nil
+ if orig_type == "table" then
+ copy = {}
+ for k, v in next, orig, nil do
+ copy[pool.copy(k)] = pool.copy(v)
+ end
+ setmetatable(copy, pool.copy(getmetatable(orig)))
+ else
+ copy = orig
+ end
+ return copy
+ end
+
+ return pool
+end
+
+-- create addon's default table pool
+do
+ local tablePool = Private.TablePool()
+ ns.tablePool = tablePool
+
+ Private.newTable = tablePool.new
+ Private.delTable = tablePool.del
+ Private.clearTable = tablePool.clear
+ Private.copyTable = tablePool.copy
+end
+
+-- alternative table reuse
+do
+ local tables = {}
+ local table_mt = {
+ __index = {
+ free = function(t, no_recurse)
+ if not no_recurse then
+ for k, v in pairs(t) do
+ if type(v) == "table" and getmetatable(t) == "TempTable" then
+ v:free()
+ end
+ end
+ end
+ wipe(t)
+ tables[t] = true
+ return nil -- to assign input reference
+ end,
+ -- aliases --
+ concat = table.concat,
+ insert = table.insert,
+ remove = table.remove,
+ sort = table.sort,
+ wipe = table.wipe,
+ },
+ __metatable = "TempTable"
+ }
+
+ function Private.TempTable(...)
+ local t = next(tables)
+ if t then
+ tables[t] = nil
+ else
+ t = setmetatable({}, table_mt)
+ end
+ for i = 1, select("#", ...) do
+ t[i] = (select(i, ...))
+ end
+ return t
+ end
+end
+
+-------------------------------------------------------------------------------
+-- class, roles ans specs registration
+
+function Private.RegisterClasses()
+ Private.RegisterClasses = nil
+
+ -- class, role and spec icons (sprite)
+ ns.classicons = format([[%s\Textures\icons]], ns.mediapath)
+ ns.roleicons = ns.classicons
+ ns.specicons = ns.classicons
+
+ -- class colors/names and valid classes
+ local classcolors, validclass = {}, {}
+ local CLASS_COLORS = CUSTOM_CLASS_COLORS or RAID_CLASS_COLORS
+ for _, class in pairs(CLASS_SORT_ORDER) do
+ local info = CLASS_COLORS[class]
+ classcolors[class] = {r = info.r, g = info.g, b = info.b, colorStr = info.colorStr}
+ L[class] = LOCALIZED_CLASS_NAMES_MALE[class]
+ validclass[class] = true
+ end
+ ns.validclass = validclass -- used to validate classes
+
+ -- custom class colors
+ classcolors.BOSS = {r = 0.203, g = 0.345, b = 0.525}
+ classcolors.ENEMY = {r = 0.94117, g = 0, b = 0.0196}
+ classcolors.MONSTER = {r = 0.549, g = 0.388, b = 0.404}
+ classcolors.NEUTRAL = {r = 1.0, g = 1.0, b = 0.1}
+ classcolors.PET = {r = 0.09, g = 0.61, b = 0.55}
+
+ -- generate colorStr
+ local RGBPercToHex = Private.RGBPercToHex
+ for class, info in pairs(classcolors) do
+ if not info.colorStr then
+ info.colorStr = RGBPercToHex(info.r, info.g, info.b, true)
+ end
+ end
+ -- alias to enemy for now...
+ classcolors.PLAYER = classcolors.ENEMY
+
+ local P = ns.profile
+
+ -- some useful functions
+ local classcolors_mt = {
+ unpack = function(class) -- returns class RGB
+ local color = class and classcolors(class)
+ if not color then return end
+ return color.r, color.g, color.b
+ end,
+ str = function(class) -- returns color string.
+ local color = class and classcolors(class)
+ return color and color.colorStr or "ffffffff"
+ end,
+ format = function(class, text) -- class colored text.
+ local color = class and classcolors(class)
+ return color and format("\124c%s%s\124r", color.colorStr or "ffffffff", text) or text
+ end
+ }
+
+ -- missing class? use uknown.
+ local unknown_classcolor = {r = 0.353, g = 0.067, b = 0.027, colorStr = "ff5a1107"}
+ setmetatable(classcolors_mt, {__index = function(t, class)
+ rawset(t, class, unknown_classcolor)
+ return unknown_classcolor
+ end})
+
+ setmetatable(classcolors, {
+ __index = classcolors_mt,
+ __call = function(t, class)
+ local color = P.usecustomcolors and P.customcolors and P.customcolors[class] or t[class]
+ color.colorStr = color.colorStr or RGBPercToHex(color.r, color.g, color.b, true)
+ return color
+ end
+ })
+ ns.classcolors = classcolors
+
+ -- common __call for coordinates
+ local coords__call = function(t, key)
+ local coords = t[key]
+ return coords[1], coords[2], coords[3], coords[4]
+ end
+
+ -- class icons and coordinates
+ local classcoords_mt = {
+ __index = function(t, class)
+ -- neutral: monster
+ if class == "NEUTRAL" then
+ local coords = t.MONSTER
+ rawset(t, class, coords)
+ return coords
+ end
+
+ local coords = {384/512, 448/512, 64/512, 128/512} -- unknown
+ rawset(t, class, coords)
+ return coords
+ end,
+ __call = coords__call
+ }
+ ns.classcoords = setmetatable({
+ -- default classes
+ DEATHKNIGHT = {64/512, 128/512, 128/512, 192/512},
+ DEMONHUNTER = {192/512, 256/512, 128/512, 192/512},
+ DRUID = {192/512, 256/512, 0/512, 64/512},
+ HUNTER = {0/512, 64/512, 64/512, 128/512},
+ MAGE = {64/512, 128/512, 0/512, 64/512},
+ MONK = {128/512, 192/512, 128/512, 192/512},
+ PALADIN = {0/512, 64/512, 128/512, 192/512},
+ PRIEST = {128/512, 192/512, 64/512, 128/512},
+ ROGUE = {128/512, 192/512, 0/512, 64/512},
+ SHAMAN = {64/512, 128/512, 64/512, 128/512},
+ WARLOCK = {192/512, 256/512, 64/512, 128/512},
+ WARRIOR = {0/512, 64/512, 0/512, 64/512},
+ -- custom classes
+ BOSS = {320/512, 384/512, 0/512, 64/512},
+ ENEMY = {448/512, 512/512, 0/512, 64/512},
+ MONSTER = {384/512, 448/512, 0/512, 64/512},
+ PET = {320/512, 384/512, 64/512, 128/512},
+ PLAYER = {448/512, 512/512, 64/512, 128/512}
+ }, classcoords_mt)
+
+ -- role icons and coordinates
+ local rolecoords_mt = {
+ __index = function(t, role)
+ local coords = {480/512, 512/512, 128/512, 160/512}
+ rawset(t, role, coords)
+ return coords
+ end,
+ __call = coords__call
+ }
+ ns.rolecoords = setmetatable({
+ DAMAGER = {480/512, 512/512, 128/512, 160/512},
+ HEALER = {480/512, 512/512, 160/512, 192/512},
+ LEADER = {448/512, 480/512, 128/512, 160/512},
+ TANK = {448/512, 480/512, 160/512, 192/512}
+ }, rolecoords_mt)
+
+ -- spec icons and coordinates
+ local speccoords_mt = {__call = coords__call}
+ ns.speccoords = setmetatable({
+ [62] = {192/512, 256/512, 192/512, 256/512}, --> Mage: Arcane
+ [63] = {256/512, 320/512, 192/512, 256/512}, --> Mage: Fire
+ [64] = {320/512, 384/512, 192/512, 256/512}, --> Mage: Frost
+ [65] = {64/512, 128/512, 384/512, 448/512}, --> Paladin: Holy
+ [66] = {128/512, 192/512, 384/512, 448/512}, --> Paladin: Protection
+ [70] = {192/512, 256/512, 384/512, 448/512}, --> Paladin: Retribution
+ [71] = {0/512, 64/512, 192/512, 256/512}, --> Warrior: Arms
+ [72] = {64/512, 128/512, 192/512, 256/512}, --> Warrior: Fury
+ [73] = {128/512, 192/512, 192/512, 256/512}, --> Warrior: Protection
+ [102] = {64/512, 128/512, 256/512, 320/512}, --> Druid: Balance
+ [103] = {128/512, 192/512, 256/512, 320/512}, --> Druid: Feral
+ [104] = {192/512, 256/512, 256/512, 320/512}, --> Druid: Guardian
+ [105] = {256/512, 320/512, 256/512, 320/512}, --> Druid: Restoration
+ [250] = {256/512, 320/512, 384/512, 448/512}, --> Death Knight: Blood
+ [251] = {320/512, 384/512, 384/512, 448/512}, --> Death Knight: Frost
+ [252] = {384/512, 448/512, 384/512, 448/512}, --> Death Knight: Unholy
+ [253] = {320/512, 384/512, 256/512, 320/512}, --> Hunter: Beastmastery
+ [254] = {384/512, 448/512, 256/512, 320/512}, --> Hunter: Marksmalship
+ [255] = {448/512, 512/512, 256/512, 320/512}, --> Hunter: Survival
+ [256] = {192/512, 256/512, 320/512, 384/512}, --> Priest: Discipline
+ [257] = {256/512, 320/512, 320/512, 384/512}, --> Priest: Holy
+ [258] = {320/512, 384/512, 320/512, 384/512}, --> Priest: Shadow
+ [259] = {384/512, 448/512, 192/512, 256/512}, --> Rogue: Assassination
+ [260] = {448/512, 512/512, 192/512, 256/512}, --> Rogue: Combat
+ [261] = {0/512, 64/512, 256/512, 320/512}, --> Rogue: Subtlty
+ [262] = {0/512, 64/512, 320/512, 384/512}, --> Shaman: Elemental
+ [263] = {64/512, 128/512, 320/512, 384/512}, --> Shaman: Enhancement
+ [264] = {128/512, 192/512, 320/512, 384/512}, --> Shaman: Restoration
+ [265] = {384/512, 448/512, 320/512, 384/512}, --> Warlock: Affliction
+ [266] = {448/512, 512/512, 320/512, 384/512}, --> Warlock: Demonology
+ [267] = {0/512, 64/512, 384/512, 448/512}, --> Warlock: Destruction
+ [268] = {448/512, 512/512, 384/512, 448/512}, --> Monk: Brewmaster
+ [269] = {64/512, 128/512, 448/512, 512/512}, --> Monk: Windwalker
+ [270] = {0/512, 64/512, 448/512, 512/512}, --> Monk: Mistweaver
+ [577] = {128/512, 192/512, 448/512, 512/512}, --> Demon Hunter: Havoc
+ [581] = {192/512, 256/512, 448/512, 512/512} --> Demon Hunter: Vengeance
+ }, speccoords_mt)
+
+ --------------------------
+ -- custom class options --
+ --------------------------
+
+ local function no_custom()
+ return not P.usecustomcolors
+ end
+
+ local colorsOpt = {
+ type = "group",
+ name = L["Colors"],
+ desc = format(L["Options for %s."], L["Colors"]),
+ order = 1000,
+ get = function(i)
+ return classcolors.unpack(i[#i])
+ end,
+ set = function(i, r, g, b)
+ local class = i[#i]
+ P.customcolors = P.customcolors or {}
+ P.customcolors[class] = P.customcolors[class] or {}
+ P.customcolors[class].r = r
+ P.customcolors[class].g = g
+ P.customcolors[class].b = b
+ P.customcolors[class].colorStr = RGBPercToHex(r, g, b, true)
+ end,
+ args = {
+ enable = {
+ type = "toggle",
+ name = L["Enable"],
+ width = "double",
+ order = 10,
+ get = function()
+ return P.usecustomcolors
+ end,
+ set = function(_, val)
+ if val then
+ P.usecustomcolors = true
+ else
+ P.usecustomcolors = nil
+ P.customcolors = nil -- free it
+ end
+ end
+ },
+ class = {
+ type = "group",
+ name = L["Class Colors"],
+ order = 20,
+ hidden = no_custom,
+ disabled = no_custom,
+ args = {}
+ },
+ custom = {
+ type = "group",
+ name = L["Custom Colors"],
+ order = 30,
+ hidden = no_custom,
+ disabled = no_custom,
+ args = {}
+ },
+ reset = {
+ type = "execute",
+ name = L["Reset"],
+ width = "double",
+ order = 90,
+ disabled = no_custom,
+ confirm = function() return L["Are you sure you want to reset all colors?"] end,
+ func = function()
+ P.customcolors = wipe(P.customcolors or {})
+ end
+ }
+ }
+ }
+
+ for class, data in pairs(classcolors) do
+ if validclass[class] then
+ colorsOpt.args.class.args[class] = {
+ type = "color",
+ name = L[class],
+ desc = format(L["Color for %s."], L[class])
+ }
+ elseif type(data) == "table" then
+ colorsOpt.args.custom.args[class] = {
+ type = "color",
+ name = L[class],
+ desc = format(L["Color for %s."], L[class])
+ }
+ end
+ end
+
+ ns.options.args.tweaks.args.advanced.args.colors = colorsOpt
+end
+
+-------------------------------------------------------------------------------
+-- spell schools registration
+
+function Private.RegisterSchools()
+ Private.RegisterSchools = nil
+
+ local spellschools = {}
+
+ -- handles adding spell schools
+ local order = {}
+ local function add_school(key, name, r, g, b)
+ if key and name and not spellschools[key] then
+ spellschools[key] = {r = r or 1, g = g or 1, b = b or 1, name = strmatch(name, "%((.+)%)") or name}
+ order[#order + 1] = key
+ end
+ end
+
+ -- main school
+ local SCHOOL_NONE = SCHOOL_MASK_NONE or 0x00 -- None
+ local SCHOOL_PHYSICAL = SCHOOL_MASK_PHYSICAL or 0x01 -- Physical
+ local SCHOOL_HOLY = SCHOOL_MASK_HOLY or 0x02 -- Holy
+ local SCHOOL_FIRE = SCHOOL_MASK_FIRE or 0x04 -- Fire
+ local SCHOOL_NATURE = SCHOOL_MASK_NATURE or 0x08 -- Nature
+ local SCHOOL_FROST = SCHOOL_MASK_FROST or 0x10 -- Frost
+ local SCHOOL_SHADOW = SCHOOL_MASK_SHADOW or 0x20 -- Shadow
+ local SCHOOL_ARCANE = SCHOOL_MASK_ARCANE or 0x40 -- Arcane
+
+ -- Single Schools
+ add_school(SCHOOL_NONE, STRING_SCHOOL_UNKNOWN, 1, 1, 1) -- Unknown
+ add_school(SCHOOL_PHYSICAL, STRING_SCHOOL_PHYSICAL, 1, 1, 0) -- Physical
+ add_school(SCHOOL_HOLY, STRING_SCHOOL_HOLY, 1, 0.9, 0.5) -- Holy
+ add_school(SCHOOL_FIRE, STRING_SCHOOL_FIRE, 1, 0.5, 0) -- Fire
+ add_school(SCHOOL_NATURE, STRING_SCHOOL_NATURE, 0.3, 1, 0.3) -- Nature
+ add_school(SCHOOL_FROST, STRING_SCHOOL_FROST, 0.5, 1, 1) -- Frost
+ add_school(SCHOOL_SHADOW, STRING_SCHOOL_SHADOW, 0.5, 0.5, 1) -- Shadow
+ add_school(SCHOOL_ARCANE, STRING_SCHOOL_ARCANE, 1, 0.5, 1) -- Arcane
+
+ -- reference to CombatLog_String_SchoolString
+ local colorFunc = CombatLog_Color_ColorArrayBySchool
+ local function get_school_name(key)
+ if not nameFunc then -- late availability
+ nameFunc = CombatLog_String_SchoolString
+ end
+
+ local name = nameFunc(key)
+ local isnone = (name == STRING_SCHOOL_UNKNOWN)
+ return strmatch(name, "%((.+)%)") or name, isnone
+ end
+
+ -- reference to COMBATLOG_DEFAULT_COLORS.schoolColoring
+ local colorTable = COMBATLOG_DEFAULT_COLORS and COMBATLOG_DEFAULT_COLORS.schoolColoring
+ local function get_school_color(key)
+ if not colorTable then -- late availability
+ colorTable = COMBATLOG_DEFAULT_COLORS and COMBATLOG_DEFAULT_COLORS.schoolColoring
+ end
+
+ local r, g, b = 1.0, 1.0, 1.0
+
+ if colorTable and colorTable[key] then
+ r = colorTable[key].r or r
+ g = colorTable[key].g or g
+ b = colorTable[key].b or b
+ elseif colorTable then
+ for i = #order, 1, -1 do
+ local k = order[i]
+ if band(key, k) ~= 0 then
+ r = colorTable[k].r or r
+ g = colorTable[k].g or g
+ b = colorTable[k].b or b
+ break
+ end
+ end
+ end
+
+ return r, g, b
+ end
+
+ ns.spellschools = setmetatable(spellschools, {
+ __index = function(t, key)
+ local name, isnone = get_school_name(key)
+ if not isnone then
+ local r, g, b = get_school_color(key)
+ local school = {name = name, r = r, g = g, b = b}
+ rawset(t, key, school)
+ return school
+ end
+ return t[0x00] -- unknown
+ end,
+ __call = function(t, key)
+ local school = t[key]
+ return school.name, school.r, school.g, school.b
+ end
+ })
+
+ ns.tooltip_school = function(tooltip, spellid)
+ local _, school = strsplit(".", spellid, 3)
+ if not school then return end
+ tooltip:AddLine(spellschools(tonumber(school)))
+ end
+end
+
+-------------------------------------------------------------------------------
+-- register LibSharedMedia stuff
+
+function Private.RegisterMedias()
+ Private.RegisterMedias = nil
+
+ local LSM = LibStub("LibSharedMedia-3.0", true)
+ if not LSM then
+ ns.MediaFetch = EmptyFunc
+ ns.MediaList = EmptyFunc
+ return
+ end
+
+ -- fonts
+ LSM:Register("font", "ABF", format([[%s\Fonts\ABF.ttf]], ns.mediapath))
+ LSM:Register("font", "Accidental Presidency", format([[%s\Fonts\Accidental Presidency.ttf]], ns.mediapath))
+ LSM:Register("font", "Adventure", format([[%s\Fonts\Adventure.ttf]], ns.mediapath))
+ LSM:Register("font", "Diablo", format([[%s\Fonts\Diablo.ttf]], ns.mediapath))
+ LSM:Register("font", "FORCED SQUARE", format([[%s\Fonts\FORCED SQUARE.ttf]], ns.mediapath))
+ LSM:Register("font", "Hooge", format([[%s\Fonts\Hooge.ttf]], ns.mediapath))
+
+ -- statusbars
+ LSM:Register("statusbar", "Aluminium", format([[%s\Statusbar\Aluminium]], ns.mediapath))
+ LSM:Register("statusbar", "Armory", format([[%s\Statusbar\Armory]], ns.mediapath))
+ LSM:Register("statusbar", "BantoBar", format([[%s\Statusbar\BantoBar]], ns.mediapath))
+ LSM:Register("statusbar", "Flat", format([[%s\Statusbar\Flat]], ns.mediapath))
+ LSM:Register("statusbar", "Gloss", format([[%s\Statusbar\Gloss]], ns.mediapath))
+ LSM:Register("statusbar", "Graphite", format([[%s\Statusbar\Graphite]], ns.mediapath))
+ LSM:Register("statusbar", "Grid", format([[%s\Statusbar\Grid]], ns.mediapath))
+ LSM:Register("statusbar", "Healbot", format([[%s\Statusbar\Healbot]], ns.mediapath))
+ LSM:Register("statusbar", "LiteStep", format([[%s\Statusbar\LiteStep]], ns.mediapath))
+ LSM:Register("statusbar", "Minimalist", format([[%s\Statusbar\Minimalist]], ns.mediapath))
+ LSM:Register("statusbar", "Otravi", format([[%s\Statusbar\Otravi]], ns.mediapath))
+ LSM:Register("statusbar", "Outline", format([[%s\Statusbar\Outline]], ns.mediapath))
+ LSM:Register("statusbar", "Round", format([[%s\Statusbar\Round]], ns.mediapath))
+ LSM:Register("statusbar", "Serenity", format([[%s\Statusbar\Serenity]], ns.mediapath))
+ LSM:Register("statusbar", "Smooth", format([[%s\Statusbar\Smooth]], ns.mediapath))
+ LSM:Register("statusbar", "Solid", [[Interface\Buttons\WHITE8X8]])
+ LSM:Register("statusbar", "TukTex", format([[%s\Statusbar\TukTex]], ns.mediapath))
+
+ -- borders
+ LSM:Register("border", "Glow", format([[%s\Border\Glow]], ns.mediapath))
+ LSM:Register("border", "Roth", format([[%s\Border\Roth]], ns.mediapath))
+
+ -- sounds
+ LSM:Register("sound", "Cartoon FX", [[Sound\Doodad\Goblin_Lottery_Open03.wav]])
+ LSM:Register("sound", "Cheer", [[Sound\Event Sounds\OgreEventCheerUnique.wav]])
+ LSM:Register("sound", "Explosion", [[Sound\Doodad\Hellfire_Raid_FX_Explosion05.wav]])
+ LSM:Register("sound", "Fel Nova", [[Sound\Spells\SeepingGaseous_Fel_Nova.wav]])
+ LSM:Register("sound", "Fel Portal", [[Sound\Spells\Sunwell_Fel_PortalStand.wav]])
+ LSM:Register("sound", "Humm", [[Sound\Spells\SimonGame_Visual_GameStart.wav]])
+ LSM:Register("sound", "Rubber Ducky", [[Sound\Doodad\Goblin_Lottery_Open01.wav]])
+ LSM:Register("sound", "Shing!", [[Sound\Doodad\PortcullisActive_Closed.wav]])
+ LSM:Register("sound", "Short Circuit", [[Sound\Spells\SimonGame_Visual_BadPress.wav]])
+ LSM:Register("sound", "Simon Chime", [[Sound\Doodad\SimonGame_LargeBlueTree.wav]])
+ LSM:Register("sound", "War Drums", [[Sound\Event Sounds\Event_wardrum_ogre.wav]])
+ LSM:Register("sound", "Wham!", [[Sound\Doodad\PVP_Lordaeron_Door_Open.wav]])
+ LSM:Register("sound", "You Will Die!", [[Sound\Creature\CThun\CThunYouWillDIe.wav]])
+
+ -- fetches media by type
+ ns.MediaFetch = function(self, mediatype, key, default)
+ return (key and LSM:Fetch(mediatype, key)) or (default and LSM:Fetch(mediatype, default)) or default
+ end
+
+ -- lists media by type
+ ns.MediaList = function(self, mediatype)
+ return LSM:HashTable(mediatype)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- color manipulation
+
+-- converts RGB colors to HEX.
+function Private.RGBPercToHex(r, g, b, prefix)
+ r = r and r <= 1 and r >= 0 and r or 0
+ g = g and g <= 1 and g >= 0 and g or 0
+ b = b and b <= 1 and b >= 0 and b or 0
+ return format(prefix and "ff%02x%02x%02x" or "%02x%02x%02x", r * 255, g * 255, b * 255)
+end
+
+-- generates a color depending on the given percent
+function Private.PercentToRGB(perc, reverse, hex)
+ -- clamp first
+ perc = min(100, max(0, perc or 0))
+
+ -- start with full red
+ local r, g, b = 1, 0, 0
+
+ -- reversed?
+ if reverse then
+ r, g = 0, 1
+
+ if perc <= 50 then -- increment red channel
+ r = r + (perc * 0.02)
+ else -- set red to 1 and decrement green channel
+ r, g = 1, g - ((perc - 50) * 0.02)
+ end
+ elseif perc <= 50 then -- increment green channel
+ g = g + (perc * 0.02)
+ else -- set green to 1 and decrement red channel
+ r, g = r - ((perc - 50) * 0.02), 1
+ end
+
+ -- return hex? channels will be as of 2nd param.
+ if hex then
+ return Private.RGBPercToHex(r, g, b, true), r, g, b
+ end
+
+ -- return only channels.
+ return r, g, b
+end
+
+-------------------------------------------------------------------------------
+-- table functions
+
+-- alternative to table.remove
+local error = error
+local tremove = table.remove
+function Private.tremove(t, index)
+ if index then
+ return tremove(t, index)
+ elseif type(t) ~= "table" then
+ error("bad argument #1 to 'tremove' (table expected, got number)")
+ end
+
+ local n = #t
+ local val = t[n]
+ t[n] = nil
+ return val
+end
+
+-- returns the length of the given table
+Private.tLength = _G.tLength
+if not Private.tLength then
+ Private.tLength = function(t)
+ local len = 0
+ if t then
+ for _ in pairs(t) do
+ len = len + 1
+ end
+ end
+ return len
+ end
+end
+
+-- copies a table from another
+function Private.tCopy(to, from, ...)
+ for k, v in pairs(from) do
+ local skip = false
+ if ... then
+ if type(...) == "table" then
+ for _, j in ipairs(...) do
+ if j == k then
+ skip = true
+ break
+ end
+ end
+ else
+ for i = 1, select("#", ...) do
+ if select(i, ...) == k then
+ skip = true
+ break
+ end
+ end
+ end
+ end
+ if not skip then
+ if type(v) == "table" then
+ to[k] = {}
+ Private.tCopy(to[k], v, ...)
+ else
+ to[k] = v
+ end
+ end
+ end
+end
+
+-- prevents duplicates in a table to format strings
+function Private.CheckDuplicate(value, tbl, key)
+ if type(tbl) == "table" then
+ local num = 0
+ local is_array = (#tbl > 0)
+
+ for k, v in pairs(tbl) do
+ local val = is_array and type(v) == "table" and v[key] or k
+ if val == value and num == 0 then
+ num = 1
+ elseif val then
+ local n, c = strmatch(val, "^(.-)%s*%((%d+)%)$")
+ if n == value then
+ num = max(num, tonumber(c), 0)
+ end
+ end
+ end
+
+ if num > 0 then
+ value = format("%s (%d)", value, num + 1)
+ end
+ end
+
+ return value
+end
+
+-------------------------------------------------------------------------------
+-- string functions
+
+do
+ -- we a fake frame/fontstring to escape the string
+ local escape_fs = nil
+ function Private.EscapeStr(str, plain)
+ escape_fs = escape_fs or UIParent:CreateFontString(nil, "ARTWORK", "ChatFontNormal")
+ escape_fs:SetText(str)
+ str = escape_fs:GetText()
+ escape_fs:SetText("")
+ if plain then
+ str = gsub(str, "|c%x%x%x%x%x%x%x%x", "")
+ str = gsub(str, "|c%x%x %x%x%x%x%x", "")
+ return gsub(str, "|r", "")
+ end
+ return str
+ end
+
+ local function replace(cap1)
+ return cap1 == "%" and L["Unknown"]
+ end
+
+ local pcall = pcall
+ function Private.uformat(fstr, ...)
+ local ok, str = pcall(format, fstr, ...)
+ return ok and str or gsub(gsub(fstr, "(%%+)([^%%%s<]+)", replace), "%%%%", "%%")
+ end
+
+ Private.WrapTextInColorCode = _G.WrapTextInColorCode
+ if not Private.WrapTextInColorCode then
+ Private.WrapTextInColorCode = function(text, colorHexString)
+ return format("\124c%s%s\124r", colorHexString, text)
+ end
+ end
+end
+
+-- alternative to lua
+do
+ local tostring = tostring
+ local tconcat = table.concat
+ local tmp, nr = {}, 0
+ function Private.Print(...)
+ nr = 0
+ for i = 1, select("#", ...) do
+ nr = nr + 1
+ tmp[nr] = tostring(select(i, ...))
+ end
+ DEFAULT_CHAT_FRAME:AddMessage(tconcat(tmp, " ", 1, nr))
+ end
+end
+
+-------------------------------------------------------------------------------
+-- Save/Restore frame positions to/from db
+
+do
+ local floor = math.floor
+ local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
+
+ function Private.SavePosition(f, db)
+ if f and f.GetCenter and db then
+ local x, y = f:GetCenter()
+ local scale = f:GetEffectiveScale()
+ local uscale = UIParent:GetScale()
+
+ db.x = ((x * scale) - (GetScreenWidth() * uscale) * 0.5) / uscale
+ db.y = ((y * scale) - (GetScreenHeight() * uscale) * 0.5) / uscale
+ db.scale = floor(f:GetScale() * 100) * 0.01
+ end
+ end
+
+ function Private.RestorePosition(f, db)
+ if f and f.SetPoint and db then
+ local scale = f:GetEffectiveScale()
+ local uscale = UIParent:GetScale()
+ local x = (db.x or 0) * uscale / scale
+ local y = (db.y or 0) * uscale / scale
+
+ f:ClearAllPoints()
+ f:SetPoint("CENTER", UIParent, "CENTER", x, y)
+ f:SetScale(db.scale or 1)
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- toast and notifications
+
+do
+ local LibToast = LibStub("SpecializedLibToast-1.0", true)
+ local toast_opt = nil
+
+ -- initialize LibToast
+ function Private.RegisterToast()
+ Private.RegisterToast = nil -- remove it
+
+ if not LibToast then
+ ns.Notify = ns.Print
+ return
+ end
+
+ -- install default options
+ local P = ns.profile
+ P.toast = P.toast or ns.defaults.toast
+
+ LibToast:Register(format("%sToastFrame", folder), function(toast, text, title, icon, urgency)
+ toast:SetTitle(title or folder)
+ toast:SetText(text or L["A damage meter."])
+ toast:SetIconTexture(icon or ns.logo)
+ toast:SetUrgencyLevel(urgency or "normal")
+ end)
+ if P.toast then
+ LibToast.config.hide_toasts = P.toast.hide_toasts
+ LibToast.config.spawn_point = P.toast.spawn_point or "TOP"
+ LibToast.config.duration = P.toast.duration or 7
+ LibToast.config.opacity = P.toast.opacity or 0.75
+ end
+
+ -- shows notifications or simply uses Print method.
+ local toast_name = format("%sToastFrame", folder)
+ function ns:Notify(text, title, icon, urgency)
+ if not (LibToast and LibToast:Spawn(toast_name, text, title, icon, urgency)) then
+ self:Print(text)
+ end
+ end
+ end
+
+ -- returns toast options
+ function Private.ToastOptions()
+ Private.ToastOptions = nil -- remove it
+
+ if not LibToast or toast_opt then
+ return toast_opt
+ end
+
+ toast_opt = {
+ type = "group",
+ name = L["Notifications"],
+ get = function(i)
+ return ns.profile.toast[i[#i]] or LibToast.config[i[#i]]
+ end,
+ set = function(i, val)
+ ns.profile.toast[i[#i]] = val
+ LibToast.config[i[#i]] = val
+ end,
+ order = 990,
+ args = {
+ toastdesc = {
+ type = "description",
+ name = L["opt_toast_desc"],
+ fontSize = "medium",
+ width = "full",
+ order = 0
+ },
+ empty_1 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ hide_toasts = {
+ type = "toggle",
+ name = L["Disable"],
+ order = 10
+ },
+ spawn_point = {
+ type = "select",
+ name = L["Position"],
+ order = 20,
+ values = {
+ TOPLEFT = L["Top Left"],
+ TOPRIGHT = L["Top Right"],
+ BOTTOMLEFT = L["Bottom Left"],
+ BOTTOMRIGHT = L["Bottom Right"],
+ TOP = L["Top"],
+ BOTTOM = L["Bottom"],
+ LEFT = L["Left"],
+ RIGHT = L["Right"]
+ }
+ },
+ duration = {
+ type = "range",
+ name = L["Duration"],
+ min = 5,
+ max = 15,
+ step = 1,
+ order = 30
+ },
+ opacity = {
+ type = "range",
+ name = L["Opacity"],
+ min = 0,
+ max = 1,
+ step = 0.01,
+ isPercent = true,
+ order = 40
+ },
+ empty_2 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 50
+ },
+ test = {
+ type = "execute",
+ name = L["Test Notifications"],
+ func = function() ns:Notify() end,
+ disabled = function() return ns.profile.toast.hide_toasts end,
+ width = "double",
+ order = 60
+ }
+ }
+ }
+
+ return toast_opt
+ end
+end
+
+-------------------------------------------------------------------------------
+-- Total segment stuff!
+
+do
+ local total_opt = nil
+
+ function Private.TotalOptions()
+ Private.TotalOptions = nil -- remove it
+
+ if total_opt then
+ return total_opt
+ end
+
+ local values = {al = 0x10, rb = 0x01, rt = 0x02, db = 0x04, dt = 0x08}
+ local disabled = function()
+ return (band(ns.profile.totalflag or 0, values.al) ~= 0)
+ end
+
+ total_opt = {
+ type = "group",
+ name = L["Total Segment"],
+ desc = format(L["Options for %s."], L["Total Segment"]),
+ order = 970,
+ args = {
+ collection = {
+ type = "group",
+ name = L["Data Collection"],
+ inline = true,
+ order = 10,
+ get = function(i)
+ return (band(ns.profile.totalflag or 0, values[i[#i]]) ~= 0)
+ end,
+ set = function(i, val)
+ local v = values[i[#i]]
+ if val and band(ns.profile.totalflag or 0, v) == 0 then
+ ns.profile.totalflag = (ns.profile.totalflag or 0) + v
+ elseif not val and band(ns.profile.totalflag or 0, v) ~= 0 then
+ ns.profile.totalflag = max(0, (ns.profile.totalflag or 0) - v)
+ end
+ end,
+ args = {
+ al = {
+ type = "toggle",
+ name = L["All Segments"],
+ desc = L["opt_tweaks_total_all_desc"],
+ width = "full",
+ order = 10
+ },
+ rb = {
+ type = "toggle",
+ name = L["Raid Bosses"],
+ desc = format(L["opt_tweaks_total_fmt_desc"], L["Raid Bosses"]),
+ order = 20,
+ disabled = disabled
+ },
+ rt = {
+ type = "toggle",
+ name = L["Raid Trash"],
+ desc = format(L["opt_tweaks_total_fmt_desc"], L["Raid Trash"]),
+ order = 30,
+ disabled = disabled
+ },
+ db = {
+ type = "toggle",
+ name = L["Dungeon Bosses"],
+ desc = format(L["opt_tweaks_total_fmt_desc"], L["Dungeon Bosses"]),
+ order = 40,
+ disabled = disabled
+ },
+ dt = {
+ type = "toggle",
+ name = L["Dungeon Trash"],
+ desc = format(L["opt_tweaks_total_fmt_desc"], L["Dungeon Trash"]),
+ order = 50,
+ disabled = disabled
+ }
+ }
+ },
+ totalidc = {
+ type = "toggle",
+ name = L["Detailed total segment"],
+ desc = L["opt_tweaks_total_full_desc"],
+ order = 20
+ }
+ }
+ }
+
+ return total_opt
+ end
+
+ function Private.total_noclick(set, mode)
+ return (not ns.profile.totalidc and set == "total" and type(mode) == "table" and mode.nototal == true)
+ end
+
+ local function total_record(set)
+ local totalflag = ns.total and set and ns.profile.totalflag
+
+ -- something missing
+ if not totalflag then
+ return false
+ end
+
+ -- raid bosses - 0x01
+ if band(totalflag, 0x01) ~= 0 then
+ if set.type == "raid" and set.gotboss then
+ return true
+ end
+ end
+
+ -- raid trash - 0x02
+ if band(totalflag, 0x02) ~= 0 then
+ if set.type == "raid" and not set.gotboss then
+ return true
+ end
+ end
+
+ -- dungeon boss - 0x04
+ if band(totalflag, 0x04) ~= 0 then
+ if set.type == "party" and set.gotboss then
+ return true
+ end
+ end
+
+ -- dungeon trash - 0x08
+ if band(totalflag, 0x08) ~= 0 then
+ if set.type == "party" and not set.gotboss then
+ return true
+ end
+ end
+
+ -- any combat - 0x10
+ if band(totalflag, 0x10) ~= 0 then
+ return true
+ end
+
+ -- battlegrouns/arenas or nothing
+ return (set.type == "pvp" or set.type == "arena")
+ end
+
+ function ns:DispatchSets(func, ...)
+ if not self.current or type(func) ~= "function" then return end
+
+ func(self.current, ...) -- record to current
+ if total_record(self.current) then -- record to total
+ func(self.total, ...)
+ end
+
+ -- record to phases
+ if not self.tempsets then return end
+ for i = 1, #self.tempsets do
+ local set = self.tempsets[i]
+ if set and not set.stopped then
+ func(set, ...)
+ end
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- creates generic dialog
+
+local dialog_name = format("%sCommonConfirmDialog", folder)
+function Private.ConfirmDialog(text, accept, cancel, override)
+ if type(cancel) == "table" and override == nil then
+ override = cancel
+ cancel = nil
+ end
+
+ local t = wipe(StaticPopupDialogs[dialog_name] or {})
+ StaticPopupDialogs[dialog_name] = t
+
+ local dialog, strata
+ t.OnAccept = function(self)
+ if type(accept) == "function" then
+ (accept)(self)
+ end
+ if dialog and strata then
+ dialog:SetFrameStrata(strata)
+ end
+ end
+ t.OnCancel = function(self)
+ if type(cancel) == "function" then
+ (cancel)(self)
+ end
+ if dialog and strata then
+ dialog:SetFrameStrata(strata)
+ end
+ end
+
+ t.preferredIndex = STATICPOPUP_NUMDIALOGS
+ t.text = text
+ t.button1 = L["Accept"]
+ t.button2 = L["Cancel"]
+ t.timeout = 0
+ t.whileDead = 1
+ t.hideOnEscape = 1
+
+ if type(override) == "table" then
+ Private.tCopy(t, override)
+ end
+
+ dialog = StaticPopup_Show(dialog_name)
+ if dialog then
+ strata = dialog:GetFrameStrata()
+ dialog:SetFrameStrata("TOOLTIP")
+ end
+end
+
+-------------------------------------------------------------------------------
+-- data serialization
+
+do
+ local AS = LibStub("AceSerializer-3.0")
+ local LC = LibStub("LibCompress")
+ local LD = LibStub("LibDeflate")
+ local LL = {level = 9}
+ local encodeTable = nil
+
+ local strbyte, strchar = string.byte, string.char
+ local lshift, tconcat = bit.lshift, table.concat
+
+ -- only used for backwards compatibility
+ local function HexDecode(str)
+ str = gsub(gsub(str, "%[.-%]", ""), "[^0123456789ABCDEF]", "")
+ if (#str == 0) or (#str % 2 ~= 0) then
+ return false, "Invalid Hex string"
+ end
+
+ local t, bl, bh = {}
+ local i = 1
+ repeat
+ bl = strbyte(str, i)
+ bl = bl >= 65 and bl - 55 or bl - 48
+ i = i + 1
+ bh = strbyte(str, i)
+ bh = bh >= 65 and bh - 55 or bh - 48
+ i = i + 1
+ t[#t + 1] = strchar(lshift(bh, 4) + bl)
+ until i >= #str
+ return tconcat(t)
+ end
+
+ function Private.serialize(comm, ...)
+ local result = LD:CompressDeflate(AS:Serialize(...), LL)
+ if comm then
+ return LD:EncodeForWoWChatChannel(result)
+ end
+ return LD:EncodeForPrint(result)
+ end
+
+ function Private.deserialize(data, comm)
+ local result = comm and LD:DecodeForWoWChatChannel(data) or LD:DecodeForPrint(data)
+ result = result and LD:DecompressDeflate(result) or nil
+ if result then
+ return AS:Deserialize(result)
+ end
+
+ -- backwards compatibility
+ local err
+ if comm then
+ encodeTable = encodeTable or LC:GetAddonEncodeTable()
+ data, err = encodeTable:Decode(data), "Error decoding"
+ else
+ data, err = HexDecode(data)
+ end
+
+ if data then
+ data, err = LC:DecompressHuffman(data)
+ if data then
+ return AS:Deserialize(data)
+ end
+ end
+ return false, err
+ end
+end
+
+-------------------------------------------------------------------------------
+-- custom "GetSpellInfo" and "GetSpellLink"
+
+do
+ local math_abs = math.abs
+ local GetSpellInfo, GetSpellLink = GetSpellInfo, GetSpellLink
+
+ local customSpells = {
+ [3] = {L["Falling"], [[Interface\ICONS\ability_rogue_quickrecovery]]},
+ [4] = {L["Drowning"], [[Interface\ICONS\spell_shadow_demonbreath]]},
+ [5] = {L["Fatigue"], [[Interface\ICONS\spell_nature_sleep]]},
+ [6] = {L["Fire"], [[Interface\ICONS\spell_fire_fire]]},
+ [7] = {L["Lava"], [[Interface\ICONS\spell_shaman_lavaflow]]},
+ [8] = {L["Slime"], [[Interface\ICONS\inv_misc_slime_01]]}
+ }
+ local customIcons = {
+ [75] = [[Interface\ICONS\inv_weapon_bow_07]], --> Auto Shot
+ [6603] = [[Interface\ICONS\inv_sword_04]], --> Melee
+ [3026] = [[Interface\ICONS\spell_shadow_soulgem]], --> Use Soulstone
+ [31786] = [[Interface\ICONS\spell_holy_revivechampion]], --> Spiritual Attunement
+ [49088] = [[Interface\ICONS\spell_shadow_antimagicshell]], --> Anti-Magic Shell
+ [54755] = [[Interface\ICONS\inv_glyph_majordruid]], --> Glyph of Rejuvenation
+ [56160] = [[Interface\ICONS\inv_glyph_majorpriest]], --> Glyph of Power Word: Shield
+ [61607] = [[Interface\ICONS\ability_hunter_rapidkilling]] --> Mark of Blood
+ }
+
+ local strfind = string.find
+ -- used to split spell: [id].[school].[petname]
+ local function SpellSplit(spellid)
+ if type(spellid) == "string" and strfind(spellid, ".") then
+ local id, school, petname = strsplit(".", spellid, 3)
+ return tonumber(id), tonumber(school), petname
+ end
+ return spellid
+ end
+ Private.SpellSplit = SpellSplit
+
+ function Private.SpellInfo(spellid)
+ if spellid then
+ spellid = math_abs(SpellSplit(spellid))
+ local res1, res2, res3, res4, res5, res6, res7, res8, res9
+ if customSpells[spellid] then
+ res1, res3 = customSpells[spellid][1], customSpells[spellid][2]
+ else
+ res1, res2, res3, res4, res5, res6, res7, res8, res9 = GetSpellInfo(spellid)
+ if spellid == 6603 then
+ res1 = L["Melee"]
+ end
+ res3 = customIcons[spellid] or res3
+ end
+ return res1, res2, res3, res4, res5, res6, res7, res8, res9
+ end
+ end
+
+ function Private.SpellLink(spellid)
+ if not customSpells[spellid] then
+ return GetSpellLink(math_abs(spellid))
+ end
+ end
+
+ -- spell icon and name to speed up things
+ local SpellInfo = Private.SpellInfo
+ ns.spellnames = setmetatable({}, {
+ __mode = "kv",
+ __index = function(t, spellid)
+ local name, _, icon = SpellInfo(spellid)
+ name = name or L["Unknown"]
+ icon = icon or [[Interface\ICONS\INV_Misc_QuestionMark]]
+ rawset(t, spellid, name)
+ rawset(ns.spellicons, spellid, icon)
+ return name
+ end,
+ __newindex = function(t, spellid, name)
+ rawset(t, spellid, name)
+ end
+ })
+ ns.spellicons = setmetatable({}, {
+ __mode = "kv",
+ __index = function(t, spellid)
+ local name, _, icon = SpellInfo(spellid)
+ name = name or L["Unknown"]
+ icon = icon or [[Interface\ICONS\INV_Misc_QuestionMark]]
+ rawset(t, spellid, icon)
+ rawset(ns.spellnames, spellid, name)
+ return icon
+ end,
+ __newindex = function(t, spellid, icon)
+ rawset(t, spellid, icon)
+ end
+ })
+end
+
+-------------------------------------------------------------------------------
+-- creatures, players and pets checkers
+
+do
+ local strsub = string.sub
+ local UnitGUID, UnitName = UnitGUID, UnitName
+ local UnitClass, UnitIsPlayer = UnitClass, UnitIsPlayer
+
+ local BITMASK_GROUP = Private.BITMASK_GROUP
+ local BITMASK_PETS = Private.BITMASK_PETS
+ local BITMASK_FRIENDLY = Private.BITMASK_FRIENDLY
+ local BITMASK_NPC = Private.BITMASK_NPC
+ local BITMASK_PLAYER = Private.BITMASK_PLAYER
+
+ ns.userGUID = UnitGUID("player")
+ _, ns.userClass = UnitClass("player")
+ ns.userName = UnitName("player")
+ ns.userRealm = gsub(GetRealmName(), "%s", "")
+
+ -- checks if the given guid/flags are those of a creature.
+ function Private.IsCreature(guid, flags)
+ if tonumber(guid) then
+ return (band(strsub(guid, 1, 5), 0x00F) == 3 or band(strsub(guid, 1, 5), 0x00F) == 5)
+ end
+ return (band(flags or 0, BITMASK_NPC) ~= 0)
+ end
+
+ -- used to protect tables
+ local table_mt = {__metatable = true}
+
+ -- players & pets [guid] = UnitID
+ local guidToUnit = setmetatable(Private.guidToUnit or {}, table_mt)
+ Private.guidToUnit = guidToUnit
+
+ -- players: [guid] = class / pets: [guid] = owner guid
+ local guidToClass = setmetatable(Private.guidToClass or {}, table_mt)
+ Private.guidToClass = guidToClass
+
+ -- players only: [guid] = name
+ local guidToName = setmetatable(Private.guidToName or {}, table_mt)
+ Private.guidToName = guidToName
+
+ -- pets only: [pet guid] = owner guid
+ local guidToOwner = setmetatable(Private.guidToOwner or {}, {
+ __metatable = true,
+ __newindex = function(t, guid, owner)
+ rawset(guidToClass, guid, owner)
+ rawset(t, guid, owner)
+ end
+ })
+ Private.guidToOwner = guidToOwner
+
+ do
+ -- tables used to cached results in order to speed up check
+ local __t1 = Private.WeakTable() -- cached players
+ local __t2 = Private.WeakTable() -- cached pets
+
+ -- checks if the guid is a player (extra: helps IsPet)
+ function Private.IsPlayer(guid, name, flags)
+ -- already cached?
+ if __t1[guid] ~= nil then
+ return __t1[guid]
+ end
+
+ -- group member?
+ if guidToName[guid] then
+ __t1[guid] = 1
+ __t2[guid] = (__t2[guid] == nil) and false or __t2[guid]
+ return 1
+ end
+
+ -- group pet?
+ if guidToClass[guid] then
+ __t1[guid] = false
+ __t2[guid] = __t2[guid] or 1
+ return false
+ end
+
+ -- player by flgs?
+ if band(flags or 0, BITMASK_PLAYER) == BITMASK_PLAYER then
+ __t1[guid] = true
+ __t2[guid] = (__t2[guid] == nil) and false or __t2[guid]
+ return true
+ end
+
+ -- player by UnitIsPlayer?
+ if name and UnitIsPlayer(name) then
+ __t1[guid] = true
+ __t2[guid] = (__t2[guid] == nil) and false or __t2[guid]
+ return true
+ end
+
+ -- just set it to false
+ __t1[guid] = false
+ return false
+ end
+
+ -- checks if the guid is a pet (extra: helps IsPlayer)
+ function Private.IsPet(guid, flags)
+ -- already cached?
+ if __t2[guid] ~= nil then
+ return __t2[guid]
+ end
+
+ -- just in case
+ if guidToName[guid] then
+ __t2[guid] = false
+ __t1[guid] = 1
+ return false
+ end
+
+ -- grouped pet?
+ if guidToClass[guid] then
+ __t2[guid] = 1
+ __t1[guid] = false
+ return 1
+ end
+
+ -- ungrouped pet?
+ if band(flags or 0, BITMASK_PETS) ~= 0 then
+ local res = (band(flags or 0, BITMASK_FRIENDLY) ~= 0) and 1 or true
+ __t2[guid] = res
+ __t1[guid] = false
+ return res
+ end
+
+ __t2[guid] = false
+ return false
+ end
+ end
+
+ -- returns unit's full name
+ local function UnitFullName(unit, ownerUnit, fmt)
+ if ownerUnit and fmt then
+ local name, realm = UnitName(ownerUnit)
+ return format("%s <%s>", UnitName(unit), realm and realm ~= "" and format("%s-%s", name, realm) or name)
+ end
+
+ local name, realm = UnitName(unit)
+ return not ownerUnit and realm and realm ~= "" and format("%s-%s", name, realm) or name
+ end
+ Private.UnitFullName = UnitFullName
+
+ -- adds a combatant
+ function Private.AddCombatant(unit, ownerUnit)
+ local guid = UnitGUID(unit)
+ if not guid then return end
+ guidToUnit[guid] = unit -- store the unit.
+
+ -- for pets...
+ if ownerUnit then
+ guidToOwner[guid] = UnitGUID(ownerUnit)
+ return
+ end
+
+ -- for players...
+ local _, class = UnitClass(unit)
+ guidToClass[guid] = class
+ guidToName[guid] = UnitFullName(unit)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- generic import and export window
+
+do
+ local AceGUI = nil
+
+ local frame_name = format("%sImportExportFrame", folder)
+ local function open_window(title, data, clickfunc, fontsize)
+ AceGUI = AceGUI or LibStub("AceGUI-3.0")
+ local frame = AceGUI:Create("Frame")
+ frame:SetTitle(L["Import/Export"])
+ frame:SetLayout("Flow")
+ frame:SetCallback("OnClose", function(widget)
+ AceGUI:Release(widget)
+ collectgarbage()
+ end)
+ frame:SetWidth(535)
+ frame:SetHeight(350)
+
+ local editbox = AceGUI:Create("MultiLineEditBox")
+ editbox.editBox:SetFontObject(GameFontHighlightSmall)
+ local fontpath = ns:MediaFetch("font", "Fira Mono Medium")
+ if fontpath then editbox.editBox:SetFont(fontpath, fontsize or 10, "") end
+ editbox:SetLabel(title)
+ editbox:SetFullWidth(true)
+ editbox:SetFullHeight(true)
+ frame:AddChild(editbox)
+
+ if type(data) == "function" then
+ clickfunc = data
+ data = nil
+ end
+
+ if data then
+ frame:SetStatusText(L["Press CTRL-C to copy the text to your clipboard."])
+ editbox:DisableButton(true)
+ editbox:SetText(data)
+ editbox.editBox:SetFocus()
+ editbox.editBox:HighlightText()
+ editbox:SetCallback("OnLeave", function(widget)
+ widget.editBox:HighlightText()
+ widget.editBox:SetFocus()
+ end)
+ editbox:SetCallback("OnEnter", function(widget)
+ widget.editBox:HighlightText()
+ widget.editBox:SetFocus()
+ end)
+ else
+ frame:SetStatusText(L["Press CTRL-V to paste the text from your clipboard."])
+ editbox:DisableButton(false)
+ editbox.editBox:SetFocus()
+ editbox.button:SetScript("OnClick", function(widget)
+ clickfunc(editbox:GetText())
+ AceGUI:Release(frame)
+ collectgarbage()
+ end)
+ end
+ -- close on escape
+ _G[frame_name] = frame.frame
+ UISpecialFrames[#UISpecialFrames + 1] = frame_name
+ end
+
+ function Private.ImportExport(title, data, clickfunc, fontsize)
+ return open_window(title, data, clickfunc, fontsize)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- prototypes and binding functions
+
+do
+ local getmetatable = getmetatable
+
+ -- fight/set prototype
+ local setPrototype = {}
+ ns.setPrototype = setPrototype
+
+ -- common actors prototype
+ local actorPrototype = {}
+ local actorPrototype_mt = {__index = actorPrototype}
+ ns.actorPrototype = actorPrototype
+
+ -- player prototype
+ local playerPrototype = setmetatable({}, actorPrototype_mt)
+ ns.playerPrototype = playerPrototype
+
+ -- enemy prototype
+ local enemyPrototype = setmetatable({}, actorPrototype_mt)
+ ns.enemyPrototype = enemyPrototype
+
+ local function bind_set_actors(actors)
+ if not actors then return end
+ for _, actor in pairs(actors) do
+ if actor.enemy then
+ enemyPrototype:Bind(actor)
+ elseif not actor.enemy then
+ playerPrototype:Bind(actor)
+ end
+ end
+ end
+
+ -- bind a set table to the set prototype
+ function setPrototype:Bind(obj)
+ if obj and getmetatable(obj) ~= self then
+ setmetatable(obj, self)
+ self.__index = self
+ bind_set_actors(obj.actors)
+ end
+ self.arena = (ns.forPVP and obj and obj.type == "arena")
+ return obj
+ end
+
+ -- bind an actor table to the prototype
+ function actorPrototype:Bind(obj)
+ if obj and getmetatable(obj) ~= self then
+ setmetatable(obj, self)
+ self.__index = self
+ end
+ return obj
+ end
+end
+
+-------------------------------------------------------------------------------
+-- combat log watch functions
+
+do
+ local IsWatching = false
+
+ function Private.StartWatching(obj)
+ if not IsWatching then
+ obj:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "ParseCombatLog")
+ obj:RegisterEvent("ENCOUNTER_START")
+ obj:RegisterEvent("ENCOUNTER_END")
+ IsWatching = true
+ end
+ end
+
+ function Private.StopWatching(obj)
+ if IsWatching then
+ obj:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
+ obj:UnregisterEvent("ENCOUNTER_START")
+ obj:UnregisterEvent("ENCOUNTER_END")
+ IsWatching = false
+ end
+ end
+end
+
+-------------------------------------------------------------------------------
+-- temporary flags check bypass
+
+do
+ local new = Private.newTable
+ local del = Private.delTable
+ local clear = Private.clearTable
+ local temp_units = nil
+
+ -- adds a temporary unit with optional info
+ function Private.AddTempUnit(guid, info)
+ if not guid then return end
+ temp_units = temp_units or new()
+ temp_units[guid] = info or true
+ end
+
+ -- deletes a temporary unit if found
+ function Private.DelTempUnit(guid)
+ if guid and temp_units and temp_units[guid] then
+ temp_units[guid] = del(temp_units[guid])
+ end
+ end
+
+ -- returns the temporary unit stored "info" or false
+ function Private.GetTempUnit(guid)
+ return guid and temp_units and temp_units[guid]
+ end
+
+ -- clears all store temporary units
+ function Private.ClearTempUnits()
+ temp_units = clear(temp_units)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- window table
+do
+ local Window = {}
+ ns.Window = Window
+
+ -- yet another recycle bin
+ local window_bin = Private.WeakTable()
+
+ -- creates a new window
+ local new = Private.newTable
+ local window_mt = {
+ __index = Window,
+ __newindex = function(self, key, value)
+ rawset(self, key, value)
+ if not self.ttwin or key == "ttwin" then return end
+ rawset(self.ttwin, key, value)
+ end
+ }
+ local tooltip_mt = {__index = setmetatable({}, window_mt)}
+
+ function Window.new(parent)
+ local win = next(window_bin) or {}
+ window_bin[win] = nil
+
+ if parent then
+ win.super = parent
+ win.dataset = new()
+ return setmetatable(win, tooltip_mt)
+ end
+
+ win.super = nil
+ win.dataset = new()
+ win.history = new()
+ win.metadata = new()
+ return setmetatable(win, window_mt)
+ end
+
+ -- deletes a window and recycles its tables
+ local del = Private.delTable
+ function Window.del(win)
+ win.super = nil
+ win.dataset = del(win.dataset)
+ if not win.super then
+ win.history = del(win.history)
+ win.metadata = del(win.metadata)
+ end
+ if win.ttwin then -- tooltip
+ win.ttwin = Window.del(win.ttwin)
+ end
+ setmetatable(win, nil)
+ window_bin[win] = true
+ return nil -- assign input reference
+ end
+
+ -- creates or reuses a dataset table
+ function Window:nr(index)
+ local d = self.dataset[index]
+ if d then
+ if d.ignore then
+ d.icon = nil
+ d.color = nil
+ end
+ d.id = nil
+ d.text = nil
+ d.class = nil
+ d.role = nil
+ d.spec = nil
+ d.ignore = nil
+ d.reportlabel = nil
+ d.reportvalue = nil
+ return d
+ end
+
+ d = new()
+ self.dataset[index] = d
+ return d
+ end
+
+ -- wipes window's dataset table
+ function Window:reset()
+ self.title = nil -- reset title
+ if not self.dataset then return end
+ for i = #self.dataset, 0, -1 do
+ if self.dataset[i] then
+ wipe(self.dataset[i])
+ end
+ end
+ end
+
+ -- cleans window from what was set by modules.
+ function Window:clean()
+ self.actorid, self.actorname, self.actorclass = nil, nil, nil
+ self.otherid, self.othername, self.otherclass = nil, nil, nil
+ self.targetid, self.targetname, self.targetclass = nil, nil, nil
+ self.spellid, self.spellname = nil, nil
+ end
+
+ -- generates a spell dataset/bar.
+ local SpellSplit = Private.SpellSplit
+ local spellnames = ns.spellnames
+ local spellicons = ns.spellicons
+ function Window:spell(d, spell, is_hot)
+ if d and spell then
+ -- create the dataset?
+ if type(d) == "number" then
+ d = self:nr(d)
+ end
+
+ d.id = spell -- locked!
+
+ local spellid, school, suffix = SpellSplit(spell)
+ d.spellid = spellid
+ d.spellschool = school
+ d.icon = spellicons[spellid]
+
+ -- for SPELL_EXTRA_ATTACKS
+ if tonumber(suffix) then
+ d.label = format("%s (%s)", spellnames[suffix], spellnames[spellid])
+ else
+ d.label = spellnames[spellid]
+ if suffix then -- has a suffix?
+ d.label = format("%s (%s)", d.label, suffix)
+ end
+ end
+
+ -- hots and dots?
+ if spellid < 0 and is_hot ~= false then
+ d.label = format("%s (%s)", d.label, is_hot and L["HoT"] or L["DoT"])
+ end
+ end
+ return d
+ end
+
+ -- generates actor's dataset/bar
+ function Window:actor(d, actor, is_enemy, actorname)
+ if d and actor then
+ -- create the dataset?
+ if type(d) == "number" then
+ d = self:nr(d)
+ end
+
+ if type(actor) == "string" then
+ d.id = actor
+ d.label = actorname or actor
+ return d
+ end
+
+ d.id = actor.id or actorname
+ d.label = actorname or L["Unknown"]
+
+ -- speed up things if it's a pet/enemy.
+ if strmatch(d.label, "%<(%a+)%>") then
+ d.class = "PET"
+ return d
+ end
+
+ -- no need to go further for enemies
+ if is_enemy then
+ d.class = actor.class or "ENEMY"
+ d.role = actor.role
+ d.spec = actor.spec
+ return d
+ end
+
+ d.class = actor.class or "UNKNOWN"
+ d.role = actor.role
+ d.spec = actor.spec
+
+ if ns.validclass[d.class] then
+ d.text = ns:FormatName(d.label, actor.id)
+ end
+ end
+ return d
+ end
+
+ -- determines whehter an actor's bar should be shown or not
+ -- prevents repeated code to check for class
+ function Window:show_actor(actor, set, strict)
+ if not actor then
+ return false
+ elseif self.class and actor.class ~= self.class then
+ return false
+ elseif strict and actor.fake then
+ return false
+ elseif strict and actor.enemy and not set.arena then
+ return false
+ else
+ return true
+ end
+ end
+
+ -- colorizes a database/bar for arena fights
+ function Window:color(d, set, is_enemy)
+ if not d or not set then
+ return
+ elseif set.arena and is_enemy then
+ d.color = ns.classcolors(set.faction and "ARENA_GREEN" or "ARENA_GOLD")
+ elseif set.arena then
+ d.color = ns.classcolors(set.faction and "ARENA_GOLD" or "ARENA_GREEN")
+ elseif d.color then
+ d.color = nil
+ end
+ end
+end
diff --git a/Skada/Core/Load.xml b/Skada/Core/Load.xml
new file mode 100644
index 0000000..fa4d1f5
--- /dev/null
+++ b/Skada/Core/Load.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Skada/Core/Menus.lua b/Skada/Core/Menus.lua
new file mode 100644
index 0000000..ec0eda6
--- /dev/null
+++ b/Skada/Core/Menus.lua
@@ -0,0 +1,1359 @@
+local folder, Skada = ...
+local Private = Skada.Private
+
+local L = Skada.Locale
+local AceGUI = LibStub("AceGUI-3.0")
+
+local pairs, next, type = pairs, next, type
+local format, min, max = string.format, math.min, math.max
+local GetCursorPosition = GetCursorPosition
+local GetScreenWidth, GetScreenHeight = GetScreenWidth, GetScreenHeight
+
+local CreateFrame = CreateFrame
+local UIDropDownMenu_CreateInfo = UIDropDownMenu_CreateInfo
+local UIDropDownMenu_AddButton = UIDropDownMenu_AddButton
+local CloseDropDownMenus = CloseDropDownMenus
+local ToggleDropDownMenu = ToggleDropDownMenu
+local IsShiftKeyDown = IsShiftKeyDown
+local del = Private.delTable
+local _
+
+local _menu_main = nil
+local _menu_fight = nil
+local _menu_mode = nil
+local _menu_large = nil
+local _menu_phase = nil
+local info = nil
+local iconName = "\124T%s:19:19:0:-1:32:32:2:30:2:30\124t %s"
+
+-- references: windows, modes, sets
+local windows = Skada.windows
+local modes = Skada.modes
+
+-- guesses the dropdown location
+local function get_dropdown_point()
+ local x, y = GetCursorPosition(UIParent)
+ x = x / UIParent:GetEffectiveScale()
+ y = y / UIParent:GetEffectiveScale()
+
+ local point, point2 = "%sLEFT", "%sLEFT"
+ if x > GetScreenWidth() * 0.5 then
+ point = "%sRIGHT"
+ point2 = "%sRIGHT"
+ end
+
+ if y > GetScreenHeight() * 0.5 then
+ point = format(point, "TOP")
+ point2 = format(point2, "BOTTOM")
+ else
+ point = format(point, "BOTTOM")
+ point2 = format(point2, "TOP")
+ end
+
+ return point, point2, x, y
+end
+
+local function set_info_text(set, i, num)
+ if set.type == "pvp" or set.type == "arena" then
+ if i and num then
+ return format("\124cffc0c0c0%02.f.\124r \124cffffd100%s\124r", num - i + 1, Skada:GetSetLabel(set, true))
+ else
+ return format("\124cffff1919%s\124r", Skada:GetSetLabel(set, true))
+ end
+ elseif set.gotboss and set.success then
+ if i and num then
+ return format("\124cffc0c0c0%02.f.\124r \124cff19ff19%s\124r", num - i + 1, Skada:GetSetLabel(set, true))
+ else
+ return format("\124cff19ff19%s\124r", Skada:GetSetLabel(set, true))
+ end
+ elseif set.gotboss then
+ if i and num then
+ return format("\124cffc0c0c0%02.f.\124r \124cffff1919%s\124r", num - i + 1, Skada:GetSetLabel(set, true))
+ else
+ return format("\124cffff1919%s\124r", Skada:GetSetLabel(set, true))
+ end
+ elseif i and num then
+ return format("\124cffc0c0c0%02.f.\124r %s", num - i + 1, Skada:GetSetLabel(set, true))
+ else
+ return Skada:GetSetLabel(set, true)
+ end
+end
+
+-- Configuration menu.
+function Skada:OpenMenu(window)
+ local menu = _menu_main
+ if not menu then
+ menu = CreateFrame("Frame", format("%sMenuMain", folder), UIParent, "UIDropDownMenuTemplate")
+ menu.displayMode = "MENU"
+ _menu_main = menu
+ end
+
+ menu.win = window
+ menu.initialize = menu.initialize or function(self, level)
+ if not level then return end
+ info = info or UIDropDownMenu_CreateInfo()
+
+ if level == 1 then
+ -- window menus
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db then
+ wipe(info)
+ info.text = win.db.name
+ info.hasArrow = 1
+ info.value = win
+ info.notCheckable = 1
+ info.colorCode = (self.win and self.win == win) and "\124cffffd100"
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+
+ -- create window
+ wipe(info)
+ info.text = L["Create Window"]
+ info.func = function()
+ Skada:NewWindow(self.win)
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- toggle window
+ wipe(info)
+ info.text = L["Toggle Windows"]
+ info.func = function()
+ Skada:ToggleWindow()
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- quick access menu
+ wipe(info)
+ info.text = L["Quick Access"]
+ info.value = "shortcut"
+ info.hasArrow = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- Can't report if we are not in a mode.
+ if not self.win or (self.win and self.win.selectedmode) then
+ wipe(info)
+ info.text = L["Report"]
+ info.func = function()
+ Private.OpenReport(self.win)
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ -- delete segment menu
+ wipe(info)
+ info.text = L["Delete Segment"]
+ info.value = "delete"
+ info.hasArrow = 1
+ info.disabled = (not Skada.sets or #Skada.sets == 0)
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ if Skada.profile.setstokeep > 0 then
+ -- keep segment
+ wipe(info)
+ info.text = L["Keep Segment"]
+ info.value = "keep"
+ info.hasArrow = 1
+ info.disabled = (not Skada.sets or #Skada.sets == 0)
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ if self.win and (not self.win.db.enabletitle or (self.win.db.enabletitle and not self.win.db.buttons.segment)) then
+ wipe(info)
+ info.text = L["Select Segment"]
+ info.value = "segment"
+ info.hasArrow = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- start new segment
+ wipe(info)
+ info.text = L["New Segment"]
+ info.func = function()
+ Skada:NewSegment()
+ end
+ info.notCheckable = 1
+ info.disabled = (Skada.current == nil)
+ UIDropDownMenu_AddButton(info, level)
+
+ -- start new phase
+ wipe(info)
+ info.text = L["New Phase"]
+ info.func = function()
+ Skada:NewPhase()
+ end
+ info.notCheckable = 1
+ info.disabled = (Skada.current == nil)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- reset
+ wipe(info)
+ info.text = L["Reset"]
+ info.func = function()
+ Skada:ShowPopup()
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- Configure
+ wipe(info)
+ info.text = L["Configure"]
+ info.func = function()
+ Private.OpenOptions(self.win)
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- Close menu item
+ wipe(info)
+ info.text = L["Close"]
+ info.func = function()
+ CloseDropDownMenus()
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ elseif level == 2 then
+ if type(UIDROPDOWNMENU_MENU_VALUE) == "table" then
+ local win = UIDROPDOWNMENU_MENU_VALUE
+
+ -- window
+ wipe(info)
+ info.text = L["Window"]
+ info.isTitle = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- lock window
+ wipe(info)
+ info.text = L["Lock Window"]
+ info.func = function()
+ win.db.barslocked = (win.db.barslocked ~= true) and true or nil
+ Skada:ApplySettings(win.db.name)
+ end
+ info.checked = win.db.barslocked
+ UIDropDownMenu_AddButton(info, level)
+
+ -- hide window
+ wipe(info)
+ info.text = L["Hide Window"]
+ info.func = function()
+ if win:IsShown() then
+ win.db.hidden = true
+ win:Hide()
+ else
+ win.db.hidden = false
+ win:Show()
+ end
+ Skada:ApplySettings(win.db.name, true)
+ end
+ info.checked = not win:IsShown()
+ UIDropDownMenu_AddButton(info, level)
+
+ -- snap window
+ if win.db.display == "bar" then
+ wipe(info)
+ info.text = L["Sticky Window"]
+ info.func = function()
+ win.db.sticky = (win.db.sticky ~= true) and true or nil
+ if not win.db.sticky then
+ for i = 1, #windows do
+ local w = windows[i]
+ if w and w.db and w.db.sticked and w.db.sticked[win.db.name] then
+ w.db.sticked[win.db.name] = nil
+ if next(w.db.sticked) == nil then
+ w.db.sticked = del(w.db.sticked)
+ end
+ end
+ end
+ end
+ Skada:ApplySettings(win.db.name)
+ end
+ info.checked = win.db.sticky
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ -- clamped to screen
+ wipe(info)
+ info.text = L["Clamped To Screen"]
+ info.func = function()
+ win.db.clamped = (win.db.clamped ~= true) and true or nil
+ Skada:ApplySettings(win.db.name)
+ end
+ info.checked = win.db.clamped
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- window
+ if win.db.display == "bar" then
+ wipe(info)
+ info.text = L["Options"]
+ info.isTitle = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ if Skada.profile.showself ~= true then
+ wipe(info)
+ info.text = L["Always show self"]
+ info.func = function()
+ win.db.showself = (win.db.showself ~= true) and true or nil
+ Skada:ApplySettings(win.db.name)
+ end
+ info.checked = (win.db.showself == true)
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ if Skada.profile.showtotals ~= true then
+ wipe(info)
+ info.text = L["Show totals"]
+ info.func = function()
+ win.db.showtotals = (win.db.showtotals ~= true) and true or nil
+ win:Wipe(true)
+ Skada:UpdateDisplay()
+ end
+ info.checked = (win.db.showtotals == true)
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ wipe(info)
+ info.text = L["Include set"]
+ info.func = function()
+ win.db.titleset = (win.db.titleset ~= true) and true or nil
+ Skada:ApplySettings(win.db.name)
+ end
+ info.checked = (win.db.titleset == true)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Encounter Timer"]
+ info.func = function()
+ win.db.combattimer = (win.db.combattimer ~= true) and true or nil
+ Skada:ApplySettings(win.db.name)
+ end
+ info.checked = (win.db.combattimer == true)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ -- delete window
+ wipe(info)
+ info.text = L["Delete Window"]
+ info.func = function()
+ return Skada:DeleteWindow(win.db.name, IsShiftKeyDown())
+ end
+ info.notCheckable = 1
+ info.leftPadding = 16
+ info.colorCode = "\124cffeb4c34"
+ UIDropDownMenu_AddButton(info, level)
+ elseif UIDROPDOWNMENU_MENU_VALUE == "segment" then
+ wipe(info)
+ info.text = L["Total"]
+ info.func = function()
+ self.win:SetSelectedSet("total")
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == "total")
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Current"]
+ info.func = function()
+ self.win:SetSelectedSet("current")
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == "current")
+ UIDropDownMenu_AddButton(info, level)
+
+ local sets = Skada.sets
+ if #sets > 0 then
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ local num = #sets
+ for i = 1, num do
+ local set = sets[i]
+ wipe(info)
+ info.text = set_info_text(set, i, num)
+ info.func = function()
+ self.win:SetSelectedSet(i)
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == i)
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+ elseif UIDROPDOWNMENU_MENU_VALUE == "delete" then
+ local sets = Skada.sets
+ local num = #sets
+ for i = 1, num do
+ local set = sets[i]
+ wipe(info)
+ info.text = set_info_text(set, i, num)
+ info.func = function()
+ Skada:DeleteSet(set, i)
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+ elseif UIDROPDOWNMENU_MENU_VALUE == "keep" then
+ local sets = Skada.sets
+ local num, kept = #sets, 0
+ for i = 1, num do
+ local set = sets[i]
+ if set.keep then
+ kept = kept + 1
+ end
+
+ wipe(info)
+ info.text = set_info_text(set, i, num)
+ info.func = function()
+ set.keep = (set.keep ~= true) and true or nil
+ end
+ info.checked = set.keep
+ info.keepShownOnClick = true
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ if num > 0 then
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Select All"]
+ info.func = function()
+ local sets = Skada.sets
+ for i = 1, #sets do
+ sets[i].keep = true
+ end
+ end
+ info.notCheckable = 1
+ info.leftPadding = 16
+ info.disabled = (num == kept)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Deselect All"]
+ info.func = function()
+ local sets = Skada.sets
+ for i = 1, #sets do
+ sets[i].keep = nil
+ end
+ end
+ info.notCheckable = 1
+ info.leftPadding = 16
+ info.disabled = (kept == 0)
+ UIDropDownMenu_AddButton(info, level)
+ end
+ elseif UIDROPDOWNMENU_MENU_VALUE == "shortcut" then
+ -- time measure
+ wipe(info)
+ info.text = L["Time Measure"]
+ info.isTitle = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Activity Time"]
+ info.func = function()
+ Skada.profile.timemesure = 1
+ Skada:ApplySettings(true)
+ end
+ info.checked = (Skada.profile.timemesure == 1)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Effective Time"]
+ info.func = function()
+ Skada.profile.timemesure = 2
+ Skada:ApplySettings(true)
+ end
+ info.checked = (Skada.profile.timemesure == 2)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- number format
+ wipe(info)
+ info.text = L["Number format"]
+ info.isTitle = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Condensed"]
+ info.func = function()
+ Skada.profile.numberformat = 1
+ Skada:ApplySettings(true)
+ end
+ info.checked = (Skada.profile.numberformat == 1)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Comma"]
+ info.func = function()
+ Skada.profile.numberformat = 2
+ Skada:ApplySettings(true)
+ end
+ info.checked = (Skada.profile.numberformat == 2)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Detailed"]
+ info.func = function()
+ Skada.profile.numberformat = 3
+ Skada:ApplySettings(true)
+ end
+ info.checked = (Skada.profile.numberformat == 3)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ -- number format
+ wipe(info)
+ info.text = L["Other"]
+ info.isTitle = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Show totals"]
+ info.func = function()
+ Skada.profile.showtotals = (Skada.profile.showtotals ~= true) and true or nil
+ Skada:Wipe()
+ Skada:UpdateDisplay(true)
+ end
+ info.checked = (Skada.profile.showtotals == true)
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Show rank numbers"]
+ info.func = function()
+ Skada.profile.showranks = (Skada.profile.showranks ~= true) and true or nil
+ Skada:ApplySettings()
+ end
+ info.checked = (Skada.profile.showranks == true)
+ info.keepShownOnClick = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Always show self"]
+ info.func = function()
+ Skada.profile.showself = (Skada.profile.showself ~= true) and true or nil
+ Skada:ApplySettings()
+ end
+ info.checked = (Skada.profile.showself == true)
+ info.keepShownOnClick = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Aggressive combat detection"]
+ info.func = function()
+ Skada.profile.tentativecombatstart = (Skada.profile.tentativecombatstart ~= true) and true or nil
+ Skada:ApplySettings()
+ end
+ info.checked = (Skada.profile.tentativecombatstart == true)
+ info.keepShownOnClick = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Merge pets"]
+ info.func = function()
+ Skada.profile.mergepets = not Skada.profile.mergepets
+ Skada:ApplySettings()
+ end
+ info.checked = (Skada.profile.mergepets == true)
+ info.keepShownOnClick = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Absorbed Damage"]
+ info.func = function()
+ Skada.profile.absdamage = (Skada.profile.absdamage ~= true) and true or nil
+ Skada:ApplySettings()
+ end
+ info.checked = (Skada.profile.absdamage == true)
+ info.keepShownOnClick = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+ end
+
+ local x, y
+ menu.point, _, x, y = get_dropdown_point()
+ ToggleDropDownMenu(1, nil, menu, "UIParent", x, y)
+end
+
+function Skada:SegmentMenu(window)
+ if self.testMode then return end
+
+ local menu = _menu_fight
+ if not menu then
+ menu = CreateFrame("Frame", format("%sMenuFight", folder), UIParent, "UIDropDownMenuTemplate")
+ menu.displayMode = "MENU"
+ _menu_fight = menu
+ end
+
+ menu.win = window
+ menu.initialize = menu.initialize or function(self, level)
+ if not level or not self.win then return end
+ info = info or UIDropDownMenu_CreateInfo()
+
+ local sets = Skada.sets
+ local numsets = #sets
+
+ if level == 1 then
+ wipe(info)
+ info.text = L["Total"]
+ info.func = function()
+ self.win:SetSelectedSet("total")
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == "total")
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["Current"]
+ info.func = function()
+ self.win:SetSelectedSet("current")
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == "current")
+ UIDropDownMenu_AddButton(info, level)
+
+ if numsets > 0 then
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ local offset = 1
+ if type(self.win.selectedset) == "number" and self.win.selectedset > 25 then
+ offset = min(25, max(1, numsets - 24))
+ end
+
+ local nr = 0
+ for i = offset, numsets do
+ nr = nr + 1
+ local set = sets[i]
+ wipe(info)
+ info.text = set_info_text(set, i, numsets)
+ info.func = function()
+ self.win:SetSelectedSet(i)
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == i)
+ UIDropDownMenu_AddButton(info, level)
+ if nr == 25 then
+ break
+ end
+ end
+
+ if numsets > nr then
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ if offset == 1 then
+ info.text = L["Previous"]
+ info.value = "prev"
+ else
+ info.text = L["Next"]
+ info.value = "next"
+ end
+ info.padding = 40
+ info.hasArrow = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+ elseif level == 2 then
+ if UIDROPDOWNMENU_MENU_VALUE == "prev" or UIDROPDOWNMENU_MENU_VALUE == "next" then
+ local start, stop = 26, numsets
+ if UIDROPDOWNMENU_MENU_VALUE == "next" then
+ start, stop = 1, max(1, numsets - 25)
+ end
+
+ for i = start, stop do
+ local set = sets[i]
+ wipe(info)
+ info.text = set_info_text(set, i, numsets)
+ info.func = function()
+ self.win:SetSelectedSet(i)
+ Skada:UpdateDisplay()
+ end
+ info.checked = (self.win.selectedset == i)
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+ end
+ end
+
+ local x, y
+ menu.point, _, x, y = get_dropdown_point()
+ ToggleDropDownMenu(1, nil, menu, "UIParent", x, y)
+end
+
+do
+ local tContains, tsort = tContains, table.sort
+ local categories -- list of mode categories.
+ local categorized -- modes organized by category.
+
+ local function construct_categories()
+ if categories then return end
+
+ categories = {}
+ categorized = {}
+
+ -- alphabetical order of modes!
+ tsort(modes, function(a, b)
+ return a and b and a.localeName and b.localeName and a.localeName < b.localeName
+ end)
+
+ for _, mode in pairs(modes) do
+ categorized[mode.category] = categorized[mode.category] or {}
+ categorized[mode.category][#categorized[mode.category] + 1] = mode
+ if not tContains(categories, mode.category) then
+ categories[#categories + 1] = mode.category
+ end
+ end
+
+ -- alphabetical order of categories (Other is left last)!
+ tsort(categories, function(a, b)
+ if a == "Other" then
+ return false
+ elseif b == "Other" then
+ return true
+ else
+ return a < b
+ end
+ end)
+ end
+
+ local function build_large_menu()
+ local menu_name = format("%sMenuModeLarge", folder)
+ local menu = CreateFrame("Button", menu_name, UIParent)
+ menu:SetFrameStrata("TOOLTIP")
+ menu:SetClampedToScreen(true)
+ menu:SetBackdrop({
+ bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
+ edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
+ inset = 4,
+ edgeSize = 8,
+ tile = true,
+ insets = {left = 2, right = 2, top = 2, bottom = 2}
+ })
+ menu:SetBackdropColor(0, 0, 0, 0.83)
+ menu:SetBackdropBorderColor(0, 0, 0, 1)
+ menu:SetPoint("CENTER")
+ menu.headers = {}
+ menu.buttons = {}
+
+ local function click_on_mode(self, button)
+ local mode = menu.win and menu.buttons[self]
+ if mode and button == "LeftButton" then
+ menu.win:DisplayMode(mode)
+ end
+ menu:Hide()
+ end
+
+ local function create_button(mode, index, header)
+ local btn = CreateFrame("Button", nil, menu)
+ btn:SetFrameLevel(menu:GetFrameLevel() + 1)
+ btn:SetNormalFontObject("GameFontHighlightSmallLeft")
+ btn:SetHighlightFontObject("GameFontNormalSmallLeft")
+ btn:SetScript("OnClick", click_on_mode)
+
+ -- format button text
+ if mode.metadata and mode.metadata.icon then
+ btn:SetText(format(iconName, mode.metadata.icon, mode.localeName))
+ else
+ btn:SetText(mode.localeName)
+ end
+
+ local fs = btn:GetFontString()
+ local width = fs:GetStringWidth() + 12
+ local height = fs:GetStringHeight() + 4
+ btn:SetWidth(width)
+ btn:SetHeight(height)
+
+ -- position
+ local prev = header.buttons[index - 1]
+ btn:ClearAllPoints()
+ if index == 1 then
+ height = height + 12 -- extra bottom margin
+ btn:SetPoint("TOPLEFT", header, "BOTTOMLEFT")
+ btn:SetPoint("TOPRIGHT", header, "TOPRIGHT")
+ elseif prev then
+ btn:SetPoint("TOPLEFT", prev, "BOTTOMLEFT")
+ btn:SetPoint("TOPRIGHT", prev, "TOPRIGHT")
+ end
+
+ menu.buttons[btn] = mode
+ header.buttons[index] = btn
+ return width, height
+ end
+
+ local function create_header(text, index, modules)
+ local header = menu:CreateFontString(nil, "ARTWORK", "GameFontNormalSmallLeft")
+ header:SetWordWrap(false)
+ header:SetText(L[text])
+ menu.headers[index] = header
+ header.buttons = header.buttons or {}
+
+ local width = header:GetStringWidth() + 12
+ local height = header:GetStringHeight() + 8
+ header:SetHeight(height)
+
+ -- position
+ local prev = menu.headers[index - 1]
+ header:ClearAllPoints()
+ if index == 1 then
+ header:SetPoint("TOPLEFT", menu, "TOPLEFT", 12, -6)
+ elseif prev then
+ header:SetPoint("LEFT", prev, "RIGHT", 12, 0)
+ end
+
+ for i, mode in pairs(modules) do
+ local w, h = create_button(mode, i, header)
+ if w > width then
+ width = w
+ end
+ height = height + h
+ end
+
+ header:SetWidth(width)
+
+ if index > 0 then -- small left margin
+ width = width + 12
+ end
+ return width, height
+ end
+
+ local width, height = 12, 0
+ for index, name in pairs(categories) do
+ local w, h = create_header(name, index, categorized[name])
+ width = width + w
+ if h > height then
+ height = h
+ end
+ end
+
+ menu:SetWidth(width)
+ menu:SetHeight(height)
+
+ menu:RegisterForClicks("AnyUp")
+ menu:SetScript("OnMouseDown", function(self, button)
+ if button == "RightButton" then
+ self:Hide()
+ end
+ end)
+
+ -- to set highlight stuff
+ menu:SetScript("OnShow", function(self)
+ self.opened = true
+ local mode = self.win and self.win.selectedmode
+ if not mode then return end
+ for btn, module in pairs(self.buttons) do
+ if module == mode then
+ btn:LockHighlight()
+ else
+ btn:UnlockHighlight()
+ end
+ end
+ end)
+ menu:SetScript("OnHide", function(self)
+ self.opened = nil
+ end)
+
+ menu:Hide()
+ UISpecialFrames[#UISpecialFrames + 1] = menu_name
+ return menu
+ end
+
+ local function large_mode_menu(self, window, frame)
+ local menu = _menu_large
+ if not menu then
+ menu = build_large_menu()
+ _menu_large = menu
+ end
+
+ menu.win = window
+
+ if menu.opened then
+ menu:Hide()
+ menu.opened = nil
+ else
+ local point, rPoint = get_dropdown_point()
+ if point then
+ menu:ClearAllPoints()
+ menu:SetPoint(point, frame or UIParent, rPoint)
+ end
+ menu.opened = true
+ menu:Show()
+ CloseDropDownMenus()
+ end
+ end
+
+ function Skada:ModeMenu(window, frame, large)
+ construct_categories()
+
+ if large then
+ return large_mode_menu(self, window, frame)
+ elseif _menu_large then
+ _menu_large:Hide()
+ end
+
+ local menu = _menu_mode
+ if not menu then
+ menu = CreateFrame("Frame", format("%sMenuMode", folder), UIParent, "UIDropDownMenuTemplate")
+ menu.displayMode = "MENU"
+ _menu_mode = menu
+ end
+
+ menu.win = window
+ menu.initialize = menu.initialize or function(self, level)
+ if not level or not self.win then return end
+ info = info or UIDropDownMenu_CreateInfo()
+
+ if level == 1 then
+ if #categories > 0 then
+ for i = 1, #categories do
+ local category = categories[i]
+ wipe(info)
+ info.text = L[category]
+ info.value = category
+ info.hasArrow = 1
+ info.notCheckable = 1
+ if self.win and self.win.selectedmode and (self.win.selectedmode.category == category or (self.win.parentmode and self.win.parentmode.category == category)) then
+ info.colorCode = "\124cffffd100"
+ end
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ -- Close menu item
+ wipe(info)
+ info.text = L["Close"]
+ info.func = function()
+ CloseDropDownMenus()
+ end
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ elseif level == 2 and categorized[UIDROPDOWNMENU_MENU_VALUE] then
+ for i = 1, #categorized[UIDROPDOWNMENU_MENU_VALUE] do
+ local mode = categorized[UIDROPDOWNMENU_MENU_VALUE][i]
+ wipe(info)
+
+ if Skada.profile.moduleicons and mode.metadata and mode.metadata.icon then
+ info.text = format(iconName, mode.metadata.icon, mode.localeName)
+ else
+ info.text = mode.localeName
+ end
+
+ info.func = function()
+ self.win:DisplayMode(mode)
+ CloseDropDownMenus()
+ end
+
+ if self.win and self.win.selectedmode and (self.win.selectedmode == mode or self.win.parentmode == mode) then
+ info.checked = 1
+ info.colorCode = "\124cffffd100"
+ end
+
+ UIDropDownMenu_AddButton(info, level)
+ end
+ end
+ end
+
+ local x, y
+ menu.point, _, x, y = get_dropdown_point()
+ ToggleDropDownMenu(1, nil, menu, "UIParent", x, y)
+ end
+end
+
+do
+ local strtrim = strtrim or string.trim
+ local UnitExists, UnitFullName = UnitExists, Private.UnitFullName
+
+ -- handles reporting
+ local function do_report(window, barid)
+ local mode = Skada.profile.report.mode
+ local set = Skada.profile.report.set
+ local channel = Skada.profile.report.channel
+ local chantype = Skada.profile.report.chantype
+ local number = Skada.profile.report.number
+
+ if channel == "whisper" then
+ channel = Skada.profile.report.target
+ if channel and #strtrim(channel) == 0 then
+ channel = nil
+ end
+ elseif channel == "target" then
+ if UnitExists("target") then
+ channel = UnitFullName("target")
+ else
+ channel = nil
+ end
+ end
+
+ if channel and chantype and mode and set and number then
+ Skada:Report(channel, chantype, mode, set, number, window, barid)
+
+ -- hide report window if shown.
+ if Skada.reportwindow and Skada.reportwindow:IsShown() then
+ Skada.reportwindow:Hide()
+ end
+ else
+ Skada:Print("Error: Whisper target not found")
+ end
+ end
+
+ local channellist
+ local build_report_channels
+ do
+ local IsInGuild, IsInRaid = IsInGuild, IsInRaid
+ local GetNumSubgroupMembers = GetNumSubgroupMembers
+ local GetChannelList = GetChannelList
+ local TempTable = Private.TempTable
+
+ local defaults = {
+ whisper = {L["Whisper"], "whisper"},
+ target = {L["Whisper Target"], "whisper"},
+ say = {L["Say"], "preset"},
+ raid = {L["Raid"], "preset", IsInRaid},
+ party = {L["Party"], "preset", function() return GetNumSubgroupMembers() > 0 end},
+ guild = {L["Guild"], "preset", IsInGuild},
+ officer = {L["Officer"], "preset", IsInGuild},
+ self = {L["Self"], "self"},
+ text = {L["Copy & Paste"], "text"}
+ }
+
+ -- what's the purpose of spamming these
+ -- channels other than flexing?
+ local ignored_channels = {
+ [L["[Trade]"]] = true,
+ [L["[General]"]] = true,
+ [L["[LocalDefense]"]] = true,
+ [L["[LookingForGroup]"]] = true
+ }
+
+ function build_report_channels()
+ local channels = TempTable()
+ for k, v in pairs(defaults) do
+ if (type(v[3]) == "function" and v[3]()) or type(v[3]) ~= "function" then
+ channels[k] = TempTable(v[1], v[2], v[3])
+ end
+ end
+
+ local list = TempTable(GetChannelList())
+ for i = 1, #list, 2 do
+ local channel = list[i + 1]
+ if channel and type(channel) ~= "boolean" and not ignored_channels[channel] then
+ channels[channel] = TempTable(format("%s: %d/%s", L["Channel"], list[i], channel), "channel")
+ end
+ end
+ list:free()
+ return channels
+ end
+ end
+
+ local function destroy_report_window()
+ if not Skada.reportwindow then return end
+
+ -- remove AceGUI hacks before recycling the widget
+ local frame = Skada.reportwindow
+ frame.LayoutFinished = frame.orig_LayoutFinished
+ frame.frame:EnableKeyboard(false)
+ frame:ReleaseChildren()
+ frame:Release()
+ Skada.reportwindow = nil
+
+ if not channellist then return end
+
+ for k, v in pairs(channellist) do
+ channellist[k] = v:free()
+ end
+ channellist = channellist:free()
+ end
+
+ local function create_report_window(window)
+ Skada.reportwindow = AceGUI:Create("Window")
+
+ local frame = Skada.reportwindow
+ frame:SetLayout("List")
+ frame:EnableResize(false)
+ frame:SetWidth(225)
+ frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
+
+ if window then
+ frame:SetTitle(format("%s - %s", L["Report"], window.db.name))
+ else
+ frame:SetTitle(L["Report"])
+ end
+
+ frame:SetCallback("OnClose", destroy_report_window)
+
+ -- make the frame closable with Escape button
+ _G.SkadaReportWindow = frame.frame
+ UISpecialFrames[#UISpecialFrames + 1] = "SkadaReportWindow"
+
+ -- slight AceGUI hack to auto-set height of Window widget:
+ frame.orig_LayoutFinished = frame.LayoutFinished
+ frame.LayoutFinished = function(self, _, height)
+ frame:SetHeight(height + 57)
+ end
+
+ local barid
+ if window then
+ Skada.profile.report.set = window.selectedset
+ Skada.profile.report.mode = window.db.mode
+
+ -- report a specific line
+ if window.selectedset and window.selectedmode then
+ local linebox = AceGUI:Create("Dropdown")
+ linebox:SetLabel(L["Line"])
+ linebox:SetList({[""] = L["None"]})
+
+ local dataset = window.dataset
+ for i = 1, #dataset do
+ local data = dataset[i]
+ if data and data.id and not data.ignore then
+ linebox:AddItem(data.id, format("%s %s", data.text or data.label, data.valuetext))
+ end
+ end
+ linebox:SetCallback("OnValueChanged", function(f, e, value) barid = (value ~= "") and value or nil end)
+ linebox:SetValue(barid or "")
+ frame:AddChild(linebox)
+ end
+ else
+ -- Mode, default last chosen or first available.
+ local modebox = AceGUI:Create("Dropdown")
+ modebox:SetLabel(L["Mode"])
+ modebox:SetList({})
+
+ for _, mode in pairs(modes)do
+ modebox:AddItem(mode.moduleName, mode.localeName)
+ end
+ modebox:SetCallback("OnValueChanged", function(f, e, value) Skada.profile.report.mode = value end)
+ modebox:SetValue(Skada.profile.report.mode or modes[1])
+ frame:AddChild(modebox)
+
+ -- Segment, default last chosen or last set.
+ local setbox = AceGUI:Create("Dropdown")
+ setbox:SetLabel(L["Segment"])
+ setbox:SetList({total = L["Total"], current = L["Current"]})
+ local sets = Skada.sets
+ for i = 1, #sets do
+ setbox:AddItem(i, sets[i].name)
+ end
+ setbox:SetCallback("OnValueChanged", function(f, e, value) Skada.profile.report.set = value end)
+ setbox:SetValue(Skada.profile.report.set or Skada.sets[1])
+ frame:AddChild(setbox)
+ end
+
+ channellist = build_report_channels()
+
+ -- Channel, default last chosen or Say.
+ local channelbox = AceGUI:Create("Dropdown")
+ channelbox:SetLabel(L["Channel"])
+ channelbox:SetList({})
+ for chan, kind in pairs(channellist) do
+ channelbox:AddItem(chan, kind[1])
+ end
+
+ local origchan = Skada.profile.report.channel or "say"
+ if not channellist[origchan] then
+ origchan = "say"
+ end
+
+ channelbox:SetValue(origchan)
+ channelbox:SetCallback("OnValueChanged", function(f, e, value)
+ Skada.profile.report.channel = value
+ Skada.profile.report.chantype = channellist[value][2]
+ if origchan ~= value then
+ -- redraw in-place to add/remove whisper widget
+ local point, relativeTo, relativePoint, xOfs, yOfs = frame:GetPoint()
+ destroy_report_window()
+ create_report_window(window)
+ Skada.reportwindow:SetPoint(point, relativeTo, relativePoint, xOfs, yOfs)
+ end
+ end)
+ frame:AddChild(channelbox)
+
+ local lines = AceGUI:Create("Slider")
+ lines:SetLabel(L["Lines"])
+ lines:SetValue(Skada.profile.report.number ~= nil and Skada.profile.report.number or 10)
+ lines:SetSliderValues(1, 25, 1)
+ lines:SetCallback("OnValueChanged", function(self, event, value)
+ Skada.profile.report.number = value
+ end)
+ lines:SetFullWidth(true)
+ frame:AddChild(lines)
+
+ if origchan == "whisper" then
+ local whisperbox = AceGUI:Create("EditBox")
+ whisperbox:SetLabel(L["Whisper Target"])
+ whisperbox:SetText(Skada.profile.report.target or "")
+
+ whisperbox:SetCallback("OnEnterPressed", function(box, event, text)
+ -- remove spaces which are always non-meaningful and can sometimes cause problems
+ if strlenutf8(text) == #text then
+ local ntext = text:gsub("%s", "")
+ if ntext ~= text then
+ text = ntext
+ whisperbox:SetText(text)
+ end
+ end
+ Skada.profile.report.target = text
+ frame.button.frame:Click()
+ end)
+
+ whisperbox:SetCallback("OnTextChanged", function(box, event, text)
+ Skada.profile.report.target = text
+ end)
+ whisperbox:SetFullWidth(true)
+ frame:AddChild(whisperbox)
+ end
+
+ local report = AceGUI:Create("Button")
+ frame.button = report
+ report:SetText(L["Report"])
+ report:SetCallback("OnClick", function()
+ do_report(window, barid)
+ end)
+
+ report:SetFullWidth(true)
+ frame:AddChild(report)
+ end
+
+ function Private.OpenReport(window)
+ if Skada.testMode then
+ return -- nothing to do.
+ elseif IsShiftKeyDown() then
+ do_report(window) -- quick report?
+ elseif Skada.reportwindow == nil then
+ create_report_window(window)
+ elseif Skada.reportwindow:IsShown() then
+ Skada.reportwindow:Hide()
+ else
+ Skada.reportwindow:Show()
+ end
+ end
+end
+
+function Skada:PhaseMenu(window)
+ if self.testMode or not self.tempsets or #self.tempsets == 0 then return end
+
+ local menu = _menu_phase
+ if not menu then
+ menu = CreateFrame("Frame", format("%sMenuPhase", folder), UIParent, "UIDropDownMenuTemplate")
+ menu.displayMode = "MENU"
+ _menu_phase = menu
+ end
+
+ menu.initialize = menu.initialize or function(self, level)
+ if not level then return end
+ info = info or UIDropDownMenu_CreateInfo()
+
+ for i = #Skada.tempsets, 1, -1 do
+ wipe(info)
+ local set = Skada.tempsets[i]
+ info.text = format(L["%s - Phase %s"], set.mobname or L["Unknown"], set.phase)
+ info.func = function()
+ if set.stopped then
+ Skada:ResumeSegment(nil, i)
+ else
+ Skada:StopSegment(nil, i)
+ end
+ end
+ info.notCheckable = 1
+ info.colorCode = set.stopped and "\124cffff1919"
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ wipe(info)
+ info.disabled = 1
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+
+ wipe(info)
+ info.text = L["All Segments"]
+ info.func = function()
+ if Skada.current.stopped then
+ Skada:ResumeSegment()
+ else
+ Skada:StopSegment()
+ end
+ end
+ info.colorCode = Skada.current.stopped and "\124cffff1919"
+ info.notCheckable = 1
+ UIDropDownMenu_AddButton(info, level)
+ end
+
+ local x, y
+ menu.point, _, x, y = get_dropdown_point()
+ ToggleDropDownMenu(1, nil, menu, "UIParent", x, y)
+end
+
+function Skada:CloseMenus()
+ CloseDropDownMenus()
+ if _menu_large then
+ _menu_large:Hide()
+ end
+end
diff --git a/Skada/Core/Options.lua b/Skada/Core/Options.lua
new file mode 100644
index 0000000..32be66f
--- /dev/null
+++ b/Skada/Core/Options.lua
@@ -0,0 +1,1689 @@
+local folder, Skada = ...
+local Private = Skada.Private
+
+local L = Skada.Locale
+local ACD = LibStub("AceConfigDialog-3.0")
+local ACR = LibStub("AceConfigRegistry-3.0")
+
+local min, max = math.min, math.max
+local next, format = next, format or string.format
+local wipe, del = wipe, Private.delTable
+local ConfirmDialog = Private.ConfirmDialog
+local _
+
+-- references: windows, modes
+local windows = Skada.windows
+local modes = Skada.modes
+
+Skada.windowdefaults = {
+ name = folder,
+ barspacing = 0,
+ bartexture = "BantoBar",
+ barfont = "Accidental Presidency",
+ barfontflags = "",
+ barfontsize = 13,
+ numfont = "Accidental Presidency",
+ numfontflags = "",
+ numfontsize = 13,
+ barheight = 18,
+ barwidth = 240,
+ baroffset = 0,
+ barorientation = 1,
+ barcolor = {r = 0.3, g = 0.3, b = 0.8, a = 1},
+ barbgcolor = {r = 0.3, g = 0.3, b = 0.3, a = 0.6},
+ spellschoolcolors = true,
+ classcolorbars = true,
+ classicons = true,
+ specicons = true,
+ spark = true,
+ -- buttons
+ buttons = {menu = true, reset = true, report = true, mode = true, segment = true},
+ -- title options
+ title = {
+ height = 20,
+ font = "Accidental Presidency",
+ fontsize = 13,
+ fontflags = "",
+ color = {r = 0.15, g = 0.15, b = 0.15, a = 1},
+ texture = "Armory",
+ textcolor = {r = 0.9, g = 0.9, b = 0.9, a = 1},
+ bordercolor = {r = 0, g = 0, b = 0, a = 1},
+ bordertexture = "None",
+ borderthickness = 2,
+ borderinsets = 0,
+ toolbar = 2,
+ spacing = 1
+ },
+ background = {
+ tilesize = 0,
+ color = {r = 0, g = 0, b = 0, a = 0.4},
+ texture = "Solid",
+ bordercolor = {r = 0, g = 0, b = 0, a = 0.5},
+ bordertexture = "None",
+ borderthickness = 1,
+ borderinsets = 0,
+ height = 200
+ },
+ strata = "LOW",
+ scale = 1,
+ modeincombat = "",
+ wipemode = "",
+ enabletitle = true,
+ titleset = true,
+ set = "current",
+ display = "bar",
+ child = "",
+ sticky = true,
+ clamped = true,
+ tooltippos = "NONE",
+ hideauto = 1,
+ -- inline bar display
+ isusingclasscolors = true,
+ height = 30,
+ width = 600,
+ color = {r = 0.3, g = 0.3, b = 0.3, a = 0.6},
+ isusingelvuiskin = true,
+ -- data broker display
+ textcolor = {r = 0.9, g = 0.9, b = 0.9},
+ useframe = true,
+ -- legacy display
+ baraltcolor = {r = 0.45, g = 0.45, b = 0.8, a = 1},
+ menubutton = true,
+ barmax = 10
+}
+
+local windefaultscopy = {}
+Private.tCopy(windefaultscopy, Skada.windowdefaults)
+
+Skada.defaults = {
+ profile = {
+ firsthit = true,
+ hidedisables = true,
+ informativetooltips = true,
+ memorycheck = true,
+ mergepets = true,
+ setnumber = true,
+ realmless = true,
+ showranks = true,
+ tooltips = true,
+ brackets = 1,
+ decimals = 1,
+ minsetlength = 5,
+ numberformat = 1,
+ numbersystem = 1,
+ separator = 1,
+ setformat = 3,
+ setslimit = 15,
+ setstokeep = 15,
+ smartwait = 3,
+ timemesure = 2,
+ tooltiprows = 3,
+ totalflag = 0x10,
+ updatefrequency = 0.5,
+ feed = "",
+ tooltippos = "smart",
+ columns = {},
+ icon = {radius = 80, minimapPos = 195},
+ modules = {},
+ report = {mode = "Damage", set = "current", channel = "Say", chantype = "preset", number = 10},
+ reset = {instance = 1, join = 3, leave = 1},
+ toast = {spawn_point = "BOTTOM", duration = 5, opacity = 0.75},
+ modulesBlocked = {
+ ["Absorbed Damage"] = true,
+ ["Avoidance & Mitigation"] = true,
+ ["CC Breaks"] = true,
+ ["Casts"] = true,
+ ["DTPS"] = true,
+ ["Damage Done By School"] = true,
+ ["Damage Done By Spell"] = true,
+ ["Enemy Buffs"] = true,
+ ["Enemy Debuffs"] = true,
+ ["Enemy Healing Done"] = true,
+ ["HPS"] = true,
+ ["Healing Done By Spell"] = true,
+ ["Healing Taken"] = true,
+ ["Healthstones"] = true,
+ ["Improvement"] = true,
+ ["Killing Blows"] = true,
+ ["My Spells"] = true,
+ ["Overhealing"] = true,
+ ["Overkill"] = true,
+ ["Player vs. Player"] = true,
+ ["Themes"] = true,
+ ["Total Healing"] = true,
+ ["Useful Damage"] = true,
+ -- display systems
+ ["Inline Bar Display"] = true,
+ ["Legacy Bar Display"] = true,
+ ["Data Text"] = true
+ },
+ windows = {windefaultscopy}
+ }
+}
+
+-------------------------------------------------------------------------------
+
+local optionsValues = {
+ RESETOPT = {
+ L["No"], -- [1]
+ L["Yes"], -- [2]
+ L["Ask"], -- [3]
+ },
+ STRATA = {
+ BACKGROUND = "BACKGROUND",
+ LOW = "LOW",
+ MEDIUM = "MEDIUM",
+ HIGH = "HIGH",
+ DIALOG = "DIALOG",
+ FULLSCREEN = "FULLSCREEN",
+ FULLSCREEN_DIALOG = "FULLSCREEN_DIALOG"
+ },
+ AUTOHIDE = {
+ L["None"], -- [1]
+ L["While in combat"], -- [2]
+ L["While out of combat"], -- [3]
+ L["While not in a group"], -- [4]
+ L["While inside an instance"], -- [5]
+ L["While not inside an instance"], -- [6]
+ L["In Battlegrounds"], -- [7]
+ },
+ CHILDMODE = {
+ L["All"], -- [1]
+ L["Segment"], -- [2]
+ L["Mode"], -- [3]
+ },
+ TOOLTIPPOS = {
+ NONE = L["None"],
+ BOTTOM = L["Bottom"],
+ BOTTOMLEFT = L["Bottom Left"],
+ BOTTOMRIGHT = L["Bottom Right"],
+ TOP = L["Top"],
+ TOPLEFT = L["Top Left"],
+ TOPRIGHT = L["Top Right"],
+ }
+}
+
+local newdisplay = "bar"
+local newwindow = nil
+
+local options = Skada.options
+
+options.get = function(info)
+ return Skada.profile[info[#info]]
+end
+
+options.set = function(info, value)
+ local key = info[#info]
+ Skada.profile[key] = value
+ Skada:ApplySettings()
+
+ if key == "showtotals" then
+ Skada:Wipe()
+ Skada:UpdateDisplay(true)
+ elseif key == "syncoff" then
+ Skada:RegisterComms(value ~= true)
+ elseif key == "setstokeep" or key == "setslimit" then
+ Skada.maxsets = Skada.profile.setstokeep + Skada.profile.setslimit
+ Skada.maxmeme = min(60, max(30, Skada.maxsets + 10))
+ elseif key == "sortmodesbyusage" then
+ if not value then -- clear the table.
+ Skada.profile.modeclicks = del(Skada.profile.modeclicks)
+ end
+ end
+end
+
+-- windows options
+local tremove = Private.tremove
+local function delete_all_windows()
+ local win = tremove(windows)
+ while win do
+ win:Destroy()
+ win = tremove(windows)
+ end
+
+ local wins = Skada.profile.windows
+ win = tremove(wins)
+ while win do
+ Skada.options.args.windows.args[win.name] = del(Skada.options.args.windows.args[win.name], true)
+ win = tremove(wins)
+ end
+ Skada:NotifyChange()
+ Skada:CleanGarbage()
+end
+
+options.args.windows = {
+ type = "group",
+ name = L["Windows"],
+ desc = format(L["Options for %s."], L["Windows"]),
+ order = 10,
+ args = {
+ create = {
+ type = "group",
+ name = L["Create Window"],
+ inline = true,
+ order = 0,
+ args = {
+ name = {
+ type = "input",
+ name = L["Window Name"],
+ desc = L["Enter the name for the new window."],
+ order = 10,
+ get = function() return newwindow end,
+ set = function(_, value)
+ if value and value:trim() ~= "" then
+ newwindow = value
+ end
+ end
+ },
+ display = {
+ type = "select",
+ name = L["Display System"],
+ desc = L["Choose the system to be used for displaying data in this window."],
+ order = 20,
+ values = function()
+ local list = {}
+ for name, display in next, Skada.displays do
+ list[name] = display.localeName
+ end
+ return list
+ end,
+ get = function()
+ return newdisplay
+ end,
+ set = function(_, display)
+ newdisplay = display
+ end
+ },
+ exec = {
+ type = "execute",
+ name = L["Create"],
+ width = "double",
+ order = 30,
+ disabled = function() return (newdisplay == nil or newwindow == nil) end,
+ func = function()
+ if newdisplay and newwindow then
+ Skada:CreateWindow(newwindow, nil, newdisplay)
+ newdisplay = "bar"
+ newwindow = nil
+ end
+ end
+ }
+ }
+ },
+ delete = {
+ type = "execute",
+ name = L["Delete All Windows"],
+ width = "full",
+ order = 1,
+ disabled = function() return (not windows or #windows <= 0) end,
+ func = function()
+ ConfirmDialog(L["Are you sure you want to delete all windows?"], delete_all_windows)
+ end
+ }
+ }
+}
+
+-- general options
+options.args.generaloptions = {
+ type = "group",
+ name = L["General Options"],
+ desc = format(L["Options for %s."], L["General Options"]),
+ childGroups = "tab",
+ order = 20,
+ args = {
+ general = {
+ type = "group",
+ name = L["General"],
+ desc = format(L["General options for %s."], folder),
+ order = 10,
+ args = {
+ mmbutton = {
+ type = "toggle",
+ name = L["Show minimap button"],
+ desc = L["Toggles showing the minimap button."],
+ order = 10,
+ get = function()
+ return not Skada.profile.icon.hide
+ end,
+ set = function()
+ Skada.profile.icon.hide = not Skada.profile.icon.hide
+ Private.RefreshButton()
+ end
+ },
+ mergepets = {
+ type = "toggle",
+ name = L["Merge pets"],
+ desc = L["Merges pets with their owners. Changing this only affects new data."],
+ order = 20
+ },
+ showtotals = {
+ type = "toggle",
+ name = L["Show totals"],
+ desc = L["Shows a extra row with a summary in certain modes."],
+ order = 30
+ },
+ onlykeepbosses = {
+ type = "toggle",
+ name = L["Only keep boss fighs"],
+ desc = L["Boss fights will be kept with this on, and non-boss fights are discarded."],
+ order = 40
+ },
+ alwayskeepbosses = {
+ type = "toggle",
+ name = L["Always save boss fights"],
+ desc = L["Boss fights will be kept with this on and will not be affected by Skada reset."],
+ order = 50
+ },
+ hidesolo = {
+ type = "toggle",
+ name = L["Hide when solo"],
+ desc = L["Hides Skada's window when not in a party or raid."],
+ order = 60
+ },
+ hidepvp = {
+ type = "toggle",
+ name = L["Hide in PvP"],
+ desc = L["Hides Skada's window when in Battlegrounds/Arenas."],
+ order = 70
+ },
+ hidecombat = {
+ type = "toggle",
+ name = L["Hide in combat"],
+ desc = L["Hides Skada's window when in combat."],
+ order = 80,
+ set = function(_, value)
+ Skada.profile.hidecombat = value or nil
+ if Skada.profile.hidecombat then
+ Skada.profile.showcombat = nil
+ end
+ Skada:ApplySettings()
+ end
+ },
+ showcombat = {
+ type = "toggle",
+ name = L["Show in combat"],
+ desc = L["Shows Skada's window when in combat."],
+ order = 90,
+ set = function(_, value)
+ Skada.profile.showcombat = value or nil
+ if Skada.profile.showcombat then
+ Skada.profile.hidecombat = nil
+ end
+ Skada:ApplySettings()
+ end
+ },
+ hidedisables = {
+ type = "toggle",
+ name = L["Disable while hidden"],
+ desc = L["Skada will not collect any data when automatically hidden."],
+ order = 100
+ },
+ sortmodesbyusage = {
+ type = "toggle",
+ name = L["Sort modes by usage"],
+ desc = L["The mode list will be sorted to reflect usage instead of alphabetically."],
+ order = 110
+ },
+ showranks = {
+ type = "toggle",
+ name = L["Show rank numbers"],
+ desc = L["Shows numbers for relative ranks for modes where it is applicable."],
+ order = 120
+ },
+ showself = {
+ type = "toggle",
+ name = L["Always show self"],
+ desc = L["opt_showself_desc"],
+ order = 130
+ },
+ reportlinks = {
+ type = "toggle",
+ name = L["Links in reports"],
+ desc = L["When possible, use links in the report messages."],
+ order = 140
+ },
+ autostop = {
+ type = "toggle",
+ name = L["Autostop"],
+ desc = L["opt_autostop_desc"],
+ order = 150
+ },
+ tentativecombatstart = {
+ type = "toggle",
+ name = L["Aggressive combat detection"],
+ desc = L["opt_tentativecombatstart_desc"],
+ order = 160
+ },
+ sep_850 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 850
+ },
+ tooltips = {
+ type = "group",
+ name = L["Tooltips"],
+ desc = format(L["Options for %s."], L["Tooltips"]),
+ inline = true,
+ order = 900,
+ args = {
+ tooltips = {
+ type = "toggle",
+ name = L["Show Tooltips"],
+ desc = L["Shows tooltips with extra information in some modes."],
+ order = 1
+ },
+ informativetooltips = {
+ type = "toggle",
+ name = L["Informative Tooltips"],
+ desc = L["Shows subview summaries in the tooltips."],
+ order = 2,
+ disabled = function()
+ return not Skada.profile.tooltips
+ end
+ },
+ tooltiprows = {
+ type = "range",
+ name = L["Subview Rows"],
+ desc = L["The number of rows from each subview to show when using informative tooltips."],
+ order = 3,
+ min = 1,
+ max = 10,
+ step = 1,
+ disabled = function()
+ return not Skada.profile.tooltips
+ end
+ },
+ tooltippos = {
+ type = "select",
+ name = L["Tooltip Position"],
+ desc = L["Position of the tooltips."],
+ order = 4,
+ values = {
+ ["default"] = L["Default"],
+ ["smart"] = L["Smart"],
+ ["topright"] = L["Top Right"],
+ ["topleft"] = L["Top Left"],
+ ["bottomright"] = L["Bottom Right"],
+ ["bottomleft"] = L["Bottom Left"],
+ ["cursor"] = L["Follow Cursor"]
+ },
+ disabled = function()
+ return not Skada.profile.tooltips
+ end
+ }
+ }
+ }
+ }
+ },
+ format = {
+ type = "group",
+ name = L["Format"],
+ desc = format(L["Format options for %s."], folder),
+ order = 20,
+ args = {
+ numberformat = {
+ type = "select",
+ name = L["Number format"],
+ desc = L["Controls the way large numbers are displayed."],
+ values = {[1] = L["Condensed"], [2] = L["Comma"], [3] = L["Detailed"]},
+ order = 10
+ },
+ numbersystem = {
+ type = "select",
+ name = L["Numeral system"],
+ desc = L["Select which numeral system to use."],
+ values = {[1] = L["Auto"], [2] = L["Western"], [3] = L["East Asia"]},
+ order = 20
+ },
+ brackets = {
+ type = "select",
+ name = L["Brackets"],
+ desc = L["Choose which type of brackets to use."],
+ values = {"(", "{", "[", "<", L["None"]},
+ order = 30
+ },
+ separator = {
+ type = "select",
+ name = L["Separator"],
+ desc = L["Choose which character is used to separator values between brackets."],
+ values = {",", ".", ";", "-", "\124", "/", "\\", "~", L["None"]},
+ order = 40
+ },
+ decimals = {
+ type = "range",
+ name = L["Number of decimals"],
+ desc = L["Controls the way percentages are displayed."],
+ min = 0,
+ max = 3,
+ step = 1,
+ width = "double",
+ order = 50
+ },
+ setformat = {
+ type = "select",
+ name = L["Set Format"],
+ desc = L["Controls the way set names are displayed."],
+ width = "double",
+ values = Skada:SetLabelFormats(),
+ order = 60
+ },
+ setnumber = {
+ type = "toggle",
+ name = L["Number set duplicates"],
+ desc = L["Append a count to set names with duplicate mob names."],
+ order = 70
+ },
+ translit = {
+ type = "toggle",
+ name = L["Transliterate"],
+ desc = L["Converts Cyrillic letters into Latin letters."],
+ order = 80
+ },
+ realmless = {
+ type = "toggle",
+ name = L["Remove realm name"],
+ desc = L["opt_realmless_desc"],
+ order = 90
+ }
+ }
+ },
+ advanced = {
+ type = "group",
+ name = L["Advanced"],
+ desc = format(L["Advanced options for %s."], folder),
+ order = 30,
+ args = {
+ timemesure = {
+ type = "select",
+ name = L["Time Measure"],
+ desc = L["opt_timemesure_desc"],
+ values = {[1] = L["Activity Time"], [2] = L["Effective Time"]},
+ order = 10
+ },
+ feed = {
+ type = "select",
+ name = L["Data Feed"],
+ desc = L["opt_feed_desc"],
+ values = function()
+ local list = {[""] = L["None"]}
+ local feeds = Skada:GetFeeds()
+ for name in next, feeds do
+ list[name] = name
+ end
+ return list
+ end,
+ order = 20
+ },
+ setscount = {
+ type = "header",
+ name = function() return format("%s: \124cffffffff%d\r", L["All Segments"], Skada.maxsets) end,
+ order = 200
+ },
+ setstokeep = {
+ type = "range",
+ name = L["Segments to keep"],
+ desc = L["The number of fight segments to keep. Persistent segments are not included in this."],
+ min = 0,
+ max = 25,
+ step = 1,
+ order = 210
+ },
+ setslimit = {
+ type = "range",
+ name = L["Persistent segments"],
+ desc = L["The number of persistent fight segments to keep."],
+ min = 0,
+ max = 25,
+ step = 1,
+ order = 220
+ },
+ empty_1 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 300
+ },
+ updatefrequency = {
+ type = "range",
+ name = L["Update frequency"],
+ desc = L["How often windows are updated. Shorter for faster updates. Increases CPU usage."],
+ min = 0.05,
+ max = 3,
+ step = 0.01,
+ order = 310
+ },
+ minsetlength = {
+ type = "range",
+ name = L["Minimum segment length"],
+ desc = L["The minimum length required in seconds for a segment to be saved."],
+ min = 3,
+ max = 30,
+ step = 1,
+ order = 320
+ },
+ empty_2 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 400
+ },
+ memorycheck = {
+ type = "toggle",
+ name = L["Memory Check"],
+ desc = function() return format(L["Checks memory usage and warns you if it is greater than or equal to %dmb."], Skada.maxmeme) end,
+ order = 410
+ },
+ syncoff = {
+ type = "toggle",
+ name = L["Disable Comms"],
+ order = 420
+ }
+ }
+ }
+ }
+}
+
+-- columns options
+options.args.columns = {
+ type = "group",
+ name = L["Columns"],
+ desc = format(L["Options for %s."], L["Columns"]),
+ childGroups = "select",
+ order = 30,
+ args = {}
+}
+
+-- rest options
+options.args.resetoptions = {
+ type = "group",
+ name = L["Data Resets"],
+ desc = format(L["Options for %s."], L["Data Resets"]),
+ order = 40,
+ get = function(info)
+ return Skada.profile.reset[info[#info]]
+ end,
+ set = function(info, value)
+ Skada.profile.reset[info[#info]] = value
+ end,
+ args = {
+ instance = {
+ type = "select",
+ name = L["Reset on entering instance"],
+ desc = L["Controls if data is reset when you enter an instance."],
+ order = 1,
+ width = "double",
+ values = optionsValues.RESETOPT
+ },
+ join = {
+ type = "select",
+ name = L["Reset on joining a group"],
+ desc = L["Controls if data is reset when you join a group."],
+ order = 2,
+ width = "double",
+ values = optionsValues.RESETOPT
+ },
+ leave = {
+ type = "select",
+ name = L["Reset on leaving a group"],
+ desc = L["Controls if data is reset when you leave a group."],
+ order = 3,
+ width = "double",
+ values = optionsValues.RESETOPT
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ order = 4,
+ width = "full"
+ },
+ skippopup = {
+ type = "toggle",
+ name = L["Skip reset dialog"],
+ desc = L["opt_skippopup_desc"],
+ descStyle = "inline",
+ order = 5,
+ width = "double",
+ get = options.get,
+ set = options.set
+ }
+ }
+}
+
+-- modules options
+options.args.modules = {
+ type = "group",
+ name = L["Modules Options"],
+ desc = format(L["Options for %s."], L["Modules"]),
+ order = 50,
+ width = "double",
+ get = function(info)
+ return Skada.profile.modules[info[#info]]
+ end,
+ set = function(info, value)
+ Skada.profile.modules[info[#info]] = value or nil
+ Skada:ApplySettings()
+ end,
+ args = {
+ header = {
+ type = "header",
+ name = L["Disabled Modules"],
+ order = 10
+ },
+ apply = {
+ type = "execute",
+ name = L["Apply"],
+ width = "full",
+ func = ReloadUI,
+ confirm = function() return L["This change requires a UI reload. Are you sure?"] end,
+ disabled = true,
+ order = 20
+ },
+ blocked = {
+ type = "group",
+ name = L["Tick the modules you want to disable."],
+ inline = true,
+ order = 30,
+ get = function(info)
+ Skada.profile.modulesBlocked = Skada.profile.modulesBlocked or {}
+ return Skada.profile.modulesBlocked[info[#info]]
+ end,
+ set = function(info, value)
+ Skada.profile.modulesBlocked[info[#info]] = value
+ options.args.modules.args.apply.disabled = nil
+ end,
+ args = {
+ modes_header = {
+ type = "header",
+ name = L["Skada: Modes"],
+ order = 0
+ },
+ display_header = {
+ type = "header",
+ name = L["Display System"],
+ order = 900
+ }
+ }
+ },
+ enableall = {
+ type = "execute",
+ name = L["Enable All"],
+ func = function()
+ for name in pairs(options.args.modules.args.blocked.args) do
+ if Skada.defaults.profile.modulesBlocked[name] then
+ Skada.profile.modulesBlocked[name] = false
+ else
+ Skada.profile.modulesBlocked[name] = nil
+ end
+ end
+ options.args.modules.args.apply.disabled = nil
+ end,
+ order = 40,
+ },
+ disable = {
+ type = "execute",
+ name = L["Disable All"],
+ func = function()
+ for name in pairs(options.args.modules.args.blocked.args) do
+ Skada.profile.modulesBlocked[name] = true
+ end
+ options.args.modules.args.apply.disabled = nil
+ end,
+ order = 50,
+ }
+ }
+}
+
+-- tweaks options
+options.args.tweaks = {
+ type = "group",
+ name = L["Tweaks"],
+ desc = format(L["Options for %s."], L["Tweaks"]),
+ childGroups = "tab",
+ order = 950,
+ args = {
+ general = {
+ type = "group",
+ name = L["General"],
+ desc = format(L["General options for %s."], L["Tweaks"]),
+ order = 10,
+ args = {
+ firsthit = {
+ type = "toggle",
+ name = L["First hit"],
+ desc = L["opt_tweaks_firsthit_desc"],
+ order = 10
+ },
+ absdamage = {
+ type = "toggle",
+ name = L["Absorbed Damage"],
+ desc = L["Enable this if you want the damage absorbed to be included in the damage done."],
+ order = 100
+ }
+ }
+ },
+ advanced = {
+ type = "group",
+ name = L["Advanced"],
+ desc = format(L["Advanced options for %s."], L["Tweaks"]),
+ order = 900,
+ args = {
+ smarthalt = {
+ type = "group",
+ name = L["Smart Stop"],
+ desc = format(L["Options for %s."], L["Smart Stop"]),
+ order = 10,
+ args = {
+ smartdesc = {
+ type = "description",
+ name = L["opt_tweaks_smarthalt_desc"],
+ fontSize = "medium",
+ order = 10,
+ width = "full"
+ },
+ smartstop = {
+ type = "toggle",
+ name = L["Enable"],
+ order = 20
+ },
+ smartwait = {
+ type = "range",
+ name = L["Duration"],
+ desc = L["opt_tweaks_smartwait_desc"],
+ disabled = function()
+ return not Skada.profile.smartstop
+ end,
+ min = 0,
+ max = 10,
+ step = 0.01,
+ bigStep = 0.1,
+ order = 30
+ }
+ }
+ },
+ toast_opt = Private.ToastOptions(),
+ total_opt = Private.TotalOptions()
+ }
+ }
+ }
+}
+
+-- profiles
+options.args.profiles = {
+ type = "group",
+ name = L["Profiles"],
+ desc = format(L["Options for %s."], L["Profiles"]),
+ childGroups = "tab",
+ order = 1000,
+ args = {}
+}
+
+-- initial options for blizzard interface options
+do
+ local GetAddOnMetadata = GetAddOnMetadata
+ local initOptions
+
+ local function get_init_options()
+ if not initOptions then
+ initOptions = {
+ type = "group",
+ name = format("\124T%s:18:18:0:0:32:32:2:30:2:30\124t \124cffffd200Skada\124r \124cffffffff%s\124r", Skada.logo, L["A damage meter."]),
+ args = {
+ open = {
+ type = "execute",
+ name = L["Open Config"],
+ width = "full",
+ order = 0,
+ func = Private.OpenOptions
+ },
+ version = {
+ type = "description",
+ name = format("\n\124cffffd200%s\124r: %s", L["Version"], Skada.version),
+ fontSize = "medium",
+ width = "double",
+ order = 10
+ },
+ date = {
+ type = "description",
+ name = format("\n\124cffffd200%s\124r: %s", L["Date"], Skada.date),
+ fontSize = "medium",
+ width = "double",
+ order = 20
+ },
+ author = {
+ type = "description",
+ name = format("\n\124cffffd200%s\124r: %s", L["Author"], Skada.author),
+ fontSize = "medium",
+ width = "double",
+ order = 30
+ },
+ license = {
+ type = "description",
+ name = format("\n\124cffffd200%s\124r: %s", L["License"], GetAddOnMetadata(folder, "X-License")),
+ fontSize = "medium",
+ width = "double",
+ order = 40
+ },
+ credits = {
+ type = "description",
+ name = format("\n\124cffffd200%s\124r: %s", L["Credits"], GetAddOnMetadata(folder, "X-Credits")),
+ fontSize = "medium",
+ width = "double",
+ order = 50
+ }
+ }
+ }
+ end
+ return initOptions
+ end
+
+ function Private.InitOptions()
+ Private.InitOptions = nil -- remove it
+
+ local frame_name = format("%s Dialog", folder)
+ LibStub("AceConfig-3.0"):RegisterOptionsTable(frame_name, get_init_options)
+ Skada.optionsFrame = ACD:AddToBlizOptions(frame_name, folder)
+ end
+end
+
+function Private.OpenOptions(win)
+ if not ACR:GetOptionsTable(folder) then
+ LibStub("AceConfig-3.0"):RegisterOptionsTable(folder, options)
+ ACD:SetDefaultSize(folder, 630, 500)
+ end
+
+ if not ACD:Close(folder) then
+ HideUIPanel(InterfaceOptionsFrame)
+ HideUIPanel(GameMenuFrame)
+ Skada:CloseMenus()
+
+ ACD:Open(folder)
+ if type(win) == "table" and win.db then
+ ACD:SelectGroup(folder, "windows", win.db.name)
+ else
+ ACD:SelectGroup(folder, type(win) == "string" and win or "generaloptions")
+ end
+ end
+end
+
+-- Adds column configuration options for a mode.
+do
+ local col_order = {
+ APS = 6, DPS = 6, DTPS = 6, HPS = 6, TPS = 6,
+ Percent = 7,
+ sAPS = 8, sDPS = 8, sDTPS = 8, sHPS = 8,
+ sPercent = 9
+ }
+ function Skada:AddColumnOptions(mod)
+ local metadata = mod and mod.metadata
+ local columns = metadata and metadata.columns
+ if not columns then return end
+
+ local db = self.profile.columns
+ local category = mod.category or "Other"
+
+ if not options.args.columns.args[category] then
+ options.args.columns.args[category] = {type = "group", name = L[category], args = {}}
+ end
+
+ local moduleName = mod.localeName
+ if metadata.icon or mod.icon then
+ moduleName = format("\124T%s:18:18:-5:0:32:32:2:30:2:30\124t %s", metadata.icon or mod.icon, moduleName)
+ end
+
+ local cols = {
+ type = "group",
+ name = moduleName,
+ inline = true,
+ get = function(info)
+ return columns[info[#info]]
+ end,
+ set = function(info, value)
+ local colname = info[#info]
+ columns[colname] = value
+ db[format("%s_%s", mod.name, colname)] = value
+ Skada:UpdateDisplay(true)
+ end,
+ args = {}
+ }
+
+ local order = 0
+ for colname in next, columns do
+ local c = format("%s_%s", mod.name, colname)
+
+ -- Set initial value from db if available, otherwise use mod default value.
+ if db[c] ~= nil then
+ columns[colname] = db[c]
+ end
+
+ -- Add column option.
+ local col = {type = "toggle", name = _G[colname] or L[colname]}
+
+ -- proper and reasonable columns order.
+ if col_order[colname] then
+ col.order = col_order[colname]
+ else
+ order = order + 1
+ col.order = order
+ end
+
+ cols.args[colname] = col
+ end
+
+ options.args.columns.args[category].args[mod.name] = cols
+ end
+end
+
+-------------------------------------------------------------------------------
+-- frame/window options
+
+do
+ local get_screen_width
+ do
+ local floor = math.floor
+ local GetScreenWidth = GetScreenWidth
+ local screenWidth = nil
+ function get_screen_width()
+ screenWidth = screenWidth or floor(GetScreenWidth() * 0.05) * 20
+ return screenWidth
+ end
+ end
+
+ local modesList, modeValues
+ function Private.FrameOptions(db, include_dimensions)
+ if not modeValues then
+ modeValues = function()
+ if not modesList then
+ modesList = {[""] = L["None"]}
+ for i = 1, #modes do
+ if modes[i] then
+ modesList[modes[i].moduleName] = modes[i].localeName
+ end
+ end
+ end
+ return modesList
+ end
+ end
+
+ local obj = {
+ type = "group",
+ name = L["Window"],
+ desc = format(L["Options for %s."], L["Window"]),
+ childGroups = "tab",
+ order = 30,
+ get = function(info)
+ return db[info[#info]]
+ end,
+ set = function(info, value)
+ db[info[#info]] = value
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ appearance = {
+ type = "group",
+ name = L["Appearance"],
+ desc = format(L["Appearance options for %s."], db.name),
+ order = 10,
+ args = {
+ scale = {
+ type = "range",
+ name = L["Scale"],
+ desc = L["Sets the scale of the window."],
+ order = 10,
+ width = "double",
+ min = 0.5,
+ max = 2,
+ step = 0.01,
+ isPercent = true
+ },
+ background = {
+ type = "group",
+ name = L["Background"],
+ inline = true,
+ order = 20,
+ get = function(info)
+ return db.background[info[#info]]
+ end,
+ set = function(info, value)
+ db.background[info[#info]] = value
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ texture = {
+ type = "select",
+ dialogControl = "LSM30_Background",
+ name = L["Background Texture"],
+ desc = L["The texture used as the background."],
+ order = 10,
+ width = "double",
+ values = Skada:MediaList("background")
+ },
+ color = {
+ type = "color",
+ name = L["Background Color"],
+ desc = L["The color of the background."],
+ order = 20,
+ hasAlpha = true,
+ get = function()
+ local c = db.background.color or Skada.windowdefaults.background.color
+ return c.r, c.g, c.b, c.a
+ end,
+ set = function(_, r, g, b, a)
+ db.background.color = db.background.color or {}
+ db.background.color.r = r
+ db.background.color.g = g
+ db.background.color.b = b
+ db.background.color.a = a
+ Skada:ApplySettings(db.name)
+ end
+ },
+ tile = {
+ type = "toggle",
+ name = L["Tile"],
+ desc = L["Tile the background texture."],
+ order = 30
+ },
+ tilesize = {
+ type = "range",
+ name = L["Tile Size"],
+ desc = L["The size of the texture pattern."],
+ order = 40,
+ width = "double",
+ min = 0,
+ max = get_screen_width(),
+ step = 0.1,
+ bigStep = 1
+ }
+ }
+ },
+ border = {
+ type = "group",
+ name = L["Border"],
+ inline = true,
+ order = 30,
+ get = function(info)
+ return db.background[info[#info]]
+ end,
+ set = function(info, value)
+ db.background[info[#info]] = value
+ Skada:ApplySettings(db.name)
+ end,
+ args = {
+ bordertexture = {
+ type = "select",
+ dialogControl = "LSM30_Border",
+ name = L["Border texture"],
+ desc = L["The texture used for the borders."],
+ order = 10,
+ values = Skada:MediaList("border"),
+ set = function(_, key)
+ db.background.bordertexture = key
+ if key == "None" then
+ db.background.borderthickness = 0
+ db.background.borderinsets = 0
+ end
+ Skada:ApplySettings(db.name)
+ end
+ },
+ bordercolor = {
+ type = "color",
+ name = L["Border Color"],
+ desc = L["The color used for the border."],
+ order = 20,
+ hasAlpha = true,
+ get = function()
+ local c = db.background.bordercolor or Skada.windowdefaults.background.bordercolor
+ return c.r, c.g, c.b, c.a
+ end,
+ set = function(_, r, g, b, a)
+ db.background.bordercolor = db.background.bordercolor or {}
+ db.background.bordercolor.r = r
+ db.background.bordercolor.g = g
+ db.background.bordercolor.b = b
+ db.background.bordercolor.a = a
+ Skada:ApplySettings(db.name)
+ end
+ },
+ borderthickness = {
+ type = "range",
+ name = L["Border Thickness"],
+ desc = L["The thickness of the borders."],
+ order = 30,
+ min = 0,
+ max = 50,
+ step = 0.01,
+ bigStep = 0.5
+ },
+ borderinsets = {
+ type = "range",
+ name = L["Border Insets"],
+ desc = L["The distance between the window and its border."],
+ order = 40,
+ min = -32,
+ max = 32,
+ step = 0.01,
+ bigStep = 1
+ }
+ }
+ }
+ }
+ },
+ position = {
+ type = "group",
+ name = L["Position"],
+ desc = format(L["Position settings for %s."], db.name),
+ order = 20,
+ args = {
+ barslocked = {
+ type = "toggle",
+ name = L["Lock Window"],
+ desc = L["Locks the bar window in place."],
+ order = 10
+ },
+ hidden = {
+ type = "toggle",
+ name = L["Hide Window"],
+ desc = L["Hides the window."],
+ order = 20
+ },
+ clamped = {
+ type = "toggle",
+ name = L["Clamped To Screen"],
+ desc = L["Toggle whether to permit movement out of screen."],
+ order = 50
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 60
+ },
+ strata = {
+ type = "select",
+ name = L["Strata"],
+ desc = L["This determines what other frames will be in front of the frame."],
+ order = 110,
+ values = optionsValues.STRATA
+ },
+ tooltippos = {
+ type = "select",
+ name = L["Tooltip Position"],
+ desc = L["Position of the tooltips."],
+ order = 120,
+ values = optionsValues.TOOLTIPPOS,
+ get = function()
+ return db.tooltippos or "NONE"
+ end
+ },
+ hideauto = {
+ type = "select",
+ name = L["Auto Hide"],
+ values = optionsValues.AUTOHIDE,
+ width = "double",
+ order = 999
+ }
+ }
+ },
+ advanced = {
+ type = "group",
+ name = L["Advanced"],
+ desc = format(L["Advanced options for %s."], db.name),
+ order = 30,
+ args = {
+ switch = {
+ type = "group",
+ name = L["Mode Switching"],
+ desc = format(L["Options for %s."], L["Mode Switching"]),
+ inline = true,
+ order = 10,
+ args = {
+ modeincombat = {
+ type = "select",
+ name = L["Combat Mode"],
+ desc = L["opt_combatmode_desc"],
+ order = 10,
+ values = modeValues
+ },
+ wipemode = {
+ type = "select",
+ name = L["Wipe Mode"],
+ desc = L["opt_wipemode_desc"],
+ order = 20,
+ values = modeValues
+ },
+ returnaftercombat = {
+ type = "toggle",
+ name = L["Return after combat"],
+ desc = L["Return to the previous set and mode after combat ends."],
+ order = 30,
+ disabled = function() return (db.modeincombat == "" and db.wipemode == "") end
+ },
+ autocurrent = {
+ type = "toggle",
+ name = L["Auto switch to current"],
+ desc = L["opt_autocurrent_desc"],
+ order = 40
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if db.display == "bar" then
+ obj.args.position.args.sticky = {
+ type = "toggle",
+ name = L["Sticky Window"],
+ desc = L["Allows the window to stick to other Skada windows."],
+ order = 30,
+ set = function(_, value)
+ db.sticky = value
+ if not db.sticky then
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.sticked then
+ if win.db.sticked[db.name] then
+ win.db.sticked[db.name] = nil
+ end
+ if next(win.db.sticked) == nil then
+ win.db.sticked = del(win.db.sticked)
+ end
+ end
+ end
+ end
+ Skada:ApplySettings(db.name)
+ end
+ }
+
+ obj.args.position.args.snapto = {
+ type = "toggle",
+ name = L["Snap to best fit"],
+ desc = L["Snaps the window size to best fit when resizing."],
+ order = 40
+ }
+
+ obj.args.position.args.noresize = {
+ type = "toggle",
+ name = L["Disable Resize Buttons"],
+ desc = L["Resize and lock/unlock buttons won't show up when you hover over the window."],
+ order = 51
+ }
+
+ obj.args.position.args.nostrech = {
+ type = "toggle",
+ name = L["Disable stretch button"],
+ desc = L["Stretch button won't show up when you hover over the window."],
+ order = 52
+ }
+
+ obj.args.position.args.botstretch = {
+ type = "toggle",
+ name = L["Reverse window stretch"],
+ desc = L["opt_botstretch_desc"],
+ order = 53
+ }
+
+ obj.args.advanced.args.childoptions = {
+ type = "group",
+ name = L["Child Window"],
+ inline = true,
+ order = 100,
+ args = {
+ desc = {
+ type = "description",
+ name = L["A child window will replicate the parent window actions."],
+ width = "full",
+ order = 0
+ },
+ child = {
+ type = "select",
+ name = L["Window"],
+ order = 10,
+ values = function()
+ local list = {[""] = L["None"]}
+ for i = 1, #windows do
+ local win = windows[i]
+ if win and win.db and win.db.name ~= db.name and win.db.child ~= db.name and win.db.display == db.display then
+ list[win.db.name] = win.db.name
+ end
+ end
+ return list
+ end,
+ get = function() return db.child or "" end,
+ set = function(_, child)
+ db.child = (child == "") and nil or child
+ db.childmode = db.child and (db.childmode or 1) or nil
+ Private.ReloadSettings()
+ end
+ },
+ childmode = {
+ type = "select",
+ name = L["Child Window Mode"],
+ order = 20,
+ values = optionsValues.CHILDMODE,
+ get = function() return db.childmode or 1 end,
+ disabled = function() return not (db.child and db.child ~= "") end
+ }
+ }
+ }
+ end
+
+ if include_dimensions then
+ obj.args.position.args.width = {
+ type = "range",
+ name = L["Width"],
+ order = 70,
+ min = 100,
+ max = get_screen_width(),
+ step = 0.01,
+ bigStep = 1
+ }
+
+ obj.args.position.args.height = {
+ type = "range",
+ name = L["Height"],
+ order = 80,
+ min = 16,
+ max = 400,
+ step = 0.01,
+ bigStep = 1
+ }
+ end
+
+ return obj
+ end
+end
+
+-------------------------------------------------------------------------------
+-- profile import, export and sharing
+
+do
+ local ipairs, strmatch, uformat, collectgarbage = ipairs, strmatch, Private.uformat, collectgarbage
+ local serialize, deserialize = Private.serialize, Private.deserialize
+ local copy, open_window = Private.tCopy, Private.ImportExport
+ local serialize_profile = nil
+
+ local function get_profile_name(str)
+ str = strmatch(strsub(str, 1, 64), "%[(.-)%]")
+ str = str and str:gsub("=", ""):gsub("profile", ""):trim()
+ return (str ~= "") and str
+ end
+
+ local function check_profile_name(name)
+ local profiles = Skada.data:GetProfiles()
+ local ProfileExists = function(name)
+ if name then
+ for _, v in ipairs(profiles) do
+ if name == v then
+ return true
+ end
+ end
+ end
+ end
+
+ name = name or Skada.userName
+
+ local n, i = name, 1
+ while ProfileExists(name) do
+ i = i + 1
+ name = format("%s (%d)", n, i)
+ end
+
+ return name
+ end
+
+ local temp = {}
+ function serialize_profile()
+ wipe(temp)
+ copy(temp, Skada.profile, "modeclicks")
+ temp.__name = Skada.data:GetCurrentProfile()
+ return serialize(false, temp)
+ end
+
+ local function import_profile(data, name)
+ if type(data) ~= "string" then
+ Skada:Print("Import profile failed, data supplied must be a string.")
+ return false
+ end
+
+ local success, profile = deserialize(data)
+ if not success or profile.numbersystem == nil then -- sanity check!
+ Skada:Print("Import profile failed!")
+ return false
+ end
+
+ name = name or get_profile_name(data)
+ if profile.__name then
+ name = name or profile.__name
+ profile.__name = nil
+ end
+ local profileName = check_profile_name(name)
+
+ -- backwards compatibility
+ if profile[folder] and type(profile[folder]) == "table" then
+ profile = profile[folder]
+ end
+
+ local Old_ReloadSettings = Private.ReloadSettings
+ Private.ReloadSettings = function()
+ Private.ReloadSettings = Old_ReloadSettings
+ copy(Skada.profile, profile)
+ Private.ReloadSettings()
+ Skada:NotifyChange()
+ end
+
+ Skada.data:SetProfile(profileName)
+ Private.ReloadSettings()
+ Skada:Wipe()
+ Skada:UpdateDisplay(true)
+ return true
+ end
+
+ function Skada:ProfileImport()
+ return open_window(L["Paste here a profile in text format."], import_profile)
+ end
+
+ function Skada:ProfileExport()
+ return open_window(L["This is your current profile in text format."], serialize_profile())
+ end
+
+ function Private.AdvancedProfile(args)
+ if not args then return end
+ Private.AdvancedProfile = nil -- remove it
+ local CONST_COMM_PROFILE = "PR"
+
+ local Share = {}
+
+ function Share:Enable(receive)
+ if receive then
+ self.enabled = true
+ Skada.AddComm(self, CONST_COMM_PROFILE, "Receive")
+ else
+ self.enabled = nil
+ Skada.RemoveAllComms(self)
+ end
+ end
+
+ function Share:Receive(sender, profileStr)
+ local acceptfunc = function()
+ import_profile(profileStr, sender)
+ collectgarbage()
+ Share:Enable(false) -- disable receiving
+ Share.target = nil -- reset target
+ end
+ ConfirmDialog(uformat(L["opt_profile_received"], sender), acceptfunc)
+ end
+
+ function Share:Send(profileStr, target)
+ Skada:SendComm("PURR", target, CONST_COMM_PROFILE, profileStr)
+ end
+
+ args.advanced = {
+ type = "group",
+ name = L["Advanced"],
+ order = 10,
+ args = {
+ sharing = {
+ type = "group",
+ name = L["Network Sharing"],
+ inline = true,
+ order = 10,
+ hidden = function() return Skada.profile.syncoff end,
+ args = {
+ name = {
+ type = "input",
+ name = L["Player Name"],
+ get = function()
+ return Share.target or ""
+ end,
+ set = function(_, value)
+ Share.target = value:trim()
+ end,
+ order = 10
+ },
+ send = {
+ type = "execute",
+ name = L["Send Profile"],
+ func = function()
+ if Share.target and Share.target ~= "" then
+ Share:Send(serialize_profile(), Share.target)
+ end
+ end,
+ disabled = function() return (not Share.target or Share.target == "") end,
+ order = 20
+ },
+ accept = {
+ type = "toggle",
+ name = L["Accept profiles from other players."],
+ get = function() return Share.enabled end,
+ set = function() Share:Enable(not Share.enabled) end,
+ width = "full",
+ order = 30
+ }
+ }
+ },
+ importexport = {
+ type = "group",
+ name = L["Profile Import/Export"],
+ inline = true,
+ order = 20,
+ args = {
+ importbtn = {
+ type = "execute",
+ name = L["Import Profile"],
+ order = 10,
+ func = Skada.ProfileImport
+ },
+ exportbtn = {
+ type = "execute",
+ name = L["Export Profile"],
+ order = 20,
+ func = Skada.ProfileExport
+ }
+ }
+ }
+ }
+ }
+ end
+end
diff --git a/Skada/Core/Prototypes.lua b/Skada/Core/Prototypes.lua
new file mode 100644
index 0000000..a2aeb70
--- /dev/null
+++ b/Skada/Core/Prototypes.lua
@@ -0,0 +1,888 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+local pairs, max, select = pairs, math.max, select
+local getmetatable, setmetatable = getmetatable, setmetatable
+local new, clear = Private.newTable, Private.clearTable
+local cacheTable = Skada.cacheTable
+
+-- prototypes
+local setPrototype = Skada.setPrototype
+local actorPrototype = Skada.actorPrototype
+
+-------------------------------------------------------------------------------
+-- segment/set prototype & functions
+
+-- returns the segment's time
+function setPrototype:GetTime()
+ return Skada:GetSetTime(self)
+end
+
+-- returns the actor's time if found (player or enemy)
+function setPrototype:GetActorTime(name, id, active)
+ local actor = self:GetActor(name, id)
+ return actor and actor:GetTime(self, active) or self:GetTime()
+end
+
+-- attempts to find an actor (player or enemy)
+function setPrototype:GetActor(name, id, no_strict)
+ return Skada:FindActor(self, name, id, no_strict)
+end
+
+do
+ local function calc_set_total(set, key, class, arena)
+ local total = set[key] -- can be nil
+
+ if class then
+ total = nil
+
+ local actors = set.actors
+ for _, actor in pairs(actors) do
+ local value = actor.class == class and (not actor.enemy or arena) and actor[key]
+ if value then total = (total or 0) + value end
+ end
+ return total
+ end
+
+ if arena then
+ key = format("e%s", key)
+ if set[key] then
+ total = (total or 0) + set[key]
+ end
+ end
+
+ return total
+ end
+
+ -- returns the total value by given key/class
+ function setPrototype:GetTotal(class, arena, ...)
+ if not ... then return end
+ local combined = (arena and self.type == "arena")
+
+ local total = nil
+ for i = 1, select("#", ...) do
+ local key = select(i, ...)
+ local value = calc_set_total(self, key, class, combined)
+ if value then total = (total or 0) + value end
+ end
+ return total
+ end
+end
+
+-- fills the give table with actor's details
+function setPrototype:_fill_actor_table(t, name, actortime, no_strict)
+ if t and (not t.class or (actortime and not t.time)) then
+ local actor = self:GetActor(name, name, no_strict)
+ if not actor then return end
+
+ t.id = t.id or actor.id
+ t.class = t.class or actor.class
+ t.role = t.role or actor.role
+ t.spec = t.spec or actor.spec
+ t.enemy = t.enemy or actor.enemy
+
+ -- should add time?
+ if actortime then
+ t.time = t.time or actor:GetTime(self)
+ end
+
+ return actor
+ end
+end
+
+-- ------------------------------------
+-- damage done functions
+-- ------------------------------------
+
+-- returns the set's damage amount
+function setPrototype:GetDamage(class, useful)
+ local absdamage = Skada.profile.absdamage
+ local total = absdamage and self:GetTotal(class, true, "totaldamage") or self:GetTotal(class, true, "damage")
+ if useful and total then
+ local overkill = self:GetTotal(class, true, "overkill")
+ if overkill then total = max(0, total - overkill) end
+ end
+ return total
+end
+
+-- returns set's dps and damage amount
+function setPrototype:GetDPS(useful, class)
+ local total = Skada.profile.absdamage and self:GetTotal(class, true, "totaldamage") or self:GetTotal(class, true, "damage")
+ if total and useful then
+ local overkill = self:GetTotal(class, true, "overkill")
+ total = overkill and max(0, total - overkill) or total
+ end
+ if not total or total == 0 then
+ return 0, 0
+ end
+ return total / self:GetTime(), total
+end
+
+-- returns the set's overkill
+function setPrototype:GetOverkill(class)
+ return self:GetTotal(class, true, "overkill")
+end
+
+-- returns the actor's damage amount
+function setPrototype:GetActorDamage(name, id, useful)
+ local actor = self:GetActor(name, id)
+ return actor and actor:GetDamage(useful) or 0
+end
+
+-- returns the actor's dps and damage amount.
+function setPrototype:GetActorDPS(name, id, useful, active)
+ local actor = self:GetActor(name, id)
+ if actor then
+ return actor:GetDPS(self, useful, active)
+ end
+ return 0, 0
+end
+
+-- returns the actor's damage targets table if found
+function setPrototype:GetActorDamageTargets(name, id, tbl)
+ local actor = self:GetActor(name, id)
+ if actor then
+ local targets, total, overkill = actor:GetDamageTargets(self, tbl)
+ return targets, total, actor, overkill
+ end
+end
+
+-- ------------------------------------
+-- damage taken functions
+-- ------------------------------------
+
+-- returns the set's damage taken amount
+function setPrototype:GetDamageTaken(class, enemy)
+ local absdamage = Skada.profile.absdamage
+ if enemy then
+ return absdamage and self:GetTotal(class, true, "etotaldamaged") or self:GetTotal(class, true, "edamaged")
+ end
+ return absdamage and self:GetTotal(class, true, "totaldamaged") or self:GetTotal(class, true, "damaged")
+end
+
+-- returns the set's dtps and damage taken amount
+function setPrototype:GetDTPS(class, enemy)
+ local total = self:GetDamageTaken(class, enemy)
+ if not total or total == 0 then
+ return 0, total
+ end
+ return total / self:GetTime(), total
+end
+
+-- returns the actor's damage taken sources table if found
+function setPrototype:GetActorDamageSources(name, id, tbl)
+ local actor = self:GetActor(name, id)
+ if actor then
+ local sources, total = actor:GetDamageSources(self, tbl)
+ return sources, total, actor
+ end
+end
+
+-- returns the damage, overkill and useful
+function setPrototype:GetActorDamageFromSource(name, id, targetname)
+ local actor = self:GetActor(name, id)
+ if actor then
+ return actor:GetDamageFromSource(targetname)
+ end
+ return 0, 0, 0
+end
+
+-- actor heal targets
+function setPrototype:GetActorHealTargets(name, id, tbl)
+ local actor = self:GetActor(name, id)
+ if actor then
+ local targets, total = actor:GetHealTargets(self, tbl)
+ return targets, total, actor
+ end
+end
+
+-- ------------------------------------
+-- absorb and healing functions
+-- ------------------------------------
+
+-- returns the set's heal amount
+function setPrototype:GetHeal(class, enemy)
+ return self:GetTotal(class, true, enemy and "eheal" or "heal")
+end
+
+-- returns the set's hps and heal amount
+function setPrototype:GetHPS(class, enemy)
+ local total = self:GetTotal(class, true, enemy and "eheal" or "heal")
+ if not total or total == 0 then
+ return 0, 0
+ end
+ return total / self:GetTime(), total
+end
+
+-- returns the set's overheal amount
+function setPrototype:GetOverheal(class)
+ return self:GetTotal(class, true, "overheal")
+end
+
+-- returns the set's overheal per second and overheal amount
+function setPrototype:GetOHPS(class)
+ local total = self:GetTotal(class, true, "overheal")
+ if not total or total == 0 then
+ return 0, 0
+ end
+ return total / self:GetTime(), total
+end
+
+-- returns the set's total heal amount, including overheal amount
+function setPrototype:GetTotalHeal(class)
+ return self:GetTotal(class, true, "heal", "overheal")
+end
+
+-- returns the set's total hps and heal
+function setPrototype:GetTHPS(class)
+ local total = self:GetTotal(class, true, "heal", "overheal")
+ if not total or total == 0 then
+ return 0, 0
+ end
+ return total / self:GetTime(), total
+end
+
+-- returns the set's absorb amount
+function setPrototype:GetAbsorb(class, enemy)
+ return self:GetTotal(class, true, enemy and "eabsorb" or "absorb")
+end
+
+-- returns the set's absorb per second and absorb amount
+function setPrototype:GetAPS(class, enemy)
+ local total = self:GetTotal(class, true, enemy and "eabsorb" or "absorb")
+ if not total or total == 0 then
+ return 0, 0
+ end
+ return total / self:GetTime(), total
+end
+
+-- returns the set's amount of heal and absorb combined
+function setPrototype:GetAbsorbHeal(class, enemy)
+ return (self:GetHeal(class, enemy) or 0) + (self:GetAbsorb(class, enemy) or 0)
+end
+
+-- returns the set's absorb and heal per sec
+function setPrototype:GetAHPS(class, enemy)
+ local total = (self:GetHeal(class, enemy) or 0) + (self:GetAbsorb(class, enemy) or 0)
+ if not total or total == 0 then
+ return 0, 0
+ end
+ return total / self:GetTime(), total
+end
+
+-------------------------------------------------------------------------------
+-- common actors functions
+
+-- for better dps calculation, we use active time for Arena/BGs.
+function actorPrototype:GetTime(set, active)
+ return Skada:GetActiveTime(set, self, active)
+end
+
+-- calculate total for the given actor.
+function actorPrototype:GetTotal(...)
+ local total = nil
+ for i = 1, select("#", ...) do
+ local value = self[select(i, ...)]
+ if value then total = (total or 0) + value end
+ end
+ return total
+end
+
+-- ------------------------------------
+-- damage done functions
+-- ------------------------------------
+
+-- returns the actor's damage amount
+function actorPrototype:GetDamage(useful)
+ local total = Skada.profile.absdamage and self.totaldamage or self.damage
+ if total and useful and self.overkill then
+ return max(0, total - self.overkill)
+ end
+ return total or 0
+end
+
+-- returns the actor's dps and damage amount
+function actorPrototype:GetDPS(set, useful, active, no_calc)
+ local total = Skada.profile.absdamage and self.totaldamage or self.damage
+ if total and useful and self.overkill then
+ total = max(0, total - self.overkill)
+ end
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set, active), total
+end
+
+-- returns the actor's overkill
+function actorPrototype:GetOverkill()
+ return self.overkill or 0
+end
+
+-- returns the actor's damage targets table if found
+do
+ local function fill_damage_targets_table(set, t, name, info)
+ local tbl = t[name]
+ if not tbl then
+ tbl = new()
+ tbl.amount = info.amount
+ tbl.total = info.total
+ tbl.o_amt = info.o_amt
+ t[name] = tbl
+ else
+ tbl.amount = tbl.amount + info.amount
+ if info.total then
+ tbl.total = (tbl.total or 0) + info.total
+ end
+ if info.o_amt then
+ tbl.o_amt = (tbl.o_amt or 0) + info.o_amt
+ end
+ end
+
+ set:_fill_actor_table(tbl, name)
+ end
+
+ function actorPrototype:GetDamageTargets(set, tbl)
+ if not self.damagespells then
+ return nil, 0, 0
+ end
+
+ local damage = Skada.profile.absdamage and self.totaldamage or self.damage
+ if not damage then
+ return nil, 0, 0
+ end
+
+ tbl = clear(tbl or cacheTable)
+ for _, spell in pairs(self.damagespells) do
+ if spell.targets then
+ for name, target in pairs(spell.targets) do
+ fill_damage_targets_table(set, tbl, name, target)
+ end
+ end
+ end
+ return tbl, damage, self.overkill or 0
+ end
+end
+
+-- returns the damage on the given target
+function actorPrototype:GetDamageOnTarget(name)
+ if not name or not self.damagespells then
+ return 0, 0, 0
+ end
+
+ local damage, overkill, useful = 0, 0, 0
+ for _, spell in pairs(self.damagespells) do
+ if spell.targets and spell.targets[name] then
+ -- damage
+ if Skada.profile.absdamage and spell.targets[name].total then
+ damage = damage + spell.targets[name].total
+ elseif spell.targets[name].amount then
+ damage = damage + spell.targets[name].amount
+ end
+
+ -- overkill
+ if spell.targets[name].o_amt then
+ overkill = overkill + spell.targets[name].o_amt
+ end
+
+ -- useful
+ if spell.targets[name].useful then
+ useful = useful + spell.targets[name].useful
+ end
+ end
+ end
+ return damage, overkill, useful
+end
+
+-- ------------------------------------
+-- damage taken functions
+-- ------------------------------------
+
+-- returns the actor's damage taken amount
+function actorPrototype:GetDamageTaken()
+ return Skada.profile.absdamage and self.totaldamaged or self.damaged or 0
+end
+
+-- returns the actor's dtps and damage taken amount
+function actorPrototype:GetDTPS(set, no_calc)
+ local total = Skada.profile.absdamage and self.totaldamaged or self.damaged
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set), total
+end
+
+-- returns the actors damage sources
+do
+ local function fill_damage_sources_table(set, t, name, info)
+ local tbl = t[name]
+ if not tbl then
+ tbl = new()
+ tbl.amount = info.amount
+ tbl.total = info.total
+ tbl.o_amt = info.o_amt -- nil for players
+ tbl.useful = info.useful -- nil for enemies
+ t[name] = tbl
+ else
+ tbl.amount = tbl.amount + info.amount
+ if info.total then
+ tbl.total = (tbl.total or 0) + info.total
+ end
+ if info.o_amt then -- nil for players
+ tbl.o_amt = (tbl.o_amt or 0) + info.o_amt
+ end
+ if info.useful then -- nil for enemies
+ tbl.useful = (tbl.useful or 0) + info.useful
+ end
+ end
+
+ set:_fill_actor_table(tbl, name)
+ end
+
+ function actorPrototype:GetDamageSources(set, tbl)
+ local spells = self.damagedspells
+ if not spells then return end
+
+ local total = Skada.profile.absdamage and self.totaldamaged or self.damaged
+ if not total then return end
+
+ tbl = clear(tbl or cacheTable)
+ for _, spell in pairs(spells) do
+ if spell.sources then
+ for name, source in pairs(spell.sources) do
+ fill_damage_sources_table(set, tbl, name, source)
+ end
+ end
+ end
+ return tbl, total
+ end
+end
+
+-- returns the actors damage from the given source
+function actorPrototype:GetDamageFromSource(name)
+ local spells = name and self.damagedspells
+ if not spells then
+ return 0, 0, 0
+ end
+
+ local damage, overkill, useful = 0, 0, 0
+ for _, spell in pairs(spells) do
+ local source = spell.sources and spell.sources[name]
+ if source then
+ if source.total or source.amount then -- damage
+ damage = damage + (Skada.profile.absdamage and source.total or source.amount)
+ end
+ if source.o_amt then -- overkill
+ overkill = overkill + source.o_amt
+ end
+ if source.useful then -- useful
+ useful = useful + source.useful
+ end
+ end
+ end
+ return damage, overkill, useful
+end
+
+-- ------------------------------------
+-- absorb and healing functions
+-- ------------------------------------
+
+-- returns the actor' heal amount
+function actorPrototype:GetHeal()
+ return self.heal or 0
+end
+
+-- returns the actor's hps and heal amount
+function actorPrototype:GetHPS(set, active, no_calc)
+ local total = self.heal
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set, active), total
+end
+
+-- returns the actor's overheal amount
+function actorPrototype:GetOverheal()
+ return self.overheal or 0
+end
+
+-- returns the actor's overheal per second and overheal amount
+function actorPrototype:GetOHPS(set, active, no_calc)
+ local total = self.overheal
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set, active), total
+end
+
+-- returns the actor's total heal, including overheal
+function actorPrototype:GetTotalHeal()
+ local total = self.heal
+ if self.overheal then
+ return total and total + self.overheal or self.overheal
+ end
+ return total or 0
+end
+
+-- returns the actor's total hps and heal
+function actorPrototype:GetTHPS(set, active, no_calc)
+ local total = self.heal
+ if self.overheal then
+ total = total and total + self.overheal or self.overheal
+ end
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set, active), total
+end
+
+-- returns the amount of heal and overheal on the given target
+function actorPrototype:GetHealOnTarget(name, inc_overheal)
+ local spells = name and self.healspells
+ if not spells then
+ return 0, inc_overheal and 0
+ end
+
+ local heal, overheal = 0, inc_overheal and 0
+ for _, spell in pairs(spells) do
+ local target = spell.targets and spell.targets[name]
+ if target then
+ heal = heal + target.amount
+ if inc_overheal and target.o_amt then
+ overheal = overheal + target.o_amt
+ end
+ end
+ end
+ return heal, overheal
+end
+
+-- returns the amount of overheal on the given target
+function actorPrototype:GetOverhealOnTarget(name)
+ local spells = self.overheal and name and self.healspells
+ if not spells then
+ return 0
+ end
+
+ local total = 0
+ for _, spell in pairs(spells) do
+ local o_amt = (spell.o_amt and spell.o_amt > 0) and spell.targets and spell.targets[name] and spell.targets[name].o_amt
+ if o_amt then
+ total = total + o_amt
+ end
+ end
+ return total
+end
+
+-- returns the total heal amount on the given target
+function actorPrototype:GetTotalHealOnTarget(name)
+ local heal, overheal = self:GetHealOnTarget(name, true)
+ return overheal and heal + overheal or heal
+end
+
+-- returns the actor's absorb amount
+function actorPrototype:GetAbsorb()
+ return self.absorb or 0
+end
+
+-- returns the actor's absorb per second and absorb amount
+function actorPrototype:GetAPS(set, active, no_calc)
+ local total = self.absorb
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set, active), total
+end
+
+-- returns the actor's amount of heal and absorb combined
+function actorPrototype:GetAbsorbHeal()
+ local total = self.heal
+ if self.absorb then
+ total = total and total + self.absorb
+ end
+ return total or 0
+end
+
+-- returns the actor's absorb and heal per sec
+function actorPrototype:GetAHPS(set, active, no_calc)
+ local total = self.heal
+ if self.absorb then
+ total = total and total + self.absorb
+ end
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(set, active), total
+end
+
+-- returns the amount of absorb and heal on the given target
+function actorPrototype:GetAbsorbHealOnTarget(name, inc_overheal)
+ if not name or not (self.absorbspells or self.healspells) then
+ return 0, inc_overheal and 0 or nil
+ end
+
+ local heal, overheal = 0, inc_overheal and 0 or nil
+
+ local spells = self.healspells -- heal spells
+ if spells then
+ for _, spell in pairs(spells) do
+ local target = spell.targets and spell.targets[name]
+ if target then
+ heal = heal + target.amount
+ if inc_overheal and target.o_amt then
+ overheal = overheal + target.o_amt
+ end
+ end
+ end
+ end
+
+ spells = self.absorbspells -- absorb spells
+ if not spells then
+ return heal, overheal
+ end
+
+ for _, spell in pairs(spells) do
+ if spell.targets and spell.targets[name] then
+ heal = heal + spell.targets[name]
+ end
+ end
+ return heal, overheal
+end
+
+do
+ local function fill_absorb_targets_table(set, t, name, amount)
+ local tbl = t[name]
+ if not tbl then
+ tbl = new()
+ tbl.amount = amount
+ t[name] = tbl
+ else
+ tbl.amount = tbl.amount + amount
+ end
+
+ set:_fill_actor_table(tbl, name)
+ end
+
+ local function fill_heal_targets_table(set, t, name, info)
+ local tbl = t[name] or new()
+ t[name] = tbl
+
+ tbl.amount = (tbl.amount or 0) + info.amount
+ if info.o_amt then
+ tbl.o_amt = (tbl.o_amt or 0) + info.o_amt
+ end
+
+ set:_fill_actor_table(tbl, name)
+ end
+
+ -- returns the actor's absorb targets table if found
+ function actorPrototype:GetAbsorbTargets(set, tbl)
+ local spells = self.absorbspells
+ if not spells then return end
+
+ tbl = clear(tbl or cacheTable)
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, amount in pairs(spell.targets) do
+ fill_absorb_targets_table(set, tbl, name, amount)
+ end
+ end
+ end
+ return tbl
+ end
+
+ -- returns the actor's heal targets table if found
+ function actorPrototype:GetHealTargets(set, tbl)
+ local spells = self.healspells
+ if not spells then return end
+
+ tbl = clear(tbl or cacheTable)
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, target in pairs(spell.targets) do
+ fill_heal_targets_table(set, tbl, name, target)
+ end
+ end
+ end
+ return tbl, self.heal or 0
+ end
+
+ -- returns the actor's absorb and heal targets table if found
+ function actorPrototype:GetAbsorbHealTargets(set, tbl)
+ if not (self.healspells or self.absorbspells) then return end
+
+ tbl = clear(tbl or cacheTable)
+
+ local spells = self.healspells -- heal spells
+ if spells then
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, target in pairs(spell.targets) do
+ fill_heal_targets_table(set, tbl, name, target)
+ end
+ end
+ end
+ end
+
+ spells = self.absorbspells -- absorb spells
+ if not spells then
+ return tbl
+ end
+
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, amount in pairs(spell.targets) do
+ fill_absorb_targets_table(set, tbl, name, amount)
+ end
+ end
+ end
+ return tbl
+ end
+end
+
+-- returns the table of overheal targets if found
+do
+ local function fill_overheal_targets_table(set, t, name, info)
+ local amt = info.o_amt
+ if not amt or amt == 0 then return end
+
+ local tbl = t[name]
+ if not tbl then
+ tbl = new()
+ tbl.amount = amt
+ tbl.total = info.amount + amt
+ t[name] = tbl
+ else
+ tbl.amount = tbl.amount + amt
+ tbl.total = tbl.total + info.amount + amt
+ end
+
+ set:_fill_actor_table(tbl, name)
+ end
+
+ function actorPrototype:GetOverhealTargets(set, tbl)
+ local spells = self.overheal and self.healspells
+ if not spells then return end
+
+ tbl = clear(tbl or cacheTable)
+ for _, spell in pairs(spells) do
+ if spell.o_amt and spell.o_amt > 0 and spell.targets then
+ for name, target in pairs(spell.targets) do
+ fill_overheal_targets_table(set, tbl, name, target)
+ end
+ end
+ end
+ return tbl
+ end
+end
+
+-- returns the total heal amount on the given target
+do
+ local function fill_total_heal_targets_table(set, t, name, info)
+ local tbl = t[name] or new()
+ t[name] = tbl
+
+ tbl.amount = (tbl.amount or 0) + info.amount
+ if info.o_amt then
+ tbl.amount = tbl.amount + info.o_amt
+ end
+
+ set:_fill_actor_table(tbl, name)
+ end
+
+ function actorPrototype:GetTotalHealTargets(set, tbl)
+ local spells = self.healspells
+ if not spells then return end
+
+ tbl = clear(tbl or cacheTable)
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, target in pairs(spell.targets) do
+ fill_total_heal_targets_table(set, tbl, name, target)
+ end
+ end
+ end
+ return tbl
+ end
+end
+
+-------------------------------------------------------------------------------
+-- display prototype & functions
+
+do
+ local displayPrototype = {}
+ Skada.displayPrototype = displayPrototype
+
+ function displayPrototype:IsShown(win)
+ local frame = win and win.frame or win.bargroup
+ if not frame then
+ return
+ elseif frame:IsShown() then
+ return true, frame
+ else
+ return false, frame
+ end
+ end
+
+ function displayPrototype:Show(win)
+ local isshown, frame = self:IsShown(win)
+ if isshown or not frame then return end
+
+ frame:Show()
+ if frame.SortBars then
+ frame:SortBars()
+ end
+ end
+
+ function displayPrototype:Hide(win)
+ local isshown, frame = self:IsShown(win)
+ if isshown and frame then
+ frame:Hide()
+ end
+ end
+
+ function displayPrototype:Wipe(win)
+ if not win then
+ return
+ elseif win.frame then -- broker/inline
+ if win.obj then -- broker
+ if win.obj.text then
+ win.obj.text = ""
+ end
+ return true
+ end
+ return -- inline
+ elseif win.bargroup then -- bar/legacy
+ win.bargroup:SetSortFunction(nil)
+ win.bargroup:SetBarOffset(0)
+ local bars = win.bargroup:GetBars()
+ if bars then
+ for _, bar in pairs(bars) do
+ bar:Hide()
+ win.bargroup:RemoveBar(bar)
+ end
+ end
+ win.bargroup:SortBars()
+ return true
+ end
+ return false
+ end
+
+ function displayPrototype:Destroy(win)
+ if win and win.bargroup then -- bar/legacy
+ win.bargroup:Hide()
+ win.bargroup.bgframe = nil
+ win.bargroup = nil
+ return true
+ elseif win and win.frame then -- broker/inline
+ if win.obj then -- broker
+ if win.obj.text then
+ win.obj.text = ""
+ end
+ win.obj = nil
+ end
+ win.frame:Hide()
+ win.frame = nil
+ return true
+ end
+ return false
+ end
+end
diff --git a/Skada/Core/Tables.lua b/Skada/Core/Tables.lua
new file mode 100644
index 0000000..bbcf0e7
--- /dev/null
+++ b/Skada/Core/Tables.lua
@@ -0,0 +1,592 @@
+-- Tables.lua
+-- Contains all tables used by different files and modules.
+local _, ns = ...
+local L = ns.Locale
+local setmetatable = setmetatable
+
+-------------------------------------------------------------------------------
+-- ingored spells
+-- a table of spells that are ignored per module.
+-- entries should be like so: [spellid] = true
+
+local ignored_spells = {
+ -- [[ absorbs modules ]] --
+ -- absorb = {},
+
+ -- [[ buffs module ]] --
+ buff = {
+ [57819] = true, -- Tabard of the Argent Crusade
+ [57820] = true, -- Tabard of the Ebon Blade
+ [57821] = true, -- Tabard of the Kirin Tor
+ [57822] = true, -- Tabard of the Wyrmrest Accord
+ [57940] = true, -- Essence of Wintergrasp
+ [72968] = true, -- Precious's Ribbon
+
+ -- uncertain about the follwing spells:
+ -- [73816] = true, -- Hellscream's Warsong (ICC-Horde 5%)
+ -- [73818] = true, -- Hellscream's Warsong (ICC-Horde 10%)
+ -- [73819] = true, -- Hellscream's Warsong (ICC-Horde 15%)
+ -- [73820] = true, -- Hellscream's Warsong (ICC-Horde 20%)
+ -- [73821] = true, -- Hellscream's Warsong (ICC-Horde 25%)
+ -- [73822] = true, -- Hellscream's Warsong (ICC-Horde 30%)
+ -- [73762] = true, -- Hellscream's Warsong (ICC-Alliance 5%)
+ -- [73824] = true, -- Hellscream's Warsong (ICC-Alliance 10%)
+ -- [73825] = true, -- Hellscream's Warsong (ICC-Alliance 15%)
+ -- [73826] = true, -- Hellscream's Warsong (ICC-Alliance 20%)
+ -- [73827] = true, -- Hellscream's Warsong (ICC-Alliance 25%)
+ -- [73828] = true, -- Hellscream's Warsong (ICC-Alliance 30%)
+ },
+
+ -- [[ debuffs module ]] --
+ debuff = {
+ [57723] = true, -- Exhaustion (Heroism)
+ [57724] = true, -- Sated (Bloodlust)
+ },
+
+ -- [[ damage / enemy damage taken modules ]] --
+ -- damage = {},
+
+ -- [[ damage taken / enemy damage done modules ]] --
+ -- damagetaken = {},
+
+ -- [[ dispels module ]] --
+ -- dispel = {},
+
+ -- [[ fails module ]] --
+ -- fail = {},
+
+ -- [[ friendly fire module ]] --
+ -- friendfire = {},
+
+ -- [[ healing / enemy healing done modules ]] --
+ -- heal = {},
+
+ -- [[ interrupts module ]] --
+ -- interrupt = {},
+
+ -- [[ resources module ]] --
+ -- power = {},
+
+ -- [[ first hit ignored spells ]] --
+ firsthit = {
+ [1130] = true, -- Hunter's Mark
+ [56190] = true, -- Shadow Jade Focusing Lens
+ [56191] = true, -- Shadow Jade Focusing Lens
+ [60122] = true, -- Baby Spice
+ },
+
+ -- [[ no active time spells ]] --
+ time = {
+ [13008] = true, -- Retribution Aura
+ [26364] = true, -- Lightning Shield
+ [35916] = true, -- Molten Armor
+ }
+}
+
+-------------------------------------------------------------------------------
+-- ignored creautre ids (use creature ID: [cretureID] = true)
+-- a list of creature IDs of which CLEU <> events are ignored.
+
+local ignored_creatures = {}
+
+-------------------------------------------------------------------------------
+-- misc tables
+
+-- resurrect spells
+ns.ress_spells = {
+ [3026] = 0x01, -- Use Soulstone
+ [20484] = 0x08, -- Rebirth
+ [20608] = 0x08, -- Reincarnation
+}
+
+-- list of crowd control spells
+ns.cc_spells = {
+ [118] = 0x40, -- Polymorph
+ [339] = 0x08, -- Entangling Roots
+ [676] = 0x01, -- Disarm
+ [710] = 0x20, -- Banish
+ [2637] = 0x08, -- Hibernate
+ [3355] = 0x10, -- Freezing Trap Effect
+ [6358] = 0x20, -- Seduction (Succubus)
+ [6770] = 0x01, -- Sap
+ [9484] = 0x02, -- Shackle Undead
+ [20066] = 0x02, -- Repentance
+ [28271] = 0x40, -- Polymorph: Turtle
+ [28272] = 0x40, -- Polymorph: Pig
+ [33786] = 0x08, -- Cyclone
+ [96294] = 0x10, -- Chains of Ice
+ [51514] = 0x08, -- Hex
+ [51722] = 0x01, -- Dismantle
+ [52719] = 0x01, -- Concussion Blow
+}
+
+-- extended list of crowd control spells
+ns.extra_cc_spells = setmetatable({
+ -- Warrior
+ [5246] = 0x01, -- Initmidating Shout
+ [6552] = 0x01, -- Pummel
+ [7922] = 0x01, -- Charge
+ [12323] = 0x01, -- Piercing Howl
+ [46968] = 0x01, -- Shockwave
+ [58357] = 0x01, -- Heroic Throw silence
+ [107566] = 0x01, -- Staggering Shout
+ -- Death Knight
+ [47476] = 0x20, -- Strangulate
+ [47481] = 0x01, -- Gnaw
+ [49560] = 0x01, -- Death Grip
+ [79092] = 0x10, -- Hungering Cold
+ -- Paladin
+ [853] = 0x02, -- Hammer of Justice
+ [2812] = 0x02, -- Holy Wrath
+ [10326] = 0x02, -- Turn Evil
+ [31935] = 0x02, -- Avengers Shield
+ [105421] = 0x02, -- Blinding Light
+ -- Monk
+ [116706] = 0x01, -- Disable
+ -- Priest
+ [605] = 0x20, -- Dominate Mind (Mind Control)
+ [8122] = 0x20, -- Psychic Scream
+ [15487] = 0x20, -- Silence
+ [64044] = 0x20, -- Psychic Horror
+ -- Shaman
+ [3600] = 0x08, -- Earthbind (Earthbind Totem)
+ [8034] = 0x10, -- Frostbrand Weapon
+ [8056] = 0x10, -- Frost Shock
+ [64695] = 0x08, -- Earthgrab
+ -- Druid
+ [339] = 0x08, -- Entangling Roots
+ [16979] = 0x01, -- Feral Charge - Bear
+ [19975] = 0x08, -- Entangling Roots (Nature's Grasp)
+ [22570] = 0x01, -- Maim
+ [45334] = 0x01, -- Feral Charge Effect
+ [66070] = 0x08, -- Entangling Roots (Force of Nature)
+ -- Rogue
+ [408] = 0x01, -- Kidney Shot
+ [1330] = 0x01, -- Garrote - Silence
+ [1776] = 0x01, -- Gouge
+ [1833] = 0x01, -- Cheap Shot
+ [2094] = 0x01, -- Blind
+ -- Mage
+ [122] = 0x10, -- Frost Nova
+ [31661] = 0x04, -- Dragon's Breath
+ [33395] = 0x10, -- Freeze (Frost Water Elemental)
+ [44572] = 0x10, -- Deep Freeze
+ [55021] = 0x40, -- Silenced - Improved Counterspell
+ [61305] = 0x40, -- Polymorph Cat
+ [61721] = 0x40, -- Polymorph Rabbit
+ [61780] = 0x40, -- Polymorph Turkey
+ [82691] = 0x10, -- Ring of Frost
+ [111340] = 0x10, -- Ice Ward
+ -- Warlock
+ [5484] = 0x20, -- Howl of Terror
+ [6789] = 0x20, -- Death Coil
+ [22703] = 0x04, -- Infernal Awakening
+ [24259] = 0x20, -- Spell Lock
+ [30283] = 0x20, -- Shadowfury
+ [115268] = 0x20, -- Mesmerize
+ [118699] = 0x20, -- Fear
+ -- Hunter
+ [1513] = 0x08, -- Scare Beast
+ [4167] = 0x01, -- Web (Spider)
+ [5116] = 0x01, -- Concussive Shot
+ [19386] = 0x08, -- Wyvern Sting
+ [19503] = 0x01, -- Scatter Shot
+ [19577] = 0x08, -- Intimidation (stun)
+ [24394] = 0x01, -- Intimidation
+ [26090] = 0x08, -- Pummel (Gorilla)
+ [50541] = 0x01, -- Clench (Scorpid)
+ [64803] = 0x01, -- Entrapment
+ [136634] = 0x08, -- Narrow Escape
+ -- Racials
+ [20549] = 0x01, -- War Stomp (Tauren)
+ [28730] = 0x40, -- Arcane Torrent (Bloodelf)
+ [47779] = 0x40, -- Arcane Torrent (Bloodelf)
+ [50613] = 0x40, -- Arcane Torrent (Bloodelf)
+ -- Engineering
+ [67890] = 0x04 -- Cobalt Frag Bomb
+}, {__index = ns.cc_spells})
+
+-- deathlog tracked buffs.
+do
+ local spellnames = ns.spellnames
+ ns.deathlog_tracked_buff = {
+ -- Warrior
+ [spellnames[871]] = true, -- Shield Wall
+ [spellnames[2565]] = true, -- Shield Block
+ [spellnames[12975]] = true, -- Last Stand
+ [spellnames[23920]] = true, -- Spell Reflection
+ [spellnames[114028]] = true, -- Mass Spell Reflection
+ [spellnames[114030]] = true, -- Vigilance
+ [spellnames[114030]] = true, -- Vigilance
+ [spellnames[118038]] = true, -- Die by the Sword
+ -- Death Knight
+ [spellnames[42650]] = true, -- Army of the Dead
+ [spellnames[48707]] = true, -- Anti-Magic Shell
+ [spellnames[48792]] = true, -- Icebound Fortitude
+ [spellnames[49039]] = true, -- Lichborne
+ [spellnames[51052]] = true, -- Anti-Magic Zone
+ [spellnames[51271]] = true, -- Pillar of Frost
+ [spellnames[55233]] = true, -- Vampiric Blood
+ -- Paladin
+ [spellnames[498]] = true, -- Divine Protection
+ [spellnames[633]] = true, -- Lay on Hands
+ [spellnames[642]] = true, -- Divine Shield
+ [spellnames[1022]] = true, -- Hand of Protection
+ [spellnames[1044]] = true, -- Hand of Freedom
+ [spellnames[6940]] = true, -- Hand of Sacrifice
+ [spellnames[31821]] = true, -- Devotion Aura
+ [spellnames[31850]] = true, -- Ardent Defender
+ [spellnames[31884]] = true, -- Avenging Wrath
+ [spellnames[86659]] = true, -- Guardian of Ancient Kings
+ -- Monk
+ [spellnames[115176]] = true, -- Zen Meditation
+ [spellnames[115308]] = true, -- Elusive Brew
+ [spellnames[116844]] = true, -- Ring of Peace
+ [spellnames[116849]] = true, -- Life Cocoon
+ [spellnames[122278]] = true, -- Dampen Harm
+ [spellnames[122470]] = true, -- Touch of Karma
+ [spellnames[122783]] = true, -- Diffuse Magic
+ -- Priest
+ [spellnames[17]] = true, -- Power Word: Shield
+ [spellnames[586]] = true, -- Fade
+ [spellnames[27827]] = true, -- Spirit of Redemption
+ [spellnames[33206]] = true, -- Pain Suppression
+ [spellnames[47585]] = true, -- Dispersion
+ [spellnames[47788]] = true, -- Guardian Spirit
+ [spellnames[64843]] = true, -- Divine Hymn
+ [spellnames[109964]] = true, -- Spirit Shell
+ -- Shaman
+ [spellnames[85838]] = true, -- Ancestral Fortitude
+ [spellnames[108271]] = true, -- Astral Shift
+ [spellnames[108281]] = true, -- Ancestral Guidance
+ -- Druid
+ [spellnames[5487]] = true, -- Bear Form
+ [spellnames[22812]] = true, -- Barkskin
+ [spellnames[22842]] = true, -- Frenzied Regeneration
+ [spellnames[61336]] = true, -- Survival Instincts
+ [spellnames[102342]] = true, -- Ironbark
+ -- Rogue
+ [spellnames[1856]] = true, -- Vanish
+ [spellnames[1966]] = true, -- Feint
+ [spellnames[5277]] = true, -- Evasion
+ [spellnames[31224]] = true, -- Cloak of Shadows
+ [spellnames[76577]] = true, -- Smoke Bomb
+ -- Mage
+ [spellnames[66]] = true, -- Invisibility
+ [spellnames[1463]] = true, -- Incanter's Ward
+ [spellnames[1953]] = true, -- Blink
+ [spellnames[11426]] = true, -- Ice Barrier
+ [spellnames[45438]] = true, -- Ice Block
+ [spellnames[55342]] = true, -- Mirror Image
+ -- Warlock
+ [spellnames[104773]] = true, -- Unending Resolve
+ [spellnames[108359]] = true, -- Dark Regeneration
+ [spellnames[108416]] = true, -- Sacrificial Pact
+ -- Hunter
+ [spellnames[781]] = true, -- Disengage
+ [spellnames[5384]] = true, -- Feign Death
+ [spellnames[19263]] = true, -- Deterrence
+ -- Items
+ [spellnames[54861]] = true, -- Nitro Boosts
+ [spellnames[60180]] = true, -- Repelling Charge (Resolute)
+ [spellnames[60286]] = true, -- Defender's Code
+ [spellnames[64763]] = true, -- Heart of Iron
+ [spellnames[65011]] = true, -- Furnace Stone
+ [spellnames[65012]] = true, -- Royal Seal of King Llane
+ [spellnames[67596]] = true, -- Battlemaster's PvP (Tremendous Fortitude)
+ [spellnames[67631]] = true, -- The Black Heart (Aegis)
+ [spellnames[67694]] = true, -- Glyph of Indomitability (Defensive Tactics)
+ [spellnames[67753]] = true, -- Juggernaut's Vitality/Satrina's Impeding Scarab (Fortitude)
+ [spellnames[68443]] = true, -- Brawler's Souvenir (Drunken Evasiveness)
+ [spellnames[71569]] = true, -- Ick's Rotting Thumb (Increased Fortitude)
+ [spellnames[71586]] = true, -- Corroded Skeleton Key (Hardened Skin)
+ [spellnames[71638]] = true, -- Sindragosa's Flawless Fang (Aegis of Dalaran)
+ [spellnames[71639]] = true, -- Corpse Tongue Coin (Thick Skin)
+ [spellnames[75480]] = true, -- Petrified Twilight Scale (Scaly Nimbleness)
+ }
+end
+
+-------------------------------------------------------------------------------
+-- grouped and custom units
+
+do
+ ------------------------------------------------------
+ -- grouped units (fake)
+ ------------------------------------------------------
+ --
+ -- holds the units to which the damage done is collected
+ -- into a single standalone fake unit.
+ --
+ -- table structure:
+ -- option #1: [creature id] = "Group Name"
+ -- option #2: [creature name] = "Group Name"
+ --
+
+ local grouped_units = {
+ -- EXPERIMENTAL: instance bosses and trash grouped units.
+ -- IMPORTANT: only recorded to the total segment.
+ BOSS = true,
+ TRASH = true,
+
+ -- Example: The Lich King - Important targets
+ -- [36597] = L["Important targets"], -- The Lich King
+ -- [36609] = L["Important targets"], -- Val'kyr Shadowguard
+ -- [36633] = L["Important targets"], -- Ice Sphere
+ -- [36701] = L["Important targets"], -- Raging Spirit
+ -- [39190] = L["Important targets"], -- Wicked Spirit
+ }
+
+ ------------------------------------------------------
+ -- custom units (fake)
+ ------------------------------------------------------
+ --
+ -- holds units that should craete a fake unit at certain
+ -- health or power percentage.
+ -- Useful in case you want to collect stuff done to units
+ -- at certain encounter phases for example.
+ --
+ -- table structure (all fields are optional and will be generated and cached by the addon)
+ -- start: when to start collecting (0.01 = 1%, default: 100%)
+ -- stop: when to stop collecting (0.01 = 1%, default: 0%)
+ -- power: whether to track the speficied power or health
+ -- 0 - Mana
+ -- 1 - Rage
+ -- 2 - Focus
+ -- 3 - Energy
+ -- 4 - Happiness
+ -- 5 - Runes
+ -- 6 - Runic Power
+ --
+ -- name: name of the fake unit (optional)
+ -- text: text to use *format()* with (optional)
+ -- values: table of difficulties to max health (optional)
+ -- diff: table of whitelisted difficulties (optional, default: all)
+ -- {["10h"] = true, ["25h"] = true}
+ --
+ -- **optional** fields will be generated and cached by the addon.
+ --
+
+ local custom_units = {
+ -- Example ICC: Lady Deathwhisper
+ -- [36855] = {
+ -- {text = L["%s - Phase 1"], start = 1, power = 0},
+ -- {text = L["%s - Phase 2"], start = 0, power = 0}
+ -- }
+ }
+
+ ------------------------------------------------------
+
+ ns.grouped_units = grouped_units
+ ns.custom_units = custom_units
+end
+
+-------------------------------------------------------------------------------
+-- DO NOT EDIT THE CODE BELOW (unless you know what you're doing)
+-------------------------------------------------------------------------------
+
+-------------------------------------------------------------------------------
+-- creature_to_fight
+-- a table of creatures IDs used to fix segments names.
+
+ns.creature_to_fight = {
+ -- [[ Icecrown Citadel ]] --
+ [36960] = L["Icecrown Gunship Battle"], -- Kor'kron Sergeant
+ [36968] = L["Icecrown Gunship Battle"], -- Kor'kron Axethrower
+ [36982] = L["Icecrown Gunship Battle"], -- Kor'kron Rocketeer
+ [37117] = L["Icecrown Gunship Battle"], -- Kor'kron Battle-Mage
+ [37215] = L["Icecrown Gunship Battle"], -- Orgrim's Hammer
+ [36961] = L["Icecrown Gunship Battle"], -- Skybreaker Sergeant
+ [36969] = L["Icecrown Gunship Battle"], -- Skybreaker Rifleman
+ [36978] = L["Icecrown Gunship Battle"], -- Skybreaker Mortar Soldier
+ [37116] = L["Icecrown Gunship Battle"], -- Skybreaker Sorcerer
+ [37540] = L["Icecrown Gunship Battle"], -- The Skybreaker
+ [37970] = L["Blood Prince Council"], -- Prince Valanar
+ [37972] = L["Blood Prince Council"], -- Prince Keleseth
+ [37973] = L["Blood Prince Council"], -- Prince Taldaram
+ [36789] = L["Valithria Dreamwalker"], -- Valithria Dreamwalker
+ [36791] = L["Valithria Dreamwalker"], -- Blazing Skeleton
+ [37868] = L["Valithria Dreamwalker"], -- Risen Archmage
+ [37886] = L["Valithria Dreamwalker"], -- Gluttonous Abomination
+ [37934] = L["Valithria Dreamwalker"], -- Blistering Zombie
+ [37985] = L["Valithria Dreamwalker"], -- Dream Cloud
+
+ -- [[ Naxxramas ]] --
+ [16062] = L["The Four Horsemen"], -- Highlord Mograine
+ [16063] = L["The Four Horsemen"], -- Sir Zeliek
+ [16064] = L["The Four Horsemen"], -- Thane Korth'azz
+ [16065] = L["The Four Horsemen"], -- Lady Blaumeux
+ [15930] = L["Thaddius"], -- Feugen
+ [15929] = L["Thaddius"], -- Stalagg
+ [15928] = L["Thaddius"], -- Thaddius
+
+ -- [[ Trial of the Crusader ]] --
+ [34796] = L["The Northrend Beasts"], -- Gormok
+ [35144] = L["The Northrend Beasts"], -- Acidmaw
+ [34799] = L["The Northrend Beasts"], -- Dreadscale
+ [34797] = L["The Northrend Beasts"], -- Icehowl
+
+ -- Champions of the Alliance
+ [34461] = L["Faction Champions"], -- Tyrius Duskblade
+ [34460] = L["Faction Champions"], -- Kavina Grovesong
+ [34469] = L["Faction Champions"], -- Melador Valestrider
+ [34467] = L["Faction Champions"], -- Alyssia Moonstalker
+ [34468] = L["Faction Champions"], -- Noozle Whizzlestick
+ [34465] = L["Faction Champions"], -- Velanaa
+ [34471] = L["Faction Champions"], -- Baelnor Lightbearer
+ [34466] = L["Faction Champions"], -- Anthar Forgemender
+ [34473] = L["Faction Champions"], -- Brienna Nightfell
+ [34472] = L["Faction Champions"], -- Irieth Shadowstep
+ [34463] = L["Faction Champions"], -- Shaabad
+ [34470] = L["Faction Champions"], -- Saamul
+ [34474] = L["Faction Champions"], -- Serissa Grimdabbler
+ [34475] = L["Faction Champions"], -- Shocuul
+ [35465] = L["Faction Champions"], -- Zhaagrym
+
+ -- Champions of the Horde
+ [34441] = L["Faction Champions"], -- Vivienne Blackwhisper
+ [34444] = L["Faction Champions"], -- Thrakgar
+ [34445] = L["Faction Champions"], -- Liandra Suncaller
+ [34447] = L["Faction Champions"], -- Caiphus the Stern
+ [34448] = L["Faction Champions"], -- Ruj'kah
+ [34449] = L["Faction Champions"], -- Ginselle Blightslinger
+ [34450] = L["Faction Champions"], -- Harkzog
+ [34451] = L["Faction Champions"], -- Birana Stormhoof
+ [34453] = L["Faction Champions"], -- Narrhok Steelbreaker
+ [34454] = L["Faction Champions"], -- Maz'dinah
+ [34455] = L["Faction Champions"], -- Broln Stouthorn
+ [34456] = L["Faction Champions"], -- Malithas Brightblade
+ [34458] = L["Faction Champions"], -- Gorgrim Shadowcleave
+ [34459] = L["Faction Champions"], -- Erin Misthoof
+ [35610] = L["Faction Champions"], -- Cat
+
+ [34496] = L["Twin Val'kyr"], -- Eydis Darkbane
+ [34497] = L["Twin Val'kyr"], -- Fjola Lightbane
+
+ -- [[ Ulduar ]] --
+ [32857] = L["The Iron Council"], -- Stormcaller Brundir
+ [32867] = L["The Iron Council"], -- Steelbreaker
+ [32927] = L["The Iron Council"], -- Runemaster Molgeim
+ [32930] = L["Kologarn"], -- Kologarn
+ [32933] = L["Kologarn"], -- Left Arm
+ [32934] = L["Kologarn"], -- Right Arm
+ [33515] = L["Auriaya"], -- Auriaya
+ [34014] = L["Auriaya"], -- Sanctum Sentry
+ [34035] = L["Auriaya"], -- Feral Defender
+ [32882] = L["Thorim"], -- Jormungar Behemoth
+ [33288] = L["Yogg-Saron"], -- Yogg-Saron
+ [33890] = L["Yogg-Saron"], -- Brain of Yogg-Saron
+ [33136] = L["Yogg-Saron"], -- Guardian of Yogg-Saron
+ [33350] = L["Mimiron"], -- Mimiron
+ [33432] = L["Mimiron"], -- Leviathan Mk II
+ [33651] = L["Mimiron"], -- VX-001
+ [33670] = L["Mimiron"], -- Aerial Command Unit
+}
+
+-------------------------------------------------------------------------------
+-- creature_to_boss
+-- a table of adds used to deternmine the main boss in encounters.
+
+ns.creature_to_boss = {
+ -- [[ Icecrown Citadel ]] --
+ [36960] = 37215, -- Kor'kron Sergeant > Orgrim's Hammer
+ [36968] = 37215, -- Kor'kron Axethrower > Orgrim's Hammer
+ [36982] = 37215, -- Kor'kron Rocketeer > Orgrim's Hammer
+ [37117] = 37215, -- Kor'kron Battle-Mage > Orgrim's Hammer
+ [36961] = 37540, -- Skybreaker Sergeant > The Skybreaker
+ [36969] = 37540, -- Skybreaker Rifleman > The Skybreaker
+ [36978] = 37540, -- Skybreaker Mortar Soldier > The Skybreaker
+ [37116] = 37540, -- Skybreaker Sorcerer > The Skybreaker
+ [36791] = 36789, -- Blazing Skeleton > Valithria Dreamwalker
+ [37868] = 36789, -- Risen Archmage > Valithria Dreamwalker
+ [37886] = 36789, -- Gluttonous Abomination > Valithria Dreamwalker
+ [37934] = 36789, -- Blistering Zombie > Valithria Dreamwalker
+ [37985] = 36789, -- Dream Cloud > Valithria Dreamwalker
+
+ -- [[ Naxxramas ]] --
+ [15930] = 15928, -- Feugen > Thaddius
+ [15929] = 15928, -- Stalagg > Thaddius
+
+ -- [[ Trial of the Crusader ]] --
+ [34796] = 34797, -- Gormok > Icehowl
+ [35144] = 34797, -- Acidmaw > Icehowl
+ [34799] = 34797, -- Dreadscale > Icehowl
+
+ -- [[ Ulduar ]] --
+ [32933] = 32930, -- Left Arm > Kologarn
+ [32934] = 32930, -- Right Arm > Kologarn
+ [34014] = 33515, -- Sanctum Sentry > Auriaya
+ [34035] = 33515, -- Feral Defender > Auriaya
+ [32882] = 32865, -- Jormungar Behemoth > Thorim
+ [33890] = 33288, -- Brain of Yogg-Saron > Yogg-Saron
+ [33136] = 33288, -- Guardian of Yogg-Saron > Yogg-Saron
+ [33432] = 33350, -- Leviathan Mk II > Mimiron
+ [33651] = 33350, -- VX-001 > Mimiron
+ [33670] = 33350, -- Aerial Command Unit > Mimiron
+}
+
+-- use LibBossIDs-1.0 as backup plan
+local LBI = LibStub("LibBossIDs-1.0")
+setmetatable(ns.creature_to_boss, {__index = LBI.BossIDs})
+ns.BossIDs = LBI.BossIDs -- needed for some CLEU stuff.
+
+-------------------------------------------------------------------------------
+
+-- ignored spells table
+local dummyTable = ns.dummyTable
+ns.ignored_spells = setmetatable(ignored_spells, {__index = function(t, key)
+ return dummyTable
+end})
+
+-- ignored creatures table
+ns.ignored_creatures = ignored_creatures
+
+-- miss type to table key
+ns.missTypes = {
+ ABSORB = "abs_n",
+ BLOCK = "blo_n",
+ DEFLECT = "def_n",
+ DODGE = "dod_n",
+ EVADE = "eva_n",
+ IMMUNE = "imm_n",
+ MISS = "mis_n",
+ PARRY = "par_n",
+ REFLECT = "ref_n",
+ RESIST = "res_n",
+}
+
+-- list of combat events that we don't care about
+ns.ignored_events = {
+ ENCHANT_APPLIED = true,
+ ENCHANT_REMOVED = true,
+ PARTY_KILL = true,
+ SPELL_AURA_REMOVED_DOSE = true,
+ SPELL_CAST_FAILED = true,
+ SPELL_CAST_START = true,
+ SPELL_CAST_SUCCESS = true,
+ SPELL_CREATE = true,
+ SPELL_DISPEL_FAILED = true,
+ SPELL_DRAIN = true,
+ SPELL_DURABILITY_DAMAGE = true,
+ SPELL_DURABILITY_DAMAGE_ALL = true,
+ SPELL_PERIODIC_DRAIN = true
+}
+
+-- events used to start combat in aggressive combat detection
+-- mode as well as boss encounter detection.
+ns.trigger_events = {
+ SWING_DAMAGE = true,
+ SPELL_DAMAGE = true,
+ RANGE_DAMAGE = true,
+ DAMAGE_SHIELD = true,
+ SPELL_BUILDING_DAMAGE = true
+}
+
+-- local segment types used for set tooltips.
+ns.segment_types = {
+ arena = L["Arena"],
+ group = L["Group"],
+ none = L["None"],
+ party = L["Dungeon"],
+ pvp = L["Battleground"],
+ raid = L["Raid"]
+}
diff --git a/Skada/Libs/AceAddon-3.0/AceAddon-3.0.lua b/Skada/Libs/AceAddon-3.0/AceAddon-3.0.lua
new file mode 100644
index 0000000..a7f7279
--- /dev/null
+++ b/Skada/Libs/AceAddon-3.0/AceAddon-3.0.lua
@@ -0,0 +1,674 @@
+--- **AceAddon-3.0** provides a template for creating addon objects.
+-- It'll provide you with a set of callback functions that allow you to simplify the loading
+-- process of your addon.\\
+-- Callbacks provided are:\\
+-- * **OnInitialize**, which is called directly after the addon is fully loaded.
+-- * **OnEnable** which gets called during the PLAYER_LOGIN event, when most of the data provided by the game is already present.
+-- * **OnDisable**, which is only called when your addon is manually being disabled.
+-- @usage
+-- -- A small (but complete) addon, that doesn't do anything,
+-- -- but shows usage of the callbacks.
+-- local MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
+--
+-- function MyAddon:OnInitialize()
+-- -- do init tasks here, like loading the Saved Variables,
+-- -- or setting up slash commands.
+-- end
+--
+-- function MyAddon:OnEnable()
+-- -- Do more initialization here, that really enables the use of your addon.
+-- -- Register Events, Hook functions, Create Frames, Get information from
+-- -- the game that wasn't available in OnInitialize
+-- end
+--
+-- function MyAddon:OnDisable()
+-- -- Unhook, Unregister Events, Hide frames that you created.
+-- -- You would probably only use an OnDisable if you want to
+-- -- build a "standby" mode, or be able to toggle modules on/off.
+-- end
+-- @class file
+-- @name AceAddon-3.0.lua
+-- @release $Id: AceAddon-3.0.lua 1084 2013-04-27 20:14:11Z nevcairiel $
+
+local MAJOR, MINOR = "AceAddon-3.0", 12
+local AceAddon, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceAddon then return end -- No Upgrade needed.
+
+AceAddon.frame = AceAddon.frame or CreateFrame("Frame", "AceAddon30Frame") -- Our very own frame
+AceAddon.addons = AceAddon.addons or {} -- addons in general
+AceAddon.statuses = AceAddon.statuses or {} -- statuses of addon.
+AceAddon.initializequeue = AceAddon.initializequeue or {} -- addons that are new and not initialized
+AceAddon.enablequeue = AceAddon.enablequeue or {} -- addons that are initialized and waiting to be enabled
+AceAddon.embeds = AceAddon.embeds or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end }) -- contains a list of libraries embedded in an addon
+
+-- Lua APIs
+local tinsert, tconcat, tremove = table.insert, table.concat, table.remove
+local fmt, tostring = string.format, tostring
+local select, pairs, next, type, unpack = select, pairs, next, type, unpack
+local loadstring, assert, error = loadstring, assert, error
+local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
+
+-- 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, IsLoggedIn, geterrorhandler
+
+--[[
+ 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, ...)
+ -- we check to see if the func is passed is actually a function here and don't error when it isn't
+ -- this safecall is used for optional functions like OnInitialize OnEnable etc. When they are not
+ -- present execution should continue without hinderance
+ if type(func) == "function" then
+ return Dispatchers[select('#', ...)](func, ...)
+ end
+end
+
+-- local functions that will be implemented further down
+local Enable, Disable, EnableModule, DisableModule, Embed, NewModule, GetModule, GetName, SetDefaultModuleState, SetDefaultModuleLibraries, SetEnabledState, SetDefaultModulePrototype
+
+-- used in the addon metatable
+local function addontostring( self ) return self.name end
+
+-- Check if the addon is queued for initialization
+local function queuedForInitialization(addon)
+ for i = 1, #AceAddon.initializequeue do
+ if AceAddon.initializequeue[i] == addon then
+ return true
+ end
+ end
+ return false
+end
+
+--- Create a new AceAddon-3.0 addon.
+-- Any libraries you specified will be embeded, and the addon will be scheduled for
+-- its OnInitialize and OnEnable callbacks.
+-- The final addon object, with all libraries embeded, will be returned.
+-- @paramsig [object ,]name[, lib, ...]
+-- @param object Table to use as a base for the addon (optional)
+-- @param name Name of the addon object to create
+-- @param lib List of libraries to embed into the addon
+-- @usage
+-- -- Create a simple addon object
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceEvent-3.0")
+--
+-- -- Create a Addon object based on the table of a frame
+-- local MyFrame = CreateFrame("Frame")
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon(MyFrame, "MyAddon", "AceEvent-3.0")
+function AceAddon:NewAddon(objectorname, ...)
+ local object,name
+ local i=1
+ if type(objectorname)=="table" then
+ object=objectorname
+ name=...
+ i=2
+ else
+ name=objectorname
+ end
+ if type(name)~="string" then
+ error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2)
+ end
+ if self.addons[name] then
+ error(("Usage: NewAddon([object,] name, [lib, lib, lib, ...]): 'name' - Addon '%s' already exists."):format(name), 2)
+ end
+
+ object = object or {}
+ object.name = name
+
+ local addonmeta = {}
+ local oldmeta = getmetatable(object)
+ if oldmeta then
+ for k, v in pairs(oldmeta) do addonmeta[k] = v end
+ end
+ addonmeta.__tostring = addontostring
+
+ setmetatable( object, addonmeta )
+ self.addons[name] = object
+ object.modules = {}
+ object.orderedModules = {}
+ object.defaultModuleLibraries = {}
+ Embed( object ) -- embed NewModule, GetModule methods
+ self:EmbedLibraries(object, select(i,...))
+
+ -- add to queue of addons to be initialized upon ADDON_LOADED
+ tinsert(self.initializequeue, object)
+ return object
+end
+
+
+--- Get the addon object by its name from the internal AceAddon registry.
+-- Throws an error if the addon object cannot be found (except if silent is set).
+-- @param name unique name of the addon object
+-- @param silent if true, the addon is optional, silently return nil if its not found
+-- @usage
+-- -- Get the Addon
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+function AceAddon:GetAddon(name, silent)
+ if not silent and not self.addons[name] then
+ error(("Usage: GetAddon(name): 'name' - Cannot find an AceAddon '%s'."):format(tostring(name)), 2)
+ end
+ return self.addons[name]
+end
+
+-- - Embed a list of libraries into the specified addon.
+-- This function will try to embed all of the listed libraries into the addon
+-- and error if a single one fails.
+--
+-- **Note:** This function is for internal use by :NewAddon/:NewModule
+-- @paramsig addon, [lib, ...]
+-- @param addon addon object to embed the libs in
+-- @param lib List of libraries to embed into the addon
+function AceAddon:EmbedLibraries(addon, ...)
+ for i=1,select("#", ... ) do
+ local libname = select(i, ...)
+ self:EmbedLibrary(addon, libname, false, 4)
+ end
+end
+
+-- - Embed a library into the addon object.
+-- This function will check if the specified library is registered with LibStub
+-- and if it has a :Embed function to call. It'll error if any of those conditions
+-- fails.
+--
+-- **Note:** This function is for internal use by :EmbedLibraries
+-- @paramsig addon, libname[, silent[, offset]]
+-- @param addon addon object to embed the library in
+-- @param libname name of the library to embed
+-- @param silent marks an embed to fail silently if the library doesn't exist (optional)
+-- @param offset will push the error messages back to said offset, defaults to 2 (optional)
+function AceAddon:EmbedLibrary(addon, libname, silent, offset)
+ local lib = LibStub:GetLibrary(libname, true)
+ if not lib and not silent then
+ error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Cannot find a library instance of %q."):format(tostring(libname)), offset or 2)
+ elseif lib and type(lib.Embed) == "function" then
+ lib:Embed(addon)
+ tinsert(self.embeds[addon], libname)
+ return true
+ elseif lib then
+ error(("Usage: EmbedLibrary(addon, libname, silent, offset): 'libname' - Library '%s' is not Embed capable"):format(libname), offset or 2)
+ end
+end
+
+--- Return the specified module from an addon object.
+-- Throws an error if the addon object cannot be found (except if silent is set)
+-- @name //addon//:GetModule
+-- @paramsig name[, silent]
+-- @param name unique name of the module
+-- @param silent if true, the module is optional, silently return nil if its not found (optional)
+-- @usage
+-- -- Get the Addon
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- -- Get the Module
+-- MyModule = MyAddon:GetModule("MyModule")
+function GetModule(self, name, silent)
+ if not self.modules[name] and not silent then
+ error(("Usage: GetModule(name, silent): 'name' - Cannot find module '%s'."):format(tostring(name)), 2)
+ end
+ return self.modules[name]
+end
+
+local function IsModuleTrue(self) return true end
+
+--- Create a new module for the addon.
+-- The new module can have its own embeded libraries and/or use a module prototype to be mixed into the module.\\
+-- A module has the same functionality as a real addon, it can have modules of its own, and has the same API as
+-- an addon object.
+-- @name //addon//:NewModule
+-- @paramsig name[, prototype|lib[, lib, ...]]
+-- @param name unique name of the module
+-- @param prototype object to derive this module from, methods and values from this table will be mixed into the module (optional)
+-- @param lib List of libraries to embed into the addon
+-- @usage
+-- -- Create a module with some embeded libraries
+-- MyModule = MyAddon:NewModule("MyModule", "AceEvent-3.0", "AceHook-3.0")
+--
+-- -- Create a module with a prototype
+-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
+-- MyModule = MyAddon:NewModule("MyModule", prototype, "AceEvent-3.0", "AceHook-3.0")
+function NewModule(self, name, prototype, ...)
+ if type(name) ~= "string" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - string expected got '%s'."):format(type(name)), 2) end
+ if type(prototype) ~= "string" and type(prototype) ~= "table" and type(prototype) ~= "nil" then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'prototype' - table (prototype), string (lib) or nil expected got '%s'."):format(type(prototype)), 2) end
+
+ if self.modules[name] then error(("Usage: NewModule(name, [prototype, [lib, lib, lib, ...]): 'name' - Module '%s' already exists."):format(name), 2) end
+
+ -- modules are basically addons. We treat them as such. They will be added to the initializequeue properly as well.
+ -- NewModule can only be called after the parent addon is present thus the modules will be initialized after their parent is.
+ local module = AceAddon:NewAddon(fmt("%s_%s", self.name or tostring(self), name))
+
+ module.IsModule = IsModuleTrue
+ module:SetEnabledState(self.defaultModuleState)
+ module.moduleName = name
+
+ if type(prototype) == "string" then
+ AceAddon:EmbedLibraries(module, prototype, ...)
+ else
+ AceAddon:EmbedLibraries(module, ...)
+ end
+ AceAddon:EmbedLibraries(module, unpack(self.defaultModuleLibraries))
+
+ if not prototype or type(prototype) == "string" then
+ prototype = self.defaultModulePrototype or nil
+ end
+
+ if type(prototype) == "table" then
+ local mt = getmetatable(module)
+ mt.__index = prototype
+ setmetatable(module, mt) -- More of a Base class type feel.
+ end
+
+ safecall(self.OnModuleCreated, self, module) -- Was in Ace2 and I think it could be a cool thing to have handy.
+ self.modules[name] = module
+ tinsert(self.orderedModules, module)
+
+ return module
+end
+
+--- Returns the real name of the addon or module, without any prefix.
+-- @name //addon//:GetName
+-- @paramsig
+-- @usage
+-- print(MyAddon:GetName())
+-- -- prints "MyAddon"
+function GetName(self)
+ return self.moduleName or self.name
+end
+
+--- Enables the Addon, if possible, return true or false depending on success.
+-- This internally calls AceAddon:EnableAddon(), thus dispatching a OnEnable callback
+-- and enabling all modules of the addon (unless explicitly disabled).\\
+-- :Enable() also sets the internal `enableState` variable to true
+-- @name //addon//:Enable
+-- @paramsig
+-- @usage
+-- -- Enable MyModule
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- MyModule = MyAddon:GetModule("MyModule")
+-- MyModule:Enable()
+function Enable(self)
+ self:SetEnabledState(true)
+
+ -- nevcairiel 2013-04-27: don't enable an addon/module if its queued for init still
+ -- it'll be enabled after the init process
+ if not queuedForInitialization(self) then
+ return AceAddon:EnableAddon(self)
+ end
+end
+
+--- Disables the Addon, if possible, return true or false depending on success.
+-- This internally calls AceAddon:DisableAddon(), thus dispatching a OnDisable callback
+-- and disabling all modules of the addon.\\
+-- :Disable() also sets the internal `enableState` variable to false
+-- @name //addon//:Disable
+-- @paramsig
+-- @usage
+-- -- Disable MyAddon
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- MyAddon:Disable()
+function Disable(self)
+ self:SetEnabledState(false)
+ return AceAddon:DisableAddon(self)
+end
+
+--- Enables the Module, if possible, return true or false depending on success.
+-- Short-hand function that retrieves the module via `:GetModule` and calls `:Enable` on the module object.
+-- @name //addon//:EnableModule
+-- @paramsig name
+-- @usage
+-- -- Enable MyModule using :GetModule
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- MyModule = MyAddon:GetModule("MyModule")
+-- MyModule:Enable()
+--
+-- -- Enable MyModule using the short-hand
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- MyAddon:EnableModule("MyModule")
+function EnableModule(self, name)
+ local module = self:GetModule( name )
+ return module:Enable()
+end
+
+--- Disables the Module, if possible, return true or false depending on success.
+-- Short-hand function that retrieves the module via `:GetModule` and calls `:Disable` on the module object.
+-- @name //addon//:DisableModule
+-- @paramsig name
+-- @usage
+-- -- Disable MyModule using :GetModule
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- MyModule = MyAddon:GetModule("MyModule")
+-- MyModule:Disable()
+--
+-- -- Disable MyModule using the short-hand
+-- MyAddon = LibStub("AceAddon-3.0"):GetAddon("MyAddon")
+-- MyAddon:DisableModule("MyModule")
+function DisableModule(self, name)
+ local module = self:GetModule( name )
+ return module:Disable()
+end
+
+--- Set the default libraries to be mixed into all modules created by this object.
+-- Note that you can only change the default module libraries before any module is created.
+-- @name //addon//:SetDefaultModuleLibraries
+-- @paramsig lib[, lib, ...]
+-- @param lib List of libraries to embed into the addon
+-- @usage
+-- -- Create the addon object
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
+-- -- Configure default libraries for modules (all modules need AceEvent-3.0)
+-- MyAddon:SetDefaultModuleLibraries("AceEvent-3.0")
+-- -- Create a module
+-- MyModule = MyAddon:NewModule("MyModule")
+function SetDefaultModuleLibraries(self, ...)
+ if next(self.modules) then
+ error("Usage: SetDefaultModuleLibraries(...): cannot change the module defaults after a module has been registered.", 2)
+ end
+ self.defaultModuleLibraries = {...}
+end
+
+--- Set the default state in which new modules are being created.
+-- Note that you can only change the default state before any module is created.
+-- @name //addon//:SetDefaultModuleState
+-- @paramsig state
+-- @param state Default state for new modules, true for enabled, false for disabled
+-- @usage
+-- -- Create the addon object
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon")
+-- -- Set the default state to "disabled"
+-- MyAddon:SetDefaultModuleState(false)
+-- -- Create a module and explicilty enable it
+-- MyModule = MyAddon:NewModule("MyModule")
+-- MyModule:Enable()
+function SetDefaultModuleState(self, state)
+ if next(self.modules) then
+ error("Usage: SetDefaultModuleState(state): cannot change the module defaults after a module has been registered.", 2)
+ end
+ self.defaultModuleState = state
+end
+
+--- Set the default prototype to use for new modules on creation.
+-- Note that you can only change the default prototype before any module is created.
+-- @name //addon//:SetDefaultModulePrototype
+-- @paramsig prototype
+-- @param prototype Default prototype for the new modules (table)
+-- @usage
+-- -- Define a prototype
+-- local prototype = { OnEnable = function(self) print("OnEnable called!") end }
+-- -- Set the default prototype
+-- MyAddon:SetDefaultModulePrototype(prototype)
+-- -- Create a module and explicitly Enable it
+-- MyModule = MyAddon:NewModule("MyModule")
+-- MyModule:Enable()
+-- -- should print "OnEnable called!" now
+-- @see NewModule
+function SetDefaultModulePrototype(self, prototype)
+ if next(self.modules) then
+ error("Usage: SetDefaultModulePrototype(prototype): cannot change the module defaults after a module has been registered.", 2)
+ end
+ if type(prototype) ~= "table" then
+ error(("Usage: SetDefaultModulePrototype(prototype): 'prototype' - table expected got '%s'."):format(type(prototype)), 2)
+ end
+ self.defaultModulePrototype = prototype
+end
+
+--- Set the state of an addon or module
+-- This should only be called before any enabling actually happend, e.g. in/before OnInitialize.
+-- @name //addon//:SetEnabledState
+-- @paramsig state
+-- @param state the state of an addon or module (enabled=true, disabled=false)
+function SetEnabledState(self, state)
+ self.enabledState = state
+end
+
+
+--- Return an iterator of all modules associated to the addon.
+-- @name //addon//:IterateModules
+-- @paramsig
+-- @usage
+-- -- Enable all modules
+-- for name, module in MyAddon:IterateModules() do
+-- module:Enable()
+-- end
+local function IterateModules(self) return pairs(self.modules) end
+
+-- Returns an iterator of all embeds in the addon
+-- @name //addon//:IterateEmbeds
+-- @paramsig
+local function IterateEmbeds(self) return pairs(AceAddon.embeds[self]) end
+
+--- Query the enabledState of an addon.
+-- @name //addon//:IsEnabled
+-- @paramsig
+-- @usage
+-- if MyAddon:IsEnabled() then
+-- MyAddon:Disable()
+-- end
+local function IsEnabled(self) return self.enabledState end
+local mixins = {
+ NewModule = NewModule,
+ GetModule = GetModule,
+ Enable = Enable,
+ Disable = Disable,
+ EnableModule = EnableModule,
+ DisableModule = DisableModule,
+ IsEnabled = IsEnabled,
+ SetDefaultModuleLibraries = SetDefaultModuleLibraries,
+ SetDefaultModuleState = SetDefaultModuleState,
+ SetDefaultModulePrototype = SetDefaultModulePrototype,
+ SetEnabledState = SetEnabledState,
+ IterateModules = IterateModules,
+ IterateEmbeds = IterateEmbeds,
+ GetName = GetName,
+}
+local function IsModule(self) return false end
+local pmixins = {
+ defaultModuleState = true,
+ enabledState = true,
+ IsModule = IsModule,
+}
+-- Embed( target )
+-- target (object) - target object to embed aceaddon in
+--
+-- this is a local function specifically since it's meant to be only called internally
+function Embed(target, skipPMixins)
+ for k, v in pairs(mixins) do
+ target[k] = v
+ end
+ if not skipPMixins then
+ for k, v in pairs(pmixins) do
+ target[k] = target[k] or v
+ end
+ end
+end
+
+
+-- - Initialize the addon after creation.
+-- This function is only used internally during the ADDON_LOADED event
+-- It will call the **OnInitialize** function on the addon object (if present),
+-- and the **OnEmbedInitialize** function on all embeded libraries.
+--
+-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
+-- @param addon addon object to intialize
+function AceAddon:InitializeAddon(addon)
+ safecall(addon.OnInitialize, addon)
+
+ local embeds = self.embeds[addon]
+ for i = 1, #embeds do
+ local lib = LibStub:GetLibrary(embeds[i], true)
+ if lib then safecall(lib.OnEmbedInitialize, lib, addon) end
+ end
+
+ -- we don't call InitializeAddon on modules specifically, this is handled
+ -- from the event handler and only done _once_
+end
+
+-- - Enable the addon after creation.
+-- Note: This function is only used internally during the PLAYER_LOGIN event, or during ADDON_LOADED,
+-- if IsLoggedIn() already returns true at that point, e.g. for LoD Addons.
+-- It will call the **OnEnable** function on the addon object (if present),
+-- and the **OnEmbedEnable** function on all embeded libraries.\\
+-- This function does not toggle the enable state of the addon itself, and will return early if the addon is disabled.
+--
+-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
+-- Use :Enable on the addon itself instead.
+-- @param addon addon object to enable
+function AceAddon:EnableAddon(addon)
+ if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
+ if self.statuses[addon.name] or not addon.enabledState then return false end
+
+ -- set the statuses first, before calling the OnEnable. this allows for Disabling of the addon in OnEnable.
+ self.statuses[addon.name] = true
+
+ safecall(addon.OnEnable, addon)
+
+ -- make sure we're still enabled before continueing
+ if self.statuses[addon.name] then
+ local embeds = self.embeds[addon]
+ for i = 1, #embeds do
+ local lib = LibStub:GetLibrary(embeds[i], true)
+ if lib then safecall(lib.OnEmbedEnable, lib, addon) end
+ end
+
+ -- enable possible modules.
+ local modules = addon.orderedModules
+ for i = 1, #modules do
+ self:EnableAddon(modules[i])
+ end
+ end
+ return self.statuses[addon.name] -- return true if we're disabled
+end
+
+-- - Disable the addon
+-- Note: This function is only used internally.
+-- It will call the **OnDisable** function on the addon object (if present),
+-- and the **OnEmbedDisable** function on all embeded libraries.\\
+-- This function does not toggle the enable state of the addon itself, and will return early if the addon is still enabled.
+--
+-- **Note:** Do not call this function manually, unless you're absolutely sure that you know what you are doing.
+-- Use :Disable on the addon itself instead.
+-- @param addon addon object to enable
+function AceAddon:DisableAddon(addon)
+ if type(addon) == "string" then addon = AceAddon:GetAddon(addon) end
+ if not self.statuses[addon.name] then return false end
+
+ -- set statuses first before calling OnDisable, this allows for aborting the disable in OnDisable.
+ self.statuses[addon.name] = false
+
+ safecall( addon.OnDisable, addon )
+
+ -- make sure we're still disabling...
+ if not self.statuses[addon.name] then
+ local embeds = self.embeds[addon]
+ for i = 1, #embeds do
+ local lib = LibStub:GetLibrary(embeds[i], true)
+ if lib then safecall(lib.OnEmbedDisable, lib, addon) end
+ end
+ -- disable possible modules.
+ local modules = addon.orderedModules
+ for i = 1, #modules do
+ self:DisableAddon(modules[i])
+ end
+ end
+
+ return not self.statuses[addon.name] -- return true if we're disabled
+end
+
+--- Get an iterator over all registered addons.
+-- @usage
+-- -- Print a list of all installed AceAddon's
+-- for name, addon in AceAddon:IterateAddons() do
+-- print("Addon: " .. name)
+-- end
+function AceAddon:IterateAddons() return pairs(self.addons) end
+
+--- Get an iterator over the internal status registry.
+-- @usage
+-- -- Print a list of all enabled addons
+-- for name, status in AceAddon:IterateAddonStatus() do
+-- if status then
+-- print("EnabledAddon: " .. name)
+-- end
+-- end
+function AceAddon:IterateAddonStatus() return pairs(self.statuses) end
+
+-- Following Iterators are deprecated, and their addon specific versions should be used
+-- e.g. addon:IterateEmbeds() instead of :IterateEmbedsOnAddon(addon)
+function AceAddon:IterateEmbedsOnAddon(addon) return pairs(self.embeds[addon]) end
+function AceAddon:IterateModulesOfAddon(addon) return pairs(addon.modules) end
+
+-- Event Handling
+local function onEvent(this, event, arg1)
+ -- 2011-08-17 nevcairiel - ignore the load event of Blizzard_DebugTools, so a potential startup error isn't swallowed up
+ if (event == "ADDON_LOADED" and arg1 ~= "Blizzard_DebugTools") or event == "PLAYER_LOGIN" then
+ -- if a addon loads another addon, recursion could happen here, so we need to validate the table on every iteration
+ while(#AceAddon.initializequeue > 0) do
+ local addon = tremove(AceAddon.initializequeue, 1)
+ -- this might be an issue with recursion - TODO: validate
+ if event == "ADDON_LOADED" then addon.baseName = arg1 end
+ AceAddon:InitializeAddon(addon)
+ tinsert(AceAddon.enablequeue, addon)
+ end
+
+ if IsLoggedIn() then
+ while(#AceAddon.enablequeue > 0) do
+ local addon = tremove(AceAddon.enablequeue, 1)
+ AceAddon:EnableAddon(addon)
+ end
+ end
+ end
+end
+
+AceAddon.frame:RegisterEvent("ADDON_LOADED")
+AceAddon.frame:RegisterEvent("PLAYER_LOGIN")
+AceAddon.frame:SetScript("OnEvent", onEvent)
+
+-- upgrade embeded
+for name, addon in pairs(AceAddon.addons) do
+ Embed(addon, true)
+end
+
+-- 2010-10-27 nevcairiel - add new "orderedModules" table
+if oldminor and oldminor < 10 then
+ for name, addon in pairs(AceAddon.addons) do
+ addon.orderedModules = {}
+ for module_name, module in pairs(addon.modules) do
+ tinsert(addon.orderedModules, module)
+ end
+ end
+end
diff --git a/Skada/Libs/AceBucket-3.0/AceBucket-3.0.lua b/Skada/Libs/AceBucket-3.0/AceBucket-3.0.lua
new file mode 100644
index 0000000..d5e1065
--- /dev/null
+++ b/Skada/Libs/AceBucket-3.0/AceBucket-3.0.lua
@@ -0,0 +1,293 @@
+--- A bucket to catch events in. **AceBucket-3.0** provides throttling of events that fire in bursts and
+-- your addon only needs to know about the full burst.
+--
+-- This Bucket implementation works as follows:\\
+-- Initially, no schedule is running, and its waiting for the first event to happen.\\
+-- The first event will start the bucket, and get the scheduler running, which will collect all
+-- events in the given interval. When that interval is reached, the bucket is pushed to the
+-- callback and a new schedule is started. When a bucket is empty after its interval, the scheduler is
+-- stopped, and the bucket is only listening for the next event to happen, basically back in its initial state.
+--
+-- In addition, the buckets collect information about the "arg1" argument of the events that fire, and pass those as a
+-- table to your callback. This functionality was mostly designed for the UNIT_* events.\\
+-- The table will have the different values of "arg1" as keys, and the number of occurances as their value, e.g.\\
+-- { ["player"] = 2, ["target"] = 1, ["party1"] = 1 }
+--
+-- **AceBucket-3.0** can be embeded into your addon, either explicitly by calling AceBucket:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceBucket itself.\\
+-- It is recommended to embed AceBucket, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceBucket.
+-- @usage
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("BucketExample", "AceBucket-3.0")
+--
+-- function MyAddon:OnEnable()
+-- -- Register a bucket that listens to all the HP related events,
+-- -- and fires once per second
+-- self:RegisterBucketEvent({"UNIT_HEALTH", "UNIT_MAXHEALTH"}, 1, "UpdateHealth")
+-- end
+--
+-- function MyAddon:UpdateHealth(units)
+-- if units.player then
+-- print("Your HP changed!")
+-- end
+-- end
+-- @class file
+-- @name AceBucket-3.0.lua
+-- @release $Id: AceBucket-3.0.lua 895 2009-12-06 16:28:55Z nevcairiel $
+
+local MAJOR, MINOR = "AceBucket-3.0", 3
+local AceBucket, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceBucket then return end -- No Upgrade needed
+
+AceBucket.buckets = AceBucket.buckets or {}
+AceBucket.embeds = AceBucket.embeds or {}
+
+-- the libraries will be lazyly bound later, to avoid errors due to loading order issues
+local AceEvent, AceTimer
+
+-- Lua APIs
+local tconcat = table.concat
+local type, next, pairs, select = type, next, pairs, select
+local tonumber, tostring, rawset = tonumber, tostring, rawset
+local assert, loadstring, error = assert, loadstring, error
+
+-- 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, geterrorhandler
+
+local bucketCache = setmetatable({}, {__mode='k'})
+
+--[[
+ 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
+
+-- FireBucket ( bucket )
+--
+-- send the bucket to the callback function and schedule the next FireBucket in interval seconds
+local function FireBucket(bucket)
+ local received = bucket.received
+
+ -- we dont want to fire empty buckets
+ if next(received) then
+ local callback = bucket.callback
+ if type(callback) == "string" then
+ safecall(bucket.object[callback], bucket.object, received)
+ else
+ safecall(callback, received)
+ end
+
+ for k in pairs(received) do
+ received[k] = nil
+ end
+
+ -- if the bucket was not empty, schedule another FireBucket in interval seconds
+ bucket.timer = AceTimer.ScheduleTimer(bucket, FireBucket, bucket.interval, bucket)
+ else -- if it was empty, clear the timer and wait for the next event
+ bucket.timer = nil
+ end
+end
+
+-- BucketHandler ( event, arg1 )
+--
+-- callback func for AceEvent
+-- stores arg1 in the received table, and schedules the bucket if necessary
+local function BucketHandler(self, event, arg1)
+ if arg1 == nil then
+ arg1 = "nil"
+ end
+
+ self.received[arg1] = (self.received[arg1] or 0) + 1
+
+ -- if we are not scheduled yet, start a timer on the interval for our bucket to be cleared
+ if not self.timer then
+ self.timer = AceTimer.ScheduleTimer(self, FireBucket, self.interval, self)
+ end
+end
+
+-- RegisterBucket( event, interval, callback, isMessage )
+--
+-- event(string or table) - the event, or a table with the events, that this bucket listens to
+-- interval(int) - time between bucket fireings
+-- callback(func or string) - function pointer, or method name of the object, that gets called when the bucket is cleared
+-- isMessage(boolean) - register AceEvent Messages instead of game events
+local function RegisterBucket(self, event, interval, callback, isMessage)
+ -- try to fetch the librarys
+ if not AceEvent or not AceTimer then
+ AceEvent = LibStub:GetLibrary("AceEvent-3.0", true)
+ AceTimer = LibStub:GetLibrary("AceTimer-3.0", true)
+ if not AceEvent or not AceTimer then
+ error(MAJOR .. " requires AceEvent-3.0 and AceTimer-3.0", 3)
+ end
+ end
+
+ if type(event) ~= "string" and type(event) ~= "table" then error("Usage: RegisterBucket(event, interval, callback): 'event' - string or table expected.", 3) end
+ if not callback then
+ if type(event) == "string" then
+ callback = event
+ else
+ error("Usage: RegisterBucket(event, interval, callback): cannot omit callback when event is not a string.", 3)
+ end
+ end
+ if not tonumber(interval) then error("Usage: RegisterBucket(event, interval, callback): 'interval' - number expected.", 3) end
+ if type(callback) ~= "string" and type(callback) ~= "function" then error("Usage: RegisterBucket(event, interval, callback): 'callback' - string or function or nil expected.", 3) end
+ if type(callback) == "string" and type(self[callback]) ~= "function" then error("Usage: RegisterBucket(event, interval, callback): 'callback' - method not found on target object.", 3) end
+
+ local bucket = next(bucketCache)
+ if bucket then
+ bucketCache[bucket] = nil
+ else
+ bucket = { handler = BucketHandler, received = {} }
+ end
+ bucket.object, bucket.callback, bucket.interval = self, callback, tonumber(interval)
+
+ local regFunc = isMessage and AceEvent.RegisterMessage or AceEvent.RegisterEvent
+
+ if type(event) == "table" then
+ for _,e in pairs(event) do
+ regFunc(bucket, e, "handler")
+ end
+ else
+ regFunc(bucket, event, "handler")
+ end
+
+ local handle = tostring(bucket)
+ AceBucket.buckets[handle] = bucket
+
+ return handle
+end
+
+--- Register a Bucket for an event (or a set of events)
+-- @param event The event to listen for, or a table of events.
+-- @param interval The Bucket interval (burst interval)
+-- @param callback The callback function, either as a function reference, or a string pointing to a method of the addon object.
+-- @return The handle of the bucket (for unregistering)
+-- @usage
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceBucket-3.0")
+-- MyAddon:RegisterBucketEvent("BAG_UPDATE", 0.2, "UpdateBags")
+--
+-- function MyAddon:UpdateBags()
+-- -- do stuff
+-- end
+function AceBucket:RegisterBucketEvent(event, interval, callback)
+ return RegisterBucket(self, event, interval, callback, false)
+end
+
+--- Register a Bucket for an AceEvent-3.0 addon message (or a set of messages)
+-- @param message The message to listen for, or a table of messages.
+-- @param interval The Bucket interval (burst interval)
+-- @param callback The callback function, either as a function reference, or a string pointing to a method of the addon object.
+-- @return The handle of the bucket (for unregistering)
+-- @usage
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceBucket-3.0")
+-- MyAddon:RegisterBucketEvent("SomeAddon_InformationMessage", 0.2, "ProcessData")
+--
+-- function MyAddon:ProcessData()
+-- -- do stuff
+-- end
+function AceBucket:RegisterBucketMessage(message, interval, callback)
+ return RegisterBucket(self, message, interval, callback, true)
+end
+
+--- Unregister any events and messages from the bucket and clear any remaining data.
+-- @param handle The handle of the bucket as returned by RegisterBucket*
+function AceBucket:UnregisterBucket(handle)
+ local bucket = AceBucket.buckets[handle]
+ if bucket then
+ AceEvent.UnregisterAllEvents(bucket)
+ AceEvent.UnregisterAllMessages(bucket)
+
+ -- clear any remaining data in the bucket
+ for k in pairs(bucket.received) do
+ bucket.received[k] = nil
+ end
+
+ if bucket.timer then
+ AceTimer.CancelTimer(bucket, bucket.timer)
+ bucket.timer = nil
+ end
+
+ AceBucket.buckets[handle] = nil
+ -- store our bucket in the cache
+ bucketCache[bucket] = true
+ end
+end
+
+--- Unregister all buckets of the current addon object (or custom "self").
+function AceBucket:UnregisterAllBuckets()
+ -- hmm can we do this more efficient? (it is not done often so shouldn't matter much)
+ for handle, bucket in pairs(AceBucket.buckets) do
+ if bucket.object == self then
+ AceBucket.UnregisterBucket(self, handle)
+ end
+ end
+end
+
+
+
+-- embedding and embed handling
+local mixins = {
+ "RegisterBucketEvent",
+ "RegisterBucketMessage",
+ "UnregisterBucket",
+ "UnregisterAllBuckets",
+}
+
+-- Embeds AceBucket into the target object making the functions from the mixins list available on target:..
+-- @param target target object to embed AceBucket in
+function AceBucket:Embed( target )
+ for _, v in pairs( mixins ) do
+ target[v] = self[v]
+ end
+ self.embeds[target] = true
+ return target
+end
+
+function AceBucket:OnEmbedDisable( target )
+ target:UnregisterAllBuckets()
+end
+
+for addon in pairs(AceBucket.embeds) do
+ AceBucket:Embed(addon)
+end
diff --git a/Skada/Libs/AceComm-3.0/AceComm-3.0.lua b/Skada/Libs/AceComm-3.0/AceComm-3.0.lua
new file mode 100644
index 0000000..5815530
--- /dev/null
+++ b/Skada/Libs/AceComm-3.0/AceComm-3.0.lua
@@ -0,0 +1,301 @@
+--- **AceComm-3.0** allows you to send messages of unlimited length over the addon comm channels.
+-- It'll automatically split the messages into multiple parts and rebuild them on the receiving end.\\
+-- **ChatThrottleLib** is of course being used to avoid being disconnected by the server.
+--
+-- **AceComm-3.0** can be embeded into your addon, either explicitly by calling AceComm:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceComm itself.\\
+-- It is recommended to embed AceComm, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceComm.
+-- @class file
+-- @name AceComm-3.0
+-- @release $Id: AceComm-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $
+
+--[[ AceComm-3.0
+
+TODO: Time out old data rotting around from dead senders? Not a HUGE deal since the number of possible sender names is somewhat limited.
+
+]]
+
+local CallbackHandler = LibStub("CallbackHandler-1.0")
+local CTL = assert(ChatThrottleLib, "AceComm-3.0 requires ChatThrottleLib")
+
+local MAJOR, MINOR = "AceComm-3.0", 10
+local AceComm,oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceComm then return end
+
+-- Lua APIs
+local type, next, pairs, tostring = type, next, pairs, tostring
+local strsub, strfind = string.sub, string.find
+local match = string.match
+local tinsert, tconcat = table.insert, table.concat
+local error, assert = error, assert
+
+-- WoW APIs
+local Ambiguate = Ambiguate
+
+-- 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, DEFAULT_CHAT_FRAME, geterrorhandler, RegisterAddonMessagePrefix
+
+AceComm.embeds = AceComm.embeds or {}
+
+-- for my sanity and yours, let's give the message type bytes some names
+local MSG_MULTI_FIRST = "\001"
+local MSG_MULTI_NEXT = "\002"
+local MSG_MULTI_LAST = "\003"
+local MSG_ESCAPE = "\004"
+
+-- remove old structures (pre WoW 4.0)
+AceComm.multipart_origprefixes = nil
+AceComm.multipart_reassemblers = nil
+
+-- the multipart message spool: indexed by a combination of sender+distribution+
+AceComm.multipart_spool = AceComm.multipart_spool or {}
+
+--- Register for Addon Traffic on a specified prefix
+-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent), max 16 characters
+-- @param method Callback to call on message reception: Function reference, or method name (string) to call on self. Defaults to "OnCommReceived"
+function AceComm:RegisterComm(prefix, method)
+ if method == nil then
+ method = "OnCommReceived"
+ end
+
+ if #prefix > 16 then -- TODO: 15?
+ error("AceComm:RegisterComm(prefix,method): prefix length is limited to 16 characters")
+ end
+ RegisterAddonMessagePrefix(prefix)
+
+ return AceComm._RegisterComm(self, prefix, method) -- created by CallbackHandler
+end
+
+local warnedPrefix=false
+
+--- Send a message over the Addon Channel
+-- @param prefix A printable character (\032-\255) classification of the message (typically AddonName or AddonNameEvent)
+-- @param text Data to send, nils (\000) not allowed. Any length.
+-- @param distribution Addon channel, e.g. "RAID", "GUILD", etc; see SendAddonMessage API
+-- @param target Destination for some distributions; see SendAddonMessage API
+-- @param prio OPTIONAL: ChatThrottleLib priority, "BULK", "NORMAL" or "ALERT". Defaults to "NORMAL".
+-- @param callbackFn OPTIONAL: callback function to be called as each chunk is sent. receives 3 args: the user supplied arg (see next), the number of bytes sent so far, and the number of bytes total to send.
+-- @param callbackArg: OPTIONAL: first arg to the callback function. nil will be passed if not specified.
+function AceComm:SendCommMessage(prefix, text, distribution, target, prio, callbackFn, callbackArg)
+ prio = prio or "NORMAL" -- pasta's reference implementation had different prio for singlepart and multipart, but that's a very bad idea since that can easily lead to out-of-sequence delivery!
+ if not( type(prefix)=="string" and
+ type(text)=="string" and
+ type(distribution)=="string" and
+ (target==nil or type(target)=="string") and
+ (prio=="BULK" or prio=="NORMAL" or prio=="ALERT")
+ ) then
+ error('Usage: SendCommMessage(addon, "prefix", "text", "distribution"[, "target"[, "prio"[, callbackFn, callbackarg]]])', 2)
+ end
+
+ local textlen = #text
+ local maxtextlen = 255 -- Yes, the max is 255 even if the dev post said 256. I tested. Char 256+ get silently truncated. /Mikk, 20110327
+ local queueName = prefix..distribution..(target or "")
+
+ local ctlCallback = nil
+ if callbackFn then
+ ctlCallback = function(sent)
+ return callbackFn(callbackArg, sent, textlen)
+ end
+ end
+
+ local forceMultipart
+ if match(text, "^[\001-\009]") then -- 4.1+: see if the first character is a control character
+ -- we need to escape the first character with a \004
+ if textlen+1 > maxtextlen then -- would we go over the size limit?
+ forceMultipart = true -- just make it multipart, no escape problems then
+ else
+ text = "\004" .. text
+ end
+ end
+
+ if not forceMultipart and textlen <= maxtextlen then
+ -- fits all in one message
+ CTL:SendAddonMessage(prio, prefix, text, distribution, target, queueName, ctlCallback, textlen)
+ else
+ maxtextlen = maxtextlen - 1 -- 1 extra byte for part indicator in prefix(4.0)/start of message(4.1)
+
+ -- first part
+ local chunk = strsub(text, 1, maxtextlen)
+ CTL:SendAddonMessage(prio, prefix, MSG_MULTI_FIRST..chunk, distribution, target, queueName, ctlCallback, maxtextlen)
+
+ -- continuation
+ local pos = 1+maxtextlen
+
+ while pos+maxtextlen <= textlen do
+ chunk = strsub(text, pos, pos+maxtextlen-1)
+ CTL:SendAddonMessage(prio, prefix, MSG_MULTI_NEXT..chunk, distribution, target, queueName, ctlCallback, pos+maxtextlen-1)
+ pos = pos + maxtextlen
+ end
+
+ -- final part
+ chunk = strsub(text, pos)
+ CTL:SendAddonMessage(prio, prefix, MSG_MULTI_LAST..chunk, distribution, target, queueName, ctlCallback, textlen)
+ end
+end
+
+
+----------------------------------------
+-- Message receiving
+----------------------------------------
+
+do
+ local compost = setmetatable({}, {__mode = "k"})
+ local function new()
+ local t = next(compost)
+ if t then
+ compost[t]=nil
+ for i=#t,3,-1 do -- faster than pairs loop. don't even nil out 1/2 since they'll be overwritten
+ t[i]=nil
+ end
+ return t
+ end
+
+ return {}
+ end
+
+ local function lostdatawarning(prefix,sender,where)
+ DEFAULT_CHAT_FRAME:AddMessage(MAJOR..": Warning: lost network data regarding '"..tostring(prefix).."' from '"..tostring(sender).."' (in "..where..")")
+ end
+
+ function AceComm:OnReceiveMultipartFirst(prefix, message, distribution, sender)
+ local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
+ local spool = AceComm.multipart_spool
+
+ --[[
+ if spool[key] then
+ lostdatawarning(prefix,sender,"First")
+ -- continue and overwrite
+ end
+ --]]
+
+ spool[key] = message -- plain string for now
+ end
+
+ function AceComm:OnReceiveMultipartNext(prefix, message, distribution, sender)
+ local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
+ local spool = AceComm.multipart_spool
+ local olddata = spool[key]
+
+ if not olddata then
+ --lostdatawarning(prefix,sender,"Next")
+ return
+ end
+
+ if type(olddata)~="table" then
+ -- ... but what we have is not a table. So make it one. (Pull a composted one if available)
+ local t = new()
+ t[1] = olddata -- add old data as first string
+ t[2] = message -- and new message as second string
+ spool[key] = t -- and put the table in the spool instead of the old string
+ else
+ tinsert(olddata, message)
+ end
+ end
+
+ function AceComm:OnReceiveMultipartLast(prefix, message, distribution, sender)
+ local key = prefix.."\t"..distribution.."\t"..sender -- a unique stream is defined by the prefix + distribution + sender
+ local spool = AceComm.multipart_spool
+ local olddata = spool[key]
+
+ if not olddata then
+ --lostdatawarning(prefix,sender,"End")
+ return
+ end
+
+ spool[key] = nil
+
+ if type(olddata) == "table" then
+ -- if we've received a "next", the spooled data will be a table for rapid & garbage-free tconcat
+ tinsert(olddata, message)
+ AceComm.callbacks:Fire(prefix, tconcat(olddata, ""), distribution, sender)
+ compost[olddata] = true
+ else
+ -- if we've only received a "first", the spooled data will still only be a string
+ AceComm.callbacks:Fire(prefix, olddata..message, distribution, sender)
+ end
+ end
+end
+
+
+
+
+
+
+----------------------------------------
+-- Embed CallbackHandler
+----------------------------------------
+
+if not AceComm.callbacks then
+ AceComm.callbacks = CallbackHandler:New(AceComm,
+ "_RegisterComm",
+ "UnregisterComm",
+ "UnregisterAllComm")
+end
+
+AceComm.callbacks.OnUsed = nil
+AceComm.callbacks.OnUnused = nil
+
+local function OnEvent(self, event, prefix, message, distribution, sender)
+ if event == "CHAT_MSG_ADDON" then
+ sender = Ambiguate(sender, "none")
+ local control, rest = match(message, "^([\001-\009])(.*)")
+ if control then
+ if control==MSG_MULTI_FIRST then
+ AceComm:OnReceiveMultipartFirst(prefix, rest, distribution, sender)
+ elseif control==MSG_MULTI_NEXT then
+ AceComm:OnReceiveMultipartNext(prefix, rest, distribution, sender)
+ elseif control==MSG_MULTI_LAST then
+ AceComm:OnReceiveMultipartLast(prefix, rest, distribution, sender)
+ elseif control==MSG_ESCAPE then
+ AceComm.callbacks:Fire(prefix, rest, distribution, sender)
+ else
+ -- unknown control character, ignore SILENTLY (dont warn unnecessarily about future extensions!)
+ end
+ else
+ -- single part: fire it off immediately and let CallbackHandler decide if it's registered or not
+ AceComm.callbacks:Fire(prefix, message, distribution, sender)
+ end
+ else
+ assert(false, "Received "..tostring(event).." event?!")
+ end
+end
+
+AceComm.frame = AceComm.frame or CreateFrame("Frame", "AceComm30Frame")
+AceComm.frame:SetScript("OnEvent", OnEvent)
+AceComm.frame:UnregisterAllEvents()
+AceComm.frame:RegisterEvent("CHAT_MSG_ADDON")
+
+
+----------------------------------------
+-- Base library stuff
+----------------------------------------
+
+local mixins = {
+ "RegisterComm",
+ "UnregisterComm",
+ "UnregisterAllComm",
+ "SendCommMessage",
+}
+
+-- Embeds AceComm-3.0 into the target object making the functions from the mixins list available on target:..
+-- @param target target object to embed AceComm-3.0 in
+function AceComm:Embed(target)
+ for k, v in pairs(mixins) do
+ target[v] = self[v]
+ end
+ self.embeds[target] = true
+ return target
+end
+
+function AceComm:OnEmbedDisable(target)
+ target:UnregisterAllComm()
+end
+
+-- Update embeds
+for target, v in pairs(AceComm.embeds) do
+ AceComm:Embed(target)
+end
diff --git a/Skada/Libs/AceComm-3.0/AceComm-3.0.xml b/Skada/Libs/AceComm-3.0/AceComm-3.0.xml
new file mode 100644
index 0000000..09e8d87
--- /dev/null
+++ b/Skada/Libs/AceComm-3.0/AceComm-3.0.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/Skada/Libs/AceComm-3.0/ChatThrottleLib.lua b/Skada/Libs/AceComm-3.0/ChatThrottleLib.lua
new file mode 100644
index 0000000..05a0363
--- /dev/null
+++ b/Skada/Libs/AceComm-3.0/ChatThrottleLib.lua
@@ -0,0 +1,524 @@
+--
+-- ChatThrottleLib by Mikk
+--
+-- Manages AddOn chat output to keep player from getting kicked off.
+--
+-- ChatThrottleLib:SendChatMessage/:SendAddonMessage functions that accept
+-- a Priority ("BULK", "NORMAL", "ALERT") as well as prefix for SendChatMessage.
+--
+-- Priorities get an equal share of available bandwidth when fully loaded.
+-- Communication channels are separated on extension+chattype+destination and
+-- get round-robinned. (Destination only matters for whispers and channels,
+-- obviously)
+--
+-- Will install hooks for SendChatMessage and SendAddonMessage to measure
+-- bandwidth bypassing the library and use less bandwidth itself.
+--
+--
+-- Fully embeddable library. Just copy this file into your addon directory,
+-- add it to the .toc, and it's done.
+--
+-- Can run as a standalone addon also, but, really, just embed it! :-)
+--
+-- LICENSE: ChatThrottleLib is released into the Public Domain
+--
+
+local CTL_VERSION = 23
+
+local _G = _G
+
+if _G.ChatThrottleLib then
+ if _G.ChatThrottleLib.version >= CTL_VERSION then
+ -- There's already a newer (or same) version loaded. Buh-bye.
+ return
+ elseif not _G.ChatThrottleLib.securelyHooked then
+ print("ChatThrottleLib: Warning: There's an ANCIENT ChatThrottleLib.lua (pre-wow 2.0, =v16) in it!")
+ -- ATTEMPT to unhook; this'll behave badly if someone else has hooked...
+ -- ... and if someone has securehooked, they can kiss that goodbye too... >.<
+ _G.SendChatMessage = _G.ChatThrottleLib.ORIG_SendChatMessage
+ if _G.ChatThrottleLib.ORIG_SendAddonMessage then
+ _G.SendAddonMessage = _G.ChatThrottleLib.ORIG_SendAddonMessage
+ end
+ end
+ _G.ChatThrottleLib.ORIG_SendChatMessage = nil
+ _G.ChatThrottleLib.ORIG_SendAddonMessage = nil
+end
+
+if not _G.ChatThrottleLib then
+ _G.ChatThrottleLib = {}
+end
+
+ChatThrottleLib = _G.ChatThrottleLib -- in case some addon does "local ChatThrottleLib" above us and we're copypasted (AceComm-2, sigh)
+local ChatThrottleLib = _G.ChatThrottleLib
+
+ChatThrottleLib.version = CTL_VERSION
+
+
+
+------------------ TWEAKABLES -----------------
+
+ChatThrottleLib.MAX_CPS = 800 -- 2000 seems to be safe if NOTHING ELSE is happening. let's call it 800.
+ChatThrottleLib.MSG_OVERHEAD = 40 -- Guesstimate overhead for sending a message; source+dest+chattype+protocolstuff
+
+ChatThrottleLib.BURST = 4000 -- WoW's server buffer seems to be about 32KB. 8KB should be safe, but seen disconnects on _some_ servers. Using 4KB now.
+
+ChatThrottleLib.MIN_FPS = 20 -- Reduce output CPS to half (and don't burst) if FPS drops below this value
+
+
+local setmetatable = setmetatable
+local table_remove = table.remove
+local tostring = tostring
+local GetTime = GetTime
+local math_min = math.min
+local math_max = math.max
+local next = next
+local strlen = string.len
+local GetFramerate = GetFramerate
+local strlower = string.lower
+local unpack,type,pairs,wipe = unpack,type,pairs,wipe
+local UnitInRaid,UnitInParty = UnitInRaid,UnitInParty
+
+
+-----------------------------------------------------------------------
+-- Double-linked ring implementation
+
+local Ring = {}
+local RingMeta = { __index = Ring }
+
+function Ring:New()
+ local ret = {}
+ setmetatable(ret, RingMeta)
+ return ret
+end
+
+function Ring:Add(obj) -- Append at the "far end" of the ring (aka just before the current position)
+ if self.pos then
+ obj.prev = self.pos.prev
+ obj.prev.next = obj
+ obj.next = self.pos
+ obj.next.prev = obj
+ else
+ obj.next = obj
+ obj.prev = obj
+ self.pos = obj
+ end
+end
+
+function Ring:Remove(obj)
+ obj.next.prev = obj.prev
+ obj.prev.next = obj.next
+ if self.pos == obj then
+ self.pos = obj.next
+ if self.pos == obj then
+ self.pos = nil
+ end
+ end
+end
+
+
+
+-----------------------------------------------------------------------
+-- Recycling bin for pipes
+-- A pipe is a plain integer-indexed queue of messages
+-- Pipes normally live in Rings of pipes (3 rings total, one per priority)
+
+ChatThrottleLib.PipeBin = nil -- pre-v19, drastically different
+local PipeBin = setmetatable({}, {__mode="k"})
+
+local function DelPipe(pipe)
+ PipeBin[pipe] = true
+end
+
+local function NewPipe()
+ local pipe = next(PipeBin)
+ if pipe then
+ wipe(pipe)
+ PipeBin[pipe] = nil
+ return pipe
+ end
+ return {}
+end
+
+
+
+
+-----------------------------------------------------------------------
+-- Recycling bin for messages
+
+ChatThrottleLib.MsgBin = nil -- pre-v19, drastically different
+local MsgBin = setmetatable({}, {__mode="k"})
+
+local function DelMsg(msg)
+ msg[1] = nil
+ -- there's more parameters, but they're very repetetive so the string pool doesn't suffer really, and it's faster to just not delete them.
+ MsgBin[msg] = true
+end
+
+local function NewMsg()
+ local msg = next(MsgBin)
+ if msg then
+ MsgBin[msg] = nil
+ return msg
+ end
+ return {}
+end
+
+
+-----------------------------------------------------------------------
+-- ChatThrottleLib:Init
+-- Initialize queues, set up frame for OnUpdate, etc
+
+
+function ChatThrottleLib:Init()
+
+ -- Set up queues
+ if not self.Prio then
+ self.Prio = {}
+ self.Prio["ALERT"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
+ self.Prio["NORMAL"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
+ self.Prio["BULK"] = { ByName = {}, Ring = Ring:New(), avail = 0 }
+ end
+
+ -- v4: total send counters per priority
+ for _, Prio in pairs(self.Prio) do
+ Prio.nTotalSent = Prio.nTotalSent or 0
+ end
+
+ if not self.avail then
+ self.avail = 0 -- v5
+ end
+ if not self.nTotalSent then
+ self.nTotalSent = 0 -- v5
+ end
+
+
+ -- Set up a frame to get OnUpdate events
+ if not self.Frame then
+ self.Frame = CreateFrame("Frame")
+ self.Frame:Hide()
+ end
+ self.Frame:SetScript("OnUpdate", self.OnUpdate)
+ self.Frame:SetScript("OnEvent", self.OnEvent) -- v11: Monitor P_E_W so we can throttle hard for a few seconds
+ self.Frame:RegisterEvent("PLAYER_ENTERING_WORLD")
+ self.OnUpdateDelay = 0
+ self.LastAvailUpdate = GetTime()
+ self.HardThrottlingBeginTime = GetTime() -- v11: Throttle hard for a few seconds after startup
+
+ -- Hook SendChatMessage and SendAddonMessage so we can measure unpiped traffic and avoid overloads (v7)
+ if not self.securelyHooked then
+ -- Use secure hooks as of v16. Old regular hook support yanked out in v21.
+ self.securelyHooked = true
+ --SendChatMessage
+ hooksecurefunc("SendChatMessage", function(...)
+ return ChatThrottleLib.Hook_SendChatMessage(...)
+ end)
+ --SendAddonMessage
+ hooksecurefunc("SendAddonMessage", function(...)
+ return ChatThrottleLib.Hook_SendAddonMessage(...)
+ end)
+ end
+ self.nBypass = 0
+end
+
+
+-----------------------------------------------------------------------
+-- ChatThrottleLib.Hook_SendChatMessage / .Hook_SendAddonMessage
+
+local bMyTraffic = false
+
+function ChatThrottleLib.Hook_SendChatMessage(text, chattype, language, destination, ...)
+ if bMyTraffic then
+ return
+ end
+ local self = ChatThrottleLib
+ local size = strlen(tostring(text or "")) + strlen(tostring(destination or "")) + self.MSG_OVERHEAD
+ self.avail = self.avail - size
+ self.nBypass = self.nBypass + size -- just a statistic
+end
+function ChatThrottleLib.Hook_SendAddonMessage(prefix, text, chattype, destination, ...)
+ if bMyTraffic then
+ return
+ end
+ local self = ChatThrottleLib
+ local size = tostring(text or ""):len() + tostring(prefix or ""):len();
+ size = size + tostring(destination or ""):len() + self.MSG_OVERHEAD
+ self.avail = self.avail - size
+ self.nBypass = self.nBypass + size -- just a statistic
+end
+
+
+
+-----------------------------------------------------------------------
+-- ChatThrottleLib:UpdateAvail
+-- Update self.avail with how much bandwidth is currently available
+
+function ChatThrottleLib:UpdateAvail()
+ local now = GetTime()
+ local MAX_CPS = self.MAX_CPS;
+ local newavail = MAX_CPS * (now - self.LastAvailUpdate)
+ local avail = self.avail
+
+ if now - self.HardThrottlingBeginTime < 5 then
+ -- First 5 seconds after startup/zoning: VERY hard clamping to avoid irritating the server rate limiter, it seems very cranky then
+ avail = math_min(avail + (newavail*0.1), MAX_CPS*0.5)
+ self.bChoking = true
+ elseif GetFramerate() < self.MIN_FPS then -- GetFrameRate call takes ~0.002 secs
+ avail = math_min(MAX_CPS, avail + newavail*0.5)
+ self.bChoking = true -- just a statistic
+ else
+ avail = math_min(self.BURST, avail + newavail)
+ self.bChoking = false
+ end
+
+ avail = math_max(avail, 0-(MAX_CPS*2)) -- Can go negative when someone is eating bandwidth past the lib. but we refuse to stay silent for more than 2 seconds; if they can do it, we can.
+
+ self.avail = avail
+ self.LastAvailUpdate = now
+
+ return avail
+end
+
+
+-----------------------------------------------------------------------
+-- Despooling logic
+-- Reminder:
+-- - We have 3 Priorities, each containing a "Ring" construct ...
+-- - ... made up of N "Pipe"s (1 for each destination/pipename)
+-- - and each pipe contains messages
+
+function ChatThrottleLib:Despool(Prio)
+ local ring = Prio.Ring
+ while ring.pos and Prio.avail > ring.pos[1].nSize do
+ local msg = table_remove(ring.pos, 1)
+ if not ring.pos[1] then -- did we remove last msg in this pipe?
+ local pipe = Prio.Ring.pos
+ Prio.Ring:Remove(pipe)
+ Prio.ByName[pipe.name] = nil
+ DelPipe(pipe)
+ else
+ Prio.Ring.pos = Prio.Ring.pos.next
+ end
+ local didSend=false
+ local lowerDest = strlower(msg[3] or "")
+ if lowerDest == "raid" and not UnitInRaid("player") then
+ -- do nothing
+ elseif lowerDest == "party" and not UnitInParty("player") then
+ -- do nothing
+ else
+ Prio.avail = Prio.avail - msg.nSize
+ bMyTraffic = true
+ msg.f(unpack(msg, 1, msg.n))
+ bMyTraffic = false
+ Prio.nTotalSent = Prio.nTotalSent + msg.nSize
+ DelMsg(msg)
+ didSend = true
+ end
+ -- notify caller of delivery (even if we didn't send it)
+ if msg.callbackFn then
+ msg.callbackFn (msg.callbackArg, didSend)
+ end
+ -- USER CALLBACK MAY ERROR
+ end
+end
+
+
+function ChatThrottleLib.OnEvent(this,event)
+ -- v11: We know that the rate limiter is touchy after login. Assume that it's touchy after zoning, too.
+ local self = ChatThrottleLib
+ if event == "PLAYER_ENTERING_WORLD" then
+ self.HardThrottlingBeginTime = GetTime() -- Throttle hard for a few seconds after zoning
+ self.avail = 0
+ end
+end
+
+
+function ChatThrottleLib.OnUpdate(this,delay)
+ local self = ChatThrottleLib
+
+ self.OnUpdateDelay = self.OnUpdateDelay + delay
+ if self.OnUpdateDelay < 0.08 then
+ return
+ end
+ self.OnUpdateDelay = 0
+
+ self:UpdateAvail()
+
+ if self.avail < 0 then
+ return -- argh. some bastard is spewing stuff past the lib. just bail early to save cpu.
+ end
+
+ -- See how many of our priorities have queued messages (we only have 3, don't worry about the loop)
+ local n = 0
+ for prioname,Prio in pairs(self.Prio) do
+ if Prio.Ring.pos or Prio.avail < 0 then
+ n = n + 1
+ end
+ end
+
+ -- Anything queued still?
+ if n<1 then
+ -- Nope. Move spillover bandwidth to global availability gauge and clear self.bQueueing
+ for prioname, Prio in pairs(self.Prio) do
+ self.avail = self.avail + Prio.avail
+ Prio.avail = 0
+ end
+ self.bQueueing = false
+ self.Frame:Hide()
+ return
+ end
+
+ -- There's stuff queued. Hand out available bandwidth to priorities as needed and despool their queues
+ local avail = self.avail/n
+ self.avail = 0
+
+ for prioname, Prio in pairs(self.Prio) do
+ if Prio.Ring.pos or Prio.avail < 0 then
+ Prio.avail = Prio.avail + avail
+ if Prio.Ring.pos and Prio.avail > Prio.Ring.pos[1].nSize then
+ self:Despool(Prio)
+ -- Note: We might not get here if the user-supplied callback function errors out! Take care!
+ end
+ end
+ end
+
+end
+
+
+
+
+-----------------------------------------------------------------------
+-- Spooling logic
+
+function ChatThrottleLib:Enqueue(prioname, pipename, msg)
+ local Prio = self.Prio[prioname]
+ local pipe = Prio.ByName[pipename]
+ if not pipe then
+ self.Frame:Show()
+ pipe = NewPipe()
+ pipe.name = pipename
+ Prio.ByName[pipename] = pipe
+ Prio.Ring:Add(pipe)
+ end
+
+ pipe[#pipe + 1] = msg
+
+ self.bQueueing = true
+end
+
+function ChatThrottleLib:SendChatMessage(prio, prefix, text, chattype, language, destination, queueName, callbackFn, callbackArg)
+ if not self or not prio or not prefix or not text or not self.Prio[prio] then
+ error('Usage: ChatThrottleLib:SendChatMessage("{BULK||NORMAL||ALERT}", "prefix", "text"[, "chattype"[, "language"[, "destination"]]]', 2)
+ end
+ if callbackFn and type(callbackFn)~="function" then
+ error('ChatThrottleLib:ChatMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
+ end
+
+ local nSize = text:len()
+
+ if nSize>255 then
+ error("ChatThrottleLib:SendChatMessage(): message length cannot exceed 255 bytes", 2)
+ end
+
+ nSize = nSize + self.MSG_OVERHEAD
+
+ -- Check if there's room in the global available bandwidth gauge to send directly
+ if not self.bQueueing and nSize < self:UpdateAvail() then
+ self.avail = self.avail - nSize
+ bMyTraffic = true
+ _G.SendChatMessage(text, chattype, language, destination)
+ bMyTraffic = false
+ self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
+ if callbackFn then
+ callbackFn (callbackArg, true)
+ end
+ -- USER CALLBACK MAY ERROR
+ return
+ end
+
+ -- Message needs to be queued
+ local msg = NewMsg()
+ msg.f = _G.SendChatMessage
+ msg[1] = text
+ msg[2] = chattype or "SAY"
+ msg[3] = language
+ msg[4] = destination
+ msg.n = 4
+ msg.nSize = nSize
+ msg.callbackFn = callbackFn
+ msg.callbackArg = callbackArg
+
+ self:Enqueue(prio, queueName or (prefix..(chattype or "SAY")..(destination or "")), msg)
+end
+
+
+function ChatThrottleLib:SendAddonMessage(prio, prefix, text, chattype, target, queueName, callbackFn, callbackArg)
+ if not self or not prio or not prefix or not text or not chattype or not self.Prio[prio] then
+ error('Usage: ChatThrottleLib:SendAddonMessage("{BULK||NORMAL||ALERT}", "prefix", "text", "chattype"[, "target"])', 2)
+ end
+ if callbackFn and type(callbackFn)~="function" then
+ error('ChatThrottleLib:SendAddonMessage(): callbackFn: expected function, got '..type(callbackFn), 2)
+ end
+
+ local nSize = text:len();
+
+ if RegisterAddonMessagePrefix then
+ if nSize>255 then
+ error("ChatThrottleLib:SendAddonMessage(): message length cannot exceed 255 bytes", 2)
+ end
+ else
+ nSize = nSize + prefix:len() + 1
+ if nSize>255 then
+ error("ChatThrottleLib:SendAddonMessage(): prefix + message length cannot exceed 254 bytes", 2)
+ end
+ end
+
+ nSize = nSize + self.MSG_OVERHEAD;
+
+ -- Check if there's room in the global available bandwidth gauge to send directly
+ if not self.bQueueing and nSize < self:UpdateAvail() then
+ self.avail = self.avail - nSize
+ bMyTraffic = true
+ _G.SendAddonMessage(prefix, text, chattype, target)
+ bMyTraffic = false
+ self.Prio[prio].nTotalSent = self.Prio[prio].nTotalSent + nSize
+ if callbackFn then
+ callbackFn (callbackArg, true)
+ end
+ -- USER CALLBACK MAY ERROR
+ return
+ end
+
+ -- Message needs to be queued
+ local msg = NewMsg()
+ msg.f = _G.SendAddonMessage
+ msg[1] = prefix
+ msg[2] = text
+ msg[3] = chattype
+ msg[4] = target
+ msg.n = (target~=nil) and 4 or 3;
+ msg.nSize = nSize
+ msg.callbackFn = callbackFn
+ msg.callbackArg = callbackArg
+
+ self:Enqueue(prio, queueName or (prefix..chattype..(target or "")), msg)
+end
+
+
+
+
+-----------------------------------------------------------------------
+-- Get the ball rolling!
+
+ChatThrottleLib:Init()
+
+--[[ WoWBench debugging snippet
+if(WOWB_VER) then
+ local function SayTimer()
+ print("SAY: "..GetTime().." "..arg1)
+ end
+ ChatThrottleLib.Frame:SetScript("OnEvent", SayTimer)
+ ChatThrottleLib.Frame:RegisterEvent("CHAT_MSG_SAY")
+end
+]]
+
+
diff --git a/Skada/Libs/AceConfig-3.0/AceConfig-3.0.lua b/Skada/Libs/AceConfig-3.0/AceConfig-3.0.lua
new file mode 100644
index 0000000..a99ddf7
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfig-3.0.lua
@@ -0,0 +1,58 @@
+--- 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 1161 2017-08-12 14:30:16Z funkydude $
+
+--[[
+AceConfig-3.0
+
+Very light wrapper library that combines all the AceConfig subcomponents into one more easily used whole.
+
+]]
+
+local cfgreg = LibStub("AceConfigRegistry-3.0")
+local cfgcmd = LibStub("AceConfigCmd-3.0")
+
+local MAJOR, MINOR = "AceConfig-3.0", 3
+local AceConfig = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfig then return end
+
+--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/Skada/Libs/AceConfig-3.0/AceConfig-3.0.xml b/Skada/Libs/AceConfig-3.0/AceConfig-3.0.xml
new file mode 100644
index 0000000..a3569b7
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfig-3.0.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
diff --git a/Skada/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua b/Skada/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua
new file mode 100644
index 0000000..33f9fe1
--- /dev/null
+++ b/Skada/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 1161 2017-08-12 14:30:16Z funkydude $
+
+--[[
+AceConfigCmd-3.0
+
+Handles commandline optionstable access
+
+REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
+
+]]
+
+-- TODO: plugin args
+
+local cfgreg = LibStub("AceConfigRegistry-3.0")
+
+local MAJOR, MINOR = "AceConfigCmd-3.0", 14
+local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfigCmd then return end
+
+AceConfigCmd.commands = AceConfigCmd.commands or {}
+local commands = AceConfigCmd.commands
+
+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 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 valinfo.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/Skada/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml b/Skada/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
new file mode 100644
index 0000000..9e157b5
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/Skada/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua b/Skada/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
new file mode 100644
index 0000000..f2d5266
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.lua
@@ -0,0 +1,1974 @@
+--- 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 1163 2017-08-14 14:04:39Z nevcairiel $
+
+local LibStub = LibStub
+local gui = LibStub("AceGUI-3.0")
+local reg = LibStub("AceConfigRegistry-3.0")
+
+local MAJOR, MINOR = "AceConfigDialog-3.0", 64
+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 {}
+
+-- 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 validationErrorPopup(message)
+ if not StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] then
+ StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"] = {}
+ end
+ local t = StaticPopupDialogs["ACECONFIGDIALOG30_VALIDATION_ERROR_DIALOG"]
+ t.text = message
+ t.button1 = OKAY
+ t.preferredIndex = STATICPOPUP_NUMDIALOGS
+ local dialog, oldstrata
+ t.OnAccept = function()
+ if dialog and oldstrata then
+ dialog:SetFrameStrata(oldstrata)
+ end
+ end
+ t.timeout = 0
+ t.whileDead = 1
+ t.hideOnEscape = 1
+
+ dialog = StaticPopup_Show("ACECONFIGDIALOG30_VALIDATION_ERROR_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 not validated or type(validated) == "string" then
+ if not validated then
+ if usage then
+ validated = name..": "..usage
+ else
+ if pattern then
+ validated = name..": Expected "..pattern
+ else
+ validated = name..": Invalid Value"
+ end
+ end
+ end
+
+ -- show validate message
+ if rootframe.SetStatusText then
+ rootframe:SetStatusText(validated)
+ else
+ validationErrorPopup(validated)
+ end
+ PlaySound(PlaySoundKitID and "igPlayerInviteDecline" or 882) -- SOUNDKIT.IG_PLAYER_INVITE_DECLINE || XXX _DECLINE is actually missing from the table
+ 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" or type(image) == "number" 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" or type(image) == "number" 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" or type(image) == "number" 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/Skada/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml b/Skada/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml
new file mode 100644
index 0000000..8e1e606
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfigDialog-3.0/AceConfigDialog-3.0.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/Skada/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua b/Skada/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
new file mode 100644
index 0000000..b84e770
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.lua
@@ -0,0 +1,349 @@
+--- 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 1161 2017-08-12 14:30:16Z funkydude $
+local CallbackHandler = LibStub("CallbackHandler-1.0")
+
+local MAJOR, MINOR = "AceConfigRegistry-3.0", 17
+local AceConfigRegistry = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConfigRegistry then return end
+
+AceConfigRegistry.tables = AceConfigRegistry.tables or {}
+
+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 optstringnumberfunc={["nil"]=true,["string"]=true,["number"]=true,["function"]=true, _="string, number 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=optstringnumberfunc,
+ iconCoords=optmethodtable,
+ handler=opttable,
+ get=optmethodfalse,
+ set=optmethodfalse,
+ func=optmethodfalse,
+ arg={["*"]=true},
+ width=optstring,
+}
+
+local typedkeys={
+ header={},
+ description={
+ image=optstringnumberfunc,
+ 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=optstringnumberfunc,
+ imageCoords=optmethodtable,
+ imageHeight=optnumber,
+ imageWidth=optnumber,
+ },
+ input={
+ pattern=optstring,
+ usage=optstring,
+ control=optstring,
+ dialogControl=optstring,
+ dropdownControl=optstring,
+ multiline=optboolnumber,
+ },
+ toggle={
+ tristate=optbool,
+ image=optstringnumberfunc,
+ 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/Skada/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml b/Skada/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml
new file mode 100644
index 0000000..4ea69ca
--- /dev/null
+++ b/Skada/Libs/AceConfig-3.0/AceConfigRegistry-3.0/AceConfigRegistry-3.0.xml
@@ -0,0 +1,4 @@
+
+
+
diff --git a/Skada/Libs/AceConsole-3.0/AceConsole-3.0.lua b/Skada/Libs/AceConsole-3.0/AceConsole-3.0.lua
new file mode 100644
index 0000000..0567a65
--- /dev/null
+++ b/Skada/Libs/AceConsole-3.0/AceConsole-3.0.lua
@@ -0,0 +1,250 @@
+--- **AceConsole-3.0** provides registration facilities for slash commands.
+-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
+-- to your addons individual needs.
+--
+-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
+-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceConsole.
+-- @class file
+-- @name AceConsole-3.0
+-- @release $Id: AceConsole-3.0.lua 1143 2016-07-11 08:52:03Z nevcairiel $
+local MAJOR,MINOR = "AceConsole-3.0", 7
+
+local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConsole then return end -- No upgrade needed
+
+AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
+AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
+AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
+
+-- Lua APIs
+local tconcat, tostring, select = table.concat, tostring, select
+local type, pairs, error = type, pairs, error
+local format, strfind, strsub = string.format, string.find, string.sub
+local max = math.max
+
+-- 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: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
+
+local tmp={}
+local function Print(self,frame,...)
+ local n=0
+ if self ~= AceConsole then
+ n=n+1
+ tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
+ end
+ for i=1, select("#", ...) do
+ n=n+1
+ tmp[n] = tostring(select(i, ...))
+ end
+ frame:AddMessage( tconcat(tmp," ",1,n) )
+end
+
+--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
+-- @paramsig [chatframe ,] ...
+-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
+-- @param ... List of any values to be printed
+function AceConsole:Print(...)
+ local frame = ...
+ if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
+ return Print(self, frame, select(2,...))
+ else
+ return Print(self, DEFAULT_CHAT_FRAME, ...)
+ end
+end
+
+
+--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
+-- @paramsig [chatframe ,] "format"[, ...]
+-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
+-- @param format Format string - same syntax as standard Lua format()
+-- @param ... Arguments to the format string
+function AceConsole:Printf(...)
+ local frame = ...
+ if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member?
+ return Print(self, frame, format(select(2,...)))
+ else
+ return Print(self, DEFAULT_CHAT_FRAME, format(...))
+ end
+end
+
+
+
+
+--- Register a simple chat command
+-- @param command Chat command to be registered WITHOUT leading "/"
+-- @param func Function to call when the slash command is being used (funcref or methodname)
+-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
+function AceConsole:RegisterChatCommand( command, func, persist )
+ if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
+
+ if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk
+
+ local name = "ACECONSOLE_"..command:upper()
+
+ if type( func ) == "string" then
+ SlashCmdList[name] = function(input, editBox)
+ self[func](self, input, editBox)
+ end
+ else
+ SlashCmdList[name] = func
+ end
+ _G["SLASH_"..name.."1"] = "/"..command:lower()
+ AceConsole.commands[command] = name
+ -- non-persisting commands are registered for enabling disabling
+ if not persist then
+ if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
+ AceConsole.weakcommands[self][command] = func
+ end
+ return true
+end
+
+--- Unregister a chatcommand
+-- @param command Chat command to be unregistered WITHOUT leading "/"
+function AceConsole:UnregisterChatCommand( command )
+ local name = AceConsole.commands[command]
+ if name then
+ SlashCmdList[name] = nil
+ _G["SLASH_" .. name .. "1"] = nil
+ hash_SlashCmdList["/" .. command:upper()] = nil
+ AceConsole.commands[command] = nil
+ end
+end
+
+--- Get an iterator over all Chat Commands registered with AceConsole
+-- @return Iterator (pairs) over all commands
+function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
+
+
+local function nils(n, ...)
+ if n>1 then
+ return nil, nils(n-1, ...)
+ elseif n==1 then
+ return nil, ...
+ else
+ return ...
+ end
+end
+
+
+--- Retreive one or more space-separated arguments from a string.
+-- Treats quoted strings and itemlinks as non-spaced.
+-- @param str The raw argument string
+-- @param numargs How many arguments to get (default 1)
+-- @param startpos Where in the string to start scanning (default 1)
+-- @return Returns arg1, arg2, ..., nextposition\\
+-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
+function AceConsole:GetArgs(str, numargs, startpos)
+ numargs = numargs or 1
+ startpos = max(startpos or 1, 1)
+
+ local pos=startpos
+
+ -- find start of new arg
+ pos = strfind(str, "[^ ]", pos)
+ if not pos then -- whoops, end of string
+ return nils(numargs, 1e9)
+ end
+
+ if numargs<1 then
+ return pos
+ end
+
+ -- quoted or space separated? find out which pattern to use
+ local delim_or_pipe
+ local ch = strsub(str, pos, pos)
+ if ch=='"' then
+ pos = pos + 1
+ delim_or_pipe='([|"])'
+ elseif ch=="'" then
+ pos = pos + 1
+ delim_or_pipe="([|'])"
+ else
+ delim_or_pipe="([| ])"
+ end
+
+ startpos = pos
+
+ while true do
+ -- find delimiter or hyperlink
+ local ch,_
+ pos,_,ch = strfind(str, delim_or_pipe, pos)
+
+ if not pos then break end
+
+ if ch=="|" then
+ -- some kind of escape
+
+ if strsub(str,pos,pos+1)=="|H" then
+ -- It's a |H....|hhyper link!|h
+ pos=strfind(str, "|h", pos+2) -- first |h
+ if not pos then break end
+
+ pos=strfind(str, "|h", pos+2) -- second |h
+ if not pos then break end
+ elseif strsub(str,pos, pos+1) == "|T" then
+ -- It's a |T....|t texture
+ pos=strfind(str, "|t", pos+2)
+ if not pos then break end
+ end
+
+ pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
+
+ else
+ -- found delimiter, done with this arg
+ return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
+ end
+
+ end
+
+ -- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
+ return strsub(str, startpos), nils(numargs-1, 1e9)
+end
+
+
+--- embedding and embed handling
+
+local mixins = {
+ "Print",
+ "Printf",
+ "RegisterChatCommand",
+ "UnregisterChatCommand",
+ "GetArgs",
+}
+
+-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
+-- @param target target object to embed AceBucket in
+function AceConsole:Embed( target )
+ for k, v in pairs( mixins ) do
+ target[v] = self[v]
+ end
+ self.embeds[target] = true
+ return target
+end
+
+function AceConsole:OnEmbedEnable( target )
+ if AceConsole.weakcommands[target] then
+ for command, func in pairs( AceConsole.weakcommands[target] ) do
+ target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
+ end
+ end
+end
+
+function AceConsole:OnEmbedDisable( target )
+ if AceConsole.weakcommands[target] then
+ for command, func in pairs( AceConsole.weakcommands[target] ) do
+ target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
+ end
+ end
+end
+
+for addon in pairs(AceConsole.embeds) do
+ AceConsole:Embed(addon)
+end
diff --git a/Skada/Libs/AceDB-3.0/AceDB-3.0.lua b/Skada/Libs/AceDB-3.0/AceDB-3.0.lua
new file mode 100644
index 0000000..b42b442
--- /dev/null
+++ b/Skada/Libs/AceDB-3.0/AceDB-3.0.lua
@@ -0,0 +1,746 @@
+--- **AceDB-3.0** manages the SavedVariables of your addon.
+-- It offers profile management, smart defaults and namespaces for modules.\\
+-- Data can be saved in different data-types, depending on its intended usage.
+-- The most common data-type is the `profile` type, which allows the user to choose
+-- the active profile, and manage the profiles of all of his characters.\\
+-- The following data types are available:
+-- * **char** Character-specific data. Every character has its own database.
+-- * **realm** Realm-specific data. All of the players characters on the same realm share this database.
+-- * **class** Class-specific data. All of the players characters of the same class share this database.
+-- * **race** Race-specific data. All of the players characters of the same race share this database.
+-- * **faction** Faction-specific data. All of the players characters of the same faction share this database.
+-- * **factionrealm** Faction and realm specific data. All of the players characters on the same realm and of the same faction share this database.
+-- * **locale** Locale specific data, based on the locale of the players game client.
+-- * **global** Global Data. All characters on the same account share this database.
+-- * **profile** Profile-specific data. All characters using the same profile share this database. The user can control which profile should be used.
+--
+-- Creating a new Database using the `:New` function will return a new DBObject. A database will inherit all functions
+-- of the DBObjectLib listed here. \\
+-- If you create a new namespaced child-database (`:RegisterNamespace`), you'll get a DBObject as well, but note
+-- that the child-databases cannot individually change their profile, and are linked to their parents profile - and because of that,
+-- the profile related APIs are not available. Only `:RegisterDefaults` and `:ResetProfile` are available on child-databases.
+--
+-- For more details on how to use AceDB-3.0, see the [[AceDB-3.0 Tutorial]].
+--
+-- You may also be interested in [[libdualspec-1-0|LibDualSpec-1.0]] to do profile switching automatically when switching specs.
+--
+-- @usage
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("DBExample")
+--
+-- -- declare defaults to be used in the DB
+-- local defaults = {
+-- profile = {
+-- setting = true,
+-- }
+-- }
+--
+-- function MyAddon:OnInitialize()
+-- -- Assuming the .toc says ## SavedVariables: MyAddonDB
+-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
+-- end
+-- @class file
+-- @name AceDB-3.0.lua
+-- @release $Id: AceDB-3.0.lua 1142 2016-07-11 08:36:19Z nevcairiel $
+local ACEDB_MAJOR, ACEDB_MINOR = "AceDB-3.0", 26
+local AceDB, oldminor = LibStub:NewLibrary(ACEDB_MAJOR, ACEDB_MINOR)
+
+if not AceDB then return end -- No upgrade needed
+
+-- Lua APIs
+local type, pairs, next, error = type, pairs, next, error
+local setmetatable, getmetatable, rawset, rawget = setmetatable, getmetatable, rawset, rawget
+
+-- 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
+
+AceDB.db_registry = AceDB.db_registry or {}
+AceDB.frame = AceDB.frame or CreateFrame("Frame")
+
+local CallbackHandler
+local CallbackDummy = { Fire = function() end }
+
+local DBObjectLib = {}
+
+--[[-------------------------------------------------------------------------
+ AceDB Utility Functions
+---------------------------------------------------------------------------]]
+
+-- Simple shallow copy for copying defaults
+local function copyTable(src, dest)
+ if type(dest) ~= "table" then dest = {} end
+ if type(src) == "table" then
+ for k,v in pairs(src) do
+ if type(v) == "table" then
+ -- try to index the key first so that the metatable creates the defaults, if set, and use that table
+ v = copyTable(v, dest[k])
+ end
+ dest[k] = v
+ end
+ end
+ return dest
+end
+
+-- Called to add defaults to a section of the database
+--
+-- When a ["*"] default section is indexed with a new key, a table is returned
+-- and set in the host table. These tables must be cleaned up by removeDefaults
+-- in order to ensure we don't write empty default tables.
+local function copyDefaults(dest, src)
+ -- this happens if some value in the SV overwrites our default value with a non-table
+ --if type(dest) ~= "table" then return end
+ for k, v in pairs(src) do
+ if k == "*" or k == "**" then
+ if type(v) == "table" then
+ -- This is a metatable used for table defaults
+ local mt = {
+ -- This handles the lookup and creation of new subtables
+ __index = function(t,k)
+ if k == nil then return nil end
+ local tbl = {}
+ copyDefaults(tbl, v)
+ rawset(t, k, tbl)
+ return tbl
+ end,
+ }
+ setmetatable(dest, mt)
+ -- handle already existing tables in the SV
+ for dk, dv in pairs(dest) do
+ if not rawget(src, dk) and type(dv) == "table" then
+ copyDefaults(dv, v)
+ end
+ end
+ else
+ -- Values are not tables, so this is just a simple return
+ local mt = {__index = function(t,k) return k~=nil and v or nil end}
+ setmetatable(dest, mt)
+ end
+ elseif type(v) == "table" then
+ if not rawget(dest, k) then rawset(dest, k, {}) end
+ if type(dest[k]) == "table" then
+ copyDefaults(dest[k], v)
+ if src['**'] then
+ copyDefaults(dest[k], src['**'])
+ end
+ end
+ else
+ if rawget(dest, k) == nil then
+ rawset(dest, k, v)
+ end
+ end
+ end
+end
+
+-- Called to remove all defaults in the default table from the database
+local function removeDefaults(db, defaults, blocker)
+ -- remove all metatables from the db, so we don't accidentally create new sub-tables through them
+ setmetatable(db, nil)
+ -- loop through the defaults and remove their content
+ for k,v in pairs(defaults) do
+ if k == "*" or k == "**" then
+ if type(v) == "table" then
+ -- Loop through all the actual k,v pairs and remove
+ for key, value in pairs(db) do
+ if type(value) == "table" then
+ -- if the key was not explicitly specified in the defaults table, just strip everything from * and ** tables
+ if defaults[key] == nil and (not blocker or blocker[key] == nil) then
+ removeDefaults(value, v)
+ -- if the table is empty afterwards, remove it
+ if next(value) == nil then
+ db[key] = nil
+ end
+ -- if it was specified, only strip ** content, but block values which were set in the key table
+ elseif k == "**" then
+ removeDefaults(value, v, defaults[key])
+ end
+ end
+ end
+ elseif k == "*" then
+ -- check for non-table default
+ for key, value in pairs(db) do
+ if defaults[key] == nil and v == value then
+ db[key] = nil
+ end
+ end
+ end
+ elseif type(v) == "table" and type(db[k]) == "table" then
+ -- if a blocker was set, dive into it, to allow multi-level defaults
+ removeDefaults(db[k], v, blocker and blocker[k])
+ if next(db[k]) == nil then
+ db[k] = nil
+ end
+ else
+ -- check if the current value matches the default, and that its not blocked by another defaults table
+ if db[k] == defaults[k] and (not blocker or blocker[k] == nil) then
+ db[k] = nil
+ end
+ end
+ end
+end
+
+-- This is called when a table section is first accessed, to set up the defaults
+local function initSection(db, section, svstore, key, defaults)
+ local sv = rawget(db, "sv")
+
+ local tableCreated
+ if not sv[svstore] then sv[svstore] = {} end
+ if not sv[svstore][key] then
+ sv[svstore][key] = {}
+ tableCreated = true
+ end
+
+ local tbl = sv[svstore][key]
+
+ if defaults then
+ copyDefaults(tbl, defaults)
+ end
+ rawset(db, section, tbl)
+
+ return tableCreated, tbl
+end
+
+-- Metatable to handle the dynamic creation of sections and copying of sections.
+local dbmt = {
+ __index = function(t, section)
+ local keys = rawget(t, "keys")
+ local key = keys[section]
+ if key then
+ local defaultTbl = rawget(t, "defaults")
+ local defaults = defaultTbl and defaultTbl[section]
+
+ if section == "profile" then
+ local new = initSection(t, section, "profiles", key, defaults)
+ if new then
+ -- Callback: OnNewProfile, database, newProfileKey
+ t.callbacks:Fire("OnNewProfile", t, key)
+ end
+ elseif section == "profiles" then
+ local sv = rawget(t, "sv")
+ if not sv.profiles then sv.profiles = {} end
+ rawset(t, "profiles", sv.profiles)
+ elseif section == "global" then
+ local sv = rawget(t, "sv")
+ if not sv.global then sv.global = {} end
+ if defaults then
+ copyDefaults(sv.global, defaults)
+ end
+ rawset(t, section, sv.global)
+ else
+ initSection(t, section, section, key, defaults)
+ end
+ end
+
+ return rawget(t, section)
+ end
+}
+
+local function validateDefaults(defaults, keyTbl, offset)
+ if not defaults then return end
+ offset = offset or 0
+ for k in pairs(defaults) do
+ if not keyTbl[k] or k == "profiles" then
+ error(("Usage: AceDBObject:RegisterDefaults(defaults): '%s' is not a valid datatype."):format(k), 3 + offset)
+ end
+ end
+end
+
+local preserve_keys = {
+ ["callbacks"] = true,
+ ["RegisterCallback"] = true,
+ ["UnregisterCallback"] = true,
+ ["UnregisterAllCallbacks"] = true,
+ ["children"] = true,
+}
+
+local realmKey = GetRealmName()
+local charKey = UnitName("player") .. " - " .. realmKey
+local _, classKey = UnitClass("player")
+local _, raceKey = UnitRace("player")
+local factionKey = UnitFactionGroup("player")
+local factionrealmKey = factionKey .. " - " .. realmKey
+local localeKey = GetLocale():lower()
+
+local regionTable = { "US", "KR", "EU", "TW", "CN" }
+local regionKey = regionTable[GetCurrentRegion()]
+local factionrealmregionKey = factionrealmKey .. " - " .. regionKey
+
+-- Actual database initialization function
+local function initdb(sv, defaults, defaultProfile, olddb, parent)
+ -- Generate the database keys for each section
+
+ -- map "true" to our "Default" profile
+ if defaultProfile == true then defaultProfile = "Default" end
+
+ local profileKey
+ if not parent then
+ -- Make a container for profile keys
+ if not sv.profileKeys then sv.profileKeys = {} end
+
+ -- Try to get the profile selected from the char db
+ profileKey = sv.profileKeys[charKey] or defaultProfile or charKey
+
+ -- save the selected profile for later
+ sv.profileKeys[charKey] = profileKey
+ else
+ -- Use the profile of the parents DB
+ profileKey = parent.keys.profile or defaultProfile or charKey
+
+ -- clear the profileKeys in the DB, namespaces don't need to store them
+ sv.profileKeys = nil
+ end
+
+ -- This table contains keys that enable the dynamic creation
+ -- of each section of the table. The 'global' and 'profiles'
+ -- have a key of true, since they are handled in a special case
+ local keyTbl= {
+ ["char"] = charKey,
+ ["realm"] = realmKey,
+ ["class"] = classKey,
+ ["race"] = raceKey,
+ ["faction"] = factionKey,
+ ["factionrealm"] = factionrealmKey,
+ ["factionrealmregion"] = factionrealmregionKey,
+ ["profile"] = profileKey,
+ ["locale"] = localeKey,
+ ["global"] = true,
+ ["profiles"] = true,
+ }
+
+ validateDefaults(defaults, keyTbl, 1)
+
+ -- This allows us to use this function to reset an entire database
+ -- Clear out the old database
+ if olddb then
+ for k,v in pairs(olddb) do if not preserve_keys[k] then olddb[k] = nil end end
+ end
+
+ -- Give this database the metatable so it initializes dynamically
+ local db = setmetatable(olddb or {}, dbmt)
+
+ if not rawget(db, "callbacks") then
+ -- try to load CallbackHandler-1.0 if it loaded after our library
+ if not CallbackHandler then CallbackHandler = LibStub:GetLibrary("CallbackHandler-1.0", true) end
+ db.callbacks = CallbackHandler and CallbackHandler:New(db) or CallbackDummy
+ end
+
+ -- Copy methods locally into the database object, to avoid hitting
+ -- the metatable when calling methods
+
+ if not parent then
+ for name, func in pairs(DBObjectLib) do
+ db[name] = func
+ end
+ else
+ -- hack this one in
+ db.RegisterDefaults = DBObjectLib.RegisterDefaults
+ db.ResetProfile = DBObjectLib.ResetProfile
+ end
+
+ -- Set some properties in the database object
+ db.profiles = sv.profiles
+ db.keys = keyTbl
+ db.sv = sv
+ --db.sv_name = name
+ db.defaults = defaults
+ db.parent = parent
+
+ -- store the DB in the registry
+ AceDB.db_registry[db] = true
+
+ return db
+end
+
+-- handle PLAYER_LOGOUT
+-- strip all defaults from all databases
+-- and cleans up empty sections
+local function logoutHandler(frame, event)
+ if event == "PLAYER_LOGOUT" then
+ for db in pairs(AceDB.db_registry) do
+ db.callbacks:Fire("OnDatabaseShutdown", db)
+ db:RegisterDefaults(nil)
+
+ -- cleanup sections that are empty without defaults
+ local sv = rawget(db, "sv")
+ for section in pairs(db.keys) do
+ if rawget(sv, section) then
+ -- global is special, all other sections have sub-entrys
+ -- also don't delete empty profiles on main dbs, only on namespaces
+ if section ~= "global" and (section ~= "profiles" or rawget(db, "parent")) then
+ for key in pairs(sv[section]) do
+ if not next(sv[section][key]) then
+ sv[section][key] = nil
+ end
+ end
+ end
+ if not next(sv[section]) then
+ sv[section] = nil
+ end
+ end
+ end
+ end
+ end
+end
+
+AceDB.frame:RegisterEvent("PLAYER_LOGOUT")
+AceDB.frame:SetScript("OnEvent", logoutHandler)
+
+
+--[[-------------------------------------------------------------------------
+ AceDB Object Method Definitions
+---------------------------------------------------------------------------]]
+
+--- Sets the defaults table for the given database object by clearing any
+-- that are currently set, and then setting the new defaults.
+-- @param defaults A table of defaults for this database
+function DBObjectLib:RegisterDefaults(defaults)
+ if defaults and type(defaults) ~= "table" then
+ error("Usage: AceDBObject:RegisterDefaults(defaults): 'defaults' - table or nil expected.", 2)
+ end
+
+ validateDefaults(defaults, self.keys)
+
+ -- Remove any currently set defaults
+ if self.defaults then
+ for section,key in pairs(self.keys) do
+ if self.defaults[section] and rawget(self, section) then
+ removeDefaults(self[section], self.defaults[section])
+ end
+ end
+ end
+
+ -- Set the DBObject.defaults table
+ self.defaults = defaults
+
+ -- Copy in any defaults, only touching those sections already created
+ if defaults then
+ for section,key in pairs(self.keys) do
+ if defaults[section] and rawget(self, section) then
+ copyDefaults(self[section], defaults[section])
+ end
+ end
+ end
+end
+
+--- Changes the profile of the database and all of it's namespaces to the
+-- supplied named profile
+-- @param name The name of the profile to set as the current profile
+function DBObjectLib:SetProfile(name)
+ if type(name) ~= "string" then
+ error("Usage: AceDBObject:SetProfile(name): 'name' - string expected.", 2)
+ end
+
+ -- changing to the same profile, dont do anything
+ if name == self.keys.profile then return end
+
+ local oldProfile = self.profile
+ local defaults = self.defaults and self.defaults.profile
+
+ -- Callback: OnProfileShutdown, database
+ self.callbacks:Fire("OnProfileShutdown", self)
+
+ if oldProfile and defaults then
+ -- Remove the defaults from the old profile
+ removeDefaults(oldProfile, defaults)
+ end
+
+ self.profile = nil
+ self.keys["profile"] = name
+
+ -- if the storage exists, save the new profile
+ -- this won't exist on namespaces.
+ if self.sv.profileKeys then
+ self.sv.profileKeys[charKey] = name
+ end
+
+ -- populate to child namespaces
+ if self.children then
+ for _, db in pairs(self.children) do
+ DBObjectLib.SetProfile(db, name)
+ end
+ end
+
+ -- Callback: OnProfileChanged, database, newProfileKey
+ self.callbacks:Fire("OnProfileChanged", self, name)
+end
+
+--- Returns a table with the names of the existing profiles in the database.
+-- You can optionally supply a table to re-use for this purpose.
+-- @param tbl A table to store the profile names in (optional)
+function DBObjectLib:GetProfiles(tbl)
+ if tbl and type(tbl) ~= "table" then
+ error("Usage: AceDBObject:GetProfiles(tbl): 'tbl' - table or nil expected.", 2)
+ end
+
+ -- Clear the container table
+ if tbl then
+ for k,v in pairs(tbl) do tbl[k] = nil end
+ else
+ tbl = {}
+ end
+
+ local curProfile = self.keys.profile
+
+ local i = 0
+ for profileKey in pairs(self.profiles) do
+ i = i + 1
+ tbl[i] = profileKey
+ if curProfile and profileKey == curProfile then curProfile = nil end
+ end
+
+ -- Add the current profile, if it hasn't been created yet
+ if curProfile then
+ i = i + 1
+ tbl[i] = curProfile
+ end
+
+ return tbl, i
+end
+
+--- Returns the current profile name used by the database
+function DBObjectLib:GetCurrentProfile()
+ return self.keys.profile
+end
+
+--- Deletes a named profile. This profile must not be the active profile.
+-- @param name The name of the profile to be deleted
+-- @param silent If true, do not raise an error when the profile does not exist
+function DBObjectLib:DeleteProfile(name, silent)
+ if type(name) ~= "string" then
+ error("Usage: AceDBObject:DeleteProfile(name): 'name' - string expected.", 2)
+ end
+
+ if self.keys.profile == name then
+ error("Cannot delete the active profile in an AceDBObject.", 2)
+ end
+
+ if not rawget(self.profiles, name) and not silent then
+ error("Cannot delete profile '" .. name .. "'. It does not exist.", 2)
+ end
+
+ self.profiles[name] = nil
+
+ -- populate to child namespaces
+ if self.children then
+ for _, db in pairs(self.children) do
+ DBObjectLib.DeleteProfile(db, name, true)
+ end
+ end
+
+ -- switch all characters that use this profile back to the default
+ if self.sv.profileKeys then
+ for key, profile in pairs(self.sv.profileKeys) do
+ if profile == name then
+ self.sv.profileKeys[key] = nil
+ end
+ end
+ end
+
+ -- Callback: OnProfileDeleted, database, profileKey
+ self.callbacks:Fire("OnProfileDeleted", self, name)
+end
+
+--- Copies a named profile into the current profile, overwriting any conflicting
+-- settings.
+-- @param name The name of the profile to be copied into the current profile
+-- @param silent If true, do not raise an error when the profile does not exist
+function DBObjectLib:CopyProfile(name, silent)
+ if type(name) ~= "string" then
+ error("Usage: AceDBObject:CopyProfile(name): 'name' - string expected.", 2)
+ end
+
+ if name == self.keys.profile then
+ error("Cannot have the same source and destination profiles.", 2)
+ end
+
+ if not rawget(self.profiles, name) and not silent then
+ error("Cannot copy profile '" .. name .. "'. It does not exist.", 2)
+ end
+
+ -- Reset the profile before copying
+ DBObjectLib.ResetProfile(self, nil, true)
+
+ local profile = self.profile
+ local source = self.profiles[name]
+
+ copyTable(source, profile)
+
+ -- populate to child namespaces
+ if self.children then
+ for _, db in pairs(self.children) do
+ DBObjectLib.CopyProfile(db, name, true)
+ end
+ end
+
+ -- Callback: OnProfileCopied, database, sourceProfileKey
+ self.callbacks:Fire("OnProfileCopied", self, name)
+end
+
+--- Resets the current profile to the default values (if specified).
+-- @param noChildren if set to true, the reset will not be populated to the child namespaces of this DB object
+-- @param noCallbacks if set to true, won't fire the OnProfileReset callback
+function DBObjectLib:ResetProfile(noChildren, noCallbacks)
+ local profile = self.profile
+
+ for k,v in pairs(profile) do
+ profile[k] = nil
+ end
+
+ local defaults = self.defaults and self.defaults.profile
+ if defaults then
+ copyDefaults(profile, defaults)
+ end
+
+ -- populate to child namespaces
+ if self.children and not noChildren then
+ for _, db in pairs(self.children) do
+ DBObjectLib.ResetProfile(db, nil, noCallbacks)
+ end
+ end
+
+ -- Callback: OnProfileReset, database
+ if not noCallbacks then
+ self.callbacks:Fire("OnProfileReset", self)
+ end
+end
+
+--- Resets the entire database, using the string defaultProfile as the new default
+-- profile.
+-- @param defaultProfile The profile name to use as the default
+function DBObjectLib:ResetDB(defaultProfile)
+ if defaultProfile and type(defaultProfile) ~= "string" then
+ error("Usage: AceDBObject:ResetDB(defaultProfile): 'defaultProfile' - string or nil expected.", 2)
+ end
+
+ local sv = self.sv
+ for k,v in pairs(sv) do
+ sv[k] = nil
+ end
+
+ local parent = self.parent
+
+ initdb(sv, self.defaults, defaultProfile, self)
+
+ -- fix the child namespaces
+ if self.children then
+ if not sv.namespaces then sv.namespaces = {} end
+ for name, db in pairs(self.children) do
+ if not sv.namespaces[name] then sv.namespaces[name] = {} end
+ initdb(sv.namespaces[name], db.defaults, self.keys.profile, db, self)
+ end
+ end
+
+ -- Callback: OnDatabaseReset, database
+ self.callbacks:Fire("OnDatabaseReset", self)
+ -- Callback: OnProfileChanged, database, profileKey
+ self.callbacks:Fire("OnProfileChanged", self, self.keys["profile"])
+
+ return self
+end
+
+--- Creates a new database namespace, directly tied to the database. This
+-- is a full scale database in it's own rights other than the fact that
+-- it cannot control its profile individually
+-- @param name The name of the new namespace
+-- @param defaults A table of values to use as defaults
+function DBObjectLib:RegisterNamespace(name, defaults)
+ if type(name) ~= "string" then
+ error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - string expected.", 2)
+ end
+ if defaults and type(defaults) ~= "table" then
+ error("Usage: AceDBObject:RegisterNamespace(name, defaults): 'defaults' - table or nil expected.", 2)
+ end
+ if self.children and self.children[name] then
+ error ("Usage: AceDBObject:RegisterNamespace(name, defaults): 'name' - a namespace with that name already exists.", 2)
+ end
+
+ local sv = self.sv
+ if not sv.namespaces then sv.namespaces = {} end
+ if not sv.namespaces[name] then
+ sv.namespaces[name] = {}
+ end
+
+ local newDB = initdb(sv.namespaces[name], defaults, self.keys.profile, nil, self)
+
+ if not self.children then self.children = {} end
+ self.children[name] = newDB
+ return newDB
+end
+
+--- Returns an already existing namespace from the database object.
+-- @param name The name of the new namespace
+-- @param silent if true, the addon is optional, silently return nil if its not found
+-- @usage
+-- local namespace = self.db:GetNamespace('namespace')
+-- @return the namespace object if found
+function DBObjectLib:GetNamespace(name, silent)
+ if type(name) ~= "string" then
+ error("Usage: AceDBObject:GetNamespace(name): 'name' - string expected.", 2)
+ end
+ if not silent and not (self.children and self.children[name]) then
+ error ("Usage: AceDBObject:GetNamespace(name): 'name' - namespace does not exist.", 2)
+ end
+ if not self.children then self.children = {} end
+ return self.children[name]
+end
+
+--[[-------------------------------------------------------------------------
+ AceDB Exposed Methods
+---------------------------------------------------------------------------]]
+
+--- Creates a new database object that can be used to handle database settings and profiles.
+-- By default, an empty DB is created, using a character specific profile.
+--
+-- You can override the default profile used by passing any profile name as the third argument,
+-- or by passing //true// as the third argument to use a globally shared profile called "Default".
+--
+-- Note that there is no token replacement in the default profile name, passing a defaultProfile as "char"
+-- will use a profile named "char", and not a character-specific profile.
+-- @param tbl The name of variable, or table to use for the database
+-- @param defaults A table of database defaults
+-- @param defaultProfile The name of the default profile. If not set, a character specific profile will be used as the default.
+-- You can also pass //true// to use a shared global profile called "Default".
+-- @usage
+-- -- Create an empty DB using a character-specific default profile.
+-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB")
+-- @usage
+-- -- Create a DB using defaults and using a shared default profile
+-- self.db = LibStub("AceDB-3.0"):New("MyAddonDB", defaults, true)
+function AceDB:New(tbl, defaults, defaultProfile)
+ if type(tbl) == "string" then
+ local name = tbl
+ tbl = _G[name]
+ if not tbl then
+ tbl = {}
+ _G[name] = tbl
+ end
+ end
+
+ if type(tbl) ~= "table" then
+ error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'tbl' - table expected.", 2)
+ end
+
+ if defaults and type(defaults) ~= "table" then
+ error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaults' - table expected.", 2)
+ end
+
+ if defaultProfile and type(defaultProfile) ~= "string" and defaultProfile ~= true then
+ error("Usage: AceDB:New(tbl, defaults, defaultProfile): 'defaultProfile' - string or true expected.", 2)
+ end
+
+ return initdb(tbl, defaults, defaultProfile)
+end
+
+-- upgrade existing databases
+for db in pairs(AceDB.db_registry) do
+ if not db.parent then
+ for name,func in pairs(DBObjectLib) do
+ db[name] = func
+ end
+ else
+ db.RegisterDefaults = DBObjectLib.RegisterDefaults
+ db.ResetProfile = DBObjectLib.ResetProfile
+ end
+end
diff --git a/Skada/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua b/Skada/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
new file mode 100644
index 0000000..5028fef
--- /dev/null
+++ b/Skada/Libs/AceDBOptions-3.0/AceDBOptions-3.0.lua
@@ -0,0 +1,460 @@
+--- AceDBOptions-3.0 provides a universal AceConfig options screen for managing AceDB-3.0 profiles.
+-- @class file
+-- @name AceDBOptions-3.0
+-- @release $Id: AceDBOptions-3.0.lua 1140 2016-07-03 07:53:29Z nevcairiel $
+local ACEDBO_MAJOR, ACEDBO_MINOR = "AceDBOptions-3.0", 15
+local AceDBOptions, oldminor = LibStub:NewLibrary(ACEDBO_MAJOR, ACEDBO_MINOR)
+
+if not AceDBOptions then return end -- No upgrade needed
+
+-- Lua APIs
+local pairs, next = pairs, next
+
+-- WoW APIs
+local UnitClass = UnitClass
+
+-- 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_CODE, FONT_COLOR_CODE_CLOSE
+
+AceDBOptions.optionTables = AceDBOptions.optionTables or {}
+AceDBOptions.handlers = AceDBOptions.handlers or {}
+
+--[[
+ Localization of AceDBOptions-3.0
+]]
+
+local L = {
+ choose = "Existing Profiles",
+ choose_desc = "You can either create a new profile by entering a name in the editbox, or choose one of the already existing profiles.",
+ choose_sub = "Select one of your currently available profiles.",
+ copy = "Copy From",
+ copy_desc = "Copy the settings from one existing profile into the currently active profile.",
+ current = "Current Profile:",
+ default = "Default",
+ delete = "Delete a Profile",
+ delete_confirm = "Are you sure you want to delete the selected profile?",
+ delete_desc = "Delete existing and unused profiles from the database to save space, and cleanup the SavedVariables file.",
+ delete_sub = "Deletes a profile from the database.",
+ intro = "You can change the active database profile, so you can have different settings for every character.",
+ new = "New",
+ new_sub = "Create a new empty profile.",
+ profiles = "Profiles",
+ profiles_sub = "Manage Profiles",
+ reset = "Reset Profile",
+ reset_desc = "Reset the current profile back to its default values, in case your configuration is broken, or you simply want to start over.",
+ reset_sub = "Reset the current profile to the default",
+}
+
+local LOCALE = GetLocale()
+if LOCALE == "deDE" then
+ L["choose"] = "Vorhandene Profile"
+ L["choose_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["choose_sub"] = "Wählt ein bereits vorhandenes Profil aus."
+ L["copy"] = "Kopieren von..."
+ L["copy_desc"] = "Kopiere die Einstellungen von einem vorhandenen Profil in das aktive Profil."
+ L["current"] = "Aktuelles 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 die SavedVariables-Datei 'sauber' zu halten."
+ L["delete_sub"] = "Löscht ein Profil aus der Datenbank."
+ L["intro"] = "Hier kannst du das aktive Datenbankprofil ändern, damit du verschiedene Einstellungen für jeden Charakter erstellen kannst, wodurch eine sehr flexible Konfiguration möglich wird."
+ L["new"] = "Neu"
+ L["new_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, dass mit der Konfiguration etwas schief lief oder weil du einfach neu starten willst."
+ L["reset_sub"] = "Das aktuelle Profil auf Standard zurücksetzen."
+elseif LOCALE == "frFR" then
+ L["choose"] = "Profils existants"
+ L["choose_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["choose_sub"] = "Permet de choisir un des profils déjà disponibles."
+ L["copy"] = "Copier à partir de"
+ L["copy_desc"] = "Copie les paramètres d'un profil déjà existant dans le profil actuellement actif."
+ L["current"] = "Profil actuel :"
+ 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["new"] = "Nouveau"
+ L["new_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."
+elseif LOCALE == "koKR" then
+ L["choose"] = "저장 중인 프로필"
+ L["choose_desc"] = "입력창에 새로운 이름을 입력하거나 저장 중인 프로필 중 하나를 선택하여 새로운 프로필을 만들 수 있습니다."
+ L["choose_sub"] = "현재 이용할 수 있는 프로필 중 하나를 선택합니다."
+ L["copy"] = "복사해오기"
+ L["copy_desc"] = "현재 사용 중인 프로필에 선택한 프로필의 설정을 복사합니다."
+ L["current"] = "현재 프로필:"
+ L["default"] = "기본값"
+ L["delete"] = "프로필 삭제"
+ L["delete_confirm"] = "정말로 선택한 프로필을 삭제할까요?"
+ L["delete_desc"] = "저장 공간 절약과 SavedVariables 파일의 정리를 위해 데이터베이스에서 사용하지 않는 프로필을 삭제하세요."
+ L["delete_sub"] = "데이터베이스의 프로필을 삭제합니다."
+ L["intro"] = "활성 데이터베이스 프로필을 변경할 수 있고, 각 캐릭터 별로 다른 설정을 할 수 있습니다."
+ L["new"] = "새로운 프로필"
+ L["new_sub"] = "새로운 프로필을 만듭니다."
+ L["profiles"] = "프로필"
+ L["profiles_sub"] = "프로필 관리"
+ L["reset"] = "프로필 초기화"
+ L["reset_desc"] = "설정이 깨졌거나 처음부터 다시 설정을 원하는 경우, 현재 프로필을 기본값으로 초기화하세요."
+ L["reset_sub"] = "현재 프로필을 기본값으로 초기화합니다"
+elseif LOCALE == "esES" or LOCALE == "esMX" then
+ L["choose"] = "Perfiles existentes"
+ L["choose_desc"] = "Puedes crear un nuevo perfil introduciendo un nombre en el recuadro o puedes seleccionar un perfil de los ya existentes."
+ L["choose_sub"] = "Selecciona uno de los perfiles disponibles."
+ L["copy"] = "Copiar de"
+ L["copy_desc"] = "Copia los ajustes de un perfil existente al perfil actual."
+ L["current"] = "Perfil actual:"
+ 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["new"] = "Nuevo"
+ L["new_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"
+elseif LOCALE == "zhTW" then
+ L["choose"] = "現有的設定檔"
+ L["choose_desc"] = "您可以在文字方塊內輸入名字以建立新的設定檔,或是選擇一個現有的設定檔使用。"
+ L["choose_sub"] = "從當前可用的設定檔裡面選擇一個。"
+ L["copy"] = "複製自"
+ L["copy_desc"] = "從一個現有的設定檔,將設定複製到現在使用中的設定檔。"
+ L["current"] = "目前設定檔:"
+ L["default"] = "預設"
+ L["delete"] = "刪除一個設定檔"
+ L["delete_confirm"] = "確定要刪除所選擇的設定檔嗎?"
+ L["delete_desc"] = "從資料庫裡刪除不再使用的設定檔,以節省空間,並且清理 SavedVariables 檔案。"
+ L["delete_sub"] = "從資料庫裡刪除一個設定檔。"
+ L["intro"] = "您可以從資料庫中選擇一個設定檔來使用,如此就可以讓每個角色使用不同的設定。"
+ L["new"] = "新建"
+ L["new_sub"] = "新建一個空的設定檔。"
+ L["profiles"] = "設定檔"
+ L["profiles_sub"] = "管理設定檔"
+ L["reset"] = "重置設定檔"
+ L["reset_desc"] = "將現用的設定檔重置為預設值;用於設定檔損壞,或者單純想要重來的情況。"
+ L["reset_sub"] = "將目前的設定檔重置為預設值"
+elseif LOCALE == "zhCN" then
+ L["choose"] = "现有的配置文件"
+ L["choose_desc"] = "你可以通过在文本框内输入一个名字创立一个新的配置文件,也可以选择一个已经存在的配置文件。"
+ L["choose_sub"] = "从当前可用的配置文件里面选择一个。"
+ L["copy"] = "复制自"
+ L["copy_desc"] = "从当前某个已保存的配置文件复制到当前正使用的配置文件。"
+ L["current"] = "当前配置文件:"
+ L["default"] = "默认"
+ L["delete"] = "删除一个配置文件"
+ L["delete_confirm"] = "你确定要删除所选择的配置文件么?"
+ L["delete_desc"] = "从数据库里删除不再使用的配置文件,以节省空间,并且清理SavedVariables文件。"
+ L["delete_sub"] = "从数据库里删除一个配置文件。"
+ L["intro"] = "你可以选择一个活动的数据配置文件,这样你的每个角色就可以拥有不同的设置值,可以给你的插件配置带来极大的灵活性。"
+ L["new"] = "新建"
+ L["new_sub"] = "新建一个空的配置文件。"
+ L["profiles"] = "配置文件"
+ L["profiles_sub"] = "管理配置文件"
+ L["reset"] = "重置配置文件"
+ L["reset_desc"] = "将当前的配置文件恢复到它的默认值,用于你的配置文件损坏,或者你只是想重来的情况。"
+ L["reset_sub"] = "将当前的配置文件恢复为默认值"
+elseif LOCALE == "ruRU" then
+ L["choose"] = "Существующие профили"
+ L["choose_desc"] = "Вы можете создать новый профиль, введя название в поле ввода, или выбрать один из уже существующих профилей."
+ L["choose_sub"] = "Выбор одиного из уже доступных профилей"
+ L["copy"] = "Скопировать из"
+ L["copy_desc"] = "Скопировать настройки из выбранного профиля в активный."
+ L["current"] = "Текущий профиль:"
+ L["default"] = "По умолчанию"
+ L["delete"] = "Удалить профиль"
+ L["delete_confirm"] = "Вы уверены, что вы хотите удалить выбранный профиль?"
+ L["delete_desc"] = "Удалить существующий и неиспользуемый профиль из БД для сохранения места, и очистить SavedVariables файл."
+ L["delete_sub"] = "Удаление профиля из БД"
+ L["intro"] = "Изменяя активный профиль, вы можете задать различные настройки модификаций для каждого персонажа."
+ L["new"] = "Новый"
+ L["new_sub"] = "Создать новый чистый профиль"
+ L["profiles"] = "Профили"
+ L["profiles_sub"] = "Управление профилями"
+ L["reset"] = "Сброс профиля"
+ L["reset_desc"] = "Сбросить текущий профиль к стандартным настройкам, если ваша конфигурация испорчена или вы хотите настроить всё заново."
+ L["reset_sub"] = "Сброс текущего профиля на стандартный"
+elseif LOCALE == "itIT" then
+ L["choose"] = "Profili Esistenti"
+ L["choose_desc"] = "Puoi creare un nuovo profilo digitando il nome della casella di testo, oppure scegliendone uno tra i profili già esistenti."
+ L["choose_sub"] = "Seleziona uno dei profili attualmente disponibili."
+ L["copy"] = "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["new"] = "Nuovo"
+ L["new_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 predefinite, 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 predefiniti."
+elseif LOCALE == "ptBR" then
+ L["choose"] = "Perfis Existentes"
+ L["choose_desc"] = "Você pode tanto criar um perfil novo tanto digitando um nome na caixa de texto, quanto escolher um dos perfis já existentes."
+ L["choose_sub"] = "Selecione um de seus perfis atualmente disponíveis."
+ L["copy"] = "Copiar De"
+ L["copy_desc"] = "Copia as definições de um perfil existente no perfil atualmente ativo."
+ L["current"] = "Perfil Autal:"
+ L["default"] = "Padrão"
+ L["delete"] = "Remover um Perfil"
+ L["delete_confirm"] = "Tem certeza que deseja remover o perfil selecionado?"
+ L["delete_desc"] = "Remove perfis existentes e inutilizados do banco de dados para economizar espaço, e limpar o arquivo SavedVariables."
+ L["delete_sub"] = "Remove um perfil do banco de dados."
+ L["intro"] = "Você pode alterar o perfil do banco de dados ativo, para que possa ter definições diferentes para cada personagem."
+ L["new"] = "Novo"
+ L["new_sub"] = "Cria um novo perfil vazio."
+ L["profiles"] = "Perfis"
+ L["profiles_sub"] = "Gerenciar Perfis"
+ L["reset"] = "Resetar Perfil"
+ L["reset_desc"] = "Reseta o perfil atual para os valores padrões, no caso de sua configuração estar quebrada, ou simplesmente se deseja começar novamente."
+ L["reset_sub"] = "Resetar o perfil atual ao padrão"
+end
+
+local defaultProfiles
+local tmpprofiles = {}
+
+-- Get a list of available profiles for the specified database.
+-- You can specify which profiles to include/exclude in the list using the two boolean parameters listed below.
+-- @param db The db object to retrieve the profiles from
+-- @param common If true, getProfileList will add the default profiles to the return list, even if they have not been created yet
+-- @param nocurrent If true, then getProfileList will not display the current profile in the list
+-- @return Hashtable of all profiles with the internal name as keys and the display name as value.
+local function getProfileList(db, common, nocurrent)
+ local profiles = {}
+
+ -- copy existing profiles into the table
+ local currentProfile = db:GetCurrentProfile()
+ for i,v in pairs(db:GetProfiles(tmpprofiles)) do
+ if not (nocurrent and v == currentProfile) then
+ profiles[v] = v
+ end
+ end
+
+ -- add our default profiles to choose from ( or rename existing profiles)
+ for k,v in pairs(defaultProfiles) do
+ if (common or profiles[k]) and not (nocurrent and k == currentProfile) then
+ profiles[k] = v
+ end
+ end
+
+ return profiles
+end
+
+--[[
+ OptionsHandlerPrototype
+ prototype class for handling the options in a sane way
+]]
+local OptionsHandlerPrototype = {}
+
+--[[ Reset the profile ]]
+function OptionsHandlerPrototype:Reset()
+ self.db:ResetProfile()
+end
+
+--[[ Set the profile to value ]]
+function OptionsHandlerPrototype:SetProfile(info, value)
+ self.db:SetProfile(value)
+end
+
+--[[ returns the currently active profile ]]
+function OptionsHandlerPrototype:GetCurrentProfile()
+ return self.db:GetCurrentProfile()
+end
+
+--[[
+ List all active profiles
+ you can control the output with the .arg variable
+ currently four modes are supported
+
+ (empty) - return all available profiles
+ "nocurrent" - returns all available profiles except the currently active profile
+ "common" - returns all avaialble profiles + some commonly used profiles ("char - realm", "realm", "class", "Default")
+ "both" - common except the active profile
+]]
+function OptionsHandlerPrototype:ListProfiles(info)
+ local arg = info.arg
+ local profiles
+ if arg == "common" and not self.noDefaultProfiles then
+ profiles = getProfileList(self.db, true, nil)
+ elseif arg == "nocurrent" then
+ profiles = getProfileList(self.db, nil, true)
+ elseif arg == "both" then -- currently not used
+ profiles = getProfileList(self.db, (not self.noDefaultProfiles) and true, true)
+ else
+ profiles = getProfileList(self.db)
+ end
+
+ return profiles
+end
+
+function OptionsHandlerPrototype:HasNoProfiles(info)
+ local profiles = self:ListProfiles(info)
+ return ((not next(profiles)) and true or false)
+end
+
+--[[ Copy a profile ]]
+function OptionsHandlerPrototype:CopyProfile(info, value)
+ self.db:CopyProfile(value)
+end
+
+--[[ Delete a profile from the db ]]
+function OptionsHandlerPrototype:DeleteProfile(info, value)
+ self.db:DeleteProfile(value)
+end
+
+--[[ fill defaultProfiles with some generic values ]]
+local function generateDefaultProfiles(db)
+ defaultProfiles = {
+ ["Default"] = L["default"],
+ [db.keys.char] = db.keys.char,
+ [db.keys.realm] = db.keys.realm,
+ [db.keys.class] = UnitClass("player")
+ }
+end
+
+--[[ create and return a handler object for the db, or upgrade it if it already existed ]]
+local function getOptionsHandler(db, noDefaultProfiles)
+ if not defaultProfiles then
+ generateDefaultProfiles(db)
+ end
+
+ local handler = AceDBOptions.handlers[db] or { db = db, noDefaultProfiles = noDefaultProfiles }
+
+ for k,v in pairs(OptionsHandlerPrototype) do
+ handler[k] = v
+ end
+
+ AceDBOptions.handlers[db] = handler
+ return handler
+end
+
+--[[
+ the real options table
+]]
+local optionsTable = {
+ desc = {
+ order = 1,
+ type = "description",
+ name = L["intro"] .. "\n",
+ },
+ descreset = {
+ order = 9,
+ type = "description",
+ name = L["reset_desc"],
+ },
+ reset = {
+ order = 10,
+ type = "execute",
+ name = L["reset"],
+ desc = L["reset_sub"],
+ func = "Reset",
+ },
+ current = {
+ order = 11,
+ type = "description",
+ name = function(info) return L["current"] .. " " .. NORMAL_FONT_COLOR_CODE .. info.handler:GetCurrentProfile() .. FONT_COLOR_CODE_CLOSE end,
+ width = "default",
+ },
+ choosedesc = {
+ order = 20,
+ type = "description",
+ name = "\n" .. L["choose_desc"],
+ },
+ new = {
+ name = L["new"],
+ desc = L["new_sub"],
+ type = "input",
+ order = 30,
+ get = false,
+ set = "SetProfile",
+ },
+ choose = {
+ name = L["choose"],
+ desc = L["choose_sub"],
+ type = "select",
+ order = 40,
+ get = "GetCurrentProfile",
+ set = "SetProfile",
+ values = "ListProfiles",
+ arg = "common",
+ },
+ copydesc = {
+ order = 50,
+ type = "description",
+ name = "\n" .. L["copy_desc"],
+ },
+ copyfrom = {
+ order = 60,
+ type = "select",
+ name = L["copy"],
+ desc = L["copy_desc"],
+ get = false,
+ set = "CopyProfile",
+ values = "ListProfiles",
+ disabled = "HasNoProfiles",
+ arg = "nocurrent",
+ },
+ deldesc = {
+ order = 70,
+ type = "description",
+ name = "\n" .. L["delete_desc"],
+ },
+ delete = {
+ order = 80,
+ type = "select",
+ name = L["delete"],
+ desc = L["delete_sub"],
+ get = false,
+ set = "DeleteProfile",
+ values = "ListProfiles",
+ disabled = "HasNoProfiles",
+ arg = "nocurrent",
+ confirm = true,
+ confirmText = L["delete_confirm"],
+ },
+}
+
+--- Get/Create a option table that you can use in your addon to control the profiles of AceDB-3.0.
+-- @param db The database object to create the options table for.
+-- @return The options table to be used in AceConfig-3.0
+-- @usage
+-- -- Assuming `options` is your top-level options table and `self.db` is your database:
+-- options.args.profiles = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
+function AceDBOptions:GetOptionsTable(db, noDefaultProfiles)
+ local tbl = AceDBOptions.optionTables[db] or {
+ type = "group",
+ name = L["profiles"],
+ desc = L["profiles_sub"],
+ }
+
+ tbl.handler = getOptionsHandler(db, noDefaultProfiles)
+ tbl.args = optionsTable
+
+ AceDBOptions.optionTables[db] = tbl
+ return tbl
+end
+
+-- upgrade existing tables
+for db,tbl in pairs(AceDBOptions.optionTables) do
+ tbl.handler = getOptionsHandler(db)
+ tbl.args = optionsTable
+end
diff --git a/Skada/Libs/AceEvent-3.0/AceEvent-3.0.lua b/Skada/Libs/AceEvent-3.0/AceEvent-3.0.lua
new file mode 100644
index 0000000..bbf55c2
--- /dev/null
+++ b/Skada/Libs/AceEvent-3.0/AceEvent-3.0.lua
@@ -0,0 +1,126 @@
+--- AceEvent-3.0 provides event registration and secure dispatching.
+-- All dispatching is done using **CallbackHandler-1.0**. AceEvent is a simple wrapper around
+-- CallbackHandler, and dispatches all game events or addon message to the registrees.
+--
+-- **AceEvent-3.0** can be embeded into your addon, either explicitly by calling AceEvent:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceEvent itself.\\
+-- It is recommended to embed AceEvent, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceEvent.
+-- @class file
+-- @name AceEvent-3.0
+-- @release $Id: AceEvent-3.0.lua 1161 2017-08-12 14:30:16Z funkydude $
+local CallbackHandler = LibStub("CallbackHandler-1.0")
+
+local MAJOR, MINOR = "AceEvent-3.0", 4
+local AceEvent = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceEvent then return end
+
+-- Lua APIs
+local pairs = pairs
+
+AceEvent.frame = AceEvent.frame or CreateFrame("Frame", "AceEvent30Frame") -- our event frame
+AceEvent.embeds = AceEvent.embeds or {} -- what objects embed this lib
+
+-- APIs and registry for blizzard events, using CallbackHandler lib
+if not AceEvent.events then
+ AceEvent.events = CallbackHandler:New(AceEvent,
+ "RegisterEvent", "UnregisterEvent", "UnregisterAllEvents")
+end
+
+function AceEvent.events:OnUsed(target, eventname)
+ AceEvent.frame:RegisterEvent(eventname)
+end
+
+function AceEvent.events:OnUnused(target, eventname)
+ AceEvent.frame:UnregisterEvent(eventname)
+end
+
+
+-- APIs and registry for IPC messages, using CallbackHandler lib
+if not AceEvent.messages then
+ AceEvent.messages = CallbackHandler:New(AceEvent,
+ "RegisterMessage", "UnregisterMessage", "UnregisterAllMessages"
+ )
+ AceEvent.SendMessage = AceEvent.messages.Fire
+end
+
+--- embedding and embed handling
+local mixins = {
+ "RegisterEvent", "UnregisterEvent",
+ "RegisterMessage", "UnregisterMessage",
+ "SendMessage",
+ "UnregisterAllEvents", "UnregisterAllMessages",
+}
+
+--- Register for a Blizzard Event.
+-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
+-- Any arguments to the event will be passed on after that.
+-- @name AceEvent:RegisterEvent
+-- @class function
+-- @paramsig event[, callback [, arg]]
+-- @param event The event to register for
+-- @param callback The callback function to call when the event is triggered (funcref or method, defaults to a method with the event name)
+-- @param arg An optional argument to pass to the callback function
+
+--- Unregister an event.
+-- @name AceEvent:UnregisterEvent
+-- @class function
+-- @paramsig event
+-- @param event The event to unregister
+
+--- Register for a custom AceEvent-internal message.
+-- The callback will be called with the optional `arg` as the first argument (if supplied), and the event name as the second (or first, if no arg was supplied)
+-- Any arguments to the event will be passed on after that.
+-- @name AceEvent:RegisterMessage
+-- @class function
+-- @paramsig message[, callback [, arg]]
+-- @param message The message to register for
+-- @param callback The callback function to call when the message is triggered (funcref or method, defaults to a method with the event name)
+-- @param arg An optional argument to pass to the callback function
+
+--- Unregister a message
+-- @name AceEvent:UnregisterMessage
+-- @class function
+-- @paramsig message
+-- @param message The message to unregister
+
+--- Send a message over the AceEvent-3.0 internal message system to other addons registered for this message.
+-- @name AceEvent:SendMessage
+-- @class function
+-- @paramsig message, ...
+-- @param message The message to send
+-- @param ... Any arguments to the message
+
+
+-- Embeds AceEvent into the target object making the functions from the mixins list available on target:..
+-- @param target target object to embed AceEvent in
+function AceEvent:Embed(target)
+ for k, v in pairs(mixins) do
+ target[v] = self[v]
+ end
+ self.embeds[target] = true
+ return target
+end
+
+-- AceEvent:OnEmbedDisable( target )
+-- target (object) - target object that is being disabled
+--
+-- Unregister all events messages etc when the target disables.
+-- this method should be called by the target manually or by an addon framework
+function AceEvent:OnEmbedDisable(target)
+ target:UnregisterAllEvents()
+ target:UnregisterAllMessages()
+end
+
+-- Script to fire blizzard events into the event listeners
+local events = AceEvent.events
+AceEvent.frame:SetScript("OnEvent", function(this, event, ...)
+ events:Fire(event, ...)
+end)
+
+--- Finally: upgrade our old embeds
+for target, v in pairs(AceEvent.embeds) do
+ AceEvent:Embed(target)
+end
diff --git a/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/BackgroundWidget.lua b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/BackgroundWidget.lua
new file mode 100644
index 0000000..0b75952
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/BackgroundWidget.lua
@@ -0,0 +1,235 @@
+-- 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 AGSMW = LibStub("AceGUISharedMediaWidgets-1.0")
+
+do
+ local widgetType = "LSM30_Background"
+ local widgetVersion = 11
+
+ 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 = AGSMW: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(200)
+ frame:SetHeight(18)
+ frame:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]], "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:SetPoint("TOPLEFT", check, "TOPRIGHT", 1, 0)
+ text:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -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(200)
+ 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/Tooltips/UI-Tooltip-Border",
+ 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. <>
+
+ local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <>
+ local function GetMultiselect() return false end-- Query the multi-select flag. <>
+ local function SetItemDisabled(self, key) end-- Disable one item in the list. <>
+
+ 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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ AceGUI:ClearFocus()
+ else
+ AceGUI:SetFocus(self)
+ self.dropdown = AGSMW: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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ end
+ end
+
+ local function OnHide(this)
+ local self = this.obj
+ if self.dropdown then
+ self.dropdown = AGSMW: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 Constructor()
+ local frame = AGSMW: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)
+
+ 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/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/BorderWidget.lua b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/BorderWidget.lua
new file mode 100644
index 0000000..0cd2959
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/BorderWidget.lua
@@ -0,0 +1,230 @@
+-- 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 AGSMW = LibStub("AceGUISharedMediaWidgets-1.0")
+
+do
+ local widgetType = "LSM30_Border"
+ local widgetVersion = 11
+
+ 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 = AGSMW: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(200)
+ frame:SetHeight(18)
+ frame:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]], "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:SetPoint("TOPLEFT", check, "TOPRIGHT", 1, 0)
+ text:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -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(200)
+ 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. <>
+
+ local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <>
+ local function GetMultiselect() return false end-- Query the multi-select flag. <>
+ local function SetItemDisabled(self, key) end-- Disable one item in the list. <>
+
+ 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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ AceGUI:ClearFocus()
+ else
+ AceGUI:SetFocus(self)
+ self.dropdown = AGSMW: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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ end
+ end
+
+ local function OnHide(this)
+ local self = this.obj
+ if self.dropdown then
+ self.dropdown = AGSMW: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 Constructor()
+ local frame = AGSMW: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)
+
+ 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/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/FontWidget.lua b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/FontWidget.lua
new file mode 100644
index 0000000..eadf35f
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/FontWidget.lua
@@ -0,0 +1,216 @@
+-- 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 AGSMW = LibStub("AceGUISharedMediaWidgets-1.0")
+
+do
+ local widgetType = "LSM30_Font"
+ local widgetVersion = 11
+
+ 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 = AGSMW: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(200)
+ frame:SetHeight(18)
+ frame:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]], "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:SetPoint("TOPLEFT", check, "TOPRIGHT", 1, 0)
+ text:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -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(200)
+ 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. <>
+
+ local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <>
+ local function GetMultiselect() return false end-- Query the multi-select flag. <>
+ local function SetItemDisabled(self, key) end-- Disable one item in the list. <>
+
+ 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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ AceGUI:ClearFocus()
+ else
+ AceGUI:SetFocus(self)
+ self.dropdown = AGSMW: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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ end
+ end
+
+ local function OnHide(this)
+ local self = this.obj
+ if self.dropdown then
+ self.dropdown = AGSMW: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 Constructor()
+ local frame = AGSMW: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)
+
+ 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/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/SoundWidget.lua b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/SoundWidget.lua
new file mode 100644
index 0000000..1d39c28
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/SoundWidget.lua
@@ -0,0 +1,264 @@
+-- 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 AGSMW = LibStub("AceGUISharedMediaWidgets-1.0")
+
+do
+ local widgetType = "LSM30_Sound"
+ local widgetVersion = 11
+
+ 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 = AGSMW: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(200)
+ frame:SetHeight(18)
+ frame:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]], "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:SetPoint("TOPLEFT", check, "TOPRIGHT", 1, 0)
+ text:SetPoint("BOTTOMRIGHT", soundbutton, "BOTTOMLEFT", -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(200)
+ 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. <>
+
+ local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <>
+ local function GetMultiselect() return false end-- Query the multi-select flag. <>
+ local function SetItemDisabled(self, key) end-- Disable one item in the list. <>
+
+ 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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ AceGUI:ClearFocus()
+ else
+ AceGUI:SetFocus(self)
+ self.dropdown = AGSMW: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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ end
+ end
+
+ local function OnHide(this)
+ local self = this.obj
+ if self.dropdown then
+ self.dropdown = AGSMW: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 Constructor()
+ local frame = AGSMW: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)
+
+
+ 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/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/StatusbarWidget.lua b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/StatusbarWidget.lua
new file mode 100644
index 0000000..2d0e32c
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/StatusbarWidget.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 AGSMW = LibStub("AceGUISharedMediaWidgets-1.0")
+
+do
+ local widgetType = "LSM30_Statusbar"
+ local widgetVersion = 11
+
+ 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 = AGSMW: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(200)
+ frame:SetHeight(18)
+ frame:SetHighlightTexture([[Interface\QuestFrame\UI-QuestTitleHighlight]], "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:SetPoint("TOPLEFT", check, "TOPRIGHT", 3, 0)
+ text:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -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(200)
+ 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. <>
+
+ local function SetMultiselect(self, flag) end -- Toggle multi-selecting. <>
+ local function GetMultiselect() return false end-- Query the multi-select flag. <>
+ local function SetItemDisabled(self, key) end-- Disable one item in the list. <>
+
+ 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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ AceGUI:ClearFocus()
+ else
+ AceGUI:SetFocus(self)
+ self.dropdown = AGSMW: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 = AGSMW:ReturnDropDownFrame(self.dropdown)
+ end
+ end
+
+ local function OnHide(this)
+ local self = this.obj
+ if self.dropdown then
+ self.dropdown = AGSMW: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 Constructor()
+ local frame = AGSMW: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)
+
+ 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/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/prototypes.lua b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/prototypes.lua
new file mode 100644
index 0000000..98bc818
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/prototypes.lua
@@ -0,0 +1,273 @@
+-- Widget created by Yssaril
+--[===[@debug@
+local DataVersion = 9001 -- dev version always overwrites everything else :)
+--@end-debug@]===]
+--@non-debug@
+local DataVersion = 56
+--@end-non-debug@
+local AGSMW = LibStub:NewLibrary("AceGUISharedMediaWidgets-1.0", DataVersion)
+
+if not AGSMW then
+ return -- already loaded and no upgrade necessary
+end
+
+local AceGUI = LibStub("AceGUI-3.0")
+local Media = LibStub("LibSharedMedia-3.0")
+
+AGSMW = AGSMW or {}
+
+AceGUIWidgetLSMlists = {
+ ['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/Tooltips/UI-Tooltip-Border",
+ tile = true, tileSize = 16, edgeSize = 16,
+ insets = { left = 4, right = 4, top = 4, bottom = 4 },
+ }
+
+ -- create or retrieve BaseFrame
+ function AGSMW:GetBaseFrame()
+ local frame = CreateFrame("Frame", nil, UIParent)
+ frame:SetHeight(44)
+ frame:SetWidth(200)
+
+ 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: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: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 AGSMW: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\Buttons\UI-SliderBar-Background]],
+ ["edgeFile"] = [[Interface\Buttons\UI-SliderBar-Border]],
+ ["tile"] = true,
+ ["edgeSize"] = 8,
+ ["tileSize"] = 8,
+ ["insets"] = {
+ ["left"] = 3,
+ ["right"] = 3,
+ ["top"] = 3,
+ ["bottom"] = 3,
+ },
+ }
+ local frameBackdrop = {
+ bgFile=[[Interface\DialogFrame\UI-DialogBox-Background-Dark]],
+ edgeFile = [[Interface\DialogFrame\UI-DialogBox-Border]],
+ tile = true, tileSize = 32, edgeSize = 32,
+ insets = { left = 11, right = 12, top = 12, bottom = 9 },
+ }
+
+ 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", -28, 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", -14, 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 AGSMW:GetDropDownFrame()
+ local frame
+ if next(DropDownCache) then
+ frame = table.remove(DropDownCache)
+ else
+ frame = CreateFrame("Frame", nil, UIParent)
+ frame:SetClampedToScreen(true)
+ frame:SetWidth(188)
+ frame:SetBackdrop(frameBackdrop)
+ frame:SetFrameStrata("TOOLTIP")
+ frame:EnableMouseWheel(true)
+
+ local contentframe = CreateFrame("Frame", nil, frame)
+ contentframe:SetWidth(160)
+ contentframe:SetHeight(0)
+ frame.contentframe = contentframe
+
+ local scrollframe = CreateFrame("ScrollFrame", nil, frame)
+ scrollframe:SetWidth(160)
+ scrollframe:SetPoint("TOPLEFT", frame, "TOPLEFT", 14, -13)
+ scrollframe:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -14, 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", -14, -10)
+ slider:SetPoint("BOTTOMRIGHT", frame, "BOTTOMRIGHT", -14, 10)
+ slider:SetBackdrop(sliderBackdrop)
+ slider:SetThumbTexture([[Interface\Buttons\UI-SliderBar-Button-Vertical]])
+ 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 AGSMW:ReturnDropDownFrame(frame)
+ ClearFrames(frame)
+ frame:ClearAllPoints()
+ frame:Hide()
+ frame:SetBackdrop(frameBackdrop)
+ frame.bgTex:SetTexture(nil)
+ table.insert(DropDownCache, frame)
+ return nil
+ end
+end
diff --git a/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/widget.xml b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/widget.xml
new file mode 100644
index 0000000..15cd102
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0-SharedMediaWidgets/widget.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Skada/Libs/AceGUI-3.0/AceGUI-3.0.lua b/Skada/Libs/AceGUI-3.0/AceGUI-3.0.lua
new file mode 100644
index 0000000..9853644
--- /dev/null
+++ b/Skada/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/Skada/Libs/AceGUI-3.0/AceGUI-3.0.xml b/Skada/Libs/AceGUI-3.0/AceGUI-3.0.xml
new file mode 100644
index 0000000..b515077
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/AceGUI-3.0.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-BlizOptionsGroup.lua
new file mode 100644
index 0000000..9a48f8b
--- /dev/null
+++ b/Skada/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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-DropDownGroup.lua
new file mode 100644
index 0000000..b0f81b7
--- /dev/null
+++ b/Skada/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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
new file mode 100644
index 0000000..020eaf6
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-Frame.lua
@@ -0,0 +1,316 @@
+--[[-----------------------------------------------------------------------------
+Frame Container
+-------------------------------------------------------------------------------]]
+local Type, Version = "Frame", 26
+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(PlaySoundKitID and "gsTitleOptionExit" or 799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
+ frame.obj:Hide()
+end
+
+local function Frame_OnShow(frame)
+ frame.obj:Fire("OnShow")
+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("OnShow", Frame_OnShow)
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-InlineGroup.lua
new file mode 100644
index 0000000..f3db7d6
--- /dev/null
+++ b/Skada/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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-ScrollFrame.lua
new file mode 100644
index 0000000..9afb54b
--- /dev/null
+++ b/Skada/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", 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 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-SimpleGroup.lua
new file mode 100644
index 0000000..57512c3
--- /dev/null
+++ b/Skada/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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-TabGroup.lua
new file mode 100644
index 0000000..d00470e
--- /dev/null
+++ b/Skada/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", 36
+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(PlaySoundKitID and "igCharacterInfoTab" or 841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
new file mode 100644
index 0000000..617d5dc
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-TreeGroup.lua
@@ -0,0 +1,710 @@
+--[[-----------------------------------------------------------------------------
+TreeGroup Container
+Container that uses a tree control to switch between groups.
+-------------------------------------------------------------------------------]]
+local Type, Version = "TreeGroup", 40
+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)
+ self.frame:SetScript("OnUpdate", FirstFrameUpdate)
+ 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 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
new file mode 100644
index 0000000..6c36aca
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIContainer-Window.lua
@@ -0,0 +1,336 @@
+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 = 6
+
+ local function frameOnShow(this)
+ this.obj:Fire("OnShow")
+ end
+
+ local function frameOnClose(this)
+ this.obj:Fire("OnClose")
+ end
+
+ local function closeOnClick(this)
+ PlaySound(PlaySoundKitID and "gsTitleOptionExit" or 799) -- SOUNDKIT.GS_TITLE_OPTION_EXIT
+ 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("OnShow",frameOnShow)
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
new file mode 100644
index 0000000..55b7bc8
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Button.lua
@@ -0,0 +1,103 @@
+--[[-----------------------------------------------------------------------------
+Button Widget
+Graphical Button.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Button", 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 _G = _G
+local PlaySound, CreateFrame, UIParent = PlaySound, CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+Scripts
+-------------------------------------------------------------------------------]]
+local function Button_OnClick(frame, ...)
+ AceGUI:ClearFocus()
+ PlaySound(PlaySoundKitID and "igMainMenuOption" or 852) -- SOUNDKIT.IG_MAINMENU_OPTION
+ 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, "UIPanelButtonTemplate")
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
new file mode 100644
index 0000000..b8426e3
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-CheckBox.lua
@@ -0,0 +1,295 @@
+--[[-----------------------------------------------------------------------------
+Checkbox Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "CheckBox", 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 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(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ else -- for both nil and false (tristate)
+ PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOff" or 857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
new file mode 100644
index 0000000..05e2b57
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-ColorPicker.lua
@@ -0,0 +1,188 @@
+--[[-----------------------------------------------------------------------------
+ColorPicker Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "ColorPicker", 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 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
new file mode 100644
index 0000000..cb9c14c
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown-Items.lua
@@ -0,0 +1,471 @@
+--[[ $Id: AceGUIWidget-DropDown-Items.lua 1161 2017-08-12 14:30:16Z funkydude $ ]]--
+
+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 = 4
+
+ 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(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ else
+ PlaySound(PlaySoundKitID and "igMainMenuOptionCheckBoxOff" or 857) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_OFF
+ 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 = 2
+
+ -- 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
new file mode 100644
index 0000000..37a365b
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-DropDown.lua
@@ -0,0 +1,737 @@
+--[[ $Id: AceGUIWidget-DropDown.lua 1161 2017-08-12 14:30:16Z funkydude $ ]]--
+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 = 31
+
+ --[[ 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(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
new file mode 100644
index 0000000..6594684
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-EditBox.lua
@@ -0,0 +1,265 @@
+--[[-----------------------------------------------------------------------------
+EditBox Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "EditBox", 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 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(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ 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,
+
+ ["HighlightText"] = function(self, from, to)
+ self.editbox:HighlightText(from, to)
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Heading.lua
new file mode 100644
index 0000000..1aaf3f5
--- /dev/null
+++ b/Skada/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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
new file mode 100644
index 0000000..561da73
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Icon.lua
@@ -0,0 +1,140 @@
+--[[-----------------------------------------------------------------------------
+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 = CreateFrame, UIParent
+
+--[[-----------------------------------------------------------------------------
+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
+
+ widget.SetText = function(self, ...) print("AceGUI-3.0-Icon: SetText is deprecated! Use SetLabel instead!"); self:SetLabel(...) end
+
+ return AceGUI:RegisterAsWidget(widget)
+end
+
+AceGUI:RegisterWidgetType(Type, Constructor, Version)
diff --git a/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
new file mode 100644
index 0000000..036efee
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-InteractiveLabel.lua
@@ -0,0 +1,101 @@
+--[[-----------------------------------------------------------------------------
+InteractiveLabel Widget
+-------------------------------------------------------------------------------]]
+local Type, Version = "InteractiveLabel", 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 = 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
new file mode 100644
index 0000000..ec4cead
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Keybinding.lua
@@ -0,0 +1,249 @@
+--[[-----------------------------------------------------------------------------
+Keybinding Widget
+Set Keybindings in the Config UI.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Keybinding", 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 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
+
+--[[-----------------------------------------------------------------------------
+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)
+ frame:EnableMouseWheel(false)
+ self.msgframe:Hide()
+ frame:UnlockHighlight()
+ self.waitingForKey = nil
+ else
+ frame:EnableKeyboard(true)
+ frame:EnableMouseWheel(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)
+ frame:EnableMouseWheel(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
+
+local function Keybinding_OnMouseWheel(frame, direction)
+ local button
+ if direction >= 0 then
+ button = "MOUSEWHEELUP"
+ else
+ button = "MOUSEWHEELDOWN"
+ 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)
+ self.button:EnableMouseWheel(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, "UIPanelButtonTemplate")
+
+ button:EnableMouse(true)
+ button:EnableMouseWheel(false)
+ 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:SetScript("OnMouseWheel", Keybinding_OnMouseWheel)
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
new file mode 100644
index 0000000..75817a0
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Label.lua
@@ -0,0 +1,173 @@
+--[[-----------------------------------------------------------------------------
+Label Widget
+Displays text and optionally an icon.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Label", 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 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()
+ self:SetJustifyH("LEFT")
+ self:SetJustifyV("TOP")
+
+ -- 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,
+
+ ["SetJustifyH"] = function(self, justifyH)
+ self.label:SetJustifyH(justifyH)
+ end,
+
+ ["SetJustifyV"] = function(self, justifyV)
+ self.label:SetJustifyV(justifyV)
+ end,
+}
+
+--[[-----------------------------------------------------------------------------
+Constructor
+-------------------------------------------------------------------------------]]
+local function Constructor()
+ local frame = CreateFrame("Frame", nil, UIParent)
+ frame:Hide()
+
+ local label = frame:CreateFontString(nil, "BACKGROUND", "GameFontHighlightSmall")
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
new file mode 100644
index 0000000..9af4b87
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-MultiLineEditBox.lua
@@ -0,0 +1,366 @@
+local Type, Version = "MultiLineEditBox", 28
+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
+
+--[[-----------------------------------------------------------------------------
+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,
+
+ ["HighlightText"] = function(self, from, to)
+ self.editBox:HighlightText(from, to)
+ 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, "UIPanelButtonTemplate")
+ 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/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
new file mode 100644
index 0000000..5946d8d
--- /dev/null
+++ b/Skada/Libs/AceGUI-3.0/widgets/AceGUIWidget-Slider.lua
@@ -0,0 +1,285 @@
+--[[-----------------------------------------------------------------------------
+Slider Widget
+Graphical Slider, like, for Range values.
+-------------------------------------------------------------------------------]]
+local Type, Version = "Slider", 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 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(PlaySoundKitID and "igMainMenuOptionCheckBoxOn" or 856) -- SOUNDKIT.IG_MAINMENU_OPTION_CHECKBOX_ON
+ 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/Skada/Libs/AceHook-3.0/AceHook-3.0.lua b/Skada/Libs/AceHook-3.0/AceHook-3.0.lua
new file mode 100644
index 0000000..8302334
--- /dev/null
+++ b/Skada/Libs/AceHook-3.0/AceHook-3.0.lua
@@ -0,0 +1,511 @@
+--- **AceHook-3.0** offers safe Hooking/Unhooking of functions, methods and frame scripts.
+-- Using AceHook-3.0 is recommended when you need to unhook your hooks again, so the hook chain isn't broken
+-- when you manually restore the original function.
+--
+-- **AceHook-3.0** can be embeded into your addon, either explicitly by calling AceHook:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceHook itself.\\
+-- It is recommended to embed AceHook, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceHook.
+-- @class file
+-- @name AceHook-3.0
+-- @release $Id: AceHook-3.0.lua 1118 2014-10-12 08:21:54Z nevcairiel $
+local ACEHOOK_MAJOR, ACEHOOK_MINOR = "AceHook-3.0", 8
+local AceHook, oldminor = LibStub:NewLibrary(ACEHOOK_MAJOR, ACEHOOK_MINOR)
+
+if not AceHook then return end -- No upgrade needed
+
+AceHook.embeded = AceHook.embeded or {}
+AceHook.registry = AceHook.registry or setmetatable({}, {__index = function(tbl, key) tbl[key] = {} return tbl[key] end })
+AceHook.handlers = AceHook.handlers or {}
+AceHook.actives = AceHook.actives or {}
+AceHook.scripts = AceHook.scripts or {}
+AceHook.onceSecure = AceHook.onceSecure or {}
+AceHook.hooks = AceHook.hooks or {}
+
+-- local upvalues
+local registry = AceHook.registry
+local handlers = AceHook.handlers
+local actives = AceHook.actives
+local scripts = AceHook.scripts
+local onceSecure = AceHook.onceSecure
+
+-- Lua APIs
+local pairs, next, type = pairs, next, type
+local format = string.format
+local assert, error = assert, error
+
+-- WoW APIs
+local issecurevariable, hooksecurefunc = issecurevariable, hooksecurefunc
+local _G = _G
+
+-- functions for later definition
+local donothing, createHook, hook
+
+local protectedScripts = {
+ OnClick = true,
+}
+
+-- upgrading of embeded is done at the bottom of the file
+
+local mixins = {
+ "Hook", "SecureHook",
+ "HookScript", "SecureHookScript",
+ "Unhook", "UnhookAll",
+ "IsHooked",
+ "RawHook", "RawHookScript"
+}
+
+-- AceHook:Embed( target )
+-- target (object) - target object to embed AceHook in
+--
+-- Embeds AceEevent into the target object making the functions from the mixins list available on target:..
+function AceHook:Embed( target )
+ for k, v in pairs( mixins ) do
+ target[v] = self[v]
+ end
+ self.embeded[target] = true
+ -- inject the hooks table safely
+ target.hooks = target.hooks or {}
+ return target
+end
+
+-- AceHook:OnEmbedDisable( target )
+-- target (object) - target object that is being disabled
+--
+-- Unhooks all hooks when the target disables.
+-- this method should be called by the target manually or by an addon framework
+function AceHook:OnEmbedDisable( target )
+ target:UnhookAll()
+end
+
+function createHook(self, handler, orig, secure, failsafe)
+ local uid
+ local method = type(handler) == "string"
+ if failsafe and not secure then
+ -- failsafe hook creation
+ uid = function(...)
+ if actives[uid] then
+ if method then
+ self[handler](self, ...)
+ else
+ handler(...)
+ end
+ end
+ return orig(...)
+ end
+ -- /failsafe hook
+ else
+ -- all other hooks
+ uid = function(...)
+ if actives[uid] then
+ if method then
+ return self[handler](self, ...)
+ else
+ return handler(...)
+ end
+ elseif not secure then -- backup on non secure
+ return orig(...)
+ end
+ end
+ -- /hook
+ end
+ return uid
+end
+
+function donothing() end
+
+function hook(self, obj, method, handler, script, secure, raw, forceSecure, usage)
+ if not handler then handler = method end
+
+ -- These asserts make sure AceHooks's devs play by the rules.
+ assert(not script or type(script) == "boolean")
+ assert(not secure or type(secure) == "boolean")
+ assert(not raw or type(raw) == "boolean")
+ assert(not forceSecure or type(forceSecure) == "boolean")
+ assert(usage)
+
+ -- Error checking Battery!
+ if obj and type(obj) ~= "table" then
+ error(format("%s: 'object' - nil or table expected got %s", usage, type(obj)), 3)
+ end
+ if type(method) ~= "string" then
+ error(format("%s: 'method' - string expected got %s", usage, type(method)), 3)
+ end
+ if type(handler) ~= "string" and type(handler) ~= "function" then
+ error(format("%s: 'handler' - nil, string, or function expected got %s", usage, type(handler)), 3)
+ end
+ if type(handler) == "string" and type(self[handler]) ~= "function" then
+ error(format("%s: 'handler' - Handler specified does not exist at self[handler]", usage), 3)
+ end
+ if script then
+ if not obj or not obj.GetScript or not obj:HasScript(method) then
+ error(format("%s: You can only hook a script on a frame object", usage), 3)
+ end
+ if not secure and obj.IsProtected and obj:IsProtected() and protectedScripts[method] then
+ error(format("Cannot hook secure script %q; Use SecureHookScript(obj, method, [handler]) instead.", method), 3)
+ end
+ else
+ local issecure
+ if obj then
+ issecure = onceSecure[obj] and onceSecure[obj][method] or issecurevariable(obj, method)
+ else
+ issecure = onceSecure[method] or issecurevariable(method)
+ end
+ if issecure then
+ if forceSecure then
+ if obj then
+ onceSecure[obj] = onceSecure[obj] or {}
+ onceSecure[obj][method] = true
+ else
+ onceSecure[method] = true
+ end
+ elseif not secure then
+ error(format("%s: Attempt to hook secure function %s. Use `SecureHook' or add `true' to the argument list to override.", usage, method), 3)
+ end
+ end
+ end
+
+ local uid
+ if obj then
+ uid = registry[self][obj] and registry[self][obj][method]
+ else
+ uid = registry[self][method]
+ end
+
+ if uid then
+ if actives[uid] then
+ -- Only two sane choices exist here. We either a) error 100% of the time or b) always unhook and then hook
+ -- choice b would likely lead to odd debuging conditions or other mysteries so we're going with a.
+ error(format("Attempting to rehook already active hook %s.", method))
+ end
+
+ if handlers[uid] == handler then -- turn on a decative hook, note enclosures break this ability, small memory leak
+ actives[uid] = true
+ return
+ elseif obj then -- is there any reason not to call unhook instead of doing the following several lines?
+ if self.hooks and self.hooks[obj] then
+ self.hooks[obj][method] = nil
+ end
+ registry[self][obj][method] = nil
+ else
+ if self.hooks then
+ self.hooks[method] = nil
+ end
+ registry[self][method] = nil
+ end
+ handlers[uid], actives[uid], scripts[uid] = nil, nil, nil
+ uid = nil
+ end
+
+ local orig
+ if script then
+ orig = obj:GetScript(method) or donothing
+ elseif obj then
+ orig = obj[method]
+ else
+ orig = _G[method]
+ end
+
+ if not orig then
+ error(format("%s: Attempting to hook a non existing target", usage), 3)
+ end
+
+ uid = createHook(self, handler, orig, secure, not (raw or secure))
+
+ if obj then
+ self.hooks[obj] = self.hooks[obj] or {}
+ registry[self][obj] = registry[self][obj] or {}
+ registry[self][obj][method] = uid
+
+ if not secure then
+ self.hooks[obj][method] = orig
+ end
+
+ if script then
+ if not secure then
+ obj:SetScript(method, uid)
+ else
+ obj:HookScript(method, uid)
+ end
+ else
+ if not secure then
+ obj[method] = uid
+ else
+ hooksecurefunc(obj, method, uid)
+ end
+ end
+ else
+ registry[self][method] = uid
+
+ if not secure then
+ _G[method] = uid
+ self.hooks[method] = orig
+ else
+ hooksecurefunc(method, uid)
+ end
+ end
+
+ actives[uid], handlers[uid], scripts[uid] = true, handler, script and true or nil
+end
+
+--- Hook a function or a method on an object.
+-- The hook created will be a "safe hook", that means that your handler will be called
+-- before the hooked function ("Pre-Hook"), and you don't have to call the original function yourself,
+-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
+-- This type of hook is typically used if you need to know if some function got called, and don't want to modify it.
+-- @paramsig [object], method, [handler], [hookSecure]
+-- @param object The object to hook a method from
+-- @param method If object was specified, the name of the method, or the name of the function to hook.
+-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
+-- @param hookSecure If true, AceHook will allow hooking of secure functions.
+-- @usage
+-- -- create an addon with AceHook embeded
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
+--
+-- function MyAddon:OnEnable()
+-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
+-- self:Hook("ActionButton_UpdateHotkeys", true)
+-- end
+--
+-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
+-- print(button:GetName() .. " is updating its HotKey")
+-- end
+function AceHook:Hook(object, method, handler, hookSecure)
+ if type(object) == "string" then
+ method, handler, hookSecure, object = object, method, handler, nil
+ end
+
+ if handler == true then
+ handler, hookSecure = nil, true
+ end
+
+ hook(self, object, method, handler, false, false, false, hookSecure or false, "Usage: Hook([object], method, [handler], [hookSecure])")
+end
+
+--- RawHook a function or a method on an object.
+-- The hook created will be a "raw hook", that means that your handler will completly replace
+-- the original function, and your handler has to call the original function (or not, depending on your intentions).\\
+-- The original function will be stored in `self.hooks[object][method]` or `self.hooks[functionName]` respectively.\\
+-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
+-- or want to control execution of the original function.
+-- @paramsig [object], method, [handler], [hookSecure]
+-- @param object The object to hook a method from
+-- @param method If object was specified, the name of the method, or the name of the function to hook.
+-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
+-- @param hookSecure If true, AceHook will allow hooking of secure functions.
+-- @usage
+-- -- create an addon with AceHook embeded
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
+--
+-- function MyAddon:OnEnable()
+-- -- Hook ActionButton_UpdateHotkeys, overwriting the secure status
+-- self:RawHook("ActionButton_UpdateHotkeys", true)
+-- end
+--
+-- function MyAddon:ActionButton_UpdateHotkeys(button, type)
+-- if button:GetName() == "MyButton" then
+-- -- do stuff here
+-- else
+-- self.hooks.ActionButton_UpdateHotkeys(button, type)
+-- end
+-- end
+function AceHook:RawHook(object, method, handler, hookSecure)
+ if type(object) == "string" then
+ method, handler, hookSecure, object = object, method, handler, nil
+ end
+
+ if handler == true then
+ handler, hookSecure = nil, true
+ end
+
+ hook(self, object, method, handler, false, false, true, hookSecure or false, "Usage: RawHook([object], method, [handler], [hookSecure])")
+end
+
+--- SecureHook a function or a method on an object.
+-- This function is a wrapper around the `hooksecurefunc` function in the WoW API. Using AceHook
+-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
+-- required anymore, or the addon is being disabled.\\
+-- Secure Hooks should be used if the secure-status of the function is vital to its function,
+-- and taint would block execution. Secure Hooks are always called after the original function was called
+-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
+-- @paramsig [object], method, [handler]
+-- @param object The object to hook a method from
+-- @param method If object was specified, the name of the method, or the name of the function to hook.
+-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked function)
+function AceHook:SecureHook(object, method, handler)
+ if type(object) == "string" then
+ method, handler, object = object, method, nil
+ end
+
+ hook(self, object, method, handler, false, true, false, false, "Usage: SecureHook([object], method, [handler])")
+end
+
+--- Hook a script handler on a frame.
+-- The hook created will be a "safe hook", that means that your handler will be called
+-- before the hooked script ("Pre-Hook"), and you don't have to call the original function yourself,
+-- however you cannot stop the execution of the function, or modify any of the arguments/return values.\\
+-- This is the frame script equivalent of the :Hook safe-hook. It would typically be used to be notified
+-- when a certain event happens to a frame.
+-- @paramsig frame, script, [handler]
+-- @param frame The Frame to hook the script on
+-- @param script The script to hook
+-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
+-- @usage
+-- -- create an addon with AceHook embeded
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
+--
+-- function MyAddon:OnEnable()
+-- -- Hook the OnShow of FriendsFrame
+-- self:HookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
+-- end
+--
+-- function MyAddon:FriendsFrameOnShow(frame)
+-- print("The FriendsFrame was shown!")
+-- end
+function AceHook:HookScript(frame, script, handler)
+ hook(self, frame, script, handler, true, false, false, false, "Usage: HookScript(object, method, [handler])")
+end
+
+--- RawHook a script handler on a frame.
+-- The hook created will be a "raw hook", that means that your handler will completly replace
+-- the original script, and your handler has to call the original script (or not, depending on your intentions).\\
+-- The original script will be stored in `self.hooks[frame][script]`.\\
+-- This type of hook can be used for all purposes, and is usually the most common case when you need to modify arguments
+-- or want to control execution of the original script.
+-- @paramsig frame, script, [handler]
+-- @param frame The Frame to hook the script on
+-- @param script The script to hook
+-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
+-- @usage
+-- -- create an addon with AceHook embeded
+-- MyAddon = LibStub("AceAddon-3.0"):NewAddon("HookDemo", "AceHook-3.0")
+--
+-- function MyAddon:OnEnable()
+-- -- Hook the OnShow of FriendsFrame
+-- self:RawHookScript(FriendsFrame, "OnShow", "FriendsFrameOnShow")
+-- end
+--
+-- function MyAddon:FriendsFrameOnShow(frame)
+-- -- Call the original function
+-- self.hooks[frame].OnShow(frame)
+-- -- Do our processing
+-- -- .. stuff
+-- end
+function AceHook:RawHookScript(frame, script, handler)
+ hook(self, frame, script, handler, true, false, true, false, "Usage: RawHookScript(object, method, [handler])")
+end
+
+--- SecureHook a script handler on a frame.
+-- This function is a wrapper around the `frame:HookScript` function in the WoW API. Using AceHook
+-- extends the functionality of secure hooks, and adds the ability to unhook once the hook isn't
+-- required anymore, or the addon is being disabled.\\
+-- Secure Hooks should be used if the secure-status of the function is vital to its function,
+-- and taint would block execution. Secure Hooks are always called after the original function was called
+-- ("Post Hook"), and you cannot modify the arguments, return values or control the execution.
+-- @paramsig frame, script, [handler]
+-- @param frame The Frame to hook the script on
+-- @param script The script to hook
+-- @param handler The handler for the hook, a funcref or a method name. (Defaults to the name of the hooked script)
+function AceHook:SecureHookScript(frame, script, handler)
+ hook(self, frame, script, handler, true, true, false, false, "Usage: SecureHookScript(object, method, [handler])")
+end
+
+--- Unhook from the specified function, method or script.
+-- @paramsig [obj], method
+-- @param obj The object or frame to unhook from
+-- @param method The name of the method, function or script to unhook from.
+function AceHook:Unhook(obj, method)
+ local usage = "Usage: Unhook([obj], method)"
+ if type(obj) == "string" then
+ method, obj = obj, nil
+ end
+
+ if obj and type(obj) ~= "table" then
+ error(format("%s: 'obj' - expecting nil or table got %s", usage, type(obj)), 2)
+ end
+ if type(method) ~= "string" then
+ error(format("%s: 'method' - expeting string got %s", usage, type(method)), 2)
+ end
+
+ local uid
+ if obj then
+ uid = registry[self][obj] and registry[self][obj][method]
+ else
+ uid = registry[self][method]
+ end
+
+ if not uid or not actives[uid] then
+ -- Declining to error on an unneeded unhook since the end effect is the same and this would just be annoying.
+ return false
+ end
+
+ actives[uid], handlers[uid] = nil, nil
+
+ if obj then
+ registry[self][obj][method] = nil
+ registry[self][obj] = next(registry[self][obj]) and registry[self][obj] or nil
+
+ -- if the hook reference doesnt exist, then its a secure hook, just bail out and dont do any unhooking
+ if not self.hooks[obj] or not self.hooks[obj][method] then return true end
+
+ if scripts[uid] and obj:GetScript(method) == uid then -- unhooks scripts
+ obj:SetScript(method, self.hooks[obj][method] ~= donothing and self.hooks[obj][method] or nil)
+ scripts[uid] = nil
+ elseif obj and self.hooks[obj] and self.hooks[obj][method] and obj[method] == uid then -- unhooks methods
+ obj[method] = self.hooks[obj][method]
+ end
+
+ self.hooks[obj][method] = nil
+ self.hooks[obj] = next(self.hooks[obj]) and self.hooks[obj] or nil
+ else
+ registry[self][method] = nil
+
+ -- if self.hooks[method] doesn't exist, then this is a SecureHook, just bail out
+ if not self.hooks[method] then return true end
+
+ if self.hooks[method] and _G[method] == uid then -- unhooks functions
+ _G[method] = self.hooks[method]
+ end
+
+ self.hooks[method] = nil
+ end
+ return true
+end
+
+--- Unhook all existing hooks for this addon.
+function AceHook:UnhookAll()
+ for key, value in pairs(registry[self]) do
+ if type(key) == "table" then
+ for method in pairs(value) do
+ self:Unhook(key, method)
+ end
+ else
+ self:Unhook(key)
+ end
+ end
+end
+
+--- Check if the specific function, method or script is already hooked.
+-- @paramsig [obj], method
+-- @param obj The object or frame to unhook from
+-- @param method The name of the method, function or script to unhook from.
+function AceHook:IsHooked(obj, method)
+ -- we don't check if registry[self] exists, this is done by evil magicks in the metatable
+ if type(obj) == "string" then
+ if registry[self][obj] and actives[registry[self][obj]] then
+ return true, handlers[registry[self][obj]]
+ end
+ else
+ if registry[self][obj] and registry[self][obj][method] and actives[registry[self][obj][method]] then
+ return true, handlers[registry[self][obj][method]]
+ end
+ end
+
+ return false, nil
+end
+
+--- Upgrade our old embeded
+for target, v in pairs( AceHook.embeded ) do
+ AceHook:Embed( target )
+end
diff --git a/Skada/Libs/AceLocale-3.0/AceLocale-3.0.lua b/Skada/Libs/AceLocale-3.0/AceLocale-3.0.lua
new file mode 100644
index 0000000..e133781
--- /dev/null
+++ b/Skada/Libs/AceLocale-3.0/AceLocale-3.0.lua
@@ -0,0 +1,137 @@
+--- **AceLocale-3.0** manages localization in addons, allowing for multiple locale to be registered with fallback to the base locale for untranslated strings.
+-- @class file
+-- @name AceLocale-3.0
+-- @release $Id: AceLocale-3.0.lua 1035 2011-07-09 03:20:13Z kaelten $
+local MAJOR,MINOR = "AceLocale-3.0", 6
+
+local AceLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceLocale then return end -- no upgrade needed
+
+-- Lua APIs
+local assert, tostring, error = assert, tostring, error
+local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: GAME_LOCALE, geterrorhandler
+
+local gameLocale = GetLocale()
+if gameLocale == "enGB" then
+ gameLocale = "enUS"
+end
+
+AceLocale.apps = AceLocale.apps or {} -- array of ["AppName"]=localetableref
+AceLocale.appnames = AceLocale.appnames or {} -- array of [localetableref]="AppName"
+
+-- This metatable is used on all tables returned from GetLocale
+local readmeta = {
+ __index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
+ rawset(self, key, key) -- only need to see the warning once, really
+ geterrorhandler()(MAJOR..": "..tostring(AceLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
+ return key
+ end
+}
+
+-- This metatable is used on all tables returned from GetLocale if the silent flag is true, it does not issue a warning on unknown keys
+local readmetasilent = {
+ __index = function(self, key) -- requesting totally unknown entries: return key
+ rawset(self, key, key) -- only need to invoke this function once
+ return key
+ end
+}
+
+-- Remember the locale table being registered right now (it gets set by :NewLocale())
+-- NOTE: Do never try to register 2 locale tables at once and mix their definition.
+local registering
+
+-- local assert false function
+local assertfalse = function() assert(false) end
+
+-- This metatable proxy is used when registering nondefault locales
+local writeproxy = setmetatable({}, {
+ __newindex = function(self, key, value)
+ rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
+ end,
+ __index = assertfalse
+})
+
+-- This metatable proxy is used when registering the default locale.
+-- It refuses to overwrite existing values
+-- Reason 1: Allows loading locales in any order
+-- Reason 2: If 2 modules have the same string, but only the first one to be
+-- loaded has a translation for the current locale, the translation
+-- doesn't get overwritten.
+--
+local writedefaultproxy = setmetatable({}, {
+ __newindex = function(self, key, value)
+ if not rawget(registering, key) then
+ rawset(registering, key, value == true and key or value)
+ end
+ end,
+ __index = assertfalse
+})
+
+--- Register a new locale (or extend an existing one) for the specified application.
+-- :NewLocale will return a table you can fill your locale into, or nil if the locale isn't needed for the players
+-- game locale.
+-- @paramsig application, locale[, isDefault[, silent]]
+-- @param application Unique name of addon / module
+-- @param locale Name of the locale to register, e.g. "enUS", "deDE", etc.
+-- @param isDefault If this is the default locale being registered (your addon is written in this language, generally enUS)
+-- @param silent If true, the locale will not issue warnings for missing keys. Must be set on the first locale registered. If set to "raw", nils will be returned for unknown keys (no metatable used).
+-- @usage
+-- -- enUS.lua
+-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "enUS", true)
+-- L["string1"] = true
+--
+-- -- deDE.lua
+-- local L = LibStub("AceLocale-3.0"):NewLocale("TestLocale", "deDE")
+-- if not L then return end
+-- L["string1"] = "Zeichenkette1"
+-- @return Locale Table to add localizations to, or nil if the current locale is not required.
+function AceLocale:NewLocale(application, locale, isDefault, silent)
+
+ -- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
+ local gameLocale = GAME_LOCALE or gameLocale
+
+ local app = AceLocale.apps[application]
+
+ if silent and app and getmetatable(app) ~= readmetasilent then
+ geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
+ end
+
+ if not app then
+ if silent=="raw" then
+ app = {}
+ else
+ app = setmetatable({}, silent and readmetasilent or readmeta)
+ end
+ AceLocale.apps[application] = app
+ AceLocale.appnames[app] = application
+ end
+
+ if locale ~= gameLocale and not isDefault then
+ return -- nop, we don't need these translations
+ end
+
+ registering = app -- remember globally for writeproxy and writedefaultproxy
+
+ if isDefault then
+ return writedefaultproxy
+ end
+
+ return writeproxy
+end
+
+--- Returns localizations for the current locale (or default locale if translations are missing).
+-- Errors if nothing is registered (spank developer, not just a missing translation)
+-- @param application Unique name of addon / module
+-- @param silent If true, the locale is optional, silently return nil if it's not found (defaults to false, optional)
+-- @return The locale table for the current language.
+function AceLocale:GetLocale(application, silent)
+ if not silent and not AceLocale.apps[application] then
+ error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
+ end
+ return AceLocale.apps[application]
+end
diff --git a/Skada/Libs/AceSerializer-3.0/AceSerializer-3.0.lua b/Skada/Libs/AceSerializer-3.0/AceSerializer-3.0.lua
new file mode 100644
index 0000000..0b19e08
--- /dev/null
+++ b/Skada/Libs/AceSerializer-3.0/AceSerializer-3.0.lua
@@ -0,0 +1,287 @@
+--- **AceSerializer-3.0** can serialize any variable (except functions or userdata) into a string format,
+-- that can be send over the addon comm channel. AceSerializer was designed to keep all data intact, especially
+-- very large numbers or floating point numbers, and table structures. The only caveat currently is, that multiple
+-- references to the same table will be send individually.
+--
+-- **AceSerializer-3.0** can be embeded into your addon, either explicitly by calling AceSerializer:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceSerializer itself.\\
+-- It is recommended to embed AceSerializer, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceSerializer.
+-- @class file
+-- @name AceSerializer-3.0
+-- @release $Id: AceSerializer-3.0.lua 1135 2015-09-19 20:39:16Z nevcairiel $
+local MAJOR,MINOR = "AceSerializer-3.0", 5
+local AceSerializer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceSerializer then return end
+
+-- Lua APIs
+local strbyte, strchar, gsub, gmatch, format = string.byte, string.char, string.gsub, string.gmatch, string.format
+local assert, error, pcall = assert, error, pcall
+local type, tostring, tonumber = type, tostring, tonumber
+local pairs, select, frexp = pairs, select, math.frexp
+local tconcat = table.concat
+
+-- quick copies of string representations of wonky numbers
+local inf = math.huge
+
+local serNaN -- can't do this in 4.3, see ace3 ticket 268
+local serInf, serInfMac = "1.#INF", "inf"
+local serNegInf, serNegInfMac = "-1.#INF", "-inf"
+
+
+-- Serialization functions
+
+local function SerializeStringHelper(ch) -- Used by SerializeValue for strings
+ -- We use \126 ("~") as an escape character for all nonprints plus a few more
+ local n = strbyte(ch)
+ if n==30 then -- v3 / ticket 115: catch a nonprint that ends up being "~^" when encoded... DOH
+ return "\126\122"
+ elseif n<=32 then -- nonprint + space
+ return "\126"..strchar(n+64)
+ elseif n==94 then -- value separator
+ return "\126\125"
+ elseif n==126 then -- our own escape character
+ return "\126\124"
+ elseif n==127 then -- nonprint (DEL)
+ return "\126\123"
+ else
+ assert(false) -- can't be reached if caller uses a sane regex
+ end
+end
+
+local function SerializeValue(v, res, nres)
+ -- We use "^" as a value separator, followed by one byte for type indicator
+ local t=type(v)
+
+ if t=="string" then -- ^S = string (escaped to remove nonprints, "^"s, etc)
+ res[nres+1] = "^S"
+ res[nres+2] = gsub(v,"[%c \94\126\127]", SerializeStringHelper)
+ nres=nres+2
+
+ elseif t=="number" then -- ^N = number (just tostring()ed) or ^F (float components)
+ local str = tostring(v)
+ if tonumber(str)==v --[[not in 4.3 or str==serNaN]] then
+ -- translates just fine, transmit as-is
+ res[nres+1] = "^N"
+ res[nres+2] = str
+ nres=nres+2
+ elseif v == inf or v == -inf then
+ res[nres+1] = "^N"
+ res[nres+2] = v == inf and serInf or serNegInf
+ nres=nres+2
+ else
+ local m,e = frexp(v)
+ res[nres+1] = "^F"
+ res[nres+2] = format("%.0f",m*2^53) -- force mantissa to become integer (it's originally 0.5--0.9999)
+ res[nres+3] = "^f"
+ res[nres+4] = tostring(e-53) -- adjust exponent to counteract mantissa manipulation
+ nres=nres+4
+ end
+
+ elseif t=="table" then -- ^T...^t = table (list of key,value pairs)
+ nres=nres+1
+ res[nres] = "^T"
+ for k,v in pairs(v) do
+ nres = SerializeValue(k, res, nres)
+ nres = SerializeValue(v, res, nres)
+ end
+ nres=nres+1
+ res[nres] = "^t"
+
+ elseif t=="boolean" then -- ^B = true, ^b = false
+ nres=nres+1
+ if v then
+ res[nres] = "^B" -- true
+ else
+ res[nres] = "^b" -- false
+ end
+
+ elseif t=="nil" then -- ^Z = nil (zero, "N" was taken :P)
+ nres=nres+1
+ res[nres] = "^Z"
+
+ else
+ error(MAJOR..": Cannot serialize a value of type '"..t.."'") -- can't produce error on right level, this is wildly recursive
+ end
+
+ return nres
+end
+
+
+
+local serializeTbl = { "^1" } -- "^1" = Hi, I'm data serialized by AceSerializer protocol rev 1
+
+--- Serialize the data passed into the function.
+-- Takes a list of values (strings, numbers, booleans, nils, tables)
+-- and returns it in serialized form (a string).\\
+-- May throw errors on invalid data types.
+-- @param ... List of values to serialize
+-- @return The data in its serialized form (string)
+function AceSerializer:Serialize(...)
+ local nres = 1
+
+ for i=1,select("#", ...) do
+ local v = select(i, ...)
+ nres = SerializeValue(v, serializeTbl, nres)
+ end
+
+ serializeTbl[nres+1] = "^^" -- "^^" = End of serialized data
+
+ return tconcat(serializeTbl, "", 1, nres+1)
+end
+
+-- Deserialization functions
+local function DeserializeStringHelper(escape)
+ if escape<"~\122" then
+ return strchar(strbyte(escape,2,2)-64)
+ elseif escape=="~\122" then -- v3 / ticket 115: special case encode since 30+64=94 ("^") - OOPS.
+ return "\030"
+ elseif escape=="~\123" then
+ return "\127"
+ elseif escape=="~\124" then
+ return "\126"
+ elseif escape=="~\125" then
+ return "\94"
+ end
+ error("DeserializeStringHelper got called for '"..escape.."'?!?") -- can't be reached unless regex is screwed up
+end
+
+local function DeserializeNumberHelper(number)
+ --[[ not in 4.3 if number == serNaN then
+ return 0/0
+ else]]if number == serNegInf or number == serNegInfMac then
+ return -inf
+ elseif number == serInf or number == serInfMac then
+ return inf
+ else
+ return tonumber(number)
+ end
+end
+
+-- DeserializeValue: worker function for :Deserialize()
+-- It works in two modes:
+-- Main (top-level) mode: Deserialize a list of values and return them all
+-- Recursive (table) mode: Deserialize only a single value (_may_ of course be another table with lots of subvalues in it)
+--
+-- The function _always_ works recursively due to having to build a list of values to return
+--
+-- Callers are expected to pcall(DeserializeValue) to trap errors
+
+local function DeserializeValue(iter,single,ctl,data)
+
+ if not single then
+ ctl,data = iter()
+ end
+
+ if not ctl then
+ error("Supplied data misses AceSerializer terminator ('^^')")
+ end
+
+ if ctl=="^^" then
+ -- ignore extraneous data
+ return
+ end
+
+ local res
+
+ if ctl=="^S" then
+ res = gsub(data, "~.", DeserializeStringHelper)
+ elseif ctl=="^N" then
+ res = DeserializeNumberHelper(data)
+ if not res then
+ error("Invalid serialized number: '"..tostring(data).."'")
+ end
+ elseif ctl=="^F" then -- ^F^f
+ local ctl2,e = iter()
+ if ctl2~="^f" then
+ error("Invalid serialized floating-point number, expected '^f', not '"..tostring(ctl2).."'")
+ end
+ local m=tonumber(data)
+ e=tonumber(e)
+ if not (m and e) then
+ error("Invalid serialized floating-point number, expected mantissa and exponent, got '"..tostring(m).."' and '"..tostring(e).."'")
+ end
+ res = m*(2^e)
+ elseif ctl=="^B" then -- yeah yeah ignore data portion
+ res = true
+ elseif ctl=="^b" then -- yeah yeah ignore data portion
+ res = false
+ elseif ctl=="^Z" then -- yeah yeah ignore data portion
+ res = nil
+ elseif ctl=="^T" then
+ -- ignore ^T's data, future extensibility?
+ res = {}
+ local k,v
+ while true do
+ ctl,data = iter()
+ if ctl=="^t" then break end -- ignore ^t's data
+ k = DeserializeValue(iter,true,ctl,data)
+ if k==nil then
+ error("Invalid AceSerializer table format (no table end marker)")
+ end
+ ctl,data = iter()
+ v = DeserializeValue(iter,true,ctl,data)
+ if v==nil then
+ error("Invalid AceSerializer table format (no table end marker)")
+ end
+ res[k]=v
+ end
+ else
+ error("Invalid AceSerializer control code '"..ctl.."'")
+ end
+
+ if not single then
+ return res,DeserializeValue(iter)
+ else
+ return res
+ end
+end
+
+--- Deserializes the data into its original values.
+-- Accepts serialized data, ignoring all control characters and whitespace.
+-- @param str The serialized data (from :Serialize)
+-- @return true followed by a list of values, OR false followed by an error message
+function AceSerializer:Deserialize(str)
+ str = gsub(str, "[%c ]", "") -- ignore all control characters; nice for embedding in email and stuff
+
+ local iter = gmatch(str, "(^.)([^^]*)") -- Any ^x followed by string of non-^
+ local ctl,data = iter()
+ if not ctl or ctl~="^1" then
+ -- we purposefully ignore the data portion of the start code, it can be used as an extension mechanism
+ return false, "Supplied data is not AceSerializer data (rev 1)"
+ end
+
+ return pcall(DeserializeValue, iter)
+end
+
+
+----------------------------------------
+-- Base library stuff
+----------------------------------------
+
+AceSerializer.internals = { -- for test scripts
+ SerializeValue = SerializeValue,
+ SerializeStringHelper = SerializeStringHelper,
+}
+
+local mixins = {
+ "Serialize",
+ "Deserialize",
+}
+
+AceSerializer.embeds = AceSerializer.embeds or {}
+
+function AceSerializer:Embed(target)
+ for k, v in pairs(mixins) do
+ target[v] = self[v]
+ end
+ self.embeds[target] = true
+ return target
+end
+
+-- Update embeds
+for target, v in pairs(AceSerializer.embeds) do
+ AceSerializer:Embed(target)
+end
diff --git a/Skada/Libs/AceTimer-3.0/AceTimer-3.0.lua b/Skada/Libs/AceTimer-3.0/AceTimer-3.0.lua
new file mode 100644
index 0000000..8ba6b3c
--- /dev/null
+++ b/Skada/Libs/AceTimer-3.0/AceTimer-3.0.lua
@@ -0,0 +1,276 @@
+--- **AceTimer-3.0** provides a central facility for registering timers.
+-- AceTimer supports one-shot timers and repeating timers. All timers are stored in an efficient
+-- data structure that allows easy dispatching and fast rescheduling. Timers can be registered
+-- or canceled at any time, even from within a running timer, without conflict or large overhead.\\
+-- AceTimer is currently limited to firing timers at a frequency of 0.01s as this is what the WoW timer API
+-- restricts us to.
+--
+-- All `:Schedule` functions will return a handle to the current timer, which you will need to store if you
+-- need to cancel the timer you just registered.
+--
+-- **AceTimer-3.0** can be embeded into your addon, either explicitly by calling AceTimer:Embed(MyAddon) or by
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceTimer itself.\\
+-- It is recommended to embed AceTimer, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceTimer.
+-- @class file
+-- @name AceTimer-3.0
+-- @release $Id: AceTimer-3.0.lua 1119 2014-10-14 17:23:29Z nevcairiel $
+
+local MAJOR, MINOR = "AceTimer-3.0", 17 -- Bump minor on changes
+local AceTimer, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceTimer then return end -- No upgrade needed
+AceTimer.activeTimers = AceTimer.activeTimers or {} -- Active timer list
+local activeTimers = AceTimer.activeTimers -- Upvalue our private data
+
+-- Lua APIs
+local type, unpack, next, error, select = type, unpack, next, error, select
+-- WoW APIs
+local GetTime, C_TimerAfter = GetTime, C_Timer.After
+
+local function new(self, loop, func, delay, ...)
+ if delay < 0.01 then
+ delay = 0.01 -- Restrict to the lowest time that the C_Timer API allows us
+ end
+
+ local timer = {...}
+ timer.object = self
+ timer.func = func
+ timer.looping = loop
+ timer.argsCount = select("#", ...)
+ timer.delay = delay
+ timer.ends = GetTime() + delay
+
+ activeTimers[timer] = timer
+
+ -- Create new timer closure to wrap the "timer" object
+ timer.callback = function()
+ if not timer.cancelled then
+ if type(timer.func) == "string" then
+ -- We manually set the unpack count to prevent issues with an arg set that contains nil and ends with nil
+ -- e.g. local t = {1, 2, nil, 3, nil} print(#t) will result in 2, instead of 5. This fixes said issue.
+ timer.object[timer.func](timer.object, unpack(timer, 1, timer.argsCount))
+ else
+ timer.func(unpack(timer, 1, timer.argsCount))
+ end
+
+ if timer.looping and not timer.cancelled then
+ -- Compensate delay to get a perfect average delay, even if individual times don't match up perfectly
+ -- due to fps differences
+ local time = GetTime()
+ local delay = timer.delay - (time - timer.ends)
+ -- Ensure the delay doesn't go below the threshold
+ if delay < 0.01 then delay = 0.01 end
+ C_TimerAfter(delay, timer.callback)
+ timer.ends = time + delay
+ else
+ activeTimers[timer.handle or timer] = nil
+ end
+ end
+ end
+
+ C_TimerAfter(delay, timer.callback)
+ return timer
+end
+
+--- Schedule a new one-shot timer.
+-- The timer will fire once in `delay` seconds, unless canceled before.
+-- @param callback Callback function for the timer pulse (funcref or method name).
+-- @param delay Delay for the timer, in seconds.
+-- @param ... An optional, unlimited amount of arguments to pass to the callback function.
+-- @usage
+-- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
+--
+-- function MyAddOn:OnEnable()
+-- self:ScheduleTimer("TimerFeedback", 5)
+-- end
+--
+-- function MyAddOn:TimerFeedback()
+-- print("5 seconds passed")
+-- end
+function AceTimer:ScheduleTimer(func, delay, ...)
+ if not func or not delay then
+ error(MAJOR..": ScheduleTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
+ end
+ if type(func) == "string" then
+ if type(self) ~= "table" then
+ error(MAJOR..": ScheduleTimer(callback, delay, args...): 'self' - must be a table.", 2)
+ elseif not self[func] then
+ error(MAJOR..": ScheduleTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
+ end
+ end
+ return new(self, nil, func, delay, ...)
+end
+
+--- Schedule a repeating timer.
+-- The timer will fire every `delay` seconds, until canceled.
+-- @param callback Callback function for the timer pulse (funcref or method name).
+-- @param delay Delay for the timer, in seconds.
+-- @param ... An optional, unlimited amount of arguments to pass to the callback function.
+-- @usage
+-- MyAddOn = LibStub("AceAddon-3.0"):NewAddon("MyAddOn", "AceTimer-3.0")
+--
+-- function MyAddOn:OnEnable()
+-- self.timerCount = 0
+-- self.testTimer = self:ScheduleRepeatingTimer("TimerFeedback", 5)
+-- end
+--
+-- function MyAddOn:TimerFeedback()
+-- self.timerCount = self.timerCount + 1
+-- print(("%d seconds passed"):format(5 * self.timerCount))
+-- -- run 30 seconds in total
+-- if self.timerCount == 6 then
+-- self:CancelTimer(self.testTimer)
+-- end
+-- end
+function AceTimer:ScheduleRepeatingTimer(func, delay, ...)
+ if not func or not delay then
+ error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'callback' and 'delay' must have set values.", 2)
+ end
+ if type(func) == "string" then
+ if type(self) ~= "table" then
+ error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): 'self' - must be a table.", 2)
+ elseif not self[func] then
+ error(MAJOR..": ScheduleRepeatingTimer(callback, delay, args...): Tried to register '"..func.."' as the callback, but it doesn't exist in the module.", 2)
+ end
+ end
+ return new(self, true, func, delay, ...)
+end
+
+--- Cancels a timer with the given id, registered by the same addon object as used for `:ScheduleTimer`
+-- Both one-shot and repeating timers can be canceled with this function, as long as the `id` is valid
+-- and the timer has not fired yet or was canceled before.
+-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
+function AceTimer:CancelTimer(id)
+ local timer = activeTimers[id]
+
+ if not timer then
+ return false
+ else
+ timer.cancelled = true
+ activeTimers[id] = nil
+ return true
+ end
+end
+
+--- Cancels all timers registered to the current addon object ('self')
+function AceTimer:CancelAllTimers()
+ for k,v in pairs(activeTimers) do
+ if v.object == self then
+ AceTimer.CancelTimer(self, k)
+ end
+ end
+end
+
+--- Returns the time left for a timer with the given id, registered by the current addon object ('self').
+-- This function will return 0 when the id is invalid.
+-- @param id The id of the timer, as returned by `:ScheduleTimer` or `:ScheduleRepeatingTimer`
+-- @return The time left on the timer.
+function AceTimer:TimeLeft(id)
+ local timer = activeTimers[id]
+ if not timer then
+ return 0
+ else
+ return timer.ends - GetTime()
+ end
+end
+
+
+-- ---------------------------------------------------------------------
+-- Upgrading
+
+-- Upgrade from old hash-bucket based timers to C_Timer.After timers.
+if oldminor and oldminor < 10 then
+ -- disable old timer logic
+ AceTimer.frame:SetScript("OnUpdate", nil)
+ AceTimer.frame:SetScript("OnEvent", nil)
+ AceTimer.frame:UnregisterAllEvents()
+ -- convert timers
+ for object,timers in pairs(AceTimer.selfs) do
+ for handle,timer in pairs(timers) do
+ if type(timer) == "table" and timer.callback then
+ local newTimer
+ if timer.delay then
+ newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.callback, timer.delay, timer.arg)
+ else
+ newTimer = AceTimer.ScheduleTimer(timer.object, timer.callback, timer.when - GetTime(), timer.arg)
+ end
+ -- Use the old handle for old timers
+ activeTimers[newTimer] = nil
+ activeTimers[handle] = newTimer
+ newTimer.handle = handle
+ end
+ end
+ end
+ AceTimer.selfs = nil
+ AceTimer.hash = nil
+ AceTimer.debug = nil
+elseif oldminor and oldminor < 17 then
+ -- Upgrade from old animation based timers to C_Timer.After timers.
+ AceTimer.inactiveTimers = nil
+ AceTimer.frame = nil
+ local oldTimers = AceTimer.activeTimers
+ -- Clear old timer table and update upvalue
+ AceTimer.activeTimers = {}
+ activeTimers = AceTimer.activeTimers
+ for handle, timer in pairs(oldTimers) do
+ local newTimer
+ -- Stop the old timer animation
+ local duration, elapsed = timer:GetDuration(), timer:GetElapsed()
+ timer:GetParent():Stop()
+ if timer.looping then
+ newTimer = AceTimer.ScheduleRepeatingTimer(timer.object, timer.func, duration, unpack(timer.args, 1, timer.argsCount))
+ else
+ newTimer = AceTimer.ScheduleTimer(timer.object, timer.func, duration - elapsed, unpack(timer.args, 1, timer.argsCount))
+ end
+ -- Use the old handle for old timers
+ activeTimers[newTimer] = nil
+ activeTimers[handle] = newTimer
+ newTimer.handle = handle
+ end
+
+ -- Migrate transitional handles
+ if oldminor < 13 and AceTimer.hashCompatTable then
+ for handle, id in pairs(AceTimer.hashCompatTable) do
+ local t = activeTimers[id]
+ if t then
+ activeTimers[id] = nil
+ activeTimers[handle] = t
+ t.handle = handle
+ end
+ end
+ AceTimer.hashCompatTable = nil
+ end
+end
+
+-- ---------------------------------------------------------------------
+-- Embed handling
+
+AceTimer.embeds = AceTimer.embeds or {}
+
+local mixins = {
+ "ScheduleTimer", "ScheduleRepeatingTimer",
+ "CancelTimer", "CancelAllTimers",
+ "TimeLeft"
+}
+
+function AceTimer:Embed(target)
+ AceTimer.embeds[target] = true
+ for _,v in pairs(mixins) do
+ target[v] = AceTimer[v]
+ end
+ return target
+end
+
+-- AceTimer:OnEmbedDisable(target)
+-- target (object) - target object that AceTimer is embedded in.
+--
+-- cancel all timers registered for the object
+function AceTimer:OnEmbedDisable(target)
+ target:CancelAllTimers()
+end
+
+for addon in pairs(AceTimer.embeds) do
+ AceTimer:Embed(addon)
+end
diff --git a/Skada/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua b/Skada/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
new file mode 100644
index 0000000..675d7b0
--- /dev/null
+++ b/Skada/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua
@@ -0,0 +1,238 @@
+--[[ $Id: CallbackHandler-1.0.lua 1131 2015-06-04 07:29:24Z nevcairiel $ ]]
+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/Skada/Libs/LibBossIDs-1.0/LibBossIDs-1.0.lua b/Skada/Libs/LibBossIDs-1.0/LibBossIDs-1.0.lua
new file mode 100644
index 0000000..65b7ef5
--- /dev/null
+++ b/Skada/Libs/LibBossIDs-1.0/LibBossIDs-1.0.lua
@@ -0,0 +1,1712 @@
+--[[
+Name: LibBossIDs-1.0
+Revision: $Revision: 96 $
+Author: Elsia
+Website: http://www.wowace.com/addons/libbossids-1-0/
+Documentation:
+SVN: svn://svn.wowace.com/wow/libbossids-1-0/mainline/trunk
+Description: Provide a table of mobIDs that belong to boss mobs (instance bosses, raid bosses, world bosses)
+Dependencies: LibStub
+License: Public Domain, Absolutely no Warranty.
+]]
+
+local MAJOR, MINOR = "LibBossIDs-1.0", "$Revision: 96 $"
+local lib = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not lib then return end
+
+-- LibBossIDs-1.0 provides a table that flags mobIDs true if the mob linked to the ID is a boss.
+-- Example: if LibStub("LibBossIDs-1.0").BossIDs[mobID] then print("Found a boss!") end
+-- How to get mobID from GUID:
+-- localmobID = tonumber(GUID:sub(-16, -12))
+
+-- Explanation of comments. First quoted string is English locale string of mob.
+-- The first list was derived from LibBabble-Boss-3.0.
+-- Commented out lines without comments are deemed to not be actual bosses, but trash mobs
+-- Otherwise comments indicate why they are not yet included.
+
+-- GENERALLY LibBossID users are interested in "Are we about to start a bossfight?" or "Did we just defeat a boss?"
+
+
+local BossIDs = {
+ -------------------------------------------------------------------------------
+ -- Abyssal Maw: Throne of the Tides
+ -------------------------------------------------------------------------------
+ [40586] = true, -- Lady Naz'jar
+ [40765] = true, -- Commander Ulthok
+ [40825] = true, -- Erunak Stonespeaker
+ [40788] = true, -- Mindbender Ghur'sha
+ [42172] = true, -- Ozumat? Not in heroic! /Mikk
+ [44566] = true, -- Ozumat - confirmed in heroic! /Mikk
+
+ -------------------------------------------------------------------------------
+ -- Ahn'kahet: The Old Kingdom
+ -------------------------------------------------------------------------------
+ [29309] = true, -- Elder Nadox
+ [29308] = true, -- Prince Taldaram (Ahn'kahet: The Old Kingdom)
+ [29310] = true, -- Jedoga Shadowseeker
+ [29311] = true, -- Herald Volazj
+ [30258] = true, -- Amanitar (Heroic)
+
+ -------------------------------------------------------------------------------
+ -- Auchindoun
+ -------------------------------------------------------------------------------
+ [75839] = true, -- Vigilant Kaathar
+ [76177] = true, -- Soulbinder Nyami
+ [75927] = true, -- Azzakel
+ [77734] = true, -- Teron'gor
+
+ -------------------------------------------------------------------------------
+ -- Auchindoun: Auchenai Crypts
+ -------------------------------------------------------------------------------
+ [18371] = true, -- Shirrak the Dead Watcher
+ [18373] = true, -- Exarch Maladaar
+
+ -------------------------------------------------------------------------------
+ -- Auchindoun: Mana-Tombs
+ -------------------------------------------------------------------------------
+ [18341] = true, -- Pandemonius
+ [18343] = true, -- Tavarok
+ [22930] = true, -- Yor (Heroic)
+ [18344] = true, -- Nexus-Prince Shaffar
+
+ -------------------------------------------------------------------------------
+ -- Auchindoun: Sethekk Halls
+ -------------------------------------------------------------------------------
+ [18472] = true, -- Darkweaver Syth
+ [23035] = true, -- Anzu (Heroic)
+ [18473] = true, -- Talon King Ikiss
+
+ -------------------------------------------------------------------------------
+ -- Auchindoun: Shadow Labyrinth
+ -------------------------------------------------------------------------------
+ [18731] = true, -- Ambassador Hellmaw
+ [18667] = true, -- Blackheart the Inciter
+ [18732] = true, -- Grandmaster Vorpil
+ [18708] = true, -- Murmur
+
+ -------------------------------------------------------------------------------
+ -- Azjol-Nerub
+ -------------------------------------------------------------------------------
+ [28684] = true, -- Krik'thir the Gatewatcher
+ [28921] = true, -- Hadronox
+ [29120] = true, -- Anub'arak
+
+ -------------------------------------------------------------------------------
+ -- Azshara
+ -------------------------------------------------------------------------------
+ [14464] = true, -- Avalanchion
+ [6109] = true, -- Azuregos
+
+ -------------------------------------------------------------------------------
+ -- Black Temple
+ -------------------------------------------------------------------------------
+ [22887] = true, -- High Warlord Naj'entus
+ [22898] = true, -- Supremus
+ [22841] = true, -- Shade of Akama
+ [22871] = true, -- Teron Gorefiend
+ [22948] = true, -- Gurtogg Bloodboil
+ [23420] = true, -- Essence of Anger
+ [23419] = true, -- Essence of Desire
+ [23418] = true, -- Essence of Suffering
+ [22947] = true, -- Mother Shahraz
+ [23426] = true, -- Illidari Council
+ [22917] = true, -- Illidan Stormrage -- Not adding solo quest IDs for now
+ [22949] = true, -- Gathios the Shatterer
+ [22950] = true, -- High Nethermancer Zerevor
+ [22951] = true, -- Lady Malande
+ [22952] = true, -- Veras Darkshadow
+
+ -------------------------------------------------------------------------------
+ -- Baradin Hold
+ -------------------------------------------------------------------------------
+ [47120] = true, -- Argaloth
+ [52363] = true, -- Occu'thar
+ [55869] = true, -- Alizabal (4.3)
+
+ -------------------------------------------------------------------------------
+ -- Blackfathom Deeps
+ -------------------------------------------------------------------------------
+ [4829] = true, -- Aku'mai
+ [4830] = true, -- Old Serra'kis
+ [4831] = true, -- Lady Sarevess
+ [4832] = true, -- Twilight Lord Kelris
+ [4887] = true, -- Ghamoo-ra
+ [6243] = true, -- Gelihast
+ [12876] = true, -- Baron Aquanis
+ [12902] = true, -- Lorgus Jett
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Depths: Detention Block
+ -------------------------------------------------------------------------------
+ [9018] = true, -- High Interrogator Gerstahn
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Depths: Grim Guzzler
+ -------------------------------------------------------------------------------
+ [9543] = true, -- Ribbly Screwspigot
+ [9537] = true, -- Hurley Blackbreath
+ [9502] = true, -- Phalanx
+ [9499] = true, -- Plugger Spazzring
+ [23872] = true, -- Coren Direbrew
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Depths: Halls of the Law
+ -------------------------------------------------------------------------------
+ [9025] = true, -- Lord Roccor
+ [9319] = true, -- Houndmaster Grebmar
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Depths: Inner Blackrock Depths
+ -------------------------------------------------------------------------------
+ [9156] = true, -- Ambassador Flamelash
+ [8923] = true, -- Panzor the Invincible
+ [17808] = true, -- Anger'rel
+ [9039] = true, -- Doom'rel
+ [9040] = true, -- Dope'rel
+ [9037] = true, -- Gloom'rel
+ [9034] = true, -- Hate'rel
+ [9038] = true, -- Seeth'rel
+ [9036] = true, -- Vile'rel
+ [9938] = true, -- Magmus
+ [10076] = true, -- High Priestess of Thaurissan
+ [8929] = true, -- Princess Moira Bronzebeard
+ [9019] = true, -- Emperor Dagran Thaurissan
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Depths: Outer Blackrock Depths
+ -------------------------------------------------------------------------------
+ [9024] = true, -- Pyromancer Loregrain
+ [9041] = true, -- Warder Stilgiss
+ [9042] = true, -- Verek
+ [9476] = true, -- Watchman Doomgrip
+
+ [9056] = true, -- Fineous Darkvire
+ [9017] = true, -- Lord Incendius
+ [9016] = true, -- Bael'Gar
+ [9033] = true, -- General Angerforge
+ [8983] = true, -- Golem Lord Argelmach
+ -- Dark Keepers, 6 of em: http://www.wowpedia.org/Dark_Keeper
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Depths: Ring of Law (Arena)
+ -------------------------------------------------------------------------------
+ [9031] = true, -- Anub'shiah
+ [9029] = true, -- Eviscerator
+ [9027] = true, -- Gorosh the Dervish
+ [9028] = true, -- Grizzle
+ [9032] = true, -- Hedrum the Creeper
+ [9030] = true, -- Ok'thor the Breaker
+ [16059] = true, -- Theldren
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Foundry
+ -------------------------------------------------------------------------------
+ -- Slagworks
+ [76877] = true, -- Gruul
+ [77182] = true, -- Oregorger
+ [76806] = true, -- Blast Furnace - Heart of the Mountain
+ [76809] = true, -- Blast Furnace - Foreman Feldspar
+ -- The Black Forge
+ [76973] = true, -- Hans'gar & Franzok - Hans'gar
+ [76974] = true, -- Hans'gar & Franzok - Franzok
+ [76814] = true, -- Flamebender Ka'graz
+ [77692] = true, -- Kromog
+ -- Iron Assembly
+ [76865] = true, -- Beastlord Darmac
+ [76906] = true, -- Operator Thogar
+ [77557] = true, -- Iron Maidens - Admiral Gar'an
+ [77231] = true, -- Iron Maidens - Enforcer Sorka
+ [77477] = true, -- Iron Maidens - Marak the Blooded
+ -- Blackhand's Crucible
+ [77325] = true, -- Blackhand
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Mountain: Blackrock Caverns
+ -------------------------------------------------------------------------------
+ [39665] = true, -- Rom'ogg Bonecrusher
+ [39679] = true, -- Corla, Herald of Twilight
+ [39698] = true, -- Karsh Steelbender
+ [39700] = true, -- Beauty
+ [39705] = true, -- Ascendant Lord Obsidius
+
+ -------------------------------------------------------------------------------
+ -- Blackrock Mountain: Blackwing Descent
+ -------------------------------------------------------------------------------
+ [41570] = true, -- Magmaw
+ [42166] = true, -- Arcanotron
+ [42178] = true, -- Magmatron
+ [42179] = true, -- Electron
+ [42180] = true, -- Toxitron
+ [41378] = true, -- Maloriak
+ [41442] = true, -- Atramedes
+ [43296] = true, -- Chimaeron
+ [41376] = true, -- Nefarian
+
+ -------------------------------------------------------------------------------
+ -- Blackwing Lair
+ -------------------------------------------------------------------------------
+ [12435] = true, -- Razorgore the Untamed
+ [13020] = true, -- Vaelastrasz the Corrupt
+ [12017] = true, -- Broodlord Lashlayer
+ [11983] = true, -- Firemaw
+ [14601] = true, -- Ebonroc
+ [11981] = true, -- Flamegor
+ [14020] = true, -- Chromaggus
+ [11583] = true, -- Nefarian
+ [12557] = true, -- Grethok the Controller
+ [10162] = true, -- Lord Victor Nefarius (Also found in Blackrock Spire)
+
+ -------------------------------------------------------------------------------
+ -- Bloodmaul Slag Mines
+ -------------------------------------------------------------------------------
+ [74787] = true, -- Slave Watcher Crushto
+ [74366] = true, -- Forgemaster Gog'duh
+ [75786] = true, -- Roltall
+ [74790] = true, -- Gug'rokk
+
+ -------------------------------------------------------------------------------
+ -- Caverns of Time: Battle for Mount Hyjal
+ -------------------------------------------------------------------------------
+ [17767] = true, -- Rage Winterchill
+ [17808] = true, -- Anetheron
+ [17888] = true, -- Kaz'rogal
+ [17842] = true, -- Azgalor
+ [17968] = true, -- Archimonde
+
+ -------------------------------------------------------------------------------
+ -- Caverns of Time: Culling of Stratholme
+ -------------------------------------------------------------------------------
+ [26529] = true, -- Meathook
+ [26530] = true, -- Salramm the Fleshcrafter
+ [26532] = true, -- Chrono-Lord Epoch
+ [32273] = true, -- Infinite Corruptor
+ [26533] = true, -- Mal'Ganis
+ [29620] = true, -- Mal'Ganis
+
+ -------------------------------------------------------------------------------
+ -- Caverns of Time: Escape from Durnholde Keep
+ -------------------------------------------------------------------------------
+ [17848] = true, -- Lieutenant Drake
+ [17862] = true, -- Captain Skarloc
+ [18096] = true, -- Epoch Hunter
+ [28132] = true, -- Don Carlos
+
+ -------------------------------------------------------------------------------
+ -- Caverns of Time: Opening the Dark Portal
+ -------------------------------------------------------------------------------
+ [17879] = true, -- Chrono Lord Deja
+ [17880] = true, -- Temporus
+ [17881] = true, -- Aeonus
+
+ -------------------------------------------------------------------------------
+ -- Coilfang Reservoir: Serpentshrine Cavern
+ -------------------------------------------------------------------------------
+ [21216] = true, -- Hydross the Unstable
+ [21217] = true, -- The Lurker Below
+ [21215] = true, -- Leotheras the Blind
+ [21214] = true, -- Fathom-Lord Karathress
+ [21213] = true, -- Morogrim Tidewalker
+ [21212] = true, -- Lady Vashj
+ [21875] = true, -- Shadow of Leotheras
+
+ -------------------------------------------------------------------------------
+ -- Coilfang Reservoir: Slave Pens
+ -------------------------------------------------------------------------------
+ [25740] = true, -- Ahune
+ [17941] = true, -- Mennu the Betrayer
+ [17991] = true, -- Rokmar the Crackler
+ [17942] = true, -- Quagmirran
+
+ -------------------------------------------------------------------------------
+ -- Coilfang Reservoir: The Steamvault
+ -------------------------------------------------------------------------------
+ [17797] = true, -- Hydromancer Thespia
+ [17796] = true, -- Mekgineer Steamrigger
+ [17798] = true, -- Warlord Kalithresh
+
+ -------------------------------------------------------------------------------
+ -- Coilfang Reservoir: The Underbog
+ -------------------------------------------------------------------------------
+ [17770] = true, -- Hungarfen
+ [18105] = true, -- Ghaz'an
+ [17826] = true, -- Swamplord Musel'ek
+ [17827] = true, -- Claw
+ [17882] = true, -- The Black Stalker
+
+ -------------------------------------------------------------------------------
+ -- Dire Maul: Arena
+ -------------------------------------------------------------------------------
+ [11447] = true, -- Mushgog
+ [11498] = true, -- Skarr the Unbreakable
+ [11497] = true, -- The Razza
+
+ -------------------------------------------------------------------------------
+ -- Dire Maul: East
+ -------------------------------------------------------------------------------
+ [14354] = true, -- Pusillin
+ [14327] = true, -- Lethtendris
+ [14349] = true, -- Pimgib
+ [13280] = true, -- Hydrospawn
+ [11490] = true, -- Zevrim Thornhoof
+ [11492] = true, -- Alzzin the Wildshaper
+ [16097] = true, -- Isalien
+
+ -------------------------------------------------------------------------------
+ -- Dire Maul: North
+ -------------------------------------------------------------------------------
+ [14326] = true, -- Guard Mol'dar
+ [14322] = true, -- Stomper Kreeg
+ [14321] = true, -- Guard Fengus
+ [14323] = true, -- Guard Slip'kik
+ [14325] = true, -- Captain Kromcrush
+ [14324] = true, -- Cho'Rush the Observer
+ [11501] = true, -- King Gordok
+
+ -------------------------------------------------------------------------------
+ -- Dire Maul: West
+ -------------------------------------------------------------------------------
+ [11489] = true, -- Tendris Warpwood
+ [11487] = true, -- Magister Kalendris
+ [11467] = true, -- Tsu'zee
+ [11488] = true, -- Illyanna Ravenoak
+ [14690] = true, -- Revanchion (Scourge Invasion)
+ [11496] = true, -- Immol'thar
+ [14506] = true, -- Lord Hel'nurath
+ [11486] = true, -- Prince Tortheldrin
+
+ -------------------------------------------------------------------------------
+ -- Drak'Tharon Keep
+ -------------------------------------------------------------------------------
+ [26630] = true, -- Trollgore
+ [26631] = true, -- Novos the Summoner
+ [27483] = true, -- King Dred
+ [26632] = true, -- The Prophet Tharon'ja
+ [27696] = true, -- The Prophet Tharon'ja
+
+ -------------------------------------------------------------------------------
+ -- End Time 4.3
+ -------------------------------------------------------------------------------
+ [54431] = true, -- Echo of Baine
+ [54445] = true, -- Echo of Jaina
+ [54123] = true, -- Echo of Sylvanas
+ [54544] = true, -- Echo of Tyrande
+ [54432] = true, -- Murozond
+
+ -------------------------------------------------------------------------------
+ -- Firelands 4.2 PTR
+ -------------------------------------------------------------------------------
+ [52530] = true, -- Alysrazor
+ [53494] = true, -- Baleroc
+ [52498] = true, -- Bethtilac
+ [52571] = true, -- FandralStaghelm
+ [52409] = true, -- Ragnaros
+ [52558] = true, -- Rhyolith
+ [53691] = true, -- Shannox
+
+ -------------------------------------------------------------------------------
+ -- Forge of Souls
+ -------------------------------------------------------------------------------
+ [36497] = true, -- Bronjahm
+ [36502] = true, -- Devourer of Souls
+
+ -------------------------------------------------------------------------------
+ -- Gate of the Setting Sun (MoP-Dungeon 5.0.1)
+ -------------------------------------------------------------------------------
+ [54432] = true, -- Gadok
+ [56636] = true, -- Rimok
+ [56877] = true, -- Raigon
+ [56906] = true, -- Kiptilak
+
+ -------------------------------------------------------------------------------
+ -- Gnomeregan
+ -------------------------------------------------------------------------------
+ [7800] = true, -- Mekgineer Thermaplugg
+ [7079] = true, -- Viscous Fallout
+ [7361] = true, -- Grubbis
+ [6235] = true, -- Electrocutioner 6000
+ [6229] = true, -- Crowd Pummeler 9-60
+ [6228] = true, -- Dark Iron Ambassador
+ [6231] = true, -- Techbot, outside
+
+ -------------------------------------------------------------------------------
+ -- Gorgrond
+ -------------------------------------------------------------------------------
+ [81252] = true, -- Drov the Ruiner
+ [81535] = true, -- Tarlna the Ageless
+
+ -------------------------------------------------------------------------------
+ -- Grim Batol
+ -------------------------------------------------------------------------------
+ [39625] = true, -- General Umbriss
+ [40177] = true, -- Forgemaster Throngus
+ [40319] = true, -- Drahga Shadowburner
+ [40484] = true, -- Erudax
+
+ -------------------------------------------------------------------------------
+ -- Grimrail Depot
+ -------------------------------------------------------------------------------
+ [77803] = true, -- Railmaster Rocketspark
+ [77816] = true, -- Borka the Brute
+ [79545] = true, -- Nitrogg Thundertower
+ [80005] = true, -- Skylord Tovra
+
+ -------------------------------------------------------------------------------
+ -- Gruul's Lair
+ -------------------------------------------------------------------------------
+ [18831] = true, -- High King Maulgar
+ [19044] = true, -- Gruul the Dragonkiller
+
+ -- Gruul's Lair: Maulgar's Ogre Council
+ [18835] = true, -- Kiggler the Crazed
+ [18836] = true, -- Blindeye the Seer
+ [18834] = true, -- Olm the Summoner
+ [18832] = true, -- Krosh Firehand
+
+ -------------------------------------------------------------------------------
+ -- Gundrak
+ -------------------------------------------------------------------------------
+ [29304] = true, -- Slad'ran
+ [29305] = true, -- Moorabi
+ [29307] = true, -- Drakkari Colossus
+ [29306] = true, -- Gal'darah
+ [29932] = true, -- Eck the Ferocious (Heroic)
+
+ -------------------------------------------------------------------------------
+ -- Halls of Lightning
+ -------------------------------------------------------------------------------
+ [28586] = true, -- General Bjarngrim
+ [28587] = true, -- Volkhan
+ [28546] = true, -- Ionar
+ [28923] = true, -- Loken
+
+ -------------------------------------------------------------------------------
+ -- Halls of Origination
+ -------------------------------------------------------------------------------
+ [39425] = true, -- Temple Guardian Anhuur
+ [39428] = true, -- Earthrager Ptah
+ [39788] = true, -- Anraphet
+ [39587] = true, -- Isiset
+ [39731] = true, -- Ammunae
+ [39732] = true, -- Setesh
+ [39378] = true, -- Rajh
+
+ -------------------------------------------------------------------------------
+ -- Halls of Reflection
+ -------------------------------------------------------------------------------
+ [38112] = true, -- Falric
+ [38113] = true, -- Marwyn
+ [37226] = true, -- The Lich King
+ [38113] = true, -- Marvyn
+
+ -------------------------------------------------------------------------------
+ -- Halls of Stone
+ -------------------------------------------------------------------------------
+ [27977] = true, -- Krystallus
+ [27975] = true, -- Maiden of Grief
+ [28234] = true, -- The Tribunal of Ages
+ [27978] = true, -- Sjonnir The Ironshaper
+
+ -------------------------------------------------------------------------------
+ -- Heart of Fear (MoP-Raid 5.0.1)
+ -------------------------------------------------------------------------------
+ [62837] = true, -- Grand Empress Shek'zeer
+ [62543] = true, -- Blade Lord Ta'yak
+ [62511] = true, -- Amber-Shaper Un'sok
+ [63191] = true, -- Garalon
+ [62397] = true, -- Wind Lord Mel'jarak
+ [62980] = true, -- Zorlok
+
+ -------------------------------------------------------------------------------
+ -- Hellfire Citadel (Draenor)
+ -------------------------------------------------------------------------------
+ -- Hellbreach
+ [95068] = true, -- Hellfire Assault - Siegemaster Mar'tak
+ [90284] = true, -- Iron Reaver
+ [90776] = true, -- Kormrok
+ -- Halls of Blood
+ [90378] = true, -- Kilrogg Deadeye
+ [92144] = true, -- Hellfire High Council - Dia Darkwhisper
+ [92146] = true, -- Hellfire High Council - Gurtogg Bloodboil
+ [93713] = true, -- Hellfire High Council - Blademaster Jubei'thos
+ [91809] = true, -- Gorefiend
+ -- Bastion of Shadows
+ [95067] = true, -- Shadow-Lord Iskar
+ [90296] = true, -- Socrethar the Eternal - Soulbound Construct
+ [93439] = true, -- Tyrant Velhari
+ -- Destructors Rise
+ [89890] = true, -- Fel Lord Zakuun
+ [93068] = true, -- Xhul'horac
+ [91349] = true, -- Mannoroth
+ -- The Black Gate
+ [91331] = true, -- Archimonde
+
+ -------------------------------------------------------------------------------
+ -- Hellfire Citadel: Hellfire Ramparts
+ -------------------------------------------------------------------------------
+ [17306] = true, -- Watchkeeper Gargolmar
+ [17308] = true, -- Omor the Unscarred
+ [17537] = true, -- Vazruden
+ [17307] = true, -- Vazruden the Herald
+ [17536] = true, -- Nazan
+
+ -------------------------------------------------------------------------------
+ -- Hellfire Citadel: Magtheridon's Lair
+ -------------------------------------------------------------------------------
+ [17257] = true, -- Magtheridon
+
+ -------------------------------------------------------------------------------
+ -- Hellfire Citadel: Shattered Halls
+ -------------------------------------------------------------------------------
+ [16807] = true, -- Grand Warlock Nethekurse
+ [20923] = true, -- Blood Guard Porung (Heroic)
+ [16809] = true, -- Warbringer O'mrogg
+ [16808] = true, -- Warchief Kargath Bladefist
+
+ -------------------------------------------------------------------------------
+ -- Hellfire Citadel: The Blood Furnace
+ -------------------------------------------------------------------------------
+ [17381] = true, -- The Maker
+ [17380] = true, -- Broggok
+ [17377] = true, -- Keli'dan the Breaker
+
+ -------------------------------------------------------------------------------
+ -- Hellfire Peninsula
+ -------------------------------------------------------------------------------
+ [18728] = true, -- Doom Lord Kazzak
+ [12397] = true, -- Lord Kazzak
+
+ -------------------------------------------------------------------------------
+ -- Highmaul
+ -------------------------------------------------------------------------------
+ -- Walled City
+ [78714] = true, -- Kargath Bladefist
+ [77404] = true, -- The Butcher
+ [78491] = true, -- Brackenspore
+ -- Arcane Sanctum
+ [78948] = true, -- Tectus
+ [78238] = true, -- Twin Ogron - Pol
+ [78237] = true, -- Twin Ogron - Phemos
+ [79015] = true, -- Ko'ragh
+ -- Imperator's Rise
+ [77428] = true, -- Imperator Mar'gok
+
+ -------------------------------------------------------------------------------
+ -- Hour of Twilight 4.3
+ -------------------------------------------------------------------------------
+ [54590] = true, -- Arcurion
+ [54968] = true, -- Asira Dawnslayer
+ [54938] = true, -- Archbishop Benedictus
+
+ -------------------------------------------------------------------------------
+ -- Icecrown Citadel
+ -------------------------------------------------------------------------------
+ [36612] = true, -- Lord Marrowgar
+ [36855] = true, -- Lady Deathwhisper
+
+ -- Gunship Battle
+ [37813] = true, -- Deathbringer Saurfang
+ [36626] = true, -- Festergut
+ [36627] = true, -- Rotface
+ [36678] = true, -- Professor Putricide
+ [37972] = true, -- Prince Keleseth (Icecrown Citadel)
+ [37970] = true, -- Prince Valanar
+ [37973] = true, -- Prince Taldaram (Icecrown Citadel)
+ [37955] = true, -- Queen Lana'thel
+ [36789] = true, -- Valithria Dreamwalker
+ [37950] = true, -- Valithria Dreamwalker (Phased)
+ [37868] = true, -- Risen Archmage, Valitrhia Add
+ [36791] = true, -- Blazing Skeleton, Valithria Add
+ [37934] = true, -- Blistering Zombie, Valithria Add
+ [37886] = true, -- Gluttonous Abomination, Valithria Add
+ [37985] = true, -- Dream Cloud , Valithria "Add"
+ [36853] = true, -- Sindragosa
+ [36597] = true, -- The Lich King (Icecrown Citadel)
+ [37217] = true, -- Precious
+ [37025] = true, -- Stinki
+ [36661] = true, -- Rimefang
+
+ -------------------------------------------------------------------------------
+ -- Iron Docks
+ -------------------------------------------------------------------------------
+ [81305] = true, -- Fleshrender Nok'gar
+ [81297] = true, -- Fleshrender Nok'gar - Dreadfang
+ [80816] = true, -- Grimrail Enforcers - Ahri'ok Dugru
+ [80805] = true, -- Grimrail Enforcers - Makogg Emberblade
+ [80808] = true, -- Grimrail Enforcers - Neesa Nox
+ [79852] = true, -- Oshir
+ [83612] = true, -- Skulloc
+ [83613] = true, -- Skulloc - Koramar
+ [83616] = true, -- Skulloc - Zoggosh
+
+ -------------------------------------------------------------------------------
+ -- Isle of Giants
+ -------------------------------------------------------------------------------
+ [69161] = true, -- Oondasta
+
+ -------------------------------------------------------------------------------
+ -- Isle of Thunder
+ -------------------------------------------------------------------------------
+ [69099] = true, -- Nalak
+
+ -------------------------------------------------------------------------------
+ -- Karazhan
+ -------------------------------------------------------------------------------
+ [15550] = true, -- Attumen the Huntsman
+ [16151] = true, -- Midnight
+ [28194] = true, -- Tenris Mirkblood (Scourge invasion)
+ [15687] = true, -- Moroes
+ [16457] = true, -- Maiden of Virtue
+ [15691] = true, -- The Curator
+ [15688] = true, -- Terestian Illhoof
+ [16524] = true, -- Shade of Aran
+ [15689] = true, -- Netherspite
+ [15690] = true, -- Prince Malchezaar
+ [17225] = true, -- Nightbane
+ [17229] = true, -- Kil'rek
+ -- Chess event
+
+ -------------------------------------------------------------------------------
+ -- Karazhan: Servants' Quarters Beasts
+ -------------------------------------------------------------------------------
+ [16179] = true, -- Hyakiss the Lurker
+ [16181] = true, -- Rokad the Ravager
+ [16180] = true, -- Shadikith the Glider
+
+ -------------------------------------------------------------------------------
+ -- Karazhan: Opera Event
+ -------------------------------------------------------------------------------
+ [17535] = true, -- Dorothee
+ [17546] = true, -- Roar
+ [17543] = true, -- Strawman
+ [17547] = true, -- Tinhead
+ [17548] = true, -- Tito
+ [18168] = true, -- The Crone
+ [17521] = true, -- The Big Bad Wolf
+ [17533] = true, -- Romulo
+ [17534] = true, -- Julianne
+
+ -------------------------------------------------------------------------------
+ -- Kun-Lai Summit: MoP World bosses
+ -------------------------------------------------------------------------------
+ [60491] = true, -- Sha of Anger
+ [62346] = true, -- Galleon
+
+ -------------------------------------------------------------------------------
+ -- Lost City of the Tol'vir
+ -------------------------------------------------------------------------------
+ [44577] = true, -- General Husam
+ [43612] = true, -- High Prophet Barim
+ [43614] = true, -- Lockmaw
+ [49045] = true, -- Augh
+ [44819] = true, -- Siamat
+
+ -------------------------------------------------------------------------------
+ -- Lower Blackrock Spire
+ -------------------------------------------------------------------------------
+ [10263] = true, -- Burning Felguard
+ [9218] = true, -- Spirestone Battle Lord
+ [9219] = true, -- Spirestone Butcher
+ [9217] = true, -- Spirestone Lord Magus
+ [9196] = true, -- Highlord Omokk
+ [9236] = true, -- Shadow Hunter Vosh'gajin
+ [9237] = true, -- War Master Voone
+ [16080] = true, -- Mor Grayhoof
+ [9596] = true, -- Bannok Grimaxe
+ [10596] = true, -- Mother Smolderweb
+ [10376] = true, -- Crystal Fang
+ [10584] = true, -- Urok Doomhowl
+ [9736] = true, -- Quartermaster Zigris
+ [10220] = true, -- Halycon
+ [10268] = true, -- Gizrul the Slavener
+ [9718] = true, -- Ghok Bashguud
+ [9568] = true, -- Overlord Wyrmthalak
+
+ -------------------------------------------------------------------------------
+ -- Magisters' Terrace
+ -------------------------------------------------------------------------------
+ [24723] = true, -- Selin Fireheart
+ [24744] = true, -- Vexallus
+ [24560] = true, -- Priestess Delrissa
+ [24664] = true, -- Kael'thas Sunstrider
+
+ -------------------------------------------------------------------------------
+ -- Maraudon
+ -------------------------------------------------------------------------------
+ -- [13718] = true, -- The Nameless Prophet (Pre-instance)
+ [13742] = true, -- Kolk
+ [13741] = true, -- Gelk
+ [13740] = true, -- Magra
+ [13739] = true, -- Maraudos
+ [12236] = true, -- Lord Vyletongue
+ [13738] = true, -- Veng
+ [13282] = true, -- Noxxion
+ [12258] = true, -- Razorlash
+ [12237] = true, -- Meshlok the Harvester
+ [12225] = true, -- Celebras the Cursed
+ [12203] = true, -- Landslide
+ [13601] = true, -- Tinkerer Gizlock
+ [13596] = true, -- Rotgrip
+ [12201] = true, -- Princess Theradras
+
+ -------------------------------------------------------------------------------
+ -- Mogu'Shan Palace (MoP-Dungeon 5.0.1)
+ -------------------------------------------------------------------------------
+ [61442] = true, -- Kuai the Brute, Trial of the King
+ [61444] = true, -- Ming the Cunning, Trial of the King
+ [61445] = true, -- Haiyan the Unstoppable, Trial of the King
+ [61243] = true, -- Gekkan
+ [61398] = true, -- Xin the Weaponmaster
+
+ -------------------------------------------------------------------------------
+ -- Mogu'Shan Vault (MoP-Raid 5.0.1)
+ -------------------------------------------------------------------------------
+ [59915] = true, -- Jasper, Stone Guard
+ [60009] = true, -- Feng the Accursed
+ [60043] = true, -- Jade, Stone Guard
+ [60047] = true, -- Amethyst, Stone Guard
+ [60051] = true, -- Cobalt, Stone Guard
+ [60143] = true, -- Gara'jal the Spiritbinder
+ [60399] = true, -- Qin-xi
+ [60400] = true, -- Jan-xi
+ [60410] = true, -- Elegon
+ [60701] = true, -- Zian of the Endless Shadow
+ [60709] = true, -- Qiang the Merciless
+ [60710] = true, -- Subetai the Swift
+ [60708] = true, -- Meng the Demented
+
+ -------------------------------------------------------------------------------
+ -- Molten Core
+ -------------------------------------------------------------------------------
+ [12118] = true, -- Lucifron
+ [11982] = true, -- Magmadar
+ [12259] = true, -- Gehennas
+ [12057] = true, -- Garr
+ [12056] = true, -- Baron Geddon
+ [12264] = true, -- Shazzrah
+ [12098] = true, -- Sulfuron Harbinger
+ [11988] = true, -- Golemagg the Incinerator
+ [12018] = true, -- Majordomo Executus
+ [11502] = true, -- Ragnaros
+
+ -------------------------------------------------------------------------------
+ -- Nagrand
+ -------------------------------------------------------------------------------
+ [18398] = true, -- Brokentoe
+ [18069] = true, -- Mogor , friendly
+ [18399] = true, -- Murkblood Twin
+ [18400] = true, -- Rokdar the Sundered Lord
+ [18401] = true, -- Skra'gath
+ [18402] = true, -- Warmaul Champion
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas
+ -------------------------------------------------------------------------------
+ [30549] = true, -- Baron Rivendare (Naxxramas)
+ [16803] = true, -- Death Knight Understudy
+ [15930] = true, -- Feugen
+ [15929] = true, -- Stalagg
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas: Abomination Wing
+ -------------------------------------------------------------------------------
+ [16028] = true, -- Patchwerk
+ [15931] = true, -- Grobbulus
+ [15932] = true, -- Gluth
+ [15928] = true, -- Thaddius
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas: Deathknight Wing
+ -------------------------------------------------------------------------------
+ [16061] = true, -- Instructor Razuvious
+ [16060] = true, -- Gothik the Harvester
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas: Frostwyrm Lair
+ -------------------------------------------------------------------------------
+ [15989] = true, -- Sapphiron
+ [15990] = true, -- Kel'Thuzad
+ [25465] = true, -- Kel'Thuzad
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas: Plague Wing
+ -------------------------------------------------------------------------------
+ [15954] = true, -- Noth the Plaguebringer
+ [15936] = true, -- Heigan the Unclean
+ [16011] = true, -- Loatheb
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas: Spider Wing
+ -------------------------------------------------------------------------------
+ [15956] = true, -- Anub'Rekhan
+ [15953] = true, -- Grand Widow Faerlina
+ [15952] = true, -- Maexxna
+
+ -------------------------------------------------------------------------------
+ -- Naxxramas: The Four Horsemen
+ -------------------------------------------------------------------------------
+ [16065] = true, -- Lady Blaumeux
+ [16064] = true, -- Thane Korth'azz
+ [16062] = true, -- Highlord Mograine
+ [16063] = true, -- Sir Zeliek
+
+ -------------------------------------------------------------------------------
+ -- Nizuao Temple (MoP-Dungeon 5.0.1)
+ -------------------------------------------------------------------------------
+
+ [61634] = true, -- Vojak
+ [61567] = true, -- Jinbak
+ [62205] = true, -- Neronok
+ [61485] = true, -- Pavalak
+
+ -------------------------------------------------------------------------------
+ -- Obsidian Sanctum
+ -------------------------------------------------------------------------------
+ [30451] = true, -- Shadron
+ [30452] = true, -- Tenebron
+ [30449] = true, -- Vesperon
+ [28860] = true, -- Sartharion
+
+ -------------------------------------------------------------------------------
+ -- Onyxia's Lair
+ -------------------------------------------------------------------------------
+ [10184] = true, -- Onyxia
+
+ -------------------------------------------------------------------------------
+ -- Pit of Saron
+ -------------------------------------------------------------------------------
+ [36494] = true, -- Forgemaster Garfrost
+ [36477] = true, -- Krick
+ [36476] = true, -- Ick
+ [36658] = true, -- Scourgelord Tyrannus
+
+ -------------------------------------------------------------------------------
+ -- Ragefire Chasm
+ -------------------------------------------------------------------------------
+ [11517] = true, -- Oggleflint
+ [11518] = true, -- Jergosh the Invoker
+ [11519] = true, -- Bazzalan
+ [11520] = true, -- Taragaman the Hungerer
+ [17830] = true, -- Zelemar the Wrathful
+
+ -------------------------------------------------------------------------------
+ -- Razorfen Downs
+ -------------------------------------------------------------------------------
+ [7355] = true, -- Tuten'kash
+ [14686] = true, -- Lady Falther'ess (Scourge invasion only)
+ [7356] = true, -- Plaguemaw the Rotting
+ [7357] = true, -- Mordresh Fire Eye
+ [8567] = true, -- Glutton
+ [7354] = true, -- Ragglesnout
+ [7358] = true, -- Amnennar the Coldbringer
+
+ -------------------------------------------------------------------------------
+ -- Razorfen Kraul
+ -------------------------------------------------------------------------------
+ [4421] = true, -- Charlga Razorflank
+ [4420] = true, -- Overlord Ramtusk
+ [4422] = true, -- Agathelos the Raging
+ [4428] = true, -- Death Speaker Jargba
+ [4424] = true, -- Aggem Thorncurse
+ [6168] = true, -- Roogug
+ [4425] = true, -- Blind Hunter
+ [4842] = true, -- Earthcaller Halmgar
+
+ -------------------------------------------------------------------------------
+ -- Ruby Sanctum
+ -------------------------------------------------------------------------------
+ [39746] = true, -- Zarithrian
+ [39747] = true, -- Saviana
+ [39751] = true, -- Baltharus
+ [39863] = true, -- Halion
+ [39899] = true, -- Baltharus (Copy has an own id apparently)
+ [40142] = true, -- Halion (twilight realm)
+
+ -------------------------------------------------------------------------------
+ -- Ruins of Ahn'Qiraj
+ -------------------------------------------------------------------------------
+ [15348] = true, -- Kurinnaxx
+ [15341] = true, -- General Rajaxx
+ [15340] = true, -- Moam
+ [15370] = true, -- Buru the Gorger
+ [15369] = true, -- Ayamiss the Hunter
+ [15339] = true, -- Ossirian the Unscarred
+
+ -------------------------------------------------------------------------------
+ -- Scarlet Halls (MoP Dungeon)
+ -------------------------------------------------------------------------------
+ [58632] = true, -- Armsmaster Harlan
+ [59150] = true, -- Flameweaver Koegler
+ [59303] = true, -- Houndmaster Braun
+
+ -------------------------------------------------------------------------------
+ -- Scarlet Monastery: Armory
+ -------------------------------------------------------------------------------
+ [3975] = true, -- Herod
+
+ -------------------------------------------------------------------------------
+ -- Scarlet Monastery: Cathedral
+ -------------------------------------------------------------------------------
+ [4542] = true, -- High Inquisitor Fairbanks
+ [3976] = true, -- Scarlet Commander Mograine
+ [3977] = true, -- High Inquisitor Whitemane
+ [59789] = true, -- Thalnos the Soulrender (MoP Heroic 5.0.1)
+ [59223] = true, -- Brother Korlof (MoP Heroic 5.0.1)
+ [60040] = true, -- Commander Durand (MoP Heroic 5.0.1)
+
+ -------------------------------------------------------------------------------
+ -- Scarlet Monastery: Graveyard
+ -------------------------------------------------------------------------------
+ [3983] = true, -- Interrogator Vishas
+ [6488] = true, -- Fallen Champion
+ [6490] = true, -- Azshir the Sleepless
+ [6489] = true, -- Ironspine
+ [14693] = true, -- Scorn (Scourge invasion only)
+ [4543] = true, -- Bloodmage Thalnos
+ [23682] = true, -- Headless Horseman
+ [23800] = true, -- Headless Horseman
+
+ -------------------------------------------------------------------------------
+ -- Scarlet Monastery: Library
+ -------------------------------------------------------------------------------
+ [3974] = true, -- Houndmaster Loksey
+ [6487] = true, -- Arcanist Doan
+
+ -------------------------------------------------------------------------------
+ -- Scholomance
+ -------------------------------------------------------------------------------
+ [14861] = true, -- Blood Steward of Kirtonos
+ [10506] = true, -- Kirtonos the Herald
+ [14695] = true, -- Lord Blackwood (Scourge Invasion)
+ [10503] = true, -- Jandice Barov
+ [11622] = true, -- Rattlegore
+ [14516] = true, -- Death Knight Darkreaver
+ [10433] = true, -- Marduk Blackpool
+ [10432] = true, -- Vectus
+ [16118] = true, -- Kormok
+ [10508] = true, -- Ras Frostwhisper
+ [10505] = true, -- Instructor Malicia
+ [11261] = true, -- Doctor Theolen Krastinov
+ [10901] = true, -- Lorekeeper Polkelt
+ [10507] = true, -- The Ravenian
+ [10504] = true, -- Lord Alexei Barov
+ [10502] = true, -- Lady Illucia Barov
+ [1853] = true, -- Darkmaster Gandling
+ [58633] = true, -- Instructor Chillheart (MoP Heroic)
+ [59200] = true, -- Lilian Voss (MoP Heroic)
+
+ -------------------------------------------------------------------------------
+ -- Searing Gorge
+ -------------------------------------------------------------------------------
+ [9026] = true, -- Overmaster Pyron
+
+ -------------------------------------------------------------------------------
+ -- Shado-Pan Monastery (MoP Dungeon)
+ -------------------------------------------------------------------------------
+ [56719] = true, -- Sha of Violence
+ [56747] = true, -- Gu Cloudstrike
+ [56884] = true, -- Taran Zhu
+ [64387] = true, -- Master Snowdrift
+
+ -------------------------------------------------------------------------------
+ -- Shadowfang Keep
+ -------------------------------------------------------------------------------
+ [3914] = true, -- Rethilgore
+ [3886] = true, -- Razorclaw the Butcher
+ [4279] = true, -- Odo the Blindwatcher
+ [3887] = true, -- Baron Silverlaine
+ [4278] = true, -- Commander Springvale
+ [4274] = true, -- Fenrus the Devourer
+ [3927] = true, -- Wolf Master Nandos
+ [14682] = true, -- Sever (Scourge invasion only)
+ [4275] = true, -- Archmage Arugal
+ [3872] = true, -- Deathsworn Captain
+ [46962] = true, -- Baron Ashbury
+ [46963] = true, -- Lord Walden
+ [46964] = true, -- Lord Godfrey
+
+ -------------------------------------------------------------------------------
+ -- Shadowmoon Burial Grounds
+ -------------------------------------------------------------------------------
+ [75509] = true, -- Sadana Bloodfury
+ [75829] = true, -- Nhallish
+ [75452] = true, -- Bonemaw
+ [76407] = true, -- Ner'zhul
+
+ -------------------------------------------------------------------------------
+ -- Shadowmoon Valley
+ -------------------------------------------------------------------------------
+ [17711] = true, -- Doomwalker
+
+ -------------------------------------------------------------------------------
+ -- Siege of Orgrimmar
+ -------------------------------------------------------------------------------
+ -- Vale of Eternal Sorrows
+ [71543] = true, -- Immerseus
+ [71475] = true, -- Rook Stonetoe, The Fallen Protectors
+ [71479] = true, -- He Softfoot, The Fallen Protectors
+ [71480] = true, -- Sun Tenderheart, The Fallen Protectors
+ [72276] = true, -- Norushen, Amalgam of Corruption
+ [71734] = true, -- Sha of Pride
+
+ -- Gates of Retribution
+ [72249] = true, -- Galakras
+ [72311] = true, -- Varian (part of the Galakras encounter's trigger)
+ [72560] = true, -- Lor'Themar (His hair triggers the Galakras encounter)
+ [71466] = true, -- Iron Juggernaut
+ [71859] = true, -- Haromm, his Darkness exceeded only by his Shamanism
+ [71858] = true, -- Kardriss, his Shamanism exceeded only by his Darkness
+ [71515] = true, -- General Nazgrim
+
+ -- The Underhold
+ [71454] = true, -- Malkorak
+ [73720] = true, -- Mogu Spoils (Spoils of War)
+ [71512] = true, -- Mantid Spoils (Spoils of War)
+ [71529] = true, -- Thok the Bloodthirsty, her Thirst exceeded only by her Blood
+
+ -- Downfall
+ [71504] = true, -- Siegecrafter Blackfuse, his fuses exceeded only by his... wait...
+ [71591] = true, -- Automated Shredder (Part of the Siegecrafter fight... not sure if this is the trigger or just him)
+ [71152] = true, -- Skeer the Bloodseeker,
+ [71153] = true, -- Hisek the Swarmkeeper,
+ [71154] = true, -- Ka'roz the Locust,
+ [71155] = true, -- Korven the Prime,
+ [71156] = true, -- Kaz'tik the Manipulator,
+ [71157] = true, -- Xaril The POisoned Mind,
+ [71158] = true, -- Rik'kal the Dissector,
+ [71160] = true, -- Iyyokuk the Lucid, (71159 is Ghazrooki, weird isn't it?)
+ [71161] = true, -- Kil'ruk the Wind-Reaver,
+ [71865] = true, -- Garrosh Starscream, That's right. He was a Decepticon all this time
+
+ -------------------------------------------------------------------------------
+ -- Silithus
+ -------------------------------------------------------------------------------
+ [15205] = true, -- Baron Kazum
+ [15204] = true, -- High Marshal Whirlaxis
+ [15305] = true, -- Lord Skwol
+ [15203] = true, -- Prince Skaldrenox
+ [14454] = true, -- The Windreaver
+
+ -------------------------------------------------------------------------------
+ -- Skyreach
+ -------------------------------------------------------------------------------
+ [75964] = true, -- Ranjit
+ [76141] = true, -- Araknath
+ [76379] = true, -- Rukhran
+ [76266] = true, -- High Sage Viryx
+
+ -------------------------------------------------------------------------------
+ -- Spires of Arak
+ -------------------------------------------------------------------------------
+ [83746] = true, -- Rukhmar
+
+ -------------------------------------------------------------------------------
+ -- Stormstout Brewery (MoP Dungeon)
+ -------------------------------------------------------------------------------
+ [56717] = true, -- Hoptallus
+ [57963] = true, -- Ook-Ook
+ [59479] = true, -- Yan-Zhu the Unsacked
+
+ -------------------------------------------------------------------------------
+ -- Stormwind Stockade
+ -------------------------------------------------------------------------------
+ [1716] = true, -- Bazil Thredd
+ [1663] = true, -- Dextren Ward
+ [1717] = true, -- Hamhock
+ [1666] = true, -- Kam Deepfury
+ [1696] = true, -- Targorr the Dread
+ [1720] = true, -- Bruegal Ironknuckle
+ -- Cata:
+ [46383] = true, -- Randolph Moloch
+ [46264] = true, -- Lord Overheat
+ [46254] = true, -- Hogger
+
+ -------------------------------------------------------------------------------
+ -- Stratholme: Scarlet Stratholme
+ -------------------------------------------------------------------------------
+ [10393] = true, -- Skul
+ [14684] = true, -- Balzaphon (Scourge Invasion)
+ -- [11082] = true, -- Stratholme Courier
+ [11058] = true, -- Fras Siabi
+ [10558] = true, -- Hearthsinger Forresten
+ [10516] = true, -- The Unforgiven
+ [16387] = true, -- Atiesh
+ [11143] = true, -- Postmaster Malown
+ [10808] = true, -- Timmy the Cruel
+ [11032] = true, -- Malor the Zealous
+ [11120] = true, -- Crimson Hammersmith
+ [10997] = true, -- Cannon Master Willey
+ [10811] = true, -- Archivist Galford
+ [10813] = true, -- Balnazzar
+ [16101] = true, -- Jarien
+ [16102] = true, -- Sothos
+
+ -------------------------------------------------------------------------------
+ -- Stratholme: Defenders of the Chapel
+ -------------------------------------------------------------------------------
+ [17913] = true, -- Aelmar the Vanquisher
+ [17911] = true, -- Cathela the Seeker
+ [17910] = true, -- Gregor the Justiciar
+ [17914] = true, -- Vicar Hieronymus
+ [17912] = true, -- Nemas the Arbiter
+
+ -------------------------------------------------------------------------------
+ -- Stratholme: Undead Stratholme
+ -------------------------------------------------------------------------------
+ [10809] = true, -- Stonespine
+ [10437] = true, -- Nerub'enkan
+ [10436] = true, -- Baroness Anastari
+ [11121] = true, -- Black Guard Swordsmith
+ [10438] = true, -- Maleki the Pallid
+ [10435] = true, -- Magistrate Barthilas
+ [10439] = true, -- Ramstein the Gorger
+ [10440] = true, -- Baron Rivendare (Stratholme)
+
+ -------------------------------------------------------------------------------
+ -- Sunwell Plateau
+ -------------------------------------------------------------------------------
+ [24891] = true, -- Kalecgos
+ [25319] = true, -- Kalecgos
+ [24850] = true, -- Kalecgos
+ [24882] = true, -- Brutallus
+ [25038] = true, -- Felmyst
+ [25165] = true, -- Lady Sacrolash
+ [25166] = true, -- Grand Warlock Alythess
+ [25741] = true, -- M'uru
+ [25315] = true, -- Kil'jaeden
+ [25840] = true, -- Entropius
+ [24892] = true, -- Sathrovarr the Corruptor
+
+ -------------------------------------------------------------------------------
+ -- Tanaan Jungle
+ -------------------------------------------------------------------------------
+ [94015] = true, -- Supreme Lord Kazzak
+
+ -------------------------------------------------------------------------------
+ -- Tempest Keep: The Arcatraz
+ -------------------------------------------------------------------------------
+ [20870] = true, -- Zereketh the Unbound
+ [20886] = true, -- Wrath-Scryer Soccothrates
+ [20885] = true, -- Dalliah the Doomsayer
+ [20912] = true, -- Harbinger Skyriss
+ [20904] = true, -- Warden Mellichar
+
+ -------------------------------------------------------------------------------
+ -- Tempest Keep: The Botanica
+ -------------------------------------------------------------------------------
+ [17976] = true, -- Commander Sarannis
+ [17975] = true, -- High Botanist Freywinn
+ [17978] = true, -- Thorngrin the Tender
+ [17980] = true, -- Laj
+ [17977] = true, -- Warp Splinter
+
+ -------------------------------------------------------------------------------
+ -- Tempest Keep: The Eye
+ -------------------------------------------------------------------------------
+ [19514] = true, -- Al'ar
+ [19516] = true, -- Void Reaver
+ [18805] = true, -- High Astromancer Solarian
+ [19622] = true, -- Kael'thas Sunstrider
+ [20064] = true, -- Thaladred the Darkener
+ [20060] = true, -- Lord Sanguinar
+ [20062] = true, -- Grand Astromancer Capernian
+ [20063] = true, -- Master Engineer Telonicus
+ [21270] = true, -- Cosmic Infuser
+ [21269] = true, -- Devastation
+ [21271] = true, -- Infinity Blades
+ [21268] = true, -- Netherstrand Longbow
+ [21273] = true, -- Phaseshift Bulwark
+ [21274] = true, -- Staff of Disintegration
+ [21272] = true, -- Warp Slicer
+
+ -------------------------------------------------------------------------------
+ -- Tempest Keep: The Mechanar
+ -------------------------------------------------------------------------------
+ [19218] = true, -- Gatewatcher Gyro-Kill
+ [19710] = true, -- Gatewatcher Iron-Hand
+ [19219] = true, -- Mechano-Lord Capacitus
+ [19221] = true, -- Nethermancer Sepethrea
+ [19220] = true, -- Pathaleon the Calculator
+
+ -------------------------------------------------------------------------------
+ -- Temple of Ahn'Qiraj
+ -------------------------------------------------------------------------------
+ [15263] = true, -- The Prophet Skeram
+ [15511] = true, -- Lord Kri
+ [15543] = true, -- Princess Yauj
+ [15544] = true, -- Vem
+ [15516] = true, -- Battleguard Sartura
+ [15510] = true, -- Fankriss the Unyielding
+ [15299] = true, -- Viscidus
+ [15509] = true, -- Princess Huhuran
+ [15276] = true, -- Emperor Vek'lor
+ [15275] = true, -- Emperor Vek'nilash
+ [15517] = true, -- Ouro
+ [15727] = true, -- C'Thun
+ [15589] = true, -- Eye of C'Thun
+
+ -------------------------------------------------------------------------------
+ -- Temple of Atal'Hakkar
+ -------------------------------------------------------------------------------
+ [1063] = true, -- Jade
+ [5400] = true, -- Zekkis
+ [5713] = true, -- Gasher
+ [5715] = true, -- Hukku
+ [5714] = true, -- Loro
+ [5717] = true, -- Mijan
+ [5712] = true, -- Zolo
+ [5716] = true, -- Zul'Lor
+ [5399] = true, -- Veyzhak the Cannibal
+ [5401] = true, -- Kazkaz the Unholy
+ [8580] = true, -- Atal'alarion
+ [8443] = true, -- Avatar of Hakkar
+ [5711] = true, -- Ogom the Wretched
+ [5710] = true, -- Jammal'an the Prophet
+ [5721] = true, -- Dreamscythe
+ [5720] = true, -- Weaver
+ [5719] = true, -- Morphaz
+ [5722] = true, -- Hazzas
+ [5709] = true, -- Shade of Eranikus
+
+ -------------------------------------------------------------------------------
+ -- Temple of the Jade Serpent (MoP-Dungeon 5.0.1)
+ -------------------------------------------------------------------------------
+ [56448] = true, -- Wise Mari
+ [58826] = true, -- Zao Sunseeker /Library Event
+ [59051] = true, -- (Strife) - Library Event
+ [59726] = true, -- (Anger) - Library Event
+ [56732] = true, -- Liu Flameheart
+ [56439] = true, -- Sha of Doubt
+
+ -------------------------------------------------------------------------------
+ -- Terrace of Endless Spring (MoP Raid)
+ -------------------------------------------------------------------------------
+ [60583] = true, -- Protector Kaolan
+ [60585] = true, -- Elder Regail
+ [60586] = true, -- Elder Asani
+ [60999] = true, -- Sha of Fear
+ [62442] = true, -- Tsulong
+ [63099] = true, -- Lei Shi
+
+ -------------------------------------------------------------------------------
+ -- The Bastion of Twilight
+ -------------------------------------------------------------------------------
+ [45992] = true, -- Valiona
+ [45993] = true, -- Theralion
+ [44600] = true, -- Halfus Wyrmbreaker
+ [43686] = true, -- Ignacious
+ [43687] = true, -- Feludius
+ [43688] = true, -- Arion
+ [43689] = true, -- Terrastra
+ [43735] = true, -- Elementium Monstrosity
+ [43324] = true, -- Cho'gall
+ [45213] = true, -- Sinestra (Heroic) drycoded from http://db.mmo-champion.com/c/45213/sinestra/
+
+ -------------------------------------------------------------------------------
+ -- The Deadmines
+ -------------------------------------------------------------------------------
+ [642] = true, -- Sneed's Shredder
+ [643] = true, -- Sneed
+ [644] = true, -- Rhahk'Zor
+ [645] = true, -- Cookie
+ [646] = true, -- Mr. Smite
+ [647] = true, -- Captain Greenskin
+ [3586] = true, -- Miner Johnson
+ [1763] = true, -- Gilnid
+ [639] = true, -- Edwin VanCleef
+ [596] = true, -- Brainwashed Noble, outside
+ [626] = true, -- Foreman Thistlenettle, outside
+ [599] = true, -- Marisa du'Paige, outside
+ [47162] = true, -- Glubtok
+ [47296] = true, -- Helix Gearbreaker
+ [43778] = true, -- Foe Reaper 5000
+ [47626] = true, -- Admiral Ripsnarl
+ [47739] = true, -- "Captain" Cookie
+ [49541] = true, -- Vanessa VanCleef
+
+ -------------------------------------------------------------------------------
+ -- Dragon Soul (4.3 Raid)
+ -------------------------------------------------------------------------------
+ [55265] = true, -- Morchok
+ [55308] = true, -- Warlord Zonozz
+ [55312] = true, -- Yor'sahj the Unsleeping
+ [55689] = true, -- Hagara the Binder
+ [55294] = true, -- Ultraxion
+ [56427] = true, -- Warmaster Blackhorn
+ [53879] = true, -- Spine Deathwing
+ [56173] = true, -- Madness Deathwing
+
+ -------------------------------------------------------------------------------
+ -- The Everbloom
+ -------------------------------------------------------------------------------
+ [81522] = true, -- Witherbark
+ [83892] = true, -- Ancient Protectors - Life Warden Gola
+ [83893] = true, -- Ancient Protectors - Earthshaper Telu
+ [83894] = true, -- Ancient Protectors - Dulhu
+ [84550] = true, -- Xeri'tac
+ [82682] = true, -- Archmage Sol
+ [83846] = true, -- Yalnu
+
+ -------------------------------------------------------------------------------
+ -- The Eye of Eternity
+ -------------------------------------------------------------------------------
+ [28859] = true, -- Malygos
+
+ -------------------------------------------------------------------------------
+ -- The Nexus
+ -------------------------------------------------------------------------------
+ [26798] = true, -- Commander Kolurg (Heroic)
+ [26796] = true, -- Commander Stoutbeard (Heroic)
+ [26731] = true, -- Grand Magus Telestra
+ [26832] = true, -- Grand Magus Telestra
+ [26928] = true, -- Grand Magus Telestra
+ [26929] = true, -- Grand Magus Telestra
+ [26930] = true, -- Grand Magus Telestra
+ [26763] = true, -- Anomalus
+ [26794] = true, -- Ormorok the Tree-Shaper
+ [26723] = true, -- Keristrasza
+
+ -------------------------------------------------------------------------------
+ -- The Oculus
+ -------------------------------------------------------------------------------
+ [27654] = true, -- Drakos the Interrogator
+ [27447] = true, -- Varos Cloudstrider
+ [27655] = true, -- Mage-Lord Urom
+ [27656] = true, -- Ley-Guardian Eregos
+
+ -------------------------------------------------------------------------------
+ -- The Stonecore
+ -------------------------------------------------------------------------------
+ [43438] = true, -- Corborus
+ [43214] = true, -- Slabhide
+ [42188] = true, -- Ozruk
+ [42333] = true, -- High Priestess Azil
+
+ -------------------------------------------------------------------------------
+ -- The Violet Hold
+ -------------------------------------------------------------------------------
+ [29315] = true, -- Erekem
+ [29313] = true, -- Ichoron
+ [29312] = true, -- Lavanthor
+ [29316] = true, -- Moragg
+ [29266] = true, -- Xevozz
+ [29314] = true, -- Zuramat the Obliterator
+ [31134] = true, -- Cyanigosa
+
+ -------------------------------------------------------------------------------
+ -- The Vortex Pinnacle
+ -------------------------------------------------------------------------------
+ [43878] = true, -- Grand Vizier Ertan
+ [43873] = true, -- Altairus
+ [43875] = true, -- Asaad
+
+ -------------------------------------------------------------------------------
+ -- Throne of the Four Winds
+ -------------------------------------------------------------------------------
+ [45871] = true, -- Nezir
+ [46753] = true, -- Al'Akir
+
+ -------------------------------------------------------------------------------
+ -- Throne of Thunder
+ -------------------------------------------------------------------------------
+ -- Last Stand of the Zandalari
+ [69465] = true, -- Jin'rokh the Breaker
+ [68476] = true, -- Horridon
+ [69134] = true, -- Kazra'jin, Council of Elders
+ [69078] = true, -- Sul the Sandcrawler, Council of Elders
+ [69131] = true, -- Frost King Malakk, Council of Elders
+ [69132] = true, -- High Priestess Mar'li, Council of Elders
+
+ -- Forgotten Depths
+ [67977] = true, -- Tortos
+ [70212] = true, -- Flaming Head
+ [70235] = true, -- Frozen Head
+ [70247] = true, -- Venomous Head
+ [69712] = true, -- Ji-Kun
+
+ -- Halls of Flesh-Shaping
+ [68036] = true, -- Durumu the Forgotten
+ [69017] = true, -- Primordius
+ [69427] = true, -- Dark Animus
+
+ -- Pinnacle of Storms
+ [68078] = true, -- Iron Qon
+ [68905] = true, -- Lu'lin , Twin Consorts
+ [68904] = true, -- Suen , Twin Consorts
+ [68397] = true, -- Lei Shen
+ [69473] = true, -- Ra-den
+
+ -------------------------------------------------------------------------------
+ -- Trial of the Champion
+ -------------------------------------------------------------------------------
+ -- Alliance
+ [35617] = true, -- Deathstalker Visceri
+ [35569] = true, -- Eressea Dawnsinger
+ [35572] = true, -- Mokra the Skullcrusher
+ [35571] = true, -- Runok Wildmane
+ [35570] = true, -- Zul'tore
+
+ -- Horde
+ [34702] = true, -- Ambrose Boltspark
+ [34701] = true, -- Colosos
+ [34705] = true, -- Marshal Jacob Alerius
+ [34657] = true, -- Jaelyne Evensong
+ [34703] = true, -- Lana Stouthammer
+
+ -- Neutral
+ [34928] = true, -- Argent Confessor Paletress
+ [35119] = true, -- Eadric the Pure
+ [35451] = true, -- The Black Knight
+
+ -------------------------------------------------------------------------------
+ -- Trial of the Crusader
+ -------------------------------------------------------------------------------
+ [34796] = true, -- Gormok
+ [35144] = true, -- Acidmaw
+ [34799] = true, -- Dreadscale
+ [34797] = true, -- Icehowl
+
+ [34780] = true, -- Jaraxxus
+
+ [34461] = true, -- Tyrius Duskblade
+ [34460] = true, -- Kavina Grovesong
+ [34469] = true, -- Melador Valestrider
+ [34467] = true, -- Alyssia Moonstalker
+ [34468] = true, -- Noozle Whizzlestick
+ [34465] = true, -- Velanaa
+ [34471] = true, -- Baelnor Lightbearer
+ [34466] = true, -- Anthar Forgemender
+ [34473] = true, -- Brienna Nightfell
+ [34472] = true, -- Irieth Shadowstep
+ [34470] = true, -- Saamul
+ [34463] = true, -- Shaabad
+ [34474] = true, -- Serissa Grimdabbler
+ [34475] = true, -- Shocuul
+
+ [34458] = true, -- Gorgrim Shadowcleave
+ [34451] = true, -- Birana Stormhoof
+ [34459] = true, -- Erin Misthoof
+ [34448] = true, -- Ruj'kah
+ [34449] = true, -- Ginselle Blightslinger
+ [34445] = true, -- Liandra Suncaller
+ [34456] = true, -- Malithas Brightblade
+ [34447] = true, -- Caiphus the Stern
+ [34441] = true, -- Vivienne Blackwhisper
+ [34454] = true, -- Maz'dinah
+ [34444] = true, -- Thrakgar
+ [34455] = true, -- Broln Stouthorn
+ [34450] = true, -- Harkzog
+ [34453] = true, -- Narrhok Steelbreaker
+
+ [35610] = true, -- Cat
+ [35465] = true, -- Zhaagrym
+
+ [34497] = true, -- Fjola Lightbane
+ [34496] = true, -- Eydis Darkbane
+ [34564] = true, -- Anub'arak (Trial of the Crusader)
+
+ -------------------------------------------------------------------------------
+ -- Uldaman
+ -------------------------------------------------------------------------------
+ [7057] = true, -- Digmaster Shovelphlange
+ -- [2932] = true, -- Magregan Deepshadow (Outside the instance, not elite)
+ [6910] = true, -- Revelosh
+ [7228] = true, -- Ironaya
+ [7023] = true, -- Obsidian Sentinel
+ [7206] = true, -- Ancient Stone Keeper
+ [7291] = true, -- Galgann Firehammer
+ [4854] = true, -- Grimlok
+ [2748] = true, -- Archaedas
+ [6906] = true, -- Baelog
+
+ -------------------------------------------------------------------------------
+ -- Ulduar: The Antechamber of Ulduar
+ -------------------------------------------------------------------------------
+ [32867] = true, -- Steelbreaker
+ [32927] = true, -- Runemaster Molgeim
+ [32857] = true, -- Stormcaller Brundir
+ [32930] = true, -- Kologarn
+ [33515] = true, -- Auriaya
+ [34035] = true, -- Feral Defender
+ [32933] = true, -- Left Arm
+ [32934] = true, -- Right Arm
+ [33524] = true, -- Saronite Animus
+
+ -------------------------------------------------------------------------------
+ -- Ulduar: The Celestial Planetarium
+ -------------------------------------------------------------------------------
+ [32871] = true, -- Algalon the Observer
+
+ -------------------------------------------------------------------------------
+ -- Ulduar: The Descent into Madness
+ -------------------------------------------------------------------------------
+ [33271] = true, -- General Vezax
+ [33890] = true, -- Brain of Yogg-Saron
+ [33136] = true, -- Guardian of Yogg-Saron
+ [33288] = true, -- Yogg-Saron
+ [32915] = true, -- Elder Brightleaf
+ [32913] = true, -- Elder Ironbranch
+ [32914] = true, -- Elder Stonebark
+ [32882] = true, -- Jormungar Behemoth
+ [33432] = true, -- Leviathan Mk II
+ [34014] = true, -- Sanctum Sentry
+
+ -------------------------------------------------------------------------------
+ -- Ulduar: The Keepers of Ulduar
+ -------------------------------------------------------------------------------
+ [33350] = true, -- Mimiron
+ [32906] = true, -- Freya
+ [32865] = true, -- Thorim
+ [32845] = true, -- Hodir
+
+ -------------------------------------------------------------------------------
+ -- Ulduar: The Siege of Ulduar
+ -------------------------------------------------------------------------------
+ [33113] = true, -- Flame Leviathan
+ [33118] = true, -- Ignis the Furnace Master
+ [33186] = true, -- Razorscale
+ [33293] = true, -- XT-002 Deconstructor
+ [33670] = true, -- Aerial Command Unit
+ [33329] = true, -- Heart of the Deconstructor
+ [33651] = true, -- VX-001
+
+ -------------------------------------------------------------------------------
+ -- Un'Goro Crater
+ -------------------------------------------------------------------------------
+ [14461] = true, -- Baron Charr
+
+ -------------------------------------------------------------------------------
+ -- Upper Blackrock Spire
+ -------------------------------------------------------------------------------
+ [76413] = true, -- Orebender Gor'ashan
+ [76021] = true, -- Kyrak
+ [79912] = true, -- Commander Tharbek
+ [76585] = true, -- Ragewing the Untamed
+ [77120] = true, -- Warlord Zaela
+
+ -------------------------------------------------------------------------------
+ -- Utgarde Keep: Main Bosses
+ -------------------------------------------------------------------------------
+ [23953] = true, -- Prince Keleseth (Utgarde Keep)
+ [27390] = true, -- Skarvald the Constructor
+ [24200] = true, -- Skarvald the Constructor
+ [23954] = true, -- Ingvar the Plunderer
+ [23980] = true, -- Ingvar the Plunderer
+
+ -------------------------------------------------------------------------------
+ -- Utgarde Keep: Secondary Bosses
+ -------------------------------------------------------------------------------
+ [27389] = true, -- Dalronn the Controller
+ [24201] = true, -- Dalronn the Controller
+
+ -------------------------------------------------------------------------------
+ -- Utgarde Pinnacle
+ -------------------------------------------------------------------------------
+ [26668] = true, -- Svala Sorrowgrave
+ [26687] = true, -- Gortok Palehoof
+ [26693] = true, -- Skadi the Ruthless
+ [26861] = true, -- King Ymiron
+
+ -------------------------------------------------------------------------------
+ -- Wailing Caverns
+ -------------------------------------------------------------------------------
+ [5775] = true, -- Verdan the Everliving
+ [3670] = true, -- Lord Pythas
+ [3673] = true, -- Lord Serpentis
+ [3669] = true, -- Lord Cobrahn
+ [3654] = true, -- Mutanus the Devourer
+ [3674] = true, -- Skum
+ [3653] = true, -- Kresh
+ [3671] = true, -- Lady Anacondra
+ [5912] = true, -- Deviate Faerie Dragon
+ [3672] = true, -- Boahn, outside
+ [3655] = true, -- Mad Magglish, outside
+ [3652] = true, -- Trigore the Lasher, outside
+
+ -------------------------------------------------------------------------------
+ -- Vault of Archavon
+ -------------------------------------------------------------------------------
+ [31125] = true, -- Archavon the Stone Watcher
+ [33993] = true, -- Emalon the Storm Watcher
+ [35013] = true, -- Koralon the Flamewatcher
+ [38433] = true, -- Toravon the Ice Watcher
+
+ -------------------------------------------------------------------------------
+ -- Well of Eternity 4.3
+ -------------------------------------------------------------------------------
+
+ [55085] = true, -- Peroth'arn
+ [54853] = true, -- Queen Azshara
+ [54969] = true, -- Mannoroth
+ [55419] = true, -- Varo'then
+
+ -------------------------------------------------------------------------------
+ -- Winterspring
+ -------------------------------------------------------------------------------
+ [14457] = true, -- Princess Tempestria
+
+ -------------------------------------------------------------------------------
+ -- World Dragons
+ -------------------------------------------------------------------------------
+ [14889] = true, -- Emeriss
+ [14888] = true, -- Lethon
+ [14890] = true, -- Taerar
+ [14887] = true, -- Ysondre
+
+ -------------------------------------------------------------------------------
+ -- Zul'Aman
+ -------------------------------------------------------------------------------
+ -- Animal Bosses
+ [29024] = true, -- Nalorakk
+ [28514] = true, -- Nalorakk
+ [23576] = true, -- Nalorakk
+ [23574] = true, -- Akil'zon
+ [23578] = true, -- Jan'alai
+ [28515] = true, -- Jan'alai
+ [29023] = true, -- Jan'alai
+ [23577] = true, -- Halazzi
+ [28517] = true, -- Halazzi
+ [29022] = true, -- Halazzi
+ [24239] = true, -- Malacrass
+
+ -- Final Bosses
+ [24239] = true, -- Hex Lord Malacrass
+ [23863] = true, -- Zul'jin
+
+ -------------------------------------------------------------------------------
+ -- Zul'Farrak
+ -------------------------------------------------------------------------------
+ [7267] = true, -- Chief Ukorz Sandscalp
+ [7271] = true, -- Witch Doctor Zum'rah
+ [7272] = true, -- Theka the Martyr
+ [7273] = true, -- Gahz'rilla
+ [7274] = true, -- Sandfury Executioner
+ [7275] = true, -- Shadowpriest Sezz'ziz
+ [7604] = true, -- Sergeant Bly
+ [7605] = true, -- Raven
+ [7606] = true, -- Oro Eyegouge
+ [7608] = true, -- Murta Grimgut
+ [7795] = true, -- Hydromancer Velratha
+ [7796] = true, -- Nekrum Gutchewer
+ [7797] = true, -- Ruuzlu
+ [8127] = true, -- Antu'sul
+ [10080] = true, -- Sandarr Dunereaver
+ [10082] = true, -- Zerillis
+ [10081] = true, -- Dustwraith
+
+ -------------------------------------------------------------------------------
+ -- Zul'Gurub - 4.1
+ -------------------------------------------------------------------------------
+ [52053] = true, -- Zanzil
+ [52059] = true, -- High Priestess Kilnara
+ [52148] = true, -- Jin'do the Godbreaker
+ [52151] = true, -- Bloodlord Mandokir
+ [52155] = true, -- High Priest Venoxis
+ --[52157] = true, -- Ohgan (Mandokirs Raptor) disabled by Mikk- this is an add, not a boss.
+ [52269] = true, -- Renataki
+ [52258] = true, -- Gri'lek
+ [52271] = true, -- Hazza'rah
+ [52286] = true, -- Wushoolay
+}
+
+lib.BossIDs = BossIDs
diff --git a/Skada/Libs/LibCompat-1.0/LibCompat-1.0.lua b/Skada/Libs/LibCompat-1.0/LibCompat-1.0.lua
new file mode 100644
index 0000000..93fb5fd
--- /dev/null
+++ b/Skada/Libs/LibCompat-1.0/LibCompat-1.0.lua
@@ -0,0 +1,466 @@
+--
+-- **LibCompat-1.0** provides few handy functions that can be embed to addons.
+-- This library was originally created for Skada as of 1.8.50.
+-- @author: Kader B (https://github.com/bkader/LibCompat-1.0)
+--
+
+local MAJOR, MINOR = "LibCompat-1.0-Skada", 37
+local lib, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end
+
+lib.embeds = lib.embeds or {}
+lib.EmptyFunc = Multibar_EmptyFunc
+
+local _G, pairs, type, max = _G, pairs, type, math.max
+local setmetatable, rawset = setmetatable, rawset
+local format, tonumber = format or string.format, tonumber
+local _
+
+local Dispatch
+local GetUnitIdFromGUID
+
+-------------------------------------------------------------------------------
+
+local Units
+do
+ -- solo, group, pets and targets
+ local solo = {"player", "pet"}
+ local group = {player = true}
+ local grouppet = {playerpet = true}
+ local target = {"target", "targettarget", "pettarget", "pettargettarget", "focus", "focustarget", "mouseover", "mouseovertarget"}
+
+ -- party
+ local party = {"player"}
+ local partypet = {"pet"}
+ for i = 1, 4 do
+ local unit = format("party%d", i)
+ party[i + 1] = unit
+ group[unit] = true
+
+ unit = format("partypet%d", i)
+ partypet[i + 1] = unit
+ grouppet[unit] = true
+
+ target[#target + 1] = format("party%dtarget", i)
+ target[#target + 1] = format("partypet%dtarget", i)
+ end
+
+ -- raid
+ local raid = {"player"}
+ local raidpet = {"pet"}
+ for i = 1, 40 do
+ local unit = format("raid%d", i)
+ raid[i + 1] = unit
+ group[unit] = true
+
+ unit = format("raidpet%d", i)
+ raidpet[i + 1] = unit
+ grouppet[unit] = true
+
+ target[#target + 1] = format("raid%dtarget", i)
+ target[#target + 1] = format("raidpet%dtarget", i)
+ end
+
+ -- arena
+ local arena = {}
+ local arenapet = {}
+ for i = 1, 5 do
+ arena[i] = format("arena%d", i)
+ arenapet[i] = format("arenapet%d", i)
+ target[#target + 1] = format("arena%dtarget", i)
+ target[#target + 1] = format("arenapet%dtarget", i)
+ end
+
+ -- boss
+ local boss = {}
+ for i = 1, 5 do
+ boss[i] = format("boss%d", i)
+ target[#target + 1] = format("boss%dtarget", i)
+ end
+
+ lib.Units = {
+ -- solo and targets
+ solo = solo,
+ group = group,
+ grouppet = grouppet,
+ target = target,
+ -- party units and pets
+ party = party,
+ partypet = partypet,
+ -- raid units and pets
+ raid = raid,
+ raidpet = raidpet,
+ -- arena units and pets
+ arena = arena,
+ arenapet = arenapet,
+ -- boss units
+ boss = boss
+ }
+ Units = lib.Units
+end
+
+-------------------------------------------------------------------------------
+
+do
+ local wipe, select, tconcat = wipe, select, table.concat
+ local temp = {}
+ local function _print(...)
+ wipe(temp)
+ for i = 1, select("#", ...) do
+ temp[#temp + 1] = select(i, ...)
+ end
+ DEFAULT_CHAT_FRAME:AddMessage(tconcat(temp, " "))
+ end
+
+ function Dispatch(func, ...)
+ if type(func) ~= "function" then
+ _print("\124cffff9900Error\124r: Dispatch requires a function.")
+ return
+ end
+ return func(...)
+ end
+
+
+ local pcall = pcall
+ local function QuickDispatch(func, ...)
+ if type(func) ~= "function" then return end
+ local ok, err = pcall(func, ...)
+ if not ok then
+ _print("\124cffff9900Error\124r:" .. (err or ""))
+ return
+ end
+ return true
+ end
+
+ lib.Dispatch = Dispatch
+ lib.QuickDispatch = QuickDispatch
+end
+
+-------------------------------------------------------------------------------
+
+do
+ local UnitExists, UnitAffectingCombat, UnitIsDeadOrGhost = _G.UnitExists, _G.UnitAffectingCombat, _G.UnitIsDeadOrGhost
+ local UnitHealth, UnitHealthMax, UnitPower, UnitPowerMax = _G.UnitHealth, _G.UnitHealthMax, _G.UnitPower, _G.UnitPowerMax
+ local GetNumRaidMembers, GetNumPartyMembers = _G.GetNumRaidMembers, _G.GetNumPartyMembers
+ local GetNumGroupMembers, GetNumSubgroupMembers = _G.GetNumGroupMembers, _G.GetNumSubgroupMembers
+ local IsInGroup, IsInRaid = _G.IsInGroup, _G.IsInRaid
+
+ local function GetGroupTypeAndCount()
+ if IsInRaid() then
+ return "raid", 1, GetNumGroupMembers()
+ elseif IsInGroup() then
+ return "party", 0, GetNumSubgroupMembers()
+ else
+ return "solo", 0, 0
+ end
+ end
+
+ local UnitIterator
+ do
+ local nmem, step, count
+
+ local function SelfIterator(excPets)
+ while step do
+ local unit, owner
+ if step == 1 then
+ unit, owner, step = "player", nil, 2
+ elseif step == 2 then
+ if not excPets then
+ unit, owner = "pet", "player"
+ end
+ step = nil
+ end
+ if unit and UnitExists(unit) then
+ return unit, owner
+ end
+ end
+ end
+
+ local party = Units.party
+ local partypet = Units.partypet
+ local function PartyIterator(excPets)
+ while step do
+ local unit, owner
+ if step <= 2 then
+ unit, owner = SelfIterator(excPets)
+ step = step or 3
+ elseif step == 3 then
+ unit, owner, step = party[count], nil, 4
+ elseif step == 4 then
+ if not excPets then
+ unit, owner = partypet[count], party[count]
+ end
+ count = count + 1
+ step = count <= nmem and 3 or nil
+ end
+ if unit and UnitExists(unit) then
+ return unit, owner
+ end
+ end
+ end
+
+ local raid = Units.raid
+ local raidpet = Units.raidpet
+ local function RaidIterator(excPets)
+ while step do
+ local unit, owner
+ if step == 1 then
+ unit, owner, step = raid[count], nil, 2
+ elseif step == 2 then
+ if not excPets then
+ unit, owner = raidpet[count], raid[count]
+ end
+ count = count + 1
+ step = count <= nmem and 1 or nil
+ end
+ if unit and UnitExists(unit) then
+ return unit, owner
+ end
+ end
+ end
+
+ function UnitIterator(excPets)
+ nmem, step = GetNumGroupMembers(), 1
+ if nmem == 0 then
+ return SelfIterator, excPets
+ end
+ count = 1
+ if IsInRaid() then
+ return RaidIterator, excPets
+ end
+ return PartyIterator, excPets
+ end
+ end
+
+ local function IsGroupDead()
+ for unit in UnitIterator(true) do
+ if not UnitIsDeadOrGhost(unit) then
+ return false
+ end
+ end
+ return true
+ end
+
+ local function IsGroupInCombat()
+ for unit in UnitIterator() do
+ if UnitAffectingCombat(unit) then
+ return true
+ end
+ end
+ return false
+ end
+
+ local function GroupIterator(func, ...)
+ for unit, owner in UnitIterator() do
+ Dispatch(func, unit, owner, ...)
+ end
+ end
+
+ do
+ local function FindUnitId(guid, units)
+ if not units then return end
+ for _, unit in next, units do
+ if UnitExists(unit) and UnitGUID(unit) == guid then
+ return unit
+ end
+ end
+ end
+
+ function GetUnitIdFromGUID(guid, grouped)
+ -- start with group members
+ if grouped then
+ local unit = FindUnitId(guid, Units[IsInRaid() and "raid" or IsInGroup() and "party" or "solo"])
+ unit = unit or FindUnitId(guid, Units[IsInRaid() and "raidpet" or IsInGroup() and "partypet" or "solo"])
+ return unit or FindUnitId(guid, Units.target)
+ end
+
+ local unit = not grouped and FindUnitId(guid, Units.target)
+ unit = unit or FindUnitId(guid, Units[IsInRaid() and "raid" or IsInGroup() and "party" or "solo"])
+ return unit or FindUnitId(guid, Units[IsInRaid() and "raidpet" or IsInGroup() and "partypet" or "solo"])
+ end
+ end
+
+ local function GetClassFromGUID(guid)
+ local unit = GetUnitIdFromGUID(guid)
+ local class
+ if unit and unit:find("pet") then
+ class = "PET"
+ elseif unit and unit:find("boss") then
+ class = "BOSS"
+ elseif unit then
+ _, class = UnitClass(unit)
+ end
+ return class, unit
+ end
+
+ local GetCreatureId = setmetatable({}, {
+ __mode = "kv", -- make it weak
+ __index = function(self, guid)
+ if guid then
+ local _, _, _, _, _, id = strsplit("-", guid)
+ id = tonumber(id) or 0
+ rawset(self, guid, id) -- cache it
+ return id
+ end
+ return 0
+ end,
+ __newindex = function(self, guid, id)
+ rawset(self, guid, id)
+ end,
+ __call = function(self, guid)
+ return self[guid]
+ end
+ })
+
+ local unknownUnits = {[_G.UKNOWNBEING] = true, [_G.UNKNOWNOBJECT] = true}
+
+ local function UnitHealthInfo(unit, guid)
+ unit = (unit and not unknownUnits[unit]) and unit or (guid and GetUnitIdFromGUID(guid))
+ local percent, health, maxhealth
+ if unit and UnitExists(unit) then
+ health, maxhealth = UnitHealth(unit), UnitHealthMax(unit)
+ if health and maxhealth then
+ percent = 100 * health / max(1, maxhealth)
+ end
+ end
+ return percent, health, maxhealth
+ end
+
+ local function UnitPowerInfo(unit, guid, powerType)
+ unit = (unit and not unknownUnits[unit]) and unit or (guid and GetUnitIdFromGUID(guid))
+ local percent, power, maxpower
+ if unit and UnitExists(unit) then
+ power, maxpower = UnitPower(unit, powerType), UnitPowerMax(unit, powerType)
+ if power and maxpower then
+ percent = 100 * power / max(1, maxpower)
+ end
+ end
+ return percent, power, maxpower
+ end
+
+ lib.GetGroupTypeAndCount = GetGroupTypeAndCount
+ lib.IsGroupDead = IsGroupDead
+ lib.IsGroupInCombat = IsGroupInCombat
+ lib.GroupIterator = GroupIterator
+ lib.UnitIterator = UnitIterator
+ lib.GetUnitIdFromGUID = GetUnitIdFromGUID
+ lib.GetClassFromGUID = GetClassFromGUID
+ lib.GetCreatureId = GetCreatureId
+ lib.UnitHealthInfo = UnitHealthInfo
+ lib.UnitPowerInfo = UnitPowerInfo
+end
+
+-------------------------------------------------------------------------------
+-- Specs and Roles
+
+do
+ local rawget = rawget
+ local UnitExists, UnitGUID = UnitExists, UnitGUID
+ local LGT = LibStub("LibGroupInSpecT-1.1")
+ local GetUnitSpec, GetUnitRole = {}, {}
+
+ GetUnitSpec = setmetatable(GetUnitSpec, {
+ __index = function(self, guid)
+ local info = LGT:GetCachedInfo(guid)
+ local spec = info and info.global_spec_id or nil
+ if spec then
+ rawset(self, guid, spec)
+ if info.spec_role and not rawget(GetUnitRole, guid) then
+ rawset(GetUnitRole, guid, info.spec_role)
+ end
+ end
+ return spec
+ end,
+ __newindex = function(self, guid, spec)
+ rawset(self, guid, spec)
+ end,
+ __call = function(self, guid)
+ return self[guid]
+ end
+ })
+
+ GetUnitRole = setmetatable(GetUnitRole, {
+ __index = function(self, guid)
+ local info = LGT:GetCachedInfo(guid)
+ local role = info and info.spec_role or nil
+ if role then
+ rawset(self, guid, role)
+ if info.global_spec_id and not rawget(GetUnitSpec, guid) then
+ rawset(GetUnitSpec, guid, info.global_spec_id)
+ end
+ end
+ return role
+ end,
+ __newindex = function(self, guid, role)
+ rawset(self, guid, role)
+ end,
+ __call = function(self, guid)
+ return self[guid]
+ end
+ })
+
+ LGT:RegisterCallback("GroupInSpecT_Update", function(_, guid, _, info)
+ if not guid or not info then return end
+ rawset(GetUnitSpec, guid, info.global_spec_id or rawget(GetUnitSpec, guid))
+ rawset(GetUnitRole, guid, info.spec_role or rawget(GetUnitRole, guid))
+ end)
+
+ LGT:RegisterCallback("GroupInSpecT_Remove", function(_, guid)
+ if not guid then return end
+ rawset(GetUnitSpec, guid, nil)
+ rawset(GetUnitRole, guid, nil)
+ end)
+
+ lib.GetUnitSpec = GetUnitSpec
+ lib.GetUnitRole = GetUnitRole
+end
+
+-------------------------------------------------------------------------------
+-- Pvp
+
+do
+ local IsInInstance, instanceType = IsInInstance, nil
+
+ local function IsInPvP()
+ _, instanceType = IsInInstance()
+ return (instanceType == "pvp" or instanceType == "arena")
+ end
+
+ lib.IsInPvP = IsInPvP
+end
+
+-------------------------------------------------------------------------------
+
+local mixins = {
+ "Units",
+ "EmptyFunc",
+ "Dispatch",
+ "QuickDispatch",
+ -- roster util
+ "IsInPvP",
+ "GetGroupTypeAndCount",
+ "IsGroupDead",
+ "IsGroupInCombat",
+ "GroupIterator",
+ "UnitIterator",
+ -- unit util
+ "GetUnitIdFromGUID",
+ "GetClassFromGUID",
+ "GetCreatureId",
+ "UnitHealthInfo",
+ "UnitPowerInfo",
+ "GetUnitSpec",
+ "GetUnitRole"
+}
+
+function lib:Embed(target)
+ for _, v in pairs(mixins) do
+ target[v] = self[v]
+ end
+ self.embeds[target] = true
+ return target
+end
+
+for addon in pairs(lib.embeds) do
+ lib:Embed(addon)
+end
diff --git a/Skada/Libs/LibCompat-1.0/Libs/LibGroupInSpecT-1.1/LibGroupInSpecT-1.1.lua b/Skada/Libs/LibCompat-1.0/Libs/LibGroupInSpecT-1.1/LibGroupInSpecT-1.1.lua
new file mode 100644
index 0000000..184437e
--- /dev/null
+++ b/Skada/Libs/LibCompat-1.0/Libs/LibGroupInSpecT-1.1/LibGroupInSpecT-1.1.lua
@@ -0,0 +1,915 @@
+-- vim: ts=2 sw=2 ai et fenc=utf8
+
+--[[
+-- These events can be registered for using the regular CallbackHandler ways.
+--
+-- "GroupInSpecT_Update", guid, unit, info
+-- "GroupInSpecT_Remove, guid
+-- "GroupInSpecT_InspectReady", guid, unit
+--
+-- Where is a table containing some or all of the following:
+-- .guid
+-- .name
+-- .realm
+-- .race
+-- .race_localized
+-- .class
+-- .class_localized
+-- .class_id
+-- .gender -- 2 = male, 3 = female
+-- .global_spec_id
+-- .spec_index
+-- .spec_name_localized
+-- .spec_description
+-- .spec_icon
+-- .spec_background
+-- .spec_role
+-- .spec_role_detailed
+-- .spec_group -- active spec group (1/2/nil)
+-- .talents = {
+-- [] = {
+-- .tier
+-- .column
+-- .name_localized
+-- .icon
+-- .talent_id
+-- .spell_id
+-- }
+-- ...
+-- }
+-- .lku -- last known unit id
+-- .not_visible
+--
+-- Functions for external use:
+--
+-- lib:Rescan (guid or nil)
+-- Force a rescan of the given group member GUID, or of all current group members if nil.
+--
+-- lib:QueuedInspections ()
+-- Returns an array of GUIDs of outstanding inspects.
+--
+-- lib:StaleInspections ()
+-- Returns an array of GUIDs for which the data has become stale and is
+-- awaiting an update (no action required, the refresh happens internally).
+-- Due to Blizzard exposing no events on (re/un)talent, there will be
+-- frequent marking of inspect data as being stale.
+--
+-- lib:GetCachedInfo (guid)
+-- Returns the cached info for the given GUID, if available, nil otherwise.
+-- Information is cached for current group members only.
+--
+-- lib:GroupUnits ()
+-- Returns an array with the set of unit ids for the current group.
+--]]
+
+local MAJOR, MINOR = "LibGroupInSpecT-1.1", 90
+
+if not LibStub then error(MAJOR.." requires LibStub") end
+local lib = LibStub:NewLibrary (MAJOR, MINOR)
+if not lib then return end
+
+lib.events = lib.events or LibStub ("CallbackHandler-1.0"):New (lib)
+if not lib.events then error(MAJOR.." requires CallbackHandler") end
+
+
+local UPDATE_EVENT = "GroupInSpecT_Update"
+local REMOVE_EVENT = "GroupInSpecT_Remove"
+local INSPECT_READY_EVENT = "GroupInSpecT_InspectReady"
+local QUEUE_EVENT = "GroupInSpecT_QueueChanged"
+
+local COMMS_PREFIX = "LGIST11"
+local COMMS_FMT = "1"
+local COMMS_DELIM = "\a"
+
+local INSPECT_DELAY = 1.5
+local INSPECT_TIMEOUT = 10 -- If we get no notification within 10s, give up on unit
+
+local MAX_ATTEMPTS = 2
+
+--[===[@debug@
+lib.debug = false
+local function debug (...)
+ if lib.debug then -- allow programmatic override of debug output by client addons
+ print (...)
+ end
+end
+--@end-debug@]===]
+
+function lib.events:OnUsed(target, eventname)
+ if eventname == INSPECT_READY_EVENT then
+ target.inspect_ready_used = true
+ end
+end
+
+function lib.events:OnUnused(target, eventname)
+ if eventname == INSPECT_READY_EVENT then
+ target.inspect_ready_used = nil
+ end
+end
+
+-- Frame for events
+local frame = _G[MAJOR .. "_Frame"] or CreateFrame ("Frame", MAJOR .. "_Frame")
+lib.frame = frame
+frame:Hide()
+frame:UnregisterAllEvents ()
+frame:RegisterEvent ("PLAYER_LOGIN")
+frame:RegisterEvent ("PLAYER_LOGOUT")
+if not frame.OnEvent then
+ frame.OnEvent = function(this, event, ...)
+ local eventhandler = lib[event]
+ return eventhandler and eventhandler (lib, ...)
+ end
+ frame:SetScript ("OnEvent", frame.OnEvent)
+end
+
+
+-- Hide our run-state in an easy-to-dump object
+lib.state = {
+ mainq = {}, staleq = {}, -- inspect queues
+ t = 0,
+ last_inspect = 0,
+ current_guid = nil,
+ throttle = 0,
+ tt = 0,
+ debounce_send_update = 0,
+}
+lib.cache = {}
+lib.static_cache = {}
+
+
+-- Note: if we cache NotifyInspect, we have to hook before we cache it!
+if not lib.hooked then
+ hooksecurefunc("NotifyInspect", function (...) return lib:NotifyInspect (...) end)
+ lib.hooked = true
+end
+function lib:NotifyInspect(unit)
+ self.state.last_inspect = GetTime()
+end
+
+
+-- Get local handles on the key API functions
+local CanInspect = _G.CanInspect
+local ClearInspectPlayer = _G.ClearInspectPlayer
+local GetClassInfo = _G.GetClassInfo
+local GetNumSubgroupMembers = _G.GetNumSubgroupMembers
+local GetNumSpecializationsForClassID = _G.GetNumSpecializationsForClassID
+local GetPlayerInfoByGUID = _G.GetPlayerInfoByGUID
+local GetInspectSpecialization = _G.GetInspectSpecialization
+local GetSpecialization = _G.GetSpecialization
+local GetSpecializationInfo = _G.GetSpecializationInfo
+local GetSpecializationInfoForClassID = _G.GetSpecializationInfoForClassID
+local GetSpecializationRoleByID = _G.GetSpecializationRoleByID
+local GetSpellInfo = _G.GetSpellInfo
+local GetTalentInfo = _G.GetTalentInfo
+local IsInRaid = _G.IsInRaid
+--local NotifyInspect = _G.NotifyInspect -- Don't cache, as to avoid missing future hooks
+local GetNumClasses = _G.GetNumClasses
+local UnitExists = _G.UnitExists
+local UnitGUID = _G.UnitGUID
+local UnitInParty = _G.UnitInParty
+local UnitInRaid = _G.UnitInRaid
+local UnitIsConnected = _G.UnitIsConnected
+local UnitIsPlayer = _G.UnitIsPlayer
+local UnitIsUnit = _G.UnitIsUnit
+local UnitName = _G.UnitName
+local SendAddonMessage = C_ChatInfo and C_ChatInfo.SendAddonMessage or SendAddonMessage -- XXX 8.0 compat
+
+
+local global_spec_id_roles_detailed = {
+ -- Death Knight
+ [250] = "tank", -- Blood
+ [251] = "melee", -- Frost
+ [252] = "melee", -- Unholy
+ -- Demon Hunter
+ [577] = "melee", -- Havoc
+ [581] = "tank", -- Vengeance
+ -- Druid
+ [102] = "ranged", -- Balance
+ [103] = "melee", -- Feral
+ [104] = "tank", -- Guardian
+ [105] = "healer", -- Restoration
+ -- Hunter
+ [253] = "ranged", -- Beast Mastery
+ [254] = "ranged", -- Marksmanship
+ [255] = "melee", -- Survival
+ -- Mage
+ [62] = "ranged", -- Arcane
+ [63] = "ranged", -- Fire
+ [64] = "ranged", -- Frost
+ -- Monk
+ [268] = "tank", -- Brewmaster
+ [269] = "melee", -- Windwalker
+ [270] = "healer", -- Mistweaver
+ -- Paladin
+ [65] = "healer", -- Holy
+ [66] = "tank", -- Protection
+ [70] = "melee", -- Retribution
+ -- Priest
+ [256] = "healer", -- Discipline
+ [257] = "healer", -- Holy
+ [258] = "ranged", -- Shadow
+ -- Rogue
+ [259] = "melee", -- Assassination
+ [260] = "melee", -- Combat
+ [261] = "melee", -- Subtlety
+ -- Shaman
+ [262] = "ranged", -- Elemental
+ [263] = "melee", -- Enhancement
+ [264] = "healer", -- Restoration
+ -- Warlock
+ [265] = "ranged", -- Affliction
+ [266] = "ranged", -- Demonology
+ [267] = "ranged", -- Destruction
+ -- Warrior
+ [71] = "melee", -- Arms
+ [72] = "melee", -- Fury
+ [73] = "tank", -- Protection
+}
+
+local class_fixed_roles = {
+ HUNTER = "DAMAGER",
+ MAGE = "DAMAGER",
+ ROGUE = "DAMAGER",
+ WARLOCK = "DAMAGER",
+}
+
+local class_fixed_roles_detailed = {
+ MAGE = "ranged",
+ ROGUE = "melee",
+ WARLOCK = "ranged",
+}
+
+-- Inspects only work after being fully logged in, so track that
+function lib:PLAYER_LOGIN ()
+ self.state.logged_in = true
+
+ self:CacheGameData ()
+
+ frame:RegisterEvent ("INSPECT_READY")
+ frame:RegisterEvent ("GROUP_ROSTER_UPDATE")
+ frame:RegisterEvent ("PLAYER_ENTERING_WORLD")
+ frame:RegisterEvent ("UNIT_LEVEL")
+ frame:RegisterEvent ("PLAYER_TALENT_UPDATE")
+ frame:RegisterEvent ("PLAYER_SPECIALIZATION_CHANGED")
+ frame:RegisterEvent ("UNIT_SPELLCAST_SUCCEEDED")
+ frame:RegisterEvent ("UNIT_NAME_UPDATE")
+ frame:RegisterEvent ("UNIT_AURA")
+ frame:RegisterEvent ("CHAT_MSG_ADDON")
+ if C_ChatInfo then -- XXX 8.0 compat
+ C_ChatInfo.RegisterAddonMessagePrefix (COMMS_PREFIX)
+ else
+ RegisterAddonMessagePrefix (COMMS_PREFIX)
+ end
+
+ local guid = UnitGUID ("player")
+ local info = self:BuildInfo ("player")
+ self.events:Fire (UPDATE_EVENT, guid, "player", info)
+end
+
+function lib:PLAYER_LOGOUT ()
+ self.state.logged_in = false
+end
+
+
+-- Simple timer
+do
+ lib.state.t = 0
+ if not frame.OnUpdate then -- ticket #4 if the OnUpdate code every changes we should stop borrowing the existing handler
+ frame.OnUpdate = function(this, elapsed)
+ lib.state.t = lib.state.t + elapsed
+ lib.state.tt = lib.state.tt + elapsed
+ if lib.state.t > INSPECT_DELAY then
+ lib:ProcessQueues ()
+ lib.state.t = 0
+ end
+ -- Unthrottle, essentially allowing 1 msg every 3 seconds, but with substantial burst capacity
+ if lib.state.tt > 3 and lib.state.throttle > 0 then
+ lib.state.throttle = lib.state.throttle - 1
+ lib.state.tt = 0
+ end
+ if lib.state.debounce_send_update > 0 then
+ local debounce = lib.state.debounce_send_update - elapsed
+ lib.state.debounce_send_update = debounce
+ if debounce <= 0 then lib:SendLatestSpecData () end
+ end
+ end
+ frame:SetScript("OnUpdate", frame.OnUpdate) -- this is good regardless of the handler check above because otherwise a new anonymous function is created every time the OnUpdate code runs
+ end
+end
+
+
+-- Internal library functions
+
+-- Caches to deal with API shortcomings as well as performance
+lib.static_cache.global_specs = {} -- [gspec] -> { .idx, .name_localized, .description, .icon, .background, .role }
+lib.static_cache.class_to_class_id = {} -- [CLASS] -> class_id
+
+-- The talents cache can no longer be pre-fetched on login, but is now constructed class-by-class as we inspect people.
+-- This probably means we want to only ever access it through the GetCachedTalentInfo() helper function below.
+lib.static_cache.talents = {} -- [talent_id] -> { .spell_id, .talent_id, .name_localized, .icon, .tier, .column }
+
+-- Dridzt: I'd love another way but none of the GetTalent* functions return spellID, GetTalentLink() and parsing the link gives talentID that's not related to spellID as well
+-- A quick tooltip scan is cheap though so elegance aside this is a good workaround considering this only runs once
+local tip = CreateFrame ("GameTooltip", MAJOR.."ScanTip", nil, "GameTooltipTemplate")
+tip:SetOwner (UIParent, "ANCHOR_NONE")
+
+function lib:GetCachedTalentInfo (class_id, tier, col, group, is_inspect, unit)
+ local talents = self.static_cache.talents
+ local talent_id, name, icon, sel, avail = GetTalentInfo (tier, col, group, is_inspect, unit)
+ if not talent_id or not class_id then
+ --[===[@debug@
+ debug ("GetCachedTalentInfo("..tostring(class_id)..","..tier..","..col..","..group..","..tostring(is_inspect)..","..tostring(unit)..") returned nil") --@end-debug@]===]
+ return {}
+ end
+ talents[class_id] = talents[class_id] or {}
+ local class_talents = talents[class_id]
+ if not class_talents[talent_id] then
+ tip:ClearLines ()
+ tip:SetTalent (talent_id, is_inspect, group)
+ local _, _,spell_id = tip:GetSpell ()
+ class_talents[talent_id] = {
+ spell_id = spell_id,
+ talent_id = talent_id,
+ name_localized = name,
+ icon = icon,
+ tier = tier,
+ column = col,
+ }
+ end
+ return class_talents[talent_id], sel
+end
+
+
+function lib:CacheGameData ()
+ local gspecs = self.static_cache.global_specs
+ gspecs[0] = {} -- Handle no-specialization case
+ for class_id = 1, GetNumClasses () do
+ for idx = 1, GetNumSpecializationsForClassID (class_id) do
+ local gspec_id, name, description, icon, background = GetSpecializationInfoForClassID (class_id, idx)
+ gspecs[gspec_id] = {}
+ local gspec = gspecs[gspec_id]
+ gspec.idx = idx
+ gspec.name_localized = name
+ gspec.description = description
+ gspec.icon = icon
+ gspec.background = background
+ gspec.role = GetSpecializationRoleByID (gspec_id)
+ end
+
+ local _, class = GetClassInfo (class_id)
+ self.static_cache.class_to_class_id[class] = class_id
+ end
+end
+
+
+function lib:GuidToUnit (guid)
+ local info = self.cache[guid]
+ if info and info.lku and UnitGUID (info.lku) == guid then return info.lku end
+
+ for i,unit in ipairs (self:GroupUnits ()) do
+ if UnitExists (unit) and UnitGUID (unit) == guid then
+ if info then info.lku = unit end
+ return unit
+ end
+ end
+end
+
+
+function lib:Query (unit)
+ if not UnitIsPlayer (unit) then return end -- NPC
+
+ if UnitIsUnit (unit, "player") then
+ self.events:Fire (UPDATE_EVENT, UnitGUID("player"), "player", self:BuildInfo ("player"))
+ return
+ end
+
+ local mainq, staleq = self.state.mainq, self.state.staleq
+
+ local guid = UnitGUID (unit)
+ if not mainq[guid] then
+ mainq[guid] = 1
+ staleq[guid] = nil
+ self.frame:Show () -- Start timer if not already running
+ self.events:Fire (QUEUE_EVENT)
+ end
+end
+
+
+function lib:Refresh (unit)
+ local guid = UnitGUID (unit)
+ if not guid then return end
+ --[===[@debug@
+ debug ("Refreshing "..unit) --@end-debug@]===]
+ if not self.state.mainq[guid] then
+ self.state.staleq[guid] = 1
+ self.frame:Show ()
+ self.events:Fire (QUEUE_EVENT)
+ end
+end
+
+
+function lib:ProcessQueues ()
+ if not self.state.logged_in then return end
+ if InCombatLockdown () then return end -- Never inspect while in combat
+ if UnitIsDead ("player") then return end -- You can't inspect while dead, so don't even try
+ if InspectFrame and InspectFrame:IsShown () then return end -- Don't mess with the UI's inspections
+
+ local mainq = self.state.mainq
+ local staleq = self.state.staleq
+
+ if not next (mainq) and next(staleq) then
+ --[===[@debug@
+ debug ("Main queue empty, swapping main and stale queues") --@end-debug@]===]
+ self.state.mainq, self.state.staleq = self.state.staleq, self.state.mainq
+ mainq, staleq = staleq, mainq
+ end
+
+ if (self.state.last_inspect + INSPECT_TIMEOUT) < GetTime () then
+ -- If there was an inspect going, it's timed out, so either retry or move it to stale queue
+ local guid = self.state.current_guid
+ if guid then
+ --[===[@debug@
+ debug ("Inspect timed out for "..guid) --@end-debug@]===]
+
+ local count = mainq and mainq[guid] or (MAX_ATTEMPTS + 1)
+ if not self:GuidToUnit (guid) then
+ --[===[@debug@
+ debug ("No longer applicable, removing from queues") --@end-debug@]===]
+ mainq[guid], staleq[guid] = nil, nil
+ elseif count > MAX_ATTEMPTS then
+ --[===[@debug@
+ debug ("Excessive retries, moving to stale queue") --@end-debug@]===]
+ mainq[guid], staleq[guid] = nil, 1
+ else
+ mainq[guid] = count + 1
+ end
+ self.state.current_guid = nil
+ end
+ end
+
+ if self.state.current_guid then return end -- Still waiting on our inspect data
+
+ for guid,count in pairs (mainq) do
+ local unit = self:GuidToUnit (guid)
+ if not unit then
+ --[===[@debug@
+ debug ("No longer applicable, removing from queues") --@end-debug@]===]
+ mainq[guid], staleq[guid] = nil, nil
+ elseif not CanInspect (unit) or not UnitIsConnected (unit) then
+ --[===[@debug@
+ debug ("Cannot inspect "..unit..", aka "..(UnitName(unit) or "nil")..", moving to stale queue") --@end-debug@]===]
+ mainq[guid], staleq[guid] = nil, 1
+ else
+ --[===[@debug@
+ debug ("Inspecting "..unit..", aka "..(UnitName(unit) or "nil")) --@end-debug@]===]
+ mainq[guid] = count + 1
+ self.state.current_guid = guid
+ NotifyInspect (unit)
+ break
+ end
+ end
+
+ if not next (mainq) and not next (staleq) and self.state.throttle == 0 and self.state.debounce_send_update <= 0 then
+ frame:Hide() -- Cancel timer, nothing queued and no unthrottling to be done
+ end
+ self.events:Fire (QUEUE_EVENT)
+end
+
+
+function lib:UpdatePlayerInfo (guid, unit, info)
+ info.class_localized, info.class, info.race_localized, info.race, info.gender, info.name, info.realm = GetPlayerInfoByGUID (guid)
+ local class = info.class
+ if info.realm and info.realm == "" then info.realm = nil end
+ info.class_id = class and self.static_cache.class_to_class_id[class]
+ if not info.spec_role then info.spec_role = class and class_fixed_roles[class] end
+ if not info.spec_role_detailed then info.spec_role_detailed = class and class_fixed_roles_detailed[class] end
+ info.lku = unit
+end
+
+
+function lib:BuildInfo (unit)
+ local guid = UnitGUID (unit)
+ if not guid then return end
+
+ local cache = self.cache
+ local info = cache[guid] or {}
+ cache[guid] = info
+ info.guid = guid
+
+ self:UpdatePlayerInfo (guid, unit, info)
+ -- On a cold login, GetPlayerInfoByGUID() doesn't seem to be usable, so mark as stale
+ local class = info.class
+ if not class and not self.state.mainq[guid] then
+ self.state.staleq[guid] = 1
+ self.frame:Show ()
+ self.events:Fire (QUEUE_EVENT)
+ end
+
+ local is_inspect = not UnitIsUnit (unit, "player")
+ local spec = GetSpecialization ()
+ info.global_spec_id = is_inspect and GetInspectSpecialization (unit) or spec and GetSpecializationInfo (spec)
+
+ local gspecs = self.static_cache.global_specs
+ if not info.global_spec_id or not gspecs[info.global_spec_id] then -- not a valid spec_id
+ info.global_spec_id = nil
+ else
+ local gspec_id = info.global_spec_id
+ local spec_info = gspecs[gspec_id]
+ info.spec_index = spec_info.idx
+ info.spec_name_localized = spec_info.name_localized
+ info.spec_description = spec_info.description
+ info.spec_icon = spec_info.icon
+ info.spec_background = spec_info.background
+ info.spec_role = spec_info.role
+ info.spec_role_detailed = global_spec_id_roles_detailed[gspec_id]
+ end
+
+ if not info.spec_role then info.spec_role = class and class_fixed_roles[class] end
+ if not info.spec_role_detailed then info.spec_role_detailed = class and class_fixed_roles_detailed[class] end
+
+ info.talents = info.talents or {}
+
+ -- If GetPlayerInfoByGUID didn't return the class, we can't do talents yet
+ if info.class_id then
+ info.spec_group = GetActiveSpecGroup (is_inspect)
+ wipe (info.talents) -- Due to spec-specific talents we might leave things in on a spec-change otherwise
+ for tier = 1, MAX_TALENT_TIERS do
+ for col = 1, NUM_TALENT_COLUMNS do
+ local talent, sel = self:GetCachedTalentInfo (info.class_id, tier, col, info.spec_group, is_inspect, unit)
+ if talent and talent.talent_id and sel then
+ info.talents[talent.talent_id] = talent
+ end
+ end
+ end
+ end
+
+ info.glyphs = wipe (info.glyphs or {}) -- kept for addons that still refer to this
+
+ if is_inspect and not UnitIsVisible (unit) and UnitIsConnected (unit) then info.not_visible = true end
+
+ return info
+end
+
+
+function lib:INSPECT_READY (guid)
+ local unit = self:GuidToUnit (guid)
+ local finalize = false
+ if unit then
+ if guid == self.state.current_guid then
+ self.state.current_guid = nil -- Got what we asked for
+ finalize = true
+ --[===[@debug@
+ debug ("Got inspection data for requested guid "..guid) --@end-debug@]===]
+ end
+
+ local mainq, staleq = self.state.mainq, self.state.staleq
+ mainq[guid], staleq[guid] = nil, nil
+
+ local gspec_id = GetInspectSpecialization (unit)
+ if not self.static_cache.global_specs[gspec_id] then -- Bah, got garbage, flag as stale and try again
+ staleq[guid] = 1
+ return
+ end
+
+ self.events:Fire (UPDATE_EVENT, guid, unit, self:BuildInfo (unit))
+ self.events:Fire (INSPECT_READY_EVENT, guid, unit)
+ end
+ if finalize then
+ ClearInspectPlayer ()
+ end
+ self.events:Fire (QUEUE_EVENT)
+end
+
+
+function lib:PLAYER_ENTERING_WORLD ()
+ if self.commScope == "INSTANCE_CHAT" then
+ -- Handle moving directly from one LFG to another
+ self.commScope = nil
+ self:UpdateCommScope ()
+ end
+end
+
+
+-- Group handling parts
+
+local members = {}
+function lib:GROUP_ROSTER_UPDATE ()
+ local group = self.cache
+ local units = self:GroupUnits ()
+ -- Find new members
+ for i,unit in ipairs (self:GroupUnits ()) do
+ local guid = UnitGUID (unit)
+ if guid then
+ members[guid] = true
+ if not group[guid] then
+ self:Query (unit)
+ -- Update with what we have so far (guid, unit, name/class/race?)
+ self.events:Fire (UPDATE_EVENT, guid, unit, self:BuildInfo (unit))
+ end
+ end
+ end
+ -- Find removed members
+ for guid in pairs (group) do
+ if not members[guid] then
+ group[guid] = nil
+ self.events:Fire (REMOVE_EVENT, guid, nil)
+ end
+ end
+ wipe (members)
+ self:UpdateCommScope ()
+end
+
+
+function lib:DoPlayerUpdate ()
+ self:Query ("player")
+ self.state.debounce_send_update = 2.5 -- Hold off 2.5sec before sending update
+ self.frame:Show ()
+end
+
+
+function lib:SendLatestSpecData ()
+ local scope = self.commScope
+ if not scope then return end
+
+ local guid = UnitGUID ("player")
+ local info = self.cache[guid]
+ if not info then return end
+
+ -- fmt, guid, global_spec_id, talent1 -> MAX_TALENT_TIERS
+ -- sequentially, allow no gaps for missing talents we decode by index on the receiving end.
+ local datastr = COMMS_FMT..COMMS_DELIM..guid..COMMS_DELIM..(info.global_spec_id or 0)
+ local talentCount = 1
+ for k in pairs(info.talents) do
+ datastr = datastr..COMMS_DELIM..k
+ talentCount = talentCount + 1
+ end
+ for i=talentCount,MAX_TALENT_TIERS do
+ datastr = datastr..COMMS_DELIM..0
+ end
+
+ --[===[@debug@
+ debug ("Sending LGIST update to "..scope) --@end-debug@]===]
+ SendAddonMessage(COMMS_PREFIX, datastr, scope)
+end
+
+
+function lib:UpdateCommScope ()
+ local scope = (IsInGroup (LE_PARTY_CATEGORY_INSTANCE) and "INSTANCE_CHAT") or (IsInRaid () and "RAID") or (IsInGroup (LE_PARTY_CATEGORY_HOME) and "PARTY")
+ if self.commScope ~= scope then
+ self.commScope = scope
+ self:DoPlayerUpdate ()
+ end
+end
+
+
+-- Indicies for various parts of the split data msg
+local msg_idx = {}
+msg_idx.fmt = 1
+msg_idx.guid = msg_idx.fmt + 1
+msg_idx.global_spec_id = msg_idx.guid + 1
+msg_idx.talents = msg_idx.global_spec_id + 1
+msg_idx.end_talents = msg_idx.talents + MAX_TALENT_TIERS - 1
+
+function lib:CHAT_MSG_ADDON (prefix, datastr, scope, sender)
+ if prefix ~= COMMS_PREFIX or scope ~= self.commScope then return end
+ --[===[@debug@
+ debug ("Incoming LGIST update from "..(scope or "nil").."/"..(sender or "nil")..": "..(datastr:gsub(COMMS_DELIM,";") or "nil")) --@end-debug@]===]
+
+ local data = { strsplit (COMMS_DELIM,datastr) }
+ local fmt = data[msg_idx.fmt]
+ if fmt ~= COMMS_FMT then return end -- Unknown format, ignore
+
+ local guid = data[msg_idx.guid]
+
+ local senderguid = UnitGUID(sender)
+ if senderguid and senderguid ~= guid then return end
+
+ local info = guid and self.cache[guid]
+ if not info then return end -- Never allow random message to create new group member entries!
+
+ local unit = self:GuidToUnit (guid)
+ if not unit then return end
+ if UnitIsUnit (unit, "player") then return end -- we're already up-to-date, comment out for solo debugging
+
+ self.state.throttle = self.state.throttle + 1
+ self.frame:Show () -- Ensure we're unthrottling
+ if self.state.throttle > 40 then return end -- If we ever hit this, someone's being "funny"
+
+ info.class_localized, info.class, info.race_localized, info.race, info.gender, info.name, info.realm = GetPlayerInfoByGUID (guid)
+ if info.realm and info.realm == "" then info.realm = nil end
+ info.class_id = self.static_cache.class_to_class_id[info.class]
+
+ local gspecs = self.static_cache.global_specs
+
+ local gspec_id = data[msg_idx.global_spec_id] and tonumber (data[msg_idx.global_spec_id])
+ if not gspec_id or not gspecs[gspec_id] then return end -- Malformed message, avoid throwing errors by using this nil
+
+ info.global_spec_id = gspec_id
+ info.spec_index = gspecs[gspec_id].idx
+ info.spec_name_localized = gspecs[gspec_id].name_localized
+ info.spec_description = gspecs[gspec_id].description
+ info.spec_icon = gspecs[gspec_id].icon
+ info.spec_background = gspecs[gspec_id].background
+ info.spec_role = gspecs[gspec_id].role
+ info.spec_role_detailed = global_spec_id_roles_detailed[gspec_id]
+
+ local need_inspect = nil
+ info.talents = wipe (info.talents or {})
+ local talents = self.static_cache.talents[info.class_id]
+ if talents then -- The group entry is created before we have inspect-data, so may not have cached talents yet
+ for i = msg_idx.talents, msg_idx.end_talents do
+ local talent_id = tonumber (data[i])
+ if talent_id and talent_id > 0 then
+ if talents[talent_id] then
+ info.talents[talent_id] = talents[talent_id]
+ else
+ -- While we had some talents for this class, we apparently didn't have all for this particular spec, so mark for inspect
+ need_inspect = 1
+ end
+ end
+ end
+ else
+ -- Talents weren't pre-cached, so mark for inspect
+ need_inspect = 1
+ end
+
+ info.glyphs = wipe (info.glyphs or {}) -- kept for addons that still refer to this
+
+ local mainq, staleq = self.state.mainq, self.state.staleq
+ local want_inspect = not need_inspect and self.inspect_ready_used and (mainq[guid] or staleq[guid]) and 1 or nil
+ mainq[guid], staleq[guid] = need_inspect, want_inspect
+ if need_inspect or want_inspect then self.frame:Show () end
+
+ --[===[@debug@
+ debug ("Firing LGIST update event for unit "..unit..", GUID "..guid) --@end-debug@]===]
+ self.events:Fire (UPDATE_EVENT, guid, unit, info)
+ self.events:Fire (QUEUE_EVENT)
+end
+
+
+function lib:UNIT_LEVEL (unit)
+ if UnitInRaid (unit) or UnitInParty (unit) then
+ self:Refresh (unit)
+ end
+ if UnitIsUnit (unit, "player") then
+ self:DoPlayerUpdate ()
+ end
+end
+
+
+function lib:PLAYER_TALENT_UPDATE ()
+ self:DoPlayerUpdate ()
+end
+
+
+function lib:PLAYER_SPECIALIZATION_CHANGED (unit)
+-- This event seems to fire a lot, and for no particular reason *sigh*
+-- if UnitInRaid (unit) or UnitInParty (unit) then
+-- self:Refresh (unit)
+-- end
+ if unit and UnitIsUnit (unit, "player") then
+ self:DoPlayerUpdate ()
+ end
+end
+
+
+function lib:UNIT_NAME_UPDATE (unit)
+ local group = self.cache
+ local guid = UnitGUID (unit)
+ local info = guid and group[guid]
+ if info then
+ self:UpdatePlayerInfo (guid, unit, info)
+ if info.name ~= UNKNOWN then
+ self.events:Fire (UPDATE_EVENT, guid, unit, info)
+ end
+ end
+end
+
+
+-- Always get a UNIT_AURA when a unit's UnitIsVisible() changes
+function lib:UNIT_AURA (unit)
+ local group = self.cache
+ local guid = UnitGUID (unit)
+ local info = guid and group[guid]
+ if info then
+ if not UnitIsUnit (unit, "player") then
+ if UnitIsVisible (unit) then
+ if info.not_visible then
+ info.not_visible = nil
+ --[===[@debug@
+ debug (unit..", aka "..(UnitName(unit) or "nil")..", is now visible") --@end-debug@]===]
+ if not self.state.mainq[guid] then
+ self.state.staleq[guid] = 1
+ self.frame:Show ()
+ self.events:Fire (QUEUE_EVENT)
+ end
+ end
+ elseif UnitIsConnected (unit) then
+ --[===[@debug@
+ if not info.not_visible then
+ debug (unit..", aka "..(UnitName(unit) or "nil")..", is no longer visible")
+ end
+ --@end-debug@]===]
+ info.not_visible = true
+ end
+ end
+ end
+end
+
+
+function lib:UNIT_SPELLCAST_SUCCEEDED (unit, spellname, rank, lineid, spellid)
+ if spellid == 200749 then
+ self:Query (unit) -- Definitely changed, so high prio refresh
+ end
+end
+
+
+-- External library functions
+
+function lib:QueuedInspections ()
+ local q = {}
+ for guid in pairs (self.state.mainq) do
+ table.insert (q, guid)
+ end
+ return q
+end
+
+
+function lib:StaleInspections ()
+ local q = {}
+ for guid in pairs (self.state.staleq) do
+ table.insert (q, guid)
+ end
+ return q
+end
+
+
+function lib:IsInspectQueued (guid)
+ return guid and ((self.state.mainq[guid] or self.state.staleq[guid]) and true)
+end
+
+
+function lib:GetCachedInfo (guid)
+ local group = self.cache
+ return guid and group[guid]
+end
+
+
+function lib:Rescan (guid)
+ local mainq, staleq = self.state.mainq, self.state.staleq
+ if guid then
+ local unit = self:GuidToUnit (guid)
+ if unit then
+ if UnitIsUnit (unit, "player") then
+ self.events:Fire (UPDATE_EVENT, guid, "player", self:BuildInfo ("player"))
+ elseif not mainq[guid] then
+ staleq[guid] = 1
+ end
+ end
+ else
+ for i,unit in ipairs (self:GroupUnits ()) do
+ if UnitExists (unit) then
+ if UnitIsUnit (unit, "player") then
+ self.events:Fire (UPDATE_EVENT, UnitGUID("player"), "player", self:BuildInfo ("player"))
+ else
+ local guid = UnitGUID (unit)
+ if guid and not mainq[guid] then
+ staleq[guid] = 1
+ end
+ end
+ end
+ end
+ end
+ self.frame:Show () -- Start timer if not already running
+
+ -- Evict any stale entries
+ self:GROUP_ROSTER_UPDATE ()
+ self.events:Fire (QUEUE_EVENT)
+end
+
+
+local unitstrings = {
+ raid = { "player" }, -- This seems to be needed under certain circumstances. Odd.
+ party = { "player" }, -- Player not part of partyN
+ player = { "player" }
+}
+for i = 1,40 do table.insert (unitstrings.raid, "raid"..i) end
+for i = 1,4 do table.insert (unitstrings.party, "party"..i) end
+
+
+-- Returns an array with the set of unit ids for the current group
+function lib:GroupUnits ()
+ local units
+ if IsInRaid () then
+ units = unitstrings.raid
+ elseif GetNumSubgroupMembers () > 0 then
+ units = unitstrings.party
+ else
+ units = unitstrings.player
+ end
+ return units
+end
+
+
+-- If demand-loaded, we need to synthesize a login event
+if IsLoggedIn () then lib:PLAYER_LOGIN () end
diff --git a/Skada/Libs/LibCompat-1.0/lib.xml b/Skada/Libs/LibCompat-1.0/lib.xml
new file mode 100644
index 0000000..33b0229
--- /dev/null
+++ b/Skada/Libs/LibCompat-1.0/lib.xml
@@ -0,0 +1,5 @@
+
+
+
+
\ No newline at end of file
diff --git a/Skada/Libs/LibCompress/LibCompress.lua b/Skada/Libs/LibCompress/LibCompress.lua
new file mode 100644
index 0000000..976c89f
--- /dev/null
+++ b/Skada/Libs/LibCompress/LibCompress.lua
@@ -0,0 +1,1255 @@
+----------------------------------------------------------------------------------
+--
+-- LibCompress.lua
+--
+-- Authors: jjsheets and Galmok of European Stormrage (Horde)
+-- Email : sheets.jeff@gmail.com and galmok@gmail.com
+-- Licence: GPL version 2 (General Public License)
+-- Revision: $Revision: 83 $
+-- Date: $Date: 2018-07-03 14:33:48 +0000 (Tue, 03 Jul 2018) $
+----------------------------------------------------------------------------------
+
+
+local LibCompress = LibStub:NewLibrary("LibCompress", 90000 + tonumber(("$Revision: 83 $"):match("%d+")))
+
+if not LibCompress then return end
+
+-- list of codecs in this file:
+-- \000 - Never used
+-- \001 - Uncompressed
+-- \002 - LZW
+-- \003 - Huffman
+
+
+-- local is faster than global
+local CreateFrame = CreateFrame
+local type = type
+local tostring = tostring
+local select = select
+local next = next
+local loadstring = loadstring
+local setmetatable = setmetatable
+local rawset = rawset
+local assert = assert
+local table_insert = table.insert
+local table_remove = table.remove
+local table_concat = table.concat
+local string_char = string.char
+local string_byte = string.byte
+local string_len = string.len
+local string_sub = string.sub
+local unpack = unpack
+local pairs = pairs
+local math_modf = math.modf
+local bit_band = bit.band
+local bit_bor = bit.bor
+local bit_bxor = bit.bxor
+local bit_bnot = bit.bnot
+local bit_lshift = bit.lshift
+local bit_rshift = bit.rshift
+
+--------------------------------------------------------------------------------
+-- Cleanup
+
+local tables = {} -- tables that may be cleaned have to be kept here
+local tables_to_clean = {} -- list of tables by name (string) that may be reset to {} after a timeout
+
+-- tables that may be erased
+local function cleanup()
+ for k,v in pairs(tables_to_clean) do
+ tables[k] = {}
+ tables_to_clean[k] = nil
+ end
+end
+
+local timeout = -1
+local function onUpdate(frame, elapsed)
+ frame:Hide()
+ timeout = timeout - elapsed
+ if timeout <= 0 then
+ cleanup()
+ end
+end
+
+LibCompress.frame = LibCompress.frame or CreateFrame("frame", nil, UIParent) -- reuse the old frame
+LibCompress.frame:SetScript("OnUpdate", onUpdate)
+LibCompress.frame:Hide()
+
+local function setCleanupTables(...)
+ timeout = 15 -- empty tables after 15 seconds
+ if not LibCompress.frame:IsShown() then
+ LibCompress.frame:Show()
+ end
+ for i = 1, select("#",...) do
+ tables_to_clean[(select(i, ...))] = true
+ end
+end
+
+----------------------------------------------------------------------
+----------------------------------------------------------------------
+--
+-- compression algorithms
+
+--------------------------------------------------------------------------------
+-- LZW codec
+-- implemented by sheets.jeff@gmail.com
+
+-- encode is used to uniquely encode a number into a sequence of bytes that can be decoded using decode()
+-- the bytes returned by this do not contain "\000"
+local bytes = {}
+local function encode(x)
+ for k = 1, #bytes do
+ bytes[k] = nil
+ end
+
+ bytes[#bytes + 1] = x % 255
+ x=math.floor(x/255)
+
+ while x > 0 do
+ bytes[#bytes + 1] = x % 255
+ x=math.floor(x/255)
+ end
+ if #bytes == 1 and bytes[1] > 0 and bytes[1] < 250 then
+ return string_char(bytes[1])
+ else
+ for i = 1, #bytes do
+ bytes[i] = bytes[i] + 1
+ end
+ return string_char(256 - #bytes, unpack(bytes))
+ end
+end
+
+--decode converts a unique character sequence into its equivalent number, from ss, beginning at the ith char.
+-- returns the decoded number and the count of characters used in the decode process.
+local function decode(ss, i)
+ i = i or 1
+ local a = string_byte(ss, i, i)
+ if a > 249 then
+ local r = 0
+ a = 256 - a
+ for n = i + a, i + 1, -1 do
+ r = r * 255 + string_byte(ss, n, n) - 1
+ end
+ return r, a + 1
+ else
+ return a, 1
+ end
+end
+
+-- Compresses the given uncompressed string.
+-- Unless the uncompressed string starts with "\002", this is guaranteed to return a string equal to or smaller than
+-- the passed string.
+-- the returned string will only contain "\000" characters in rare circumstances, and will contain none if the
+-- source string has none.
+local dict = {}
+function LibCompress:CompressLZW(uncompressed)
+ if type(uncompressed) == "string" then
+ local dict_size = 256
+ for k in pairs(dict) do
+ dict[k] = nil
+ end
+
+ local result = {"\002"}
+ local w = ''
+ local ressize = 1
+
+ for i = 0, 255 do
+ dict[string_char(i)] = i
+ end
+
+ for i = 1, #uncompressed do
+ local c = uncompressed:sub(i, i)
+ local wc = w..c
+ if dict[wc] then
+ w = wc
+ else
+ dict[wc] = dict_size
+ dict_size = dict_size + 1
+ local r = encode(dict[w])
+ ressize = ressize + #r
+ result[#result + 1] = r
+ w = c
+ end
+ end
+
+ if w then
+ local r = encode(dict[w])
+ ressize = ressize + #r
+ result[#result + 1] = r
+ end
+
+ if (#uncompressed + 1) > ressize then
+ return table_concat(result)
+ else
+ return string_char(1)..uncompressed
+ end
+ else
+ return nil, "Can only compress strings"
+ end
+end
+
+-- if the passed string is a compressed string, this will decompress it and return the decompressed string.
+-- Otherwise it return an error message
+-- compressed strings are marked by beginning with "\002"
+function LibCompress:DecompressLZW(compressed)
+ if type(compressed) == "string" then
+ if compressed:sub(1, 1) ~= "\002" then
+ return nil, "Can only decompress LZW compressed data ("..tostring(compressed:sub(1, 1))..")"
+ end
+
+ compressed = compressed:sub(2)
+ local dict_size = 256
+
+ for k in pairs(dict) do
+ dict[k] = nil
+ end
+
+ for i = 0, 255 do
+ dict[i] = string_char(i)
+ end
+
+ local result = {}
+ local t = 1
+ local delta, k
+ k, delta = decode(compressed, t)
+ t = t + delta
+ result[#result + 1] = dict[k]
+
+ local w = dict[k]
+ local entry
+ while t <= #compressed do
+ k, delta = decode(compressed, t)
+ t = t + delta
+ entry = dict[k] or (w..w:sub(1, 1))
+ result[#result + 1] = entry
+ dict[dict_size] = w..entry:sub(1, 1)
+ dict_size = dict_size + 1
+ w = entry
+ end
+ return table_concat(result)
+ else
+ return nil, "Can only uncompress strings"
+ end
+end
+
+
+--------------------------------------------------------------------------------
+-- Huffman codec
+-- implemented by Galmok of European Stormrage (Horde), galmok@gmail.com
+
+local function addCode(tree, bcode, length)
+ if tree then
+ tree.bcode = bcode
+ tree.blength = length
+ if tree.c1 then
+ addCode(tree.c1, bit_bor(bcode, bit_lshift(1, length)), length + 1)
+ end
+ if tree.c2 then
+ addCode(tree.c2, bcode, length + 1)
+ end
+ end
+end
+
+local function escape_code(code, length)
+ local escaped_code = 0
+ local b
+ local l = 0
+ for i = length -1, 0, - 1 do
+ b = bit_band(code, bit_lshift(1, i)) == 0 and 0 or 1
+ escaped_code = bit_lshift(escaped_code, 1 + b) + b
+ l = l + b
+ end
+ if length + l > 32 then
+ return nil, "escape overflow ("..(length + l)..")"
+ end
+ return escaped_code, length + l
+end
+
+tables.Huffman_compressed = {}
+tables.Huffman_large_compressed = {}
+
+local compressed_size = 0
+local remainder
+local remainder_length
+local function addBits(tbl, code, length)
+ if remainder_length+length >= 32 then
+ -- we have at least 4 bytes to store; bulk it
+ remainder = remainder + bit_lshift(code, remainder_length) -- this overflows! Top part of code is lost (but we handle it below)
+ -- remainder now holds 4 full bytes to store. So lets do it.
+ compressed_size = compressed_size + 1
+ tbl[compressed_size] = string_char(bit_band(remainder, 255)) ..
+ string_char(bit_band(bit_rshift(remainder, 8), 255)) ..
+ string_char(bit_band(bit_rshift(remainder, 16), 255)) ..
+ string_char(bit_band(bit_rshift(remainder, 24), 255))
+ remainder = 0
+ code = bit_rshift(code, 32 - remainder_length)
+ length = remainder_length + length - 32
+ remainder_length = 0
+ end
+ if remainder_length+length >= 16 then
+ -- we have at least 2 bytes to store; bulk it
+ remainder = remainder + bit_lshift(code, remainder_length)
+ remainder_length = length + remainder_length
+ -- remainder now holds at least 2 full bytes to store. So lets do it.
+ compressed_size = compressed_size + 1
+ tbl[compressed_size] = string_char(bit_band(remainder, 255)) .. string_char(bit_band(bit_rshift(remainder, 8), 255))
+ remainder = bit_rshift(remainder, 16)
+ code = remainder
+ length = remainder_length - 16
+ remainder = 0
+ remainder_length = 0
+ end
+ remainder = remainder + bit_lshift(code, remainder_length)
+ remainder_length = length + remainder_length
+ if remainder_length >= 8 then
+ compressed_size = compressed_size + 1
+ tbl[compressed_size] = string_char(bit_band(remainder, 255))
+ remainder = bit_rshift(remainder, 8)
+ remainder_length = remainder_length -8
+ end
+end
+
+-- word size for this huffman algorithm is 8 bits (1 byte).
+-- this means the best compression is representing 1 byte with 1 bit, i.e. compress to 0.125 of original size.
+function LibCompress:CompressHuffman(uncompressed)
+ if type(uncompressed) ~= "string" then
+ return nil, "Can only compress strings"
+ end
+ if #uncompressed == 0 then
+ return "\001"
+ end
+
+ -- make histogram
+ local hist = {}
+ -- don't have to use all data to make the histogram
+ local uncompressed_size = string_len(uncompressed)
+ local c
+ for i = 1, uncompressed_size do
+ c = string_byte(uncompressed, i)
+ hist[c] = (hist[c] or 0) + 1
+ end
+
+ --Start with as many leaves as there are symbols.
+ local leafs = {}
+ local leaf
+ local symbols = {}
+ for symbol, weight in pairs(hist) do
+ leaf = { symbol=string_char(symbol), weight=weight }
+ symbols[symbol] = leaf
+ table_insert(leafs, leaf)
+ end
+
+ -- Enqueue all leaf nodes into the first queue (by probability in increasing order,
+ -- so that the least likely item is in the head of the queue).
+ sort(leafs, function(a, b)
+ if a.weight < b.weight then
+ return true
+ elseif a.weight > b.weight then
+ return false
+ else
+ return nil
+ end
+ end)
+
+ local nLeafs = #leafs
+
+ -- create tree
+ local huff = {}
+ --While there is more than one node in the queues:
+ local length, height, li, hi, leaf1, leaf2
+ local newNode
+ while (#leafs + #huff > 1) do
+ -- Dequeue the two nodes with the lowest weight.
+ -- Dequeue first
+ if not next(huff) then
+ li, leaf1 = next(leafs)
+ table_remove(leafs, li)
+ elseif not next(leafs) then
+ hi, leaf1 = next(huff)
+ table_remove(huff, hi)
+ else
+ li, length = next(leafs)
+ hi, height = next(huff)
+ if length.weight <= height.weight then
+ leaf1 = length
+ table_remove(leafs, li)
+ else
+ leaf1 = height
+ table_remove(huff, hi)
+ end
+ end
+
+ -- Dequeue second
+ if not next(huff) then
+ li, leaf2 = next(leafs)
+ table_remove(leafs, li)
+ elseif not next(leafs) then
+ hi, leaf2 = next(huff)
+ table_remove(huff, hi)
+ else
+ li, length = next(leafs)
+ hi, height = next(huff)
+ if length.weight <= height.weight then
+ leaf2 = length
+ table_remove(leafs, li)
+ else
+ leaf2 = height
+ table_remove(huff, hi)
+ end
+ end
+
+ --Create a new internal node, with the two just-removed nodes as children (either node can be either child) and the sum of their weights as the new weight.
+ newNode = {
+ c1 = leaf1,
+ c2 = leaf2,
+ weight = leaf1.weight + leaf2.weight
+ }
+ table_insert(huff,newNode)
+ end
+
+ if #leafs > 0 then
+ li, length = next(leafs)
+ table_insert(huff, length)
+ table_remove(leafs, li)
+ end
+ huff = huff[1]
+
+ -- assign codes to each symbol
+ -- c1 = "0", c2 = "1"
+ -- As a common convention, bit '0' represents following the left child and bit '1' represents following the right child.
+ -- c1 = left, c2 = right
+
+ addCode(huff, 0, 0)
+ if huff then
+ huff.bcode = 0
+ huff.blength = 1
+ end
+
+ -- READING
+ -- bitfield = 0
+ -- bitfield_len = 0
+ -- read byte1
+ -- bitfield = bitfield + bit_lshift(byte1, bitfield_len)
+ -- bitfield_len = bitfield_len + 8
+ -- read byte2
+ -- bitfield = bitfield + bit_lshift(byte2, bitfield_len)
+ -- bitfield_len = bitfield_len + 8
+ -- (use 5 bits)
+ -- word = bit_band( bitfield, bit_lshift(1,5)-1)
+ -- bitfield = bit_rshift( bitfield, 5)
+ -- bitfield_len = bitfield_len - 5
+ -- read byte3
+ -- bitfield = bitfield + bit_lshift(byte3, bitfield_len)
+ -- bitfield_len = bitfield_len + 8
+
+ -- WRITING
+ remainder = 0
+ remainder_length = 0
+
+ local compressed = tables.Huffman_compressed
+ --compressed_size = 0
+
+ -- first byte is version info. 0 = uncompressed, 1 = 8 - bit word huffman compressed
+ compressed[1] = "\003"
+
+ -- Header: byte 0 = #leafs, bytes 1-3 = size of uncompressed data
+ -- max 2^24 bytes
+ length = string_len(uncompressed)
+ compressed[2] = string_char(bit_band(nLeafs -1, 255)) -- number of leafs
+ compressed[3] = string_char(bit_band(length, 255)) -- bit 0-7
+ compressed[4] = string_char(bit_band(bit_rshift(length, 8), 255)) -- bit 8-15
+ compressed[5] = string_char(bit_band(bit_rshift(length, 16), 255)) -- bit 16-23
+ compressed_size = 5
+
+ -- create symbol/code map
+ local escaped_code, escaped_code_len, success, msg
+ for symbol, leaf in pairs(symbols) do
+ addBits(compressed, symbol, 8)
+ escaped_code, escaped_code_len = escape_code(leaf.bcode, leaf.blength)
+ if not escaped_code then
+ return nil, escaped_code_len
+ end
+ addBits(compressed, escaped_code, escaped_code_len)
+ addBits(compressed, 3, 2)
+ end
+
+ -- create huffman code
+ local large_compressed = tables.Huffman_large_compressed
+ local large_compressed_size = 0
+ local ulimit
+ for i = 1, length, 200 do
+ ulimit = length < (i + 199) and length or (i + 199)
+
+ for sub_i = i, ulimit do
+ c = string_byte(uncompressed, sub_i)
+ addBits(compressed, symbols[c].bcode, symbols[c].blength)
+ end
+
+ large_compressed_size = large_compressed_size + 1
+ large_compressed[large_compressed_size] = table_concat(compressed, "", 1, compressed_size)
+ compressed_size = 0
+ end
+
+ -- add remaining bits (if any)
+ if remainder_length > 0 then
+ large_compressed_size = large_compressed_size + 1
+ large_compressed[large_compressed_size] = string_char(remainder)
+ end
+ local compressed_string = table_concat(large_compressed, "", 1, large_compressed_size)
+
+ -- is compression worth it? If not, return uncompressed data.
+ if (#uncompressed + 1) <= #compressed_string then
+ return "\001"..uncompressed
+ end
+
+ setCleanupTables("Huffman_compressed", "Huffman_large_compressed")
+ return compressed_string
+end
+
+-- lookuptable (cached between calls)
+local lshiftMask = {}
+setmetatable(lshiftMask, {
+ __index = function (t, k)
+ local v = bit_lshift(1, k)
+ rawset(t, k, v)
+ return v
+ end
+})
+
+-- lookuptable (cached between calls)
+local lshiftMinusOneMask = {}
+setmetatable(lshiftMinusOneMask, {
+ __index = function (t, k)
+ local v = bit_lshift(1, k) - 1
+ rawset(t, k, v)
+ return v
+ end
+})
+
+local function bor64(valueA_high, valueA, valueB_high, valueB)
+ return bit_bor(valueA_high, valueB_high),
+ bit_bor(valueA, valueB)
+end
+
+local function band64(valueA_high, valueA, valueB_high, valueB)
+ return bit_band(valueA_high, valueB_high),
+ bit_band(valueA, valueB)
+end
+
+local function lshift64(value_high, value, lshift_amount)
+ if lshift_amount == 0 then
+ return value_high, value
+ end
+ if lshift_amount >= 64 then
+ return 0, 0
+ end
+ if lshift_amount < 32 then
+ return bit_bor(bit_lshift(value_high, lshift_amount), bit_rshift(value, 32-lshift_amount)),
+ bit_lshift(value, lshift_amount)
+ end
+ -- 32-63 bit shift
+ return bit_lshift(value, lshift_amount), -- builtin modulus 32 on shift amount
+ 0
+end
+
+local function rshift64(value_high, value, rshift_amount)
+ if rshift_amount == 0 then
+ return value_high, value
+ end
+ if rshift_amount >= 64 then
+ return 0, 0
+ end
+ if rshift_amount < 32 then
+ return bit_rshift(value_high, rshift_amount),
+ bit_bor(bit_lshift(value_high, 32-rshift_amount), bit_rshift(value, rshift_amount))
+ end
+ -- 32-63 bit shift
+ return 0,
+ bit_rshift(value_high, rshift_amount)
+end
+
+local function getCode2(bitfield_high, bitfield, field_len)
+ if field_len >= 2 then
+ -- [bitfield_high..bitfield]: bit 0 is right most in bitfield. bit is left most in bitfield_high
+ local b1, b2, remainder_high, remainder
+ for i = 0, field_len - 2 do
+ b1 = i <= 31 and bit_band(bitfield, bit_lshift(1, i)) or bit_band(bitfield_high, bit_lshift(1, i)) -- for shifts, 32 = 0 (5 bit used)
+ b2 = (i+1) <= 31 and bit_band(bitfield, bit_lshift(1, i+1)) or bit_band(bitfield_high, bit_lshift(1, i+1))
+ if not (b1 == 0) and not (b2 == 0) then
+ -- found 2 bits set right after each other (stop bits) with i pointing at the first stop bit
+ -- return the two bitfields separated by the two stopbits (3 values for each: bitfield_high, bitfield, field_len)
+ -- bits left: field_len - (i+2)
+ remainder_high, remainder = rshift64(bitfield_high, bitfield, i+2)
+ -- first bitfield is the lower part
+ return (i-1) >= 32 and bit_band(bitfield_high, bit_lshift(1, i) - 1) or 0,
+ i >= 32 and bitfield or bit_band(bitfield, bit_lshift(1, i) - 1),
+ i,
+ remainder_high,
+ remainder,
+ field_len-(i+2)
+ end
+ end
+ end
+ return nil
+end
+
+local function unescape_code(code, code_len)
+ local unescaped_code = 0
+ local b
+ local l = 0
+ local i = 0
+ while i < code_len do
+ b = bit_band( code, lshiftMask[i])
+ if not (b == 0) then
+ unescaped_code = bit_bor(unescaped_code, lshiftMask[l])
+ i = i + 1
+ end
+ i = i + 1
+ l = l + 1
+ end
+ return unescaped_code, l
+end
+
+tables.Huffman_uncompressed = {}
+tables.Huffman_large_uncompressed = {} -- will always be as big as the largest string ever decompressed. Bad, but clearing it every time takes precious time.
+
+function LibCompress:DecompressHuffman(compressed)
+ if not type(compressed) == "string" then
+ return nil, "Can only uncompress strings"
+ end
+
+ local compressed_size = #compressed
+ --decode header
+ local info_byte = string_byte(compressed)
+ -- is data compressed
+ if info_byte == 1 then
+ return compressed:sub(2) --return uncompressed data
+ end
+ if not (info_byte == 3) then
+ return nil, "Can only decompress Huffman compressed data ("..tostring(info_byte)..")"
+ end
+
+ local num_symbols = string_byte(string_sub(compressed, 2, 2)) + 1
+ local c0 = string_byte(string_sub(compressed, 3, 3))
+ local c1 = string_byte(string_sub(compressed, 4, 4))
+ local c2 = string_byte(string_sub(compressed, 5, 5))
+ local orig_size = c2 * 65536 + c1 * 256 + c0
+ if orig_size == 0 then
+ return ""
+ end
+
+ -- decode code -> symbol map
+ local bitfield = 0
+ local bitfield_high = 0
+ local bitfield_len = 0
+ local map = {} -- only table not reused in Huffman decode.
+ setmetatable(map, {
+ __index = function (t, k)
+ local v = {}
+ rawset(t, k, v)
+ return v
+ end
+ })
+
+ local i = 6 -- byte 1-5 are header bytes
+ local c, cl
+ local minCodeLen = 1000
+ local maxCodeLen = 0
+ local symbol, code_high, code, code_len, temp_high, temp, _bitfield_high, _bitfield, _bitfield_len
+ local n = 0
+ local state = 0 -- 0 = get symbol (8 bits), 1 = get code (varying bits, ends with 2 bits set)
+ while n < num_symbols do
+ if i > compressed_size then
+ return nil, "Cannot decode map"
+ end
+
+ c = string_byte(compressed, i)
+ temp_high, temp = lshift64(0, c, bitfield_len)
+ bitfield_high, bitfield = bor64(bitfield_high, bitfield, temp_high, temp)
+ bitfield_len = bitfield_len + 8
+
+ if state == 0 then
+ symbol = bit_band(bitfield, 255)
+ bitfield_high, bitfield = rshift64(bitfield_high, bitfield, 8)
+ bitfield_len = bitfield_len - 8
+ state = 1 -- search for code now
+ else
+ code_high, code, code_len, _bitfield_high, _bitfield, _bitfield_len = getCode2(bitfield_high, bitfield, bitfield_len)
+ if code_high then
+ bitfield_high, bitfield, bitfield_len = _bitfield_high, _bitfield, _bitfield_len
+ if code_len > 32 then
+ return nil, "Unsupported symbol code length ("..code_len..")"
+ end
+ c, cl = unescape_code(code, code_len)
+ map[cl][c] = string_char(symbol)
+ minCodeLen = cl < minCodeLen and cl or minCodeLen
+ maxCodeLen = cl > maxCodeLen and cl or maxCodeLen
+ --print("symbol: "..string_char(symbol).." code: "..tobinary(c, cl))
+ n = n + 1
+ state = 0 -- search for next symbol (if any)
+ end
+ end
+ i = i + 1
+ end
+
+ -- don't create new subtables for entries not in the map. Waste of space.
+ -- But do return an empty table to prevent runtime errors. (instead of returning nil)
+ local mt = {}
+ setmetatable(map, {
+ __index = function (t, k)
+ return mt
+ end
+ })
+
+ local uncompressed = tables.Huffman_uncompressed
+ local large_uncompressed = tables.Huffman_large_uncompressed
+ local uncompressed_size = 0
+ local large_uncompressed_size = 0
+ local test_code
+ local test_code_len = minCodeLen
+ local dec_size = 0
+ compressed_size = compressed_size + 1
+ local temp_limit = 200 -- first limit of uncompressed data. large_uncompressed will hold strings of length 200
+ temp_limit = temp_limit > orig_size and orig_size or temp_limit
+
+ while true do
+ if test_code_len <= bitfield_len then
+ test_code = bit_band( bitfield, lshiftMinusOneMask[test_code_len])
+ symbol = map[test_code_len][test_code]
+
+ if symbol then
+ uncompressed_size = uncompressed_size + 1
+ uncompressed[uncompressed_size] = symbol
+ dec_size = dec_size + 1
+ if dec_size >= temp_limit then
+ if dec_size >= orig_size then -- checked here for speed reasons
+ break
+ end
+ -- process compressed bytes in smaller chunks
+ large_uncompressed_size = large_uncompressed_size + 1
+ large_uncompressed[large_uncompressed_size] = table_concat(uncompressed, "", 1, uncompressed_size)
+ uncompressed_size = 0
+ temp_limit = temp_limit + 200 -- repeated chunk size is 200 uncompressed bytes
+ temp_limit = temp_limit > orig_size and orig_size or temp_limit
+ end
+
+ bitfield = bit_rshift(bitfield, test_code_len)
+ bitfield_len = bitfield_len - test_code_len
+ test_code_len = minCodeLen
+ else
+ test_code_len = test_code_len + 1
+ if test_code_len > maxCodeLen then
+ return nil, "Decompression error at "..tostring(i).."/"..tostring(#compressed)
+ end
+ end
+ else
+ c = string_byte(compressed, i)
+ bitfield = bitfield + bit_lshift(c or 0, bitfield_len)
+ bitfield_len = bitfield_len + 8
+ if i > compressed_size then
+ break
+ end
+ i = i + 1
+ end
+ end
+
+ setCleanupTables("Huffman_uncompressed", "Huffman_large_uncompressed")
+ return table_concat(large_uncompressed, "", 1, large_uncompressed_size)..table_concat(uncompressed, "", 1, uncompressed_size)
+end
+
+--------------------------------------------------------------------------------
+-- Generic codec interface
+
+function LibCompress:Store(uncompressed)
+ if type(uncompressed) ~= "string" then
+ return nil, "Can only compress strings"
+ end
+ return "\001"..uncompressed
+end
+
+function LibCompress:DecompressUncompressed(data)
+ if type(data) ~= "string" then
+ return nil, "Can only handle strings"
+ end
+ if string_byte(data) ~= 1 then
+ return nil, "Can only handle uncompressed data"
+ end
+ return data:sub(2)
+end
+
+local compression_methods = {
+ [2] = LibCompress.CompressLZW,
+ [3] = LibCompress.CompressHuffman
+}
+
+local decompression_methods = {
+ [1] = LibCompress.DecompressUncompressed,
+ [2] = LibCompress.DecompressLZW,
+ [3] = LibCompress.DecompressHuffman
+}
+
+-- try all compression codecs and return best result
+function LibCompress:Compress(data)
+ local method = next(compression_methods)
+ local result = compression_methods[method](self, data)
+ local n
+ method = next(compression_methods, method)
+ while method do
+ n = compression_methods[method](self, data)
+ if #n < #result then
+ result = n
+ end
+ method = next(compression_methods, method)
+ end
+ return result
+end
+
+function LibCompress:Decompress(data)
+ local header_info = string_byte(data)
+ if decompression_methods[header_info] then
+ return decompression_methods[header_info](self, data)
+ else
+ return nil, "Unknown compression method ("..tostring(header_info)..")"
+ end
+end
+
+----------------------------------------------------------------------
+----------------------------------------------------------------------
+--
+-- Encoding algorithms
+
+--------------------------------------------------------------------------------
+-- Prefix encoding algorithm
+-- implemented by Galmok of European Stormrage (Horde), galmok@gmail.com
+
+--[[
+ Howto: Encode and Decode:
+
+ 3 functions are supplied, 2 of them are variants of the first. They return a table with functions to encode and decode text.
+
+ table, msg = LibCompress:GetEncodeTable(reservedChars, escapeChars, mapChars)
+
+ reservedChars: The characters in this string will not appear in the encoded data.
+ escapeChars: A string of characters used as escape-characters (don't supply more than needed). #escapeChars >= 1
+ mapChars: First characters in reservedChars maps to first characters in mapChars. (#mapChars <= #reservedChars)
+
+ return value:
+ table
+ if nil then msg holds an error message, otherwise use like this:
+
+ encoded_message = table:Encode(message)
+ message = table:Decode(encoded_message)
+
+ GetAddonEncodeTable: Sets up encoding for the addon channel (\000 is encoded)
+ GetChatEncodeTable: Sets up encoding for the chat channel (many bytes encoded, see the function for details)
+
+ Except for the mapped characters, all encoding will be with 1 escape character followed by 1 suffix, i.e. 2 bytes.
+]]
+-- to be able to match any requested byte value, the search string must be preprocessed
+-- characters to escape with %:
+-- ( ) . % + - * ? [ ] ^ $
+-- "illegal" byte values:
+-- 0 is replaces %z
+local gsub_escape_table = {
+ ['\000'] = "%z",
+ [('(')] = "%(",
+ [(')')] = "%)",
+ [('.')] = "%.",
+ [('%')] = "%%",
+ [('+')] = "%+",
+ [('-')] = "%-",
+ [('*')] = "%*",
+ [('?')] = "%?",
+ [('[')] = "%[",
+ [(']')] = "%]",
+ [('^')] = "%^",
+ [('$')] = "%$"
+}
+
+local function escape_for_gsub(str)
+ return str:gsub("([%z%(%)%.%%%+%-%*%?%[%]%^%$])", gsub_escape_table)
+end
+
+function LibCompress:GetEncodeTable(reservedChars, escapeChars, mapChars)
+ reservedChars = reservedChars or ""
+ escapeChars = escapeChars or ""
+ mapChars = mapChars or ""
+
+ -- select a default escape character
+ if escapeChars == "" then
+ return nil, "No escape characters supplied"
+ end
+
+ if #reservedChars < #mapChars then
+ return nil, "Number of reserved characters must be at least as many as the number of mapped chars"
+ end
+
+ if reservedChars == "" then
+ return nil, "No characters to encode"
+ end
+
+ -- list of characters that must be encoded
+ local encodeBytes = reservedChars..escapeChars..mapChars
+
+ -- build list of bytes not available as a suffix to a prefix byte
+ local taken = {}
+ for i = 1, string_len(encodeBytes) do
+ taken[string_sub(encodeBytes, i, i)] = true
+ end
+
+ -- allocate a table to hold encode/decode strings/functions
+ local codecTable = {}
+
+ -- the encoding can be a single gsub, but the decoding can require multiple gsubs
+ local decode_func_string = {}
+
+ local encode_search = {}
+ local encode_translate = {}
+ local encode_func
+ local decode_search = {}
+ local decode_translate = {}
+ local decode_func
+ local c, r, to, from
+ local escapeCharIndex, escapeChar = 0
+
+ -- map single byte to single byte
+ if #mapChars > 0 then
+ for i = 1, #mapChars do
+ from = string_sub(reservedChars, i, i)
+ to = string_sub(mapChars, i, i)
+ encode_translate[from] = to
+ table_insert(encode_search, from)
+ decode_translate[to] = from
+ table_insert(decode_search, to)
+ end
+ codecTable["decode_search"..tostring(escapeCharIndex)] = "([".. escape_for_gsub(table_concat(decode_search)).."])"
+ codecTable["decode_translate"..tostring(escapeCharIndex)] = decode_translate
+ table_insert(decode_func_string, "str = str:gsub(self.decode_search"..tostring(escapeCharIndex)..", self.decode_translate"..tostring(escapeCharIndex)..");")
+
+ end
+
+ -- map single byte to double-byte
+ escapeCharIndex = escapeCharIndex + 1
+ escapeChar = string_sub(escapeChars, escapeCharIndex, escapeCharIndex)
+ r = 0 -- suffix char value to the escapeChar
+ decode_search = {}
+ decode_translate = {}
+ for i = 1, string_len(encodeBytes) do
+ c = string_sub(encodeBytes, i, i)
+ if not encode_translate[c] then
+ -- this loop will update escapeChar and r
+ while r >= 256 or taken[string_char(r)] do
+ r = r + 1
+ if r > 255 then -- switch to next escapeChar
+ codecTable["decode_search"..tostring(escapeCharIndex)] = escape_for_gsub(escapeChar).."([".. escape_for_gsub(table_concat(decode_search)).."])"
+ codecTable["decode_translate"..tostring(escapeCharIndex)] = decode_translate
+ table_insert(decode_func_string, "str = str:gsub(self.decode_search"..tostring(escapeCharIndex)..", self.decode_translate"..tostring(escapeCharIndex)..");")
+
+ escapeCharIndex = escapeCharIndex + 1
+ escapeChar = string_sub(escapeChars, escapeCharIndex, escapeCharIndex)
+
+ if escapeChar == "" then -- we are out of escape chars and we need more!
+ return nil, "Out of escape characters"
+ end
+
+ r = 0
+ decode_search = {}
+ decode_translate = {}
+ end
+ end
+ encode_translate[c] = escapeChar..string_char(r)
+ table_insert(encode_search, c)
+ decode_translate[string_char(r)] = c
+ table_insert(decode_search, string_char(r))
+ r = r + 1
+ end
+ end
+
+ if r > 0 then
+ codecTable["decode_search"..tostring(escapeCharIndex)] = escape_for_gsub(escapeChar).."([".. escape_for_gsub(table_concat(decode_search)).."])"
+ codecTable["decode_translate"..tostring(escapeCharIndex)] = decode_translate
+ table_insert(decode_func_string, "str = str:gsub(self.decode_search"..tostring(escapeCharIndex)..", self.decode_translate"..tostring(escapeCharIndex)..");")
+ end
+
+ -- change last line from "str = ...;" to "return ...;";
+ decode_func_string[#decode_func_string] = decode_func_string[#decode_func_string]:gsub("str = (.*);", "return %1;")
+ decode_func_string = "return function(self, str) "..table_concat(decode_func_string).." end"
+
+ encode_search = "([".. escape_for_gsub(table_concat(encode_search)).."])"
+ decode_search = escape_for_gsub(escapeChars).."([".. escape_for_gsub(table_concat(decode_search)).."])"
+
+ encode_func = assert(loadstring("return function(self, str) return str:gsub(self.encode_search, self.encode_translate); end"))()
+ decode_func = assert(loadstring(decode_func_string))()
+ codecTable.encode_search = encode_search
+ codecTable.encode_translate = encode_translate
+ codecTable.Encode = encode_func
+ codecTable.decode_search = decode_search
+ codecTable.decode_translate = decode_translate
+ codecTable.Decode = decode_func
+
+ codecTable.decode_func_string = decode_func_string -- to be deleted
+ return codecTable
+end
+
+-- Addons: Call this only once and reuse the returned table for all encodings/decodings.
+function LibCompress:GetAddonEncodeTable(reservedChars, escapeChars, mapChars )
+ reservedChars = reservedChars or ""
+ escapeChars = escapeChars or ""
+ mapChars = mapChars or ""
+ -- Following byte values are not allowed:
+ -- \000
+ if escapeChars == "" then
+ escapeChars = "\001"
+ end
+ return self:GetEncodeTable( (reservedChars or "").."\000", escapeChars, mapChars)
+end
+
+-- Addons: Call this only once and reuse the returned table for all encodings/decodings.
+function LibCompress:GetChatEncodeTable(reservedChars, escapeChars, mapChars)
+ reservedChars = reservedChars or ""
+ escapeChars = escapeChars or ""
+ mapChars = mapChars or ""
+ -- Following byte values are not allowed:
+ -- \000, s, S, \010, \013, \124, %
+ -- Because SendChatMessage will error if an UTF8 multibyte character is incomplete,
+ -- all character values above 127 have to be encoded to avoid this. This costs quite a bit of bandwidth (about 13-14%)
+ -- Also, because drunken status is unknown for the received, strings used with SendChatMessage should be terminated with
+ -- an identifying byte value, after which the server MAY add "...hic!" or as much as it can fit(!).
+ -- Pass the identifying byte as a reserved character to this function to ensure the encoding doesn't contain that value.
+ -- or use this: local message, match = arg1:gsub("^(.*)\029.-$", "%1")
+ -- arg1 is message from channel, \029 is the string terminator, but may be used in the encoded datastream as well. :-)
+ -- This encoding will expand data anywhere from:
+ -- 0% (average with pure ascii text)
+ -- 53.5% (average with random data valued zero to 255)
+ -- 100% (only encoding data that encodes to two bytes)
+ local r = {}
+
+ for i = 128, 255 do
+ table_insert(r, string_char(i))
+ end
+
+ reservedChars = "sS\000\010\013\124%"..table_concat(r)..(reservedChars or "")
+ if escapeChars == "" then
+ escapeChars = "\029\031"
+ end
+
+ if mapChars == "" then
+ mapChars = "\015\020";
+ end
+ return self:GetEncodeTable(reservedChars, escapeChars, mapChars)
+end
+
+--------------------------------------------------------------------------------
+-- 7 bit encoding algorithm
+-- implemented by Galmok of European Stormrage (Horde), galmok@gmail.com
+
+-- The encoded data holds values from 0 to 127 inclusive. Additional encoding may be necessary.
+-- This algorithm isn't exactly fast and be used with care and consideration
+
+tables.encode7bit = {}
+
+function LibCompress:Encode7bit(str)
+ local remainder = 0
+ local remainder_length = 0
+ local tbl = tables.encode7bit
+ local encoded_size = 0
+ local length = #str
+ for i = 1, length do
+ local code = string_byte(str, i)
+ remainder = remainder + bit_lshift(code, remainder_length)
+ remainder_length = 8 + remainder_length
+ while remainder_length >= 7 do
+ encoded_size = encoded_size + 1
+ tbl[encoded_size] = string_char(bit_band(remainder, 127))
+ remainder = bit_rshift(remainder, 7)
+ remainder_length = remainder_length -7
+ end
+ end
+
+ if remainder_length > 0 then
+ encoded_size = encoded_size + 1
+ tbl[encoded_size] = string_char(remainder)
+ end
+ setCleanupTables("encode7bit")
+ return table_concat(tbl, "", 1, encoded_size)
+end
+
+tables.decode8bit = {}
+
+function LibCompress:Decode7bit(str)
+ local bit8 = tables.decode8bit
+ local decoded_size = 0
+ local ch
+ local i = 1
+ local bitfield_len = 0
+ local bitfield = 0
+ local length = #str
+ while true do
+ if bitfield_len >= 8 then
+ decoded_size = decoded_size + 1
+ bit8[decoded_size] = string_char(bit_band(bitfield, 255))
+ bitfield = bit_rshift(bitfield, 8)
+ bitfield_len = bitfield_len - 8
+ end
+ ch = string_byte(str, i)
+ bitfield=bitfield + bit_lshift(ch or 0, bitfield_len)
+ bitfield_len = bitfield_len + 7
+ if i > length then
+ break
+ end
+ i = i + 1
+ end
+ setCleanupTables("decode8bit")
+ return table_concat(bit8, "", 1, decoded_size)
+end
+
+----------------------------------------------------------------------
+----------------------------------------------------------------------
+--
+-- Checksum/hash algorithms
+
+--------------------------------------------------------------------------------
+-- FCS16/32 checksum algorithms
+-- converted from C by Galmok of European Stormrage (Horde), galmok@gmail.com
+-- usage:
+-- code = LibCompress:fcs16init()
+-- code = LibCompress:fcs16update(code, data1)
+-- code = LibCompress:fcs16update(code, data2)
+-- code = LibCompress:fcs16update(code, data...)
+-- code = LibCompress:fcs16final(code)
+--
+-- data = string
+-- fcs16 provides a 16 bit checksum, fcs32 provides a 32 bit checksum.
+
+
+--[[/* The following copyright notice concerns only the FCS hash algorithm
+---------------------------------------------------------------------------
+Copyright (c) 2003, Dominik Reichl , Germany.
+All rights reserved.
+
+Distributed under the terms of the GNU General Public License v2.
+
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its properties, including, but not limited to, correctness
+and/or fitness for purpose.
+---------------------------------------------------------------------------
+*/]]
+--// FCS-16 algorithm implemented as described in RFC 1331
+local FCSINIT16 = 65535
+--// Fast 16 bit FCS lookup table
+local fcs16tab = { [0]=0, 4489, 8978, 12955, 17956, 22445, 25910, 29887,
+ 35912, 40385, 44890, 48851, 51820, 56293, 59774, 63735,
+ 4225, 264, 13203, 8730, 22181, 18220, 30135, 25662,
+ 40137, 36160, 49115, 44626, 56045, 52068, 63999, 59510,
+ 8450, 12427, 528, 5017, 26406, 30383, 17460, 21949,
+ 44362, 48323, 36440, 40913, 60270, 64231, 51324, 55797,
+ 12675, 8202, 4753, 792, 30631, 26158, 21685, 17724,
+ 48587, 44098, 40665, 36688, 64495, 60006, 55549, 51572,
+ 16900, 21389, 24854, 28831, 1056, 5545, 10034, 14011,
+ 52812, 57285, 60766, 64727, 34920, 39393, 43898, 47859,
+ 21125, 17164, 29079, 24606, 5281, 1320, 14259, 9786,
+ 57037, 53060, 64991, 60502, 39145, 35168, 48123, 43634,
+ 25350, 29327, 16404, 20893, 9506, 13483, 1584, 6073,
+ 61262, 65223, 52316, 56789, 43370, 47331, 35448, 39921,
+ 29575, 25102, 20629, 16668, 13731, 9258, 5809, 1848,
+ 65487, 60998, 56541, 52564, 47595, 43106, 39673, 35696,
+ 33800, 38273, 42778, 46739, 49708, 54181, 57662, 61623,
+ 2112, 6601, 11090, 15067, 20068, 24557, 28022, 31999,
+ 38025, 34048, 47003, 42514, 53933, 49956, 61887, 57398,
+ 6337, 2376, 15315, 10842, 24293, 20332, 32247, 27774,
+ 42250, 46211, 34328, 38801, 58158, 62119, 49212, 53685,
+ 10562, 14539, 2640, 7129, 28518, 32495, 19572, 24061,
+ 46475, 41986, 38553, 34576, 62383, 57894, 53437, 49460,
+ 14787, 10314, 6865, 2904, 32743, 28270, 23797, 19836,
+ 50700, 55173, 58654, 62615, 32808, 37281, 41786, 45747,
+ 19012, 23501, 26966, 30943, 3168, 7657, 12146, 16123,
+ 54925, 50948, 62879, 58390, 37033, 33056, 46011, 41522,
+ 23237, 19276, 31191, 26718, 7393, 3432, 16371, 11898,
+ 59150, 63111, 50204, 54677, 41258, 45219, 33336, 37809,
+ 27462, 31439, 18516, 23005, 11618, 15595, 3696, 8185,
+ 63375, 58886, 54429, 50452, 45483, 40994, 37561, 33584,
+ 31687, 27214, 22741, 18780, 15843, 11370, 7921, 3960 }
+
+function LibCompress:fcs16init()
+ return FCSINIT16
+end
+
+function LibCompress:fcs16update(uFcs16, pBuffer)
+ local length = string_len(pBuffer)
+ for i = 1, length do
+ uFcs16 = bit_bxor(bit_rshift(uFcs16,8), fcs16tab[bit_band(bit_bxor(uFcs16, string_byte(pBuffer, i)), 255)])
+ end
+ return uFcs16
+end
+
+function LibCompress:fcs16final(uFcs16)
+ return bit_bxor(uFcs16,65535)
+end
+-- END OF FCS16
+
+--[[/*
+---------------------------------------------------------------------------
+Copyright (c) 2003, Dominik Reichl , Germany.
+All rights reserved.
+
+Distributed under the terms of the GNU General Public License v2.
+
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its properties, including, but not limited to, correctness
+and/or fitness for purpose.
+---------------------------------------------------------------------------
+*/]]
+
+--// FCS-32 algorithm implemented as described in RFC 1331
+
+local FCSINIT32 = -1
+
+--// Fast 32 bit FCS lookup table
+local fcs32tab = { [0] = 0, 1996959894, -301047508, -1727442502, 124634137, 1886057615, -379345611, -1637575261,
+ 249268274, 2044508324, -522852066, -1747789432, 162941995, 2125561021, -407360249, -1866523247,
+ 498536548, 1789927666, -205950648, -2067906082, 450548861, 1843258603, -187386543, -2083289657,
+ 325883990, 1684777152, -43845254, -1973040660, 335633487, 1661365465, -99664541, -1928851979,
+ 997073096, 1281953886, -715111964, -1570279054, 1006888145, 1258607687, -770865667, -1526024853,
+ 901097722, 1119000684, -608450090, -1396901568, 853044451, 1172266101, -589951537, -1412350631,
+ 651767980, 1373503546, -925412992, -1076862698, 565507253, 1454621731, -809855591, -1195530993,
+ 671266974, 1594198024, -972236366, -1324619484, 795835527, 1483230225, -1050600021, -1234817731,
+ 1994146192, 31158534, -1731059524, -271249366, 1907459465, 112637215, -1614814043, -390540237,
+ 2013776290, 251722036, -1777751922, -519137256, 2137656763, 141376813, -1855689577, -429695999,
+ 1802195444, 476864866, -2056965928, -228458418, 1812370925, 453092731, -2113342271, -183516073,
+ 1706088902, 314042704, -1950435094, -54949764, 1658658271, 366619977, -1932296973, -69972891,
+ 1303535960, 984961486, -1547960204, -725929758, 1256170817, 1037604311, -1529756563, -740887301,
+ 1131014506, 879679996, -1385723834, -631195440, 1141124467, 855842277, -1442165665, -586318647,
+ 1342533948, 654459306, -1106571248, -921952122, 1466479909, 544179635, -1184443383, -832445281,
+ 1591671054, 702138776, -1328506846, -942167884, 1504918807, 783551873, -1212326853, -1061524307,
+ -306674912, -1698712650, 62317068, 1957810842, -355121351, -1647151185, 81470997, 1943803523,
+ -480048366, -1805370492, 225274430, 2053790376, -468791541, -1828061283, 167816743, 2097651377,
+ -267414716, -2029476910, 503444072, 1762050814, -144550051, -2140837941, 426522225, 1852507879,
+ -19653770, -1982649376, 282753626, 1742555852, -105259153, -1900089351, 397917763, 1622183637,
+ -690576408, -1580100738, 953729732, 1340076626, -776247311, -1497606297, 1068828381, 1219638859,
+ -670225446, -1358292148, 906185462, 1090812512, -547295293, -1469587627, 829329135, 1181335161,
+ -882789492, -1134132454, 628085408, 1382605366, -871598187, -1156888829, 570562233, 1426400815,
+ -977650754, -1296233688, 733239954, 1555261956, -1026031705, -1244606671, 752459403, 1541320221,
+ -1687895376, -328994266, 1969922972, 40735498, -1677130071, -351390145, 1913087877, 83908371,
+ -1782625662, -491226604, 2075208622, 213261112, -1831694693, -438977011, 2094854071, 198958881,
+ -2032938284, -237706686, 1759359992, 534414190, -2118248755, -155638181, 1873836001, 414664567,
+ -2012718362, -15766928, 1711684554, 285281116, -1889165569, -127750551, 1634467795, 376229701,
+ -1609899400, -686959890, 1308918612, 956543938, -1486412191, -799009033, 1231636301, 1047427035,
+ -1362007478, -640263460, 1088359270, 936918000, -1447252397, -558129467, 1202900863, 817233897,
+ -1111625188, -893730166, 1404277552, 615818150, -1160759803, -841546093, 1423857449, 601450431,
+ -1285129682, -1000256840, 1567103746, 711928724, -1274298825, -1022587231, 1510334235, 755167117 }
+
+function LibCompress:fcs32init()
+ return FCSINIT32
+end
+
+function LibCompress:fcs32update(uFcs32, pBuffer)
+ local length = string_len(pBuffer)
+ for i = 1, length do
+ uFcs32 = bit_bxor(bit_rshift(uFcs32, 8), fcs32tab[bit_band(bit_bxor(uFcs32, string_byte(pBuffer, i)), 255)])
+ end
+ return uFcs32
+end
+
+function LibCompress:fcs32final(uFcs32)
+ return bit_bnot(uFcs32)
+end
diff --git a/Skada/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua b/Skada/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
new file mode 100644
index 0000000..438171b
--- /dev/null
+++ b/Skada/Libs/LibDBIcon-1.0/LibDBIcon-1.0.lua
@@ -0,0 +1,334 @@
+
+-----------------------------------------------------------------------
+-- LibDBIcon-1.0
+--
+-- Allows addons to easily create a lightweight minimap icon as an alternative to heavier LDB displays.
+--
+
+local DBICON10 = "LibDBIcon-1.0"
+local DBICON10_MINOR = 36 -- Bump on changes
+if not LibStub then error(DBICON10 .. " requires LibStub.") end
+local ldb = LibStub("LibDataBroker-1.1", true)
+if not ldb then error(DBICON10 .. " requires LibDataBroker-1.1.") end
+local lib = LibStub:NewLibrary(DBICON10, DBICON10_MINOR)
+if not lib then return end
+
+lib.disabled = lib.disabled or nil
+lib.objects = lib.objects or {}
+lib.callbackRegistered = lib.callbackRegistered or nil
+lib.callbacks = lib.callbacks or LibStub("CallbackHandler-1.0"):New(lib)
+lib.notCreated = lib.notCreated or {}
+lib.tooltip = lib.tooltip or CreateFrame("GameTooltip", "LibDBIconTooltip", UIParent, "GameTooltipTemplate")
+
+function lib:IconCallback(event, name, key, value)
+ if lib.objects[name] then
+ if key == "icon" then
+ lib.objects[name].icon:SetTexture(value)
+ elseif key == "iconCoords" then
+ lib.objects[name].icon:UpdateCoord()
+ elseif key == "iconR" then
+ local _, g, b = lib.objects[name].icon:GetVertexColor()
+ lib.objects[name].icon:SetVertexColor(value, g, b)
+ elseif key == "iconG" then
+ local r, _, b = lib.objects[name].icon:GetVertexColor()
+ lib.objects[name].icon:SetVertexColor(r, value, b)
+ elseif key == "iconB" then
+ local r, g = lib.objects[name].icon:GetVertexColor()
+ lib.objects[name].icon:SetVertexColor(r, g, value)
+ end
+ end
+end
+if not lib.callbackRegistered then
+ ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__icon", "IconCallback")
+ ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconCoords", "IconCallback")
+ ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconR", "IconCallback")
+ ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconG", "IconCallback")
+ ldb.RegisterCallback(lib, "LibDataBroker_AttributeChanged__iconB", "IconCallback")
+ lib.callbackRegistered = true
+end
+
+local function getAnchors(frame)
+ local x, y = frame:GetCenter()
+ if not x or not y then return "CENTER" end
+ local hhalf = (x > UIParent:GetWidth()*2/3) and "RIGHT" or (x < UIParent:GetWidth()/3) and "LEFT" or ""
+ local vhalf = (y > UIParent:GetHeight()/2) and "TOP" or "BOTTOM"
+ return vhalf..hhalf, frame, (vhalf == "TOP" and "BOTTOM" or "TOP")..hhalf
+end
+
+local function onEnter(self)
+ if self.isMoving then return end
+ local obj = self.dataObject
+ if obj.OnTooltipShow then
+ lib.tooltip:SetOwner(self, "ANCHOR_NONE")
+ lib.tooltip:SetPoint(getAnchors(self))
+ obj.OnTooltipShow(lib.tooltip)
+ lib.tooltip:Show()
+ elseif obj.OnEnter then
+ obj.OnEnter(self)
+ end
+end
+
+local function onLeave(self)
+ local obj = self.dataObject
+ lib.tooltip:Hide()
+ if obj.OnLeave then obj.OnLeave(self) end
+end
+
+--------------------------------------------------------------------------------
+
+local onClick, onMouseUp, onMouseDown, onDragStart, onDragStop, updatePosition
+
+do
+ local minimapShapes = {
+ ["ROUND"] = {true, true, true, true},
+ ["SQUARE"] = {false, false, false, false},
+ ["CORNER-TOPLEFT"] = {false, false, false, true},
+ ["CORNER-TOPRIGHT"] = {false, false, true, false},
+ ["CORNER-BOTTOMLEFT"] = {false, true, false, false},
+ ["CORNER-BOTTOMRIGHT"] = {true, false, false, false},
+ ["SIDE-LEFT"] = {false, true, false, true},
+ ["SIDE-RIGHT"] = {true, false, true, false},
+ ["SIDE-TOP"] = {false, false, true, true},
+ ["SIDE-BOTTOM"] = {true, true, false, false},
+ ["TRICORNER-TOPLEFT"] = {false, true, true, true},
+ ["TRICORNER-TOPRIGHT"] = {true, false, true, true},
+ ["TRICORNER-BOTTOMLEFT"] = {true, true, false, true},
+ ["TRICORNER-BOTTOMRIGHT"] = {true, true, true, false},
+ }
+
+ function updatePosition(button)
+ local angle = math.rad(button.db and button.db.minimapPos or button.minimapPos or 225)
+ local x, y, q = math.cos(angle), math.sin(angle), 1
+ if x < 0 then q = q + 1 end
+ if y > 0 then q = q + 2 end
+ local minimapShape = GetMinimapShape and GetMinimapShape() or "ROUND"
+ local quadTable = minimapShapes[minimapShape]
+ if quadTable[q] then
+ x, y = x*80, y*80
+ else
+ local diagRadius = 103.13708498985 --math.sqrt(2*(80)^2)-10
+ x = math.max(-80, math.min(x*diagRadius, 80))
+ y = math.max(-80, math.min(y*diagRadius, 80))
+ end
+ button:SetPoint("CENTER", Minimap, "CENTER", x, y)
+ end
+end
+
+function onClick(self, b) if self.dataObject.OnClick then self.dataObject.OnClick(self, b) end end
+function onMouseDown(self) self.isMouseDown = true; self.icon:UpdateCoord() end
+function onMouseUp(self) self.isMouseDown = false; self.icon:UpdateCoord() end
+
+do
+ local function onUpdate(self)
+ local mx, my = Minimap:GetCenter()
+ local px, py = GetCursorPosition()
+ local scale = Minimap:GetEffectiveScale()
+ px, py = px / scale, py / scale
+ if self.db then
+ self.db.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
+ else
+ self.minimapPos = math.deg(math.atan2(py - my, px - mx)) % 360
+ end
+ updatePosition(self)
+ end
+
+ function onDragStart(self)
+ self:LockHighlight()
+ self.isMouseDown = true
+ self.icon:UpdateCoord()
+ self:SetScript("OnUpdate", onUpdate)
+ self.isMoving = true
+ lib.tooltip:Hide()
+ end
+end
+
+function onDragStop(self)
+ self:SetScript("OnUpdate", nil)
+ self.isMouseDown = false
+ self.icon:UpdateCoord()
+ self:UnlockHighlight()
+ self.isMoving = nil
+end
+
+local defaultCoords = {0, 1, 0, 1}
+local function updateCoord(self)
+ local coords = self:GetParent().dataObject.iconCoords or defaultCoords
+ local deltaX, deltaY = 0, 0
+ if not self:GetParent().isMouseDown then
+ deltaX = (coords[2] - coords[1]) * 0.05
+ deltaY = (coords[4] - coords[3]) * 0.05
+ end
+ self:SetTexCoord(coords[1] + deltaX, coords[2] - deltaX, coords[3] + deltaY, coords[4] - deltaY)
+end
+
+local function createButton(name, object, db)
+ local button = CreateFrame("Button", "LibDBIcon10_"..name, Minimap)
+ button.dataObject = object
+ button.db = db
+ button:SetFrameStrata("MEDIUM")
+ button:SetSize(31, 31)
+ button:SetFrameLevel(8)
+ button:RegisterForClicks("anyUp")
+ button:RegisterForDrag("LeftButton")
+ button:SetHighlightTexture(136477) --"Interface\\Minimap\\UI-Minimap-ZoomButton-Highlight"
+ local overlay = button:CreateTexture(nil, "OVERLAY")
+ overlay:SetSize(53, 53)
+ overlay:SetTexture(136430) --"Interface\\Minimap\\MiniMap-TrackingBorder"
+ overlay:SetPoint("TOPLEFT")
+ local background = button:CreateTexture(nil, "BACKGROUND")
+ background:SetSize(20, 20)
+ background:SetTexture(136467) --"Interface\\Minimap\\UI-Minimap-Background"
+ background:SetPoint("TOPLEFT", 7, -5)
+ local icon = button:CreateTexture(nil, "ARTWORK")
+ icon:SetSize(17, 17)
+ icon:SetTexture(object.icon)
+ icon:SetPoint("TOPLEFT", 7, -6)
+ button.icon = icon
+ button.isMouseDown = false
+
+ local r, g, b = icon:GetVertexColor()
+ icon:SetVertexColor(object.iconR or r, object.iconG or g, object.iconB or b)
+
+ icon.UpdateCoord = updateCoord
+ icon:UpdateCoord()
+
+ button:SetScript("OnEnter", onEnter)
+ button:SetScript("OnLeave", onLeave)
+ button:SetScript("OnClick", onClick)
+ if not db or not db.lock then
+ button:SetScript("OnDragStart", onDragStart)
+ button:SetScript("OnDragStop", onDragStop)
+ end
+ button:SetScript("OnMouseDown", onMouseDown)
+ button:SetScript("OnMouseUp", onMouseUp)
+
+ lib.objects[name] = button
+
+ if lib.loggedIn then
+ updatePosition(button)
+ if not db or not db.hide then button:Show()
+ else button:Hide() end
+ end
+ lib.callbacks:Fire("LibDBIcon_IconCreated", button, name) -- Fire 'Icon Created' callback
+end
+
+-- We could use a metatable.__index on lib.objects, but then we'd create
+-- the icons when checking things like :IsRegistered, which is not necessary.
+local function check(name)
+ if lib.notCreated[name] then
+ createButton(name, lib.notCreated[name][1], lib.notCreated[name][2])
+ lib.notCreated[name] = nil
+ end
+end
+
+lib.loggedIn = lib.loggedIn or false
+-- Wait a bit with the initial positioning to let any GetMinimapShape addons
+-- load up.
+if not lib.loggedIn then
+ local f = CreateFrame("Frame")
+ f:SetScript("OnEvent", function()
+ for _, object in pairs(lib.objects) do
+ updatePosition(object)
+ if not lib.disabled and (not object.db or not object.db.hide) then object:Show()
+ else object:Hide() end
+ end
+ lib.loggedIn = true
+ f:SetScript("OnEvent", nil)
+ f = nil
+ end)
+ f:RegisterEvent("PLAYER_LOGIN")
+end
+
+local function getDatabase(name)
+ return lib.notCreated[name] and lib.notCreated[name][2] or lib.objects[name].db
+end
+
+function lib:Register(name, object, db)
+ if not object.icon then error("Can't register LDB objects without icons set!") end
+ if lib.objects[name] or lib.notCreated[name] then error("Already registered, nubcake.") end
+ if not lib.disabled and (not db or not db.hide) then
+ createButton(name, object, db)
+ else
+ lib.notCreated[name] = {object, db}
+ end
+end
+
+function lib:Lock(name)
+ if not lib:IsRegistered(name) then return end
+ if lib.objects[name] then
+ lib.objects[name]:SetScript("OnDragStart", nil)
+ lib.objects[name]:SetScript("OnDragStop", nil)
+ end
+ local db = getDatabase(name)
+ if db then db.lock = true end
+end
+
+function lib:Unlock(name)
+ if not lib:IsRegistered(name) then return end
+ if lib.objects[name] then
+ lib.objects[name]:SetScript("OnDragStart", onDragStart)
+ lib.objects[name]:SetScript("OnDragStop", onDragStop)
+ end
+ local db = getDatabase(name)
+ if db then db.lock = nil end
+end
+
+function lib:Hide(name)
+ if not lib.objects[name] then return end
+ lib.objects[name]:Hide()
+end
+function lib:Show(name)
+ if lib.disabled then return end
+ check(name)
+ lib.objects[name]:Show()
+ updatePosition(lib.objects[name])
+end
+function lib:IsRegistered(name)
+ return (lib.objects[name] or lib.notCreated[name]) and true or false
+end
+function lib:Refresh(name, db)
+ if lib.disabled then return end
+ check(name)
+ local button = lib.objects[name]
+ if db then button.db = db end
+ updatePosition(button)
+ if not button.db or not button.db.hide then
+ button:Show()
+ else
+ button:Hide()
+ end
+ if not button.db or not button.db.lock then
+ button:SetScript("OnDragStart", onDragStart)
+ button:SetScript("OnDragStop", onDragStop)
+ else
+ button:SetScript("OnDragStart", nil)
+ button:SetScript("OnDragStop", nil)
+ end
+end
+function lib:GetMinimapButton(name)
+ return lib.objects[name]
+end
+
+function lib:EnableLibrary()
+ lib.disabled = nil
+ for name, object in pairs(lib.objects) do
+ if not object.db or not object.db.hide then
+ object:Show()
+ updatePosition(object)
+ end
+ end
+ for name, data in pairs(lib.notCreated) do
+ if not data.db or not data.db.hide then
+ createButton(name, data[1], data[2])
+ lib.notCreated[name] = nil
+ end
+ end
+end
+
+function lib:DisableLibrary()
+ lib.disabled = true
+ for name, object in pairs(lib.objects) do
+ object:Hide()
+ end
+end
+
diff --git a/Skada/Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua b/Skada/Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
new file mode 100644
index 0000000..f47c0cd
--- /dev/null
+++ b/Skada/Libs/LibDataBroker-1.1/LibDataBroker-1.1.lua
@@ -0,0 +1,90 @@
+
+assert(LibStub, "LibDataBroker-1.1 requires LibStub")
+assert(LibStub:GetLibrary("CallbackHandler-1.0", true), "LibDataBroker-1.1 requires CallbackHandler-1.0")
+
+local lib, oldminor = LibStub:NewLibrary("LibDataBroker-1.1", 4)
+if not lib then return end
+oldminor = oldminor or 0
+
+
+lib.callbacks = lib.callbacks or LibStub:GetLibrary("CallbackHandler-1.0"):New(lib)
+lib.attributestorage, lib.namestorage, lib.proxystorage = lib.attributestorage or {}, lib.namestorage or {}, lib.proxystorage or {}
+local attributestorage, namestorage, callbacks = lib.attributestorage, lib.namestorage, lib.callbacks
+
+if oldminor < 2 then
+ lib.domt = {
+ __metatable = "access denied",
+ __index = function(self, key) return attributestorage[self] and attributestorage[self][key] end,
+ }
+end
+
+if oldminor < 3 then
+ lib.domt.__newindex = function(self, key, value)
+ if not attributestorage[self] then attributestorage[self] = {} end
+ if attributestorage[self][key] == value then return end
+ attributestorage[self][key] = value
+ local name = namestorage[self]
+ if not name then return end
+ callbacks:Fire("LibDataBroker_AttributeChanged", name, key, value, self)
+ callbacks:Fire("LibDataBroker_AttributeChanged_"..name, name, key, value, self)
+ callbacks:Fire("LibDataBroker_AttributeChanged_"..name.."_"..key, name, key, value, self)
+ callbacks:Fire("LibDataBroker_AttributeChanged__"..key, name, key, value, self)
+ end
+end
+
+if oldminor < 2 then
+ function lib:NewDataObject(name, dataobj)
+ if self.proxystorage[name] then return end
+
+ if dataobj then
+ assert(type(dataobj) == "table", "Invalid dataobj, must be nil or a table")
+ self.attributestorage[dataobj] = {}
+ for i,v in pairs(dataobj) do
+ self.attributestorage[dataobj][i] = v
+ dataobj[i] = nil
+ end
+ end
+ dataobj = setmetatable(dataobj or {}, self.domt)
+ self.proxystorage[name], self.namestorage[dataobj] = dataobj, name
+ self.callbacks:Fire("LibDataBroker_DataObjectCreated", name, dataobj)
+ return dataobj
+ end
+end
+
+if oldminor < 1 then
+ function lib:DataObjectIterator()
+ return pairs(self.proxystorage)
+ end
+
+ function lib:GetDataObjectByName(dataobjectname)
+ return self.proxystorage[dataobjectname]
+ end
+
+ function lib:GetNameByDataObject(dataobject)
+ return self.namestorage[dataobject]
+ end
+end
+
+if oldminor < 4 then
+ local next = pairs(attributestorage)
+ function lib:pairs(dataobject_or_name)
+ local t = type(dataobject_or_name)
+ assert(t == "string" or t == "table", "Usage: ldb:pairs('dataobjectname') or ldb:pairs(dataobject)")
+
+ local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
+ assert(attributestorage[dataobj], "Data object not found")
+
+ return next, attributestorage[dataobj], nil
+ end
+
+ local ipairs_iter = ipairs(attributestorage)
+ function lib:ipairs(dataobject_or_name)
+ local t = type(dataobject_or_name)
+ assert(t == "string" or t == "table", "Usage: ldb:ipairs('dataobjectname') or ldb:ipairs(dataobject)")
+
+ local dataobj = self.proxystorage[dataobject_or_name] or dataobject_or_name
+ assert(attributestorage[dataobj], "Data object not found")
+
+ return ipairs_iter, attributestorage[dataobj], 0
+ end
+end
diff --git a/Skada/Libs/LibDeflate/LibDeflate.lua b/Skada/Libs/LibDeflate/LibDeflate.lua
new file mode 100644
index 0000000..279ac74
--- /dev/null
+++ b/Skada/Libs/LibDeflate/LibDeflate.lua
@@ -0,0 +1,3509 @@
+--[[--
+LibDeflate 1.0.0-release
+Pure Lua compressor and decompressor with high compression ratio using
+DEFLATE/zlib format.
+
+@file LibDeflate.lua
+@author Haoqian He (Github: SafeteeWoW; World of Warcraft: Safetyy-Illidan(US))
+@copyright LibDeflate <2018> Haoqian He
+@license GNU General Public License Version 3 or later
+
+This library is implemented according to the following specifications.
+Report a bug if LibDeflate is not fully compliant with those specs.
+Both compressors and decompressors have been implemented in the library.
+1. RFC1950: DEFLATE Compressed Data Format Specification version 1.3
+https://tools.ietf.org/html/rfc1951
+2. RFC1951: ZLIB Compressed Data Format Specification version 3.3
+https://tools.ietf.org/html/rfc1950
+
+This library requires Lua 5.1/5.2/5.3 interpreter or LuaJIT v2.0+.
+This library does not have any dependencies.
+
+This file "LibDeflate.lua" is the only source file of
+the library.
+Submit suggestions or report bugs to
+https://github.com/safeteeWow/LibDeflate/issues
+]]
+
+--[[
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see https://www.gnu.org/licenses/.
+
+Credits:
+1. zlib, by Jean-loup Gailly (compression) and Mark Adler (decompression).
+ http://www.zlib.net/
+ Licensed under zlib License. http://www.zlib.net/zlib_license.html
+ For the compression algorithm.
+2. puff, by Mark Adler. https://github.com/madler/zlib/tree/master/contrib/puff
+ Licensed under zlib License. http://www.zlib.net/zlib_license.html
+ For the decompression algorithm.
+3. LibCompress, by jjsheets and Galmok of European Stormrage (Horde)
+ https://www.wowace.com/projects/libcompress
+ Licensed under GPLv2.
+ https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ For the code to create customized codec.
+4. WeakAuras2,
+ https://github.com/WeakAuras/WeakAuras2
+ Licensed under GPLv2.
+ For the 6bit encoding and decoding.
+]]
+
+--[[
+ Curseforge auto-packaging replacements:
+
+ Project Date: 2018-07-29T18:58:38Z
+ Project Hash: 420f583c8c1ad0d4fc12398c86e99a65cf37a79a
+ Project Version: 1.0.0-release
+--]]
+
+local LibDeflate
+
+do
+ -- Semantic version. all lowercase.
+ -- Suffix can be alpha1, alpha2, beta1, beta2, rc1, rc2, etc.
+ -- NOTE: Two version numbers needs to modify.
+ -- 1. On the top of LibDeflate.lua
+ -- 2. HERE
+ local _VERSION = "1.0.0-release"
+
+ local _COPYRIGHT =
+ "LibDeflate ".._VERSION
+ .." Copyright (C) 2018 Haoqian He."
+ .." License GPLv3+: GNU GPL version 3 or later"
+
+ -- Register in the World of Warcraft library "LibStub" if detected.
+ if LibStub then
+ local MAJOR, MINOR = "LibDeflate", -1
+ -- When MAJOR is changed, I should name it as LibDeflate2
+ local lib, minor = LibStub:GetLibrary(MAJOR, true)
+ if lib and minor and minor >= MINOR then -- No need to update.
+ return lib
+ else -- Update or first time register
+ LibDeflate = LibStub:NewLibrary(MAJOR, _VERSION)
+ -- NOTE: It is important that new version has implemented
+ -- all exported APIs and tables in the old version,
+ -- so the old library is fully garbage collected,
+ -- and we 100% ensure the backward compatibility.
+ end
+ else -- "LibStub" is not detected.
+ LibDeflate = {}
+ end
+
+ LibDeflate._VERSION = _VERSION
+ LibDeflate._COPYRIGHT = _COPYRIGHT
+end
+
+-- localize Lua api for faster access.
+local assert = assert
+local error = error
+local pairs = pairs
+local string_byte = string.byte
+local string_char = string.char
+local string_find = string.find
+local string_gsub = string.gsub
+local string_sub = string.sub
+local table_concat = table.concat
+local table_sort = table.sort
+local tostring = tostring
+local type = type
+
+-- Converts i to 2^i, (0<=i<=32)
+-- This is used to implement bit left shift and bit right shift.
+-- "x >> y" in C: "(x-x%_pow2[y])/_pow2[y]" in Lua
+-- "x << y" in C: "x*_pow2[y]" in Lua
+local _pow2 = {}
+
+-- Converts any byte to a character, (0<=byte<=255)
+local _byte_to_char = {}
+
+-- _reverseBitsTbl[len][val] stores the bit reverse of
+-- the number with bit length "len" and value "val"
+-- For example, decimal number 6 with bits length 5 is binary 00110
+-- It's reverse is binary 01100,
+-- which is decimal 12 and 12 == _reverseBitsTbl[5][6]
+-- 1<=len<=9, 0<=val<=2^len-1
+-- The reason for 1<=len<=9 is that the max of min bitlen of huffman code
+-- of a huffman alphabet is 9?
+local _reverse_bits_tbl = {}
+
+-- Convert a LZ77 length (3<=len<=258) to
+-- a deflate literal/LZ77_length code (257<=code<=285)
+local _length_to_deflate_code = {}
+
+-- convert a LZ77 length (3<=len<=258) to
+-- a deflate literal/LZ77_length code extra bits.
+local _length_to_deflate_extra_bits = {}
+
+-- Convert a LZ77 length (3<=len<=258) to
+-- a deflate literal/LZ77_length code extra bit length.
+local _length_to_deflate_extra_bitlen = {}
+
+-- Convert a small LZ77 distance (1<=dist<=256) to a deflate code.
+local _dist256_to_deflate_code = {}
+
+-- Convert a small LZ77 distance (1<=dist<=256) to
+-- a deflate distance code extra bits.
+local _dist256_to_deflate_extra_bits = {}
+
+-- Convert a small LZ77 distance (1<=dist<=256) to
+-- a deflate distance code extra bit length.
+local _dist256_to_deflate_extra_bitlen = {}
+
+-- Convert a literal/LZ77_length deflate code to LZ77 base length
+-- The key of the table is (code - 256), 257<=code<=285
+local _literal_deflate_code_to_base_len = {
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258,
+}
+
+-- Convert a literal/LZ77_length deflate code to base LZ77 length extra bits
+-- The key of the table is (code - 256), 257<=code<=285
+local _literal_deflate_code_to_extra_bitlen = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0,
+}
+
+-- Convert a distance deflate code to base LZ77 distance. (0<=code<=29)
+local _dist_deflate_code_to_base_dist = {
+ [0] = 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+ 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+ 8193, 12289, 16385, 24577,
+}
+
+-- Convert a distance deflate code to LZ77 bits length. (0<=code<=29)
+local _dist_deflate_code_to_extra_bitlen = {
+ [0] = 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+ 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13,
+}
+
+-- The code order of the first huffman header in the dynamic deflate block.
+-- See the page 12 of RFC1951
+local _rle_codes_huffman_bitlen_order = {16, 17, 18,
+ 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15,
+}
+
+-- The following tables are used by fixed deflate block.
+-- The value of these tables are assigned at the bottom of the source.
+
+-- The huffman code of the literal/LZ77_length deflate codes,
+-- in fixed deflate block.
+local _fix_block_literal_huffman_code
+
+-- Convert huffman code of the literal/LZ77_length to deflate codes,
+-- in fixed deflate block.
+local _fix_block_literal_huffman_to_deflate_code
+
+-- The bit length of the huffman code of literal/LZ77_length deflate codes,
+-- in fixed deflate block.
+local _fix_block_literal_huffman_bitlen
+
+-- The count of each bit length of the literal/LZ77_length deflate codes,
+-- in fixed deflate block.
+local _fix_block_literal_huffman_bitlen_count
+
+-- The huffman code of the distance deflate codes,
+-- in fixed deflate block.
+local _fix_block_dist_huffman_code
+
+-- Convert huffman code of the distance to deflate codes,
+-- in fixed deflate block.
+local _fix_block_dist_huffman_to_deflate_code
+
+-- The bit length of the huffman code of the distance deflate codes,
+-- in fixed deflate block.
+local _fix_block_dist_huffman_bitlen
+
+-- The count of each bit length of the huffman code of
+-- the distance deflate codes,
+-- in fixed deflate block.
+local _fix_block_dist_huffman_bitlen_count
+
+for i = 0, 255 do
+ _byte_to_char[i] = string_char(i)
+end
+
+do
+ local pow = 1
+ for i = 0, 32 do
+ _pow2[i] = pow
+ pow = pow * 2
+ end
+end
+
+for i = 1, 9 do
+ _reverse_bits_tbl[i] = {}
+ for j=0, _pow2[i+1]-1 do
+ local reverse = 0
+ local value = j
+ for _ = 1, i do
+ -- The following line is equivalent to "res | (code %2)" in C.
+ reverse = reverse - reverse%2
+ + (((reverse%2==1) or (value % 2) == 1) and 1 or 0)
+ value = (value-value%2)/2
+ reverse = reverse * 2
+ end
+ _reverse_bits_tbl[i][j] = (reverse-reverse%2)/2
+ end
+end
+
+-- The source code is written according to the pattern in the numbers
+-- in RFC1951 Page10.
+do
+ local a = 18
+ local b = 16
+ local c = 265
+ local bitlen = 1
+ for len = 3, 258 do
+ if len <= 10 then
+ _length_to_deflate_code[len] = len + 254
+ _length_to_deflate_extra_bitlen[len] = 0
+ elseif len == 258 then
+ _length_to_deflate_code[len] = 285
+ _length_to_deflate_extra_bitlen[len] = 0
+ else
+ if len > a then
+ a = a + b
+ b = b * 2
+ c = c + 4
+ bitlen = bitlen + 1
+ end
+ local t = len-a-1+b/2
+ _length_to_deflate_code[len] = (t-(t%(b/8)))/(b/8) + c
+ _length_to_deflate_extra_bitlen[len] = bitlen
+ _length_to_deflate_extra_bits[len] = t % (b/8)
+ end
+ end
+end
+
+-- The source code is written according to the pattern in the numbers
+-- in RFC1951 Page11.
+do
+ _dist256_to_deflate_code[1] = 0
+ _dist256_to_deflate_code[2] = 1
+ _dist256_to_deflate_extra_bitlen[1] = 0
+ _dist256_to_deflate_extra_bitlen[2] = 0
+
+ local a = 3
+ local b = 4
+ local code = 2
+ local bitlen = 0
+ for dist = 3, 256 do
+ if dist > b then
+ a = a * 2
+ b = b * 2
+ code = code + 2
+ bitlen = bitlen + 1
+ end
+ _dist256_to_deflate_code[dist] = (dist <= a) and code or (code+1)
+ _dist256_to_deflate_extra_bitlen[dist] = (bitlen < 0) and 0 or bitlen
+ if b >= 8 then
+ _dist256_to_deflate_extra_bits[dist] = (dist-b/2-1) % (b/4)
+ end
+ end
+end
+
+--- Calculate the Adler-32 checksum of the string.
+-- See RFC1950 Page 9 https://tools.ietf.org/html/rfc1950 for the
+-- definition of Adler-32 checksum.
+-- @param str [string] the input string to calcuate its Adler-32 checksum.
+-- @return [integer] The Adler-32 checksum, which is greater or equal to 0,
+-- and less than 2^32 (4294967296).
+function LibDeflate:Adler32(str)
+ -- This function is loop unrolled by better performance.
+ --
+ -- Here is the minimum code:
+ --
+ -- local a = 1
+ -- local b = 0
+ -- for i=1, #str do
+ -- local s = string.byte(str, i, i)
+ -- a = (a+s)%65521
+ -- b = (b+a)%65521
+ -- end
+ -- return b*65536+a
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:Adler32(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ local strlen = #str
+
+ local i = 1
+ local a = 1
+ local b = 0
+ while i <= strlen - 15 do
+ local x1, x2, x3, x4, x5, x6, x7, x8,
+ x9, x10, x11, x12, x13, x14, x15, x16 = string_byte(str, i, i+15)
+ b = (b+16*a+16*x1+15*x2+14*x3+13*x4+12*x5+11*x6+10*x7+9*x8+8*x9
+ +7*x10+6*x11+5*x12+4*x13+3*x14+2*x15+x16)%65521
+ a = (a+x1+x2+x3+x4+x5+x6+x7+x8+x9+x10+x11+x12+x13+x14+x15+x16)%65521
+ i = i + 16
+ end
+ while (i <= strlen) do
+ local x = string_byte(str, i, i)
+ a = (a + x) % 65521
+ b = (b + a) % 65521
+ i = i + 1
+ end
+ return (b*65536+a) % 4294967296
+end
+
+-- Compare adler32 checksum.
+-- adler32 should be compared with a mod to avoid sign problem
+-- 4072834167 (unsigned) is the same adler32 as -222133129
+local function IsEqualAdler32(actual, expected)
+ return (actual % 4294967296) == (expected % 4294967296)
+end
+
+--- Create a preset dictionary.
+--
+-- This function is not fast, and the memory consumption of the produced
+-- dictionary is about 50 times of the input string. Therefore, it is suggestted
+-- to run this function only once in your program.
+--
+-- It is very important to know that if you do use a preset dictionary,
+-- compressors and decompressors MUST USE THE SAME dictionary. That is,
+-- dictionary must be created using the same string. If you update your program
+-- with a new dictionary, people with the old version won't be able to transmit
+-- data with people with the new version. Therefore, changing the dictionary
+-- must be very careful.
+--
+-- The parameters "strlen" and "adler32" add a layer of verification to ensure
+-- the parameter "str" is not modified unintentionally during the program
+-- development.
+--
+-- @usage local dict_str = "1234567890"
+--
+-- -- print(dict_str:len(), LibDeflate:Adler32(dict_str))
+-- -- Hardcode the print result below to verify it to avoid acciently
+-- -- modification of 'str' during the program development.
+-- -- string length: 10, Adler-32: 187433486,
+-- -- Don't calculate string length and its Adler-32 at run-time.
+--
+-- local dict = LibDeflate:CreateDictionary(dict_str, 10, 187433486)
+--
+-- @param str [string] The string used as the preset dictionary.
+-- You should put stuffs that frequently appears in the dictionary
+-- string and preferablely put more frequently appeared stuffs toward the end
+-- of the string.
+-- Empty string and string longer than 32768 bytes are not allowed.
+-- @param strlen [integer] The length of 'str'. Please pass in this parameter
+-- as a hardcoded constant, in order to verify the content of 'str'. The value
+-- of this parameter should be known before your program runs.
+-- @param adler32 [integer] The Adler-32 checksum of 'str'. Please pass in this
+-- parameter as a hardcoded constant, in order to verify the content of 'str'.
+-- The value of this parameter should be known before your program runs.
+-- @return [table] The dictionary used for preset dictionary compression and
+-- decompression.
+-- @raise error if 'strlen' does not match the length of 'str',
+-- or if 'adler32' does not match the Adler-32 checksum of 'str'.
+function LibDeflate:CreateDictionary(str, strlen, adler32)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ if type(strlen) ~= "number" then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'strlen' - number expected got '%s'."):format(
+ type(strlen)), 2)
+ end
+ if type(adler32) ~= "number" then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'adler32' - number expected got '%s'."):format(
+ type(adler32)), 2)
+ end
+ if strlen ~= #str then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'strlen' does not match the actual length of 'str'."
+ .." 'strlen': %u, '#str': %u ."
+ .." Please check if 'str' is modified unintentionally.")
+ :format(strlen, #str))
+ end
+ if strlen == 0 then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'str' - Empty string is not allowed."), 2)
+ end
+ if strlen > 32768 then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'str' - string longer than 32768 bytes is not allowed."
+ .." Got %d bytes."):format(strlen), 2)
+ end
+ local actual_adler32 = self:Adler32(str)
+ if not IsEqualAdler32(adler32, actual_adler32) then
+ error(("Usage: LibDeflate:CreateDictionary(str, strlen, adler32):"
+ .." 'adler32' does not match the actual adler32 of 'str'."
+ .." 'adler32': %u, 'Adler32(str)': %u ."
+ .." Please check if 'str' is modified unintentionally.")
+ :format(adler32, actual_adler32))
+ end
+
+ local dictionary = {}
+ dictionary.adler32 = adler32
+ dictionary.hash_tables = {}
+ dictionary.string_table = {}
+ dictionary.strlen = strlen
+ local string_table = dictionary.string_table
+ local hash_tables = dictionary.hash_tables
+ string_table[1] = string_byte(str, 1, 1)
+ string_table[2] = string_byte(str, 2, 2)
+ if strlen >= 3 then
+ local i = 1
+ local hash = string_table[1]*256+string_table[2]
+ while i <= strlen - 2 - 3 do
+ local x1, x2, x3, x4 = string_byte(str, i+2, i+5)
+ string_table[i+2] = x1
+ string_table[i+3] = x2
+ string_table[i+4] = x3
+ string_table[i+5] = x4
+ hash = (hash*256+x1)%16777216
+ local t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = i-strlen
+ i = i + 1
+ hash = (hash*256+x2)%16777216
+ t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = i-strlen
+ i = i + 1
+ hash = (hash*256+x3)%16777216
+ t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = i-strlen
+ i = i + 1
+ hash = (hash*256+x4)%16777216
+ t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = i-strlen
+ i = i + 1
+ end
+ while i <= strlen - 2 do
+ local x = string_byte(str, i+2)
+ string_table[i+2] = x
+ hash = (hash*256+x)%16777216
+ local t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = i-strlen
+ i = i + 1
+ end
+ end
+ return dictionary
+end
+
+-- Check if the dictionary is valid.
+-- @param dictionary The preset dictionary for compression and decompression.
+-- @return true if valid, false if not valid.
+-- @return if not valid, the error message.
+local function IsValidDictionary(dictionary)
+ if type(dictionary) ~= "table" then
+ return false, ("'dictionary' - table expected got '%s'.")
+ :format(type(dictionary))
+ end
+ if type(dictionary.adler32) ~= "number"
+ or type(dictionary.string_table) ~= "table"
+ or type(dictionary.strlen) ~= "number"
+ or dictionary.strlen <= 0
+ or dictionary.strlen > 32768
+ or dictionary.strlen ~= #dictionary.string_table
+ or type(dictionary.hash_tables) ~= "table"
+ then
+ return false, ("'dictionary' - corrupted dictionary.")
+ :format(type(dictionary))
+ end
+ return true, ""
+end
+
+--[[
+ key of the configuration table is the compression level,
+ and its value stores the compression setting.
+ These numbers come from zlib source code.
+
+ Higher compression level usually means better compression.
+ (Because LibDeflate uses a simplified version of zlib algorithm,
+ there is no guarantee that higher compression level does not create
+ bigger file than lower level, but I can say it's 99% likely)
+
+ Be careful with the high compression level. This is a pure lua
+ implementation compressor/decompressor, which is significant slower than
+ a C/C++ equivalant compressor/decompressor. Very high compression level
+ costs significant more CPU time, and usually compression size won't be
+ significant smaller when you increase compression level by 1, when the
+ level is already very high. Benchmark yourself if you can afford it.
+
+ See also https://github.com/madler/zlib/blob/master/doc/algorithm.txt,
+ https://github.com/madler/zlib/blob/master/deflate.c for more information.
+
+ The meaning of each field:
+ @field 1 use_lazy_evaluation:
+ true/false. Whether the program uses lazy evaluation.
+ See what is "lazy evaluation" in the link above.
+ lazy_evaluation improves ratio, but relatively slow.
+ @field 2 good_prev_length:
+ Only effective if lazy is set, Only use 1/4 of max_chain,
+ if prev length of lazy match is above this.
+ @field 3 max_insert_length/max_lazy_match:
+ If not using lazy evaluation,
+ insert new strings in the hash table only if the match length is not
+ greater than this length.
+ If using lazy evaluation, only continue lazy evaluation,
+ if previous match length is strictly smaller than this value.
+ @field 4 nice_length:
+ Number. Don't continue to go down the hash chain,
+ if match length is above this.
+ @field 5 max_chain:
+ Number. The maximum number of hash chains we look.
+--]]
+local _compression_level_configs = {
+ [0] = {false, nil, 0, 0, 0}, -- level 0, no compression
+ [1] = {false, nil, 4, 8, 4}, -- level 1, similar to zlib level 1
+ [2] = {false, nil, 5, 18, 8}, -- level 2, similar to zlib level 2
+ [3] = {false, nil, 6, 32, 32}, -- level 3, similar to zlib level 3
+ [4] = {true, 4, 4, 16, 16}, -- level 4, similar to zlib level 4
+ [5] = {true, 8, 16, 32, 32}, -- level 5, similar to zlib level 5
+ [6] = {true, 8, 16, 128, 128}, -- level 6, similar to zlib level 6
+ [7] = {true, 8, 32, 128, 256}, -- (SLOW) level 7, similar to zlib level 7
+ [8] = {true, 32, 128, 258, 1024} , --(SLOW) level 8,similar to zlib level 8
+ [9] = {true, 32, 258, 258, 4096},
+ -- (VERY SLOW) level 9, similar to zlib level 9
+}
+
+-- Check if the compression/decompression arguments is valid
+-- @param str The input string.
+-- @param check_dictionary if true, check if dictionary is valid.
+-- @param dictionary The preset dictionary for compression and decompression.
+-- @param check_configs if true, check if config is valid.
+-- @param configs The compression configuration table
+-- @return true if valid, false if not valid.
+-- @return if not valid, the error message.
+local function IsValidArguments(str,
+ check_dictionary, dictionary,
+ check_configs, configs)
+
+ if type(str) ~= "string" then
+ return false,
+ ("'str' - string expected got '%s'."):format(type(str))
+ end
+ if check_dictionary then
+ local dict_valid, dict_err = IsValidDictionary(dictionary)
+ if not dict_valid then
+ return false, dict_err
+ end
+ end
+ if check_configs then
+ local type_configs = type(configs)
+ if type_configs ~= "nil" and type_configs ~= "table" then
+ return false,
+ ("'configs' - nil or table expected got '%s'.")
+ :format(type(configs))
+ end
+ if type_configs == "table" then
+ for k, v in pairs(configs) do
+ if k ~= "level" and k ~= "strategy" then
+ return false,
+ ("'configs' - unsupported table key in the configs: '%s'.")
+ :format(k)
+ elseif k == "level" and not _compression_level_configs[v] then
+ return false,
+ ("'configs' - unsupported 'level': %s."):format(tostring(v))
+ elseif k == "strategy" and v ~= "fixed" and v ~= "huffman_only"
+ and v ~= "dynamic" then
+ -- random_block_type is for testing purpose
+ return false, ("'configs' - unsupported 'strategy': '%s'.")
+ :format(tostring(v))
+ end
+ end
+ end
+ end
+ return true, ""
+end
+
+
+
+--[[ --------------------------------------------------------------------------
+ Compress code
+--]] --------------------------------------------------------------------------
+
+-- partial flush to save memory
+local _FLUSH_MODE_MEMORY_CLEANUP = 0
+-- full flush with partial bytes
+local _FLUSH_MODE_OUTPUT = 1
+-- write bytes to get to byte boundary
+local _FLUSH_MODE_BYTE_BOUNDARY = 2
+-- no flush, just get num of bits written so far
+local _FLUSH_MODE_NO_FLUSH = 3
+
+--[[
+ Create an empty writer to easily write stuffs as the unit of bits.
+ Return values:
+ 1. WriteBits(code, bitlen):
+ 2. WriteString(str):
+ 3. Flush(mode):
+--]]
+local function CreateWriter()
+ local buffer_size = 0
+ local cache = 0
+ local cache_bitlen = 0
+ local total_bitlen = 0
+ local buffer = {}
+ -- When buffer is big enough, flush into result_buffer to save memory.
+ local result_buffer = {}
+
+ -- Write bits with value "value" and bit length of "bitlen" into writer.
+ -- @param value: The value being written
+ -- @param bitlen: The bit length of "value"
+ -- @return nil
+ local function WriteBits(value, bitlen)
+ cache = cache + value * _pow2[cache_bitlen]
+ cache_bitlen = cache_bitlen + bitlen
+ total_bitlen = total_bitlen + bitlen
+ -- Only bulk to buffer every 4 bytes. This is quicker.
+ if cache_bitlen >= 32 then
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] =
+ _byte_to_char[cache % 256]
+ .._byte_to_char[((cache-cache%256)/256 % 256)]
+ .._byte_to_char[((cache-cache%65536)/65536 % 256)]
+ .._byte_to_char[((cache-cache%16777216)/16777216 % 256)]
+ local rshift_mask = _pow2[32 - cache_bitlen + bitlen]
+ cache = (value - value%rshift_mask)/rshift_mask
+ cache_bitlen = cache_bitlen - 32
+ end
+ end
+
+ -- Write the entire string into the writer.
+ -- @param str The string being written
+ -- @return nil
+ local function WriteString(str)
+ for _ = 1, cache_bitlen, 8 do
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = string_char(cache % 256)
+ cache = (cache-cache%256)/256
+ end
+ cache_bitlen = 0
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = str
+ total_bitlen = total_bitlen + #str*8
+ end
+
+ -- Flush current stuffs in the writer and return it.
+ -- This operation will free most of the memory.
+ -- @param mode See the descrtion of the constant and the source code.
+ -- @return The total number of bits stored in the writer right now.
+ -- for byte boundary mode, it includes the padding bits.
+ -- for output mode, it does not include padding bits.
+ -- @return Return the outputs if mode is output.
+ local function FlushWriter(mode)
+ if mode == _FLUSH_MODE_NO_FLUSH then
+ return total_bitlen
+ end
+
+ if mode == _FLUSH_MODE_OUTPUT
+ or mode == _FLUSH_MODE_BYTE_BOUNDARY then
+ -- Full flush, also output cache.
+ -- Need to pad some bits if cache_bitlen is not multiple of 8.
+ local padding_bitlen = (8 - cache_bitlen % 8) % 8
+
+ if cache_bitlen > 0 then
+ -- padding with all 1 bits, mainly because "\000" is not
+ -- good to be tranmitted. I do this so "\000" is a little bit
+ -- less frequent.
+ cache = cache - _pow2[cache_bitlen]
+ + _pow2[cache_bitlen+padding_bitlen]
+ for _ = 1, cache_bitlen, 8 do
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = _byte_to_char[cache % 256]
+ cache = (cache-cache%256)/256
+ end
+
+ cache = 0
+ cache_bitlen = 0
+ end
+ if mode == _FLUSH_MODE_BYTE_BOUNDARY then
+ total_bitlen = total_bitlen + padding_bitlen
+ return total_bitlen
+ end
+ end
+
+ local flushed = table_concat(buffer)
+ buffer = {}
+ buffer_size = 0
+ result_buffer[#result_buffer+1] = flushed
+
+ if mode == _FLUSH_MODE_MEMORY_CLEANUP then
+ return total_bitlen
+ else
+ return total_bitlen, table_concat(result_buffer)
+ end
+ end
+
+ return WriteBits, WriteString, FlushWriter
+end
+
+-- Push an element into a max heap
+-- @param heap A max heap whose max element is at index 1.
+-- @param e The element to be pushed. Assume element "e" is a table
+-- and comparison is done via its first entry e[1]
+-- @param heap_size current number of elements in the heap.
+-- NOTE: There may be some garbage stored in
+-- heap[heap_size+1], heap[heap_size+2], etc..
+-- @return nil
+local function MinHeapPush(heap, e, heap_size)
+ heap_size = heap_size + 1
+ heap[heap_size] = e
+ local value = e[1]
+ local pos = heap_size
+ local parent_pos = (pos-pos%2)/2
+
+ while (parent_pos >= 1 and heap[parent_pos][1] > value) do
+ local t = heap[parent_pos]
+ heap[parent_pos] = e
+ heap[pos] = t
+ pos = parent_pos
+ parent_pos = (parent_pos-parent_pos%2)/2
+ end
+end
+
+-- Pop an element from a max heap
+-- @param heap A max heap whose max element is at index 1.
+-- @param heap_size current number of elements in the heap.
+-- @return the poped element
+-- Note: This function does not change table size of "heap" to save CPU time.
+local function MinHeapPop(heap, heap_size)
+ local top = heap[1]
+ local e = heap[heap_size]
+ local value = e[1]
+ heap[1] = e
+ heap[heap_size] = top
+ heap_size = heap_size - 1
+
+ local pos = 1
+ local left_child_pos = pos * 2
+ local right_child_pos = left_child_pos + 1
+
+ while (left_child_pos <= heap_size) do
+ local left_child = heap[left_child_pos]
+ if (right_child_pos <= heap_size
+ and heap[right_child_pos][1] < left_child[1]) then
+ local right_child = heap[right_child_pos]
+ if right_child[1] < value then
+ heap[right_child_pos] = e
+ heap[pos] = right_child
+ pos = right_child_pos
+ left_child_pos = pos * 2
+ right_child_pos = left_child_pos + 1
+ else
+ break
+ end
+ else
+ if left_child[1] < value then
+ heap[left_child_pos] = e
+ heap[pos] = left_child
+ pos = left_child_pos
+ left_child_pos = pos * 2
+ right_child_pos = left_child_pos + 1
+ else
+ break
+ end
+ end
+ end
+
+ return top
+end
+
+-- Deflate defines a special huffman tree, which is unique once the bit length
+-- of huffman code of all symbols are known.
+-- @param bitlen_count Number of symbols with a specific bitlen
+-- @param symbol_bitlen The bit length of a symbol
+-- @param max_symbol The max symbol among all symbols,
+-- which is (number of symbols - 1)
+-- @param max_bitlen The max huffman bit length among all symbols.
+-- @return The huffman code of all symbols.
+local function GetHuffmanCodeFromBitlen(bitlen_counts, symbol_bitlens
+ , max_symbol, max_bitlen)
+ local huffman_code = 0
+ local next_codes = {}
+ local symbol_huffman_codes = {}
+ for bitlen = 1, max_bitlen do
+ huffman_code = (huffman_code+(bitlen_counts[bitlen-1] or 0))*2
+ next_codes[bitlen] = huffman_code
+ end
+ for symbol = 0, max_symbol do
+ local bitlen = symbol_bitlens[symbol]
+ if bitlen then
+ huffman_code = next_codes[bitlen]
+ next_codes[bitlen] = huffman_code + 1
+
+ -- Reverse the bits of huffman code,
+ -- because most signifant bits of huffman code
+ -- is stored first into the compressed data.
+ -- @see RFC1951 Page5 Section 3.1.1
+ if bitlen <= 9 then -- Have cached reverse for small bitlen.
+ symbol_huffman_codes[symbol] =
+ _reverse_bits_tbl[bitlen][huffman_code]
+ else
+ local reverse = 0
+ for _ = 1, bitlen do
+ reverse = reverse - reverse%2
+ + (((reverse%2==1)
+ or (huffman_code % 2) == 1) and 1 or 0)
+ huffman_code = (huffman_code-huffman_code%2)/2
+ reverse = reverse*2
+ end
+ symbol_huffman_codes[symbol] = (reverse-reverse%2)/2
+ end
+ end
+ end
+ return symbol_huffman_codes
+end
+
+-- A helper function to sort heap elements
+-- a[1], b[1] is the huffman frequency
+-- a[2], b[2] is the symbol value.
+local function SortByFirstThenSecond(a, b)
+ return a[1] < b[1] or
+ (a[1] == b[1] and a[2] < b[2])
+end
+
+-- Calculate the huffman bit length and huffman code.
+-- @param symbol_count: A table whose table key is the symbol, and table value
+-- is the symbol frenquency (nil means 0 frequency).
+-- @param max_bitlen: See description of return value.
+-- @param max_symbol: The maximum symbol
+-- @return a table whose key is the symbol, and the value is the huffman bit
+-- bit length. We guarantee that all bit length <= max_bitlen.
+-- For 0<=symbol<=max_symbol, table value could be nil if the frequency
+-- of the symbol is 0 or nil.
+-- @return a table whose key is the symbol, and the value is the huffman code.
+-- @return a number indicating the maximum symbol whose bitlen is not 0.
+local function GetHuffmanBitlenAndCode(symbol_counts, max_bitlen, max_symbol)
+ local heap_size
+ local max_non_zero_bitlen_symbol = -1
+ local leafs = {}
+ local heap = {}
+ local symbol_bitlens = {}
+ local symbol_codes = {}
+ local bitlen_counts = {}
+
+ --[[
+ tree[1]: weight, temporarily used as parent and bitLengths
+ tree[2]: symbol
+ tree[3]: left child
+ tree[4]: right child
+ --]]
+ local number_unique_symbols = 0
+ for symbol, count in pairs(symbol_counts) do
+ number_unique_symbols = number_unique_symbols + 1
+ leafs[number_unique_symbols] = {count, symbol}
+ end
+
+ if (number_unique_symbols == 0) then
+ -- no code.
+ return {}, {}, -1
+ elseif (number_unique_symbols == 1) then
+ -- Only one code. In this case, its huffman code
+ -- needs to be assigned as 0, and bit length is 1.
+ -- This is the only case that the return result
+ -- represents an imcomplete huffman tree.
+ local symbol = leafs[1][2]
+ symbol_bitlens[symbol] = 1
+ symbol_codes[symbol] = 0
+ return symbol_bitlens, symbol_codes, symbol
+ else
+ table_sort(leafs, SortByFirstThenSecond)
+ heap_size = number_unique_symbols
+ for i = 1, heap_size do
+ heap[i] = leafs[i]
+ end
+
+ while (heap_size > 1) do
+ -- Note: pop does not change table size of heap
+ local leftChild = MinHeapPop(heap, heap_size)
+ heap_size = heap_size - 1
+ local rightChild = MinHeapPop(heap, heap_size)
+ heap_size = heap_size - 1
+ local newNode =
+ {leftChild[1]+rightChild[1], -1, leftChild, rightChild}
+ MinHeapPush(heap, newNode, heap_size)
+ heap_size = heap_size + 1
+ end
+
+ -- Number of leafs whose bit length is greater than max_len.
+ local number_bitlen_overflow = 0
+
+ -- Calculate bit length of all nodes
+ local fifo = {heap[1], 0, 0, 0} -- preallocate some spaces.
+ local fifo_size = 1
+ local index = 1
+ heap[1][1] = 0
+ while (index <= fifo_size) do -- Breath first search
+ local e = fifo[index]
+ local bitlen = e[1]
+ local symbol = e[2]
+ local left_child = e[3]
+ local right_child = e[4]
+ if left_child then
+ fifo_size = fifo_size + 1
+ fifo[fifo_size] = left_child
+ left_child[1] = bitlen + 1
+ end
+ if right_child then
+ fifo_size = fifo_size + 1
+ fifo[fifo_size] = right_child
+ right_child[1] = bitlen + 1
+ end
+ index = index + 1
+
+ if (bitlen > max_bitlen) then
+ number_bitlen_overflow = number_bitlen_overflow + 1
+ bitlen = max_bitlen
+ end
+ if symbol >= 0 then
+ symbol_bitlens[symbol] = bitlen
+ max_non_zero_bitlen_symbol =
+ (symbol > max_non_zero_bitlen_symbol)
+ and symbol or max_non_zero_bitlen_symbol
+ bitlen_counts[bitlen] = (bitlen_counts[bitlen] or 0) + 1
+ end
+ end
+
+ -- Resolve bit length overflow
+ -- @see ZLib/trees.c:gen_bitlen(s, desc), for reference
+ if (number_bitlen_overflow > 0) then
+ repeat
+ local bitlen = max_bitlen - 1
+ while ((bitlen_counts[bitlen] or 0) == 0) do
+ bitlen = bitlen - 1
+ end
+ -- move one leaf down the tree
+ bitlen_counts[bitlen] = bitlen_counts[bitlen] - 1
+ -- move one overflow item as its brother
+ bitlen_counts[bitlen+1] = (bitlen_counts[bitlen+1] or 0) + 2
+ bitlen_counts[max_bitlen] = bitlen_counts[max_bitlen] - 1
+ number_bitlen_overflow = number_bitlen_overflow - 2
+ until (number_bitlen_overflow <= 0)
+
+ index = 1
+ for bitlen = max_bitlen, 1, -1 do
+ local n = bitlen_counts[bitlen] or 0
+ while (n > 0) do
+ local symbol = leafs[index][2]
+ symbol_bitlens[symbol] = bitlen
+ n = n - 1
+ index = index + 1
+ end
+ end
+ end
+
+ symbol_codes = GetHuffmanCodeFromBitlen(bitlen_counts, symbol_bitlens,
+ max_symbol, max_bitlen)
+ return symbol_bitlens, symbol_codes, max_non_zero_bitlen_symbol
+ end
+end
+
+-- Calculate the first huffman header in the dynamic huffman block
+-- @see RFC1951 Page 12
+-- @param lcode_bitlen: The huffman bit length of literal/LZ77_length.
+-- @param max_non_zero_bitlen_lcode: The maximum literal/LZ77_length symbol
+-- whose huffman bit length is not zero.
+-- @param dcode_bitlen: The huffman bit length of LZ77 distance.
+-- @param max_non_zero_bitlen_dcode: The maximum LZ77 distance symbol
+-- whose huffman bit length is not zero.
+-- @return The run length encoded codes.
+-- @return The extra bits. One entry for each rle code that needs extra bits.
+-- (code == 16 or 17 or 18).
+-- @return The count of appearance of each rle codes.
+local function RunLengthEncodeHuffmanBitlen(
+ lcode_bitlens,
+ max_non_zero_bitlen_lcode,
+ dcode_bitlens,
+ max_non_zero_bitlen_dcode)
+ local rle_code_tblsize = 0
+ local rle_codes = {}
+ local rle_code_counts = {}
+ local rle_extra_bits_tblsize = 0
+ local rle_extra_bits = {}
+ local prev = nil
+ local count = 0
+
+ -- If there is no distance code, assume one distance code of bit length 0.
+ -- RFC1951: One distance code of zero bits means that
+ -- there are no distance codes used at all (the data is all literals).
+ max_non_zero_bitlen_dcode = (max_non_zero_bitlen_dcode < 0)
+ and 0 or max_non_zero_bitlen_dcode
+ local max_code = max_non_zero_bitlen_lcode+max_non_zero_bitlen_dcode+1
+
+ for code = 0, max_code+1 do
+ local len = (code <= max_non_zero_bitlen_lcode)
+ and (lcode_bitlens[code] or 0)
+ or ((code <= max_code)
+ and (dcode_bitlens[code-max_non_zero_bitlen_lcode-1] or 0) or nil)
+ if len == prev then
+ count = count + 1
+ if len ~= 0 and count == 6 then
+ rle_code_tblsize = rle_code_tblsize + 1
+ rle_codes[rle_code_tblsize] = 16
+ rle_extra_bits_tblsize = rle_extra_bits_tblsize + 1
+ rle_extra_bits[rle_extra_bits_tblsize] = 3
+ rle_code_counts[16] = (rle_code_counts[16] or 0) + 1
+ count = 0
+ elseif len == 0 and count == 138 then
+ rle_code_tblsize = rle_code_tblsize + 1
+ rle_codes[rle_code_tblsize] = 18
+ rle_extra_bits_tblsize = rle_extra_bits_tblsize + 1
+ rle_extra_bits[rle_extra_bits_tblsize] = 127
+ rle_code_counts[18] = (rle_code_counts[18] or 0) + 1
+ count = 0
+ end
+ else
+ if count == 1 then
+ rle_code_tblsize = rle_code_tblsize + 1
+ rle_codes[rle_code_tblsize] = prev
+ rle_code_counts[prev] = (rle_code_counts[prev] or 0) + 1
+ elseif count == 2 then
+ rle_code_tblsize = rle_code_tblsize + 1
+ rle_codes[rle_code_tblsize] = prev
+ rle_code_tblsize = rle_code_tblsize + 1
+ rle_codes[rle_code_tblsize] = prev
+ rle_code_counts[prev] = (rle_code_counts[prev] or 0) + 2
+ elseif count >= 3 then
+ rle_code_tblsize = rle_code_tblsize + 1
+ local rleCode = (prev ~= 0) and 16 or (count <= 10 and 17 or 18)
+ rle_codes[rle_code_tblsize] = rleCode
+ rle_code_counts[rleCode] = (rle_code_counts[rleCode] or 0) + 1
+ rle_extra_bits_tblsize = rle_extra_bits_tblsize + 1
+ rle_extra_bits[rle_extra_bits_tblsize] =
+ (count <= 10) and (count - 3) or (count - 11)
+ end
+
+ prev = len
+ if len and len ~= 0 then
+ rle_code_tblsize = rle_code_tblsize + 1
+ rle_codes[rle_code_tblsize] = len
+ rle_code_counts[len] = (rle_code_counts[len] or 0) + 1
+ count = 0
+ else
+ count = 1
+ end
+ end
+ end
+
+ return rle_codes, rle_extra_bits, rle_code_counts
+end
+
+-- Load the string into a table, in order to speed up LZ77.
+-- Loop unrolled 16 times to speed this function up.
+-- @param str The string to be loaded.
+-- @param t The load destination
+-- @param start str[index] will be the first character to be loaded.
+-- @param end str[index] will be the last character to be loaded
+-- @param offset str[index] will be loaded into t[index-offset]
+-- @return t
+local function LoadStringToTable(str, t, start, stop, offset)
+ local i = start - offset
+ while i <= stop - 15 - offset do
+ t[i], t[i+1], t[i+2], t[i+3], t[i+4], t[i+5], t[i+6], t[i+7], t[i+8],
+ t[i+9], t[i+10], t[i+11], t[i+12], t[i+13], t[i+14], t[i+15] =
+ string_byte(str, i + offset, i + 15 + offset)
+ i = i + 16
+ end
+ while (i <= stop - offset) do
+ t[i] = string_byte(str, i + offset, i + offset)
+ i = i + 1
+ end
+ return t
+end
+
+-- Do LZ77 process. This function uses the majority of the CPU time.
+-- @see zlib/deflate.c:deflate_fast(), zlib/deflate.c:deflate_slow()
+-- @see https://github.com/madler/zlib/blob/master/doc/algorithm.txt
+-- This function uses the algorithms used above. You should read the
+-- algorithm.txt above to understand what is the hash function and the
+-- lazy evaluation.
+--
+-- The special optimization used here is hash functions used here.
+-- The hash function is just the multiplication of the three consective
+-- characters. So if the hash matches, it guarantees 3 characters are matched.
+-- This optimization can be implemented because Lua table is a hash table.
+--
+-- @param level integer that describes compression level.
+-- @param string_table table that stores the value of string to be compressed.
+-- The index of this table starts from 1.
+-- The caller needs to make sure all values needed by this function
+-- are loaded.
+-- Assume "str" is the origin input string into the compressor
+-- str[block_start]..str[block_end+3] needs to be loaded into
+-- string_table[block_start-offset]..string_table[block_end-offset]
+-- If dictionary is presented, the last 258 bytes of the dictionary
+-- needs to be loaded into sing_table[-257..0]
+-- (See more in the description of offset.)
+-- @param hash_tables. The table key is the hash value (0<=hash<=16777216=256^3)
+-- The table value is an array0 that stores the indexes of the
+-- input data string to be compressed, such that
+-- hash == str[index]*str[index+1]*str[index+2]
+-- Indexes are ordered in this array.
+-- @param block_start The indexes of the input data string to be compressed.
+-- that starts the LZ77 block.
+-- @param block_end The indexes of the input data string to be compressed.
+-- that stores the LZ77 block.
+-- @param offset str[index] is stored in string_table[index-offset],
+-- This offset is mainly an optimization to limit the index
+-- of string_table, so lua can access this table quicker.
+-- @param dictionary See LibDeflate:CreateDictionary
+-- @return literal/LZ77_length deflate codes.
+-- @return the extra bits of literal/LZ77_length deflate codes.
+-- @return the count of each literal/LZ77 deflate code.
+-- @return LZ77 distance deflate codes.
+-- @return the extra bits of LZ77 distance deflate codes.
+-- @return the count of each LZ77 distance deflate code.
+local function GetBlockLZ77Result(level, string_table, hash_tables, block_start,
+ block_end, offset, dictionary)
+ local config = _compression_level_configs[level]
+ local config_use_lazy
+ , config_good_prev_length
+ , config_max_lazy_match
+ , config_nice_length
+ , config_max_hash_chain =
+ config[1], config[2], config[3], config[4], config[5]
+
+ local config_max_insert_length = (not config_use_lazy)
+ and config_max_lazy_match or 2147483646
+ local config_good_hash_chain =
+ (config_max_hash_chain-config_max_hash_chain%4/4)
+
+ local hash
+
+ local dict_hash_tables
+ local dict_string_table
+ local dict_string_len = 0
+
+ if dictionary then
+ dict_hash_tables = dictionary.hash_tables
+ dict_string_table = dictionary.string_table
+ dict_string_len = dictionary.strlen
+ assert(block_start == 1)
+ if block_end >= block_start and dict_string_len >= 2 then
+ hash = dict_string_table[dict_string_len-1]*65536
+ + dict_string_table[dict_string_len]*256 + string_table[1]
+ local t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = -1
+ end
+ if block_end >= block_start+1 and dict_string_len >= 1 then
+ hash = dict_string_table[dict_string_len]*65536
+ + string_table[1]*256 + string_table[2]
+ local t = hash_tables[hash]
+ if not t then t = {}; hash_tables[hash] = t end
+ t[#t+1] = 0
+ end
+ end
+
+ hash = (string_table[block_start-offset] or 0)*256
+ + (string_table[block_start+1-offset] or 0)
+
+ local lcodes = {}
+ local lcode_tblsize = 0
+ local lcodes_counts = {}
+ local dcodes = {}
+ local dcodes_tblsize = 0
+ local dcodes_counts = {}
+
+ local lextra_bits = {}
+ local lextra_bits_tblsize = 0
+ local dextra_bits = {}
+ local dextra_bits_tblsize = 0
+
+ local match_available = false
+ local prev_len
+ local prev_dist
+ local cur_len = 0
+ local cur_dist = 0
+
+ local index = block_start
+ local index_end = block_end + (config_use_lazy and 1 or 0)
+
+ -- the zlib source code writes separate code for lazy evaluation and
+ -- not lazy evaluation, which is easier to understand.
+ -- I put them together, so it is a bit harder to understand.
+ -- because I think this is easier for me to maintain it.
+ while (index <= index_end) do
+ local string_table_index = index - offset
+ prev_len = cur_len
+ prev_dist = cur_dist
+ cur_len = 0
+
+ hash = (hash*256+(string_table[string_table_index+2] or 0))%16777216
+
+ local chain_index
+ local cur_chain
+ local hash_chain = hash_tables[hash]
+ local chain_old_size
+ if not hash_chain then
+ chain_old_size = 0
+ hash_chain = {}
+ hash_tables[hash] = hash_chain
+ if dict_hash_tables then
+ cur_chain = dict_hash_tables[hash]
+ chain_index = cur_chain and #cur_chain or 0
+ else
+ chain_index = 0
+ end
+ else
+ chain_old_size = #hash_chain
+ cur_chain = hash_chain
+ chain_index = chain_old_size
+ end
+
+ if index <= block_end then
+ hash_chain[chain_old_size+1] = index
+ end
+
+ if (chain_index > 0 and index + 2 <= block_end
+ and (not config_use_lazy or prev_len < config_max_lazy_match)) then
+
+ local depth =
+ (config_use_lazy and prev_len >= config_good_prev_length)
+ and config_good_hash_chain or config_max_hash_chain
+
+ while chain_index >= 1 and depth > 0 do
+ local prev = cur_chain[chain_index]
+
+ if index - prev > 32768 then
+ break
+ end
+ if prev < index then
+ local j = 3
+
+ if prev >= -257 then
+ local prev_table_index = prev-offset
+ -- NOTE for author:
+ -- j < 258 and index + j <= block_end
+ -- This is the right condition
+ while (j < 258 and index + j <= block_end) do
+ if (string_table[prev_table_index+j]
+ == string_table[string_table_index+j]) then
+ j = j + 1
+ else
+ break
+ end
+ end
+ else
+ local prev_table_index = dict_string_len+prev
+ -- NOTE for author:
+ -- j < 258 and index + j <= block_end
+ -- This is the right condition
+ while (j < 258 and index + j <= block_end) do
+ if (dict_string_table[prev_table_index+j]
+ == string_table[string_table_index+j]) then
+ j = j + 1
+ else
+ break
+ end
+ end
+ end
+ if j > cur_len then
+ cur_len = j
+ cur_dist = index - prev
+ end
+ if cur_len >= config_nice_length then
+ break
+ end
+ end
+
+ chain_index = chain_index - 1
+ depth = depth - 1
+ if chain_index == 0 and prev > 0 and dict_hash_tables then
+ cur_chain = dict_hash_tables[hash]
+ chain_index = cur_chain and #cur_chain or 0
+ end
+ end
+ end
+
+ if not config_use_lazy then
+ prev_len, prev_dist = cur_len, cur_dist
+ end
+ if ((not config_use_lazy or match_available)
+ and (prev_len > 3 or (prev_len == 3 and prev_dist < 4096))
+ and cur_len <= prev_len )then
+ local code = _length_to_deflate_code[prev_len]
+ local length_extra_bits_bitlen =
+ _length_to_deflate_extra_bitlen[prev_len]
+ local dist_code, dist_extra_bits_bitlen, dist_extra_bits
+ if prev_dist <= 256 then -- have cached code for small distance.
+ dist_code = _dist256_to_deflate_code[prev_dist]
+ dist_extra_bits = _dist256_to_deflate_extra_bits[prev_dist]
+ dist_extra_bits_bitlen =
+ _dist256_to_deflate_extra_bitlen[prev_dist]
+ else
+ dist_code = 16
+ dist_extra_bits_bitlen = 7
+ local a = 384
+ local b = 512
+
+ while true do
+ if prev_dist <= a then
+ dist_extra_bits = (prev_dist-(b/2)-1) % (b/4)
+ break
+ elseif prev_dist <= b then
+ dist_extra_bits = (prev_dist-(b/2)-1) % (b/4)
+ dist_code = dist_code + 1
+ break
+ else
+ dist_code = dist_code + 2
+ dist_extra_bits_bitlen = dist_extra_bits_bitlen + 1
+ a = a*2
+ b = b*2
+ end
+ end
+ end
+ lcode_tblsize = lcode_tblsize + 1
+ lcodes[lcode_tblsize] = code
+ lcodes_counts[code] = (lcodes_counts[code] or 0) + 1
+
+ dcodes_tblsize = dcodes_tblsize + 1
+ dcodes[dcodes_tblsize] = dist_code
+ dcodes_counts[dist_code] = (dcodes_counts[dist_code] or 0) + 1
+
+ if length_extra_bits_bitlen > 0 then
+ local lenExtraBits = _length_to_deflate_extra_bits[prev_len]
+ lextra_bits_tblsize = lextra_bits_tblsize + 1
+ lextra_bits[lextra_bits_tblsize] = lenExtraBits
+ end
+ if dist_extra_bits_bitlen > 0 then
+ dextra_bits_tblsize = dextra_bits_tblsize + 1
+ dextra_bits[dextra_bits_tblsize] = dist_extra_bits
+ end
+
+ for i=index+1, index+prev_len-(config_use_lazy and 2 or 1) do
+ hash = (hash*256+(string_table[i-offset+2] or 0))%16777216
+ if prev_len <= config_max_insert_length then
+ hash_chain = hash_tables[hash]
+ if not hash_chain then
+ hash_chain = {}
+ hash_tables[hash] = hash_chain
+ end
+ hash_chain[#hash_chain+1] = i
+ end
+ end
+ index = index + prev_len - (config_use_lazy and 1 or 0)
+ match_available = false
+ elseif (not config_use_lazy) or match_available then
+ local code = string_table[config_use_lazy
+ and (string_table_index-1) or string_table_index]
+ lcode_tblsize = lcode_tblsize + 1
+ lcodes[lcode_tblsize] = code
+ lcodes_counts[code] = (lcodes_counts[code] or 0) + 1
+ index = index + 1
+ else
+ match_available = true
+ index = index + 1
+ end
+ end
+
+ -- Write "end of block" symbol
+ lcode_tblsize = lcode_tblsize + 1
+ lcodes[lcode_tblsize] = 256
+ lcodes_counts[256] = (lcodes_counts[256] or 0) + 1
+
+ return lcodes, lextra_bits, lcodes_counts, dcodes, dextra_bits
+ , dcodes_counts
+end
+
+-- Get the header data of dynamic block.
+-- @param lcodes_count The count of each literal/LZ77_length codes.
+-- @param dcodes_count The count of each Lz77 distance codes.
+-- @return a lots of stuffs.
+-- @see RFC1951 Page 12
+local function GetBlockDynamicHuffmanHeader(lcodes_counts, dcodes_counts)
+ local lcodes_huffman_bitlens, lcodes_huffman_codes
+ , max_non_zero_bitlen_lcode =
+ GetHuffmanBitlenAndCode(lcodes_counts, 15, 285)
+ local dcodes_huffman_bitlens, dcodes_huffman_codes
+ , max_non_zero_bitlen_dcode =
+ GetHuffmanBitlenAndCode(dcodes_counts, 15, 29)
+
+ local rle_deflate_codes, rle_extra_bits, rle_codes_counts =
+ RunLengthEncodeHuffmanBitlen(lcodes_huffman_bitlens
+ ,max_non_zero_bitlen_lcode, dcodes_huffman_bitlens
+ , max_non_zero_bitlen_dcode)
+
+ local rle_codes_huffman_bitlens, rle_codes_huffman_codes =
+ GetHuffmanBitlenAndCode(rle_codes_counts, 7, 18)
+
+ local HCLEN = 0
+ for i = 1, 19 do
+ local symbol = _rle_codes_huffman_bitlen_order[i]
+ local length = rle_codes_huffman_bitlens[symbol] or 0
+ if length ~= 0 then
+ HCLEN = i
+ end
+ end
+
+ HCLEN = HCLEN - 4
+ local HLIT = max_non_zero_bitlen_lcode + 1 - 257
+ local HDIST = max_non_zero_bitlen_dcode + 1 - 1
+ if HDIST < 0 then HDIST = 0 end
+
+ return HLIT, HDIST, HCLEN, rle_codes_huffman_bitlens
+ , rle_codes_huffman_codes, rle_deflate_codes, rle_extra_bits
+ , lcodes_huffman_bitlens, lcodes_huffman_codes
+ , dcodes_huffman_bitlens, dcodes_huffman_codes
+end
+
+-- Get the size of dynamic block without writing any bits into the writer.
+-- @param ... Read the source code of GetBlockDynamicHuffmanHeader()
+-- @return the bit length of the dynamic block
+local function GetDynamicHuffmanBlockSize(lcodes, dcodes, HCLEN
+ , rle_codes_huffman_bitlens, rle_deflate_codes
+ , lcodes_huffman_bitlens, dcodes_huffman_bitlens)
+
+ local block_bitlen = 17 -- 1+2+5+5+4
+ block_bitlen = block_bitlen + (HCLEN+4)*3
+
+ for i = 1, #rle_deflate_codes do
+ local code = rle_deflate_codes[i]
+ block_bitlen = block_bitlen + rle_codes_huffman_bitlens[code]
+ if code >= 16 then
+ block_bitlen = block_bitlen +
+ ((code == 16) and 2 or (code == 17 and 3 or 7))
+ end
+ end
+
+ local length_code_count = 0
+ for i = 1, #lcodes do
+ local code = lcodes[i]
+ local huffman_bitlen = lcodes_huffman_bitlens[code]
+ block_bitlen = block_bitlen + huffman_bitlen
+ if code > 256 then -- Length code
+ length_code_count = length_code_count + 1
+ if code > 264 and code < 285 then -- Length code with extra bits
+ local extra_bits_bitlen =
+ _literal_deflate_code_to_extra_bitlen[code-256]
+ block_bitlen = block_bitlen + extra_bits_bitlen
+ end
+ local dist_code = dcodes[length_code_count]
+ local dist_huffman_bitlen = dcodes_huffman_bitlens[dist_code]
+ block_bitlen = block_bitlen + dist_huffman_bitlen
+
+ if dist_code > 3 then -- dist code with extra bits
+ local dist_extra_bits_bitlen = (dist_code-dist_code%2)/2 - 1
+ block_bitlen = block_bitlen + dist_extra_bits_bitlen
+ end
+ end
+ end
+ return block_bitlen
+end
+
+-- Write dynamic block.
+-- @param ... Read the source code of GetBlockDynamicHuffmanHeader()
+local function CompressDynamicHuffmanBlock(WriteBits, is_last_block
+ , lcodes, lextra_bits, dcodes, dextra_bits, HLIT, HDIST, HCLEN
+ , rle_codes_huffman_bitlens, rle_codes_huffman_codes
+ , rle_deflate_codes, rle_extra_bits
+ , lcodes_huffman_bitlens, lcodes_huffman_codes
+ , dcodes_huffman_bitlens, dcodes_huffman_codes)
+
+ WriteBits(is_last_block and 1 or 0, 1) -- Last block identifier
+ WriteBits(2, 2) -- Dynamic Huffman block identifier
+
+ WriteBits(HLIT, 5)
+ WriteBits(HDIST, 5)
+ WriteBits(HCLEN, 4)
+
+ for i = 1, HCLEN+4 do
+ local symbol = _rle_codes_huffman_bitlen_order[i]
+ local length = rle_codes_huffman_bitlens[symbol] or 0
+ WriteBits(length, 3)
+ end
+
+ local rleExtraBitsIndex = 1
+ for i=1, #rle_deflate_codes do
+ local code = rle_deflate_codes[i]
+ WriteBits(rle_codes_huffman_codes[code]
+ , rle_codes_huffman_bitlens[code])
+ if code >= 16 then
+ local extraBits = rle_extra_bits[rleExtraBitsIndex]
+ WriteBits(extraBits, (code == 16) and 2 or (code == 17 and 3 or 7))
+ rleExtraBitsIndex = rleExtraBitsIndex + 1
+ end
+ end
+
+ local length_code_count = 0
+ local length_code_with_extra_count = 0
+ local dist_code_with_extra_count = 0
+
+ for i=1, #lcodes do
+ local deflate_codee = lcodes[i]
+ local huffman_code = lcodes_huffman_codes[deflate_codee]
+ local huffman_bitlen = lcodes_huffman_bitlens[deflate_codee]
+ WriteBits(huffman_code, huffman_bitlen)
+ if deflate_codee > 256 then -- Length code
+ length_code_count = length_code_count + 1
+ if deflate_codee > 264 and deflate_codee < 285 then
+ -- Length code with extra bits
+ length_code_with_extra_count = length_code_with_extra_count + 1
+ local extra_bits = lextra_bits[length_code_with_extra_count]
+ local extra_bits_bitlen =
+ _literal_deflate_code_to_extra_bitlen[deflate_codee-256]
+ WriteBits(extra_bits, extra_bits_bitlen)
+ end
+ -- Write distance code
+ local dist_deflate_code = dcodes[length_code_count]
+ local dist_huffman_code = dcodes_huffman_codes[dist_deflate_code]
+ local dist_huffman_bitlen =
+ dcodes_huffman_bitlens[dist_deflate_code]
+ WriteBits(dist_huffman_code, dist_huffman_bitlen)
+
+ if dist_deflate_code > 3 then -- dist code with extra bits
+ dist_code_with_extra_count = dist_code_with_extra_count + 1
+ local dist_extra_bits = dextra_bits[dist_code_with_extra_count]
+ local dist_extra_bits_bitlen =
+ (dist_deflate_code-dist_deflate_code%2)/2 - 1
+ WriteBits(dist_extra_bits, dist_extra_bits_bitlen)
+ end
+ end
+ end
+end
+
+-- Get the size of fixed block without writing any bits into the writer.
+-- @param lcodes literal/LZ77_length deflate codes
+-- @param decodes LZ77 distance deflate codes
+-- @return the bit length of the fixed block
+local function GetFixedHuffmanBlockSize(lcodes, dcodes)
+ local block_bitlen = 3
+ local length_code_count = 0
+ for i=1, #lcodes do
+ local code = lcodes[i]
+ local huffman_bitlen = _fix_block_literal_huffman_bitlen[code]
+ block_bitlen = block_bitlen + huffman_bitlen
+ if code > 256 then -- Length code
+ length_code_count = length_code_count + 1
+ if code > 264 and code < 285 then -- Length code with extra bits
+ local extra_bits_bitlen =
+ _literal_deflate_code_to_extra_bitlen[code-256]
+ block_bitlen = block_bitlen + extra_bits_bitlen
+ end
+ local dist_code = dcodes[length_code_count]
+ block_bitlen = block_bitlen + 5
+
+ if dist_code > 3 then -- dist code with extra bits
+ local dist_extra_bits_bitlen =
+ (dist_code-dist_code%2)/2 - 1
+ block_bitlen = block_bitlen + dist_extra_bits_bitlen
+ end
+ end
+ end
+ return block_bitlen
+end
+
+-- Write fixed block.
+-- @param lcodes literal/LZ77_length deflate codes
+-- @param decodes LZ77 distance deflate codes
+local function CompressFixedHuffmanBlock(WriteBits, is_last_block,
+ lcodes, lextra_bits, dcodes, dextra_bits)
+ WriteBits(is_last_block and 1 or 0, 1) -- Last block identifier
+ WriteBits(1, 2) -- Fixed Huffman block identifier
+ local length_code_count = 0
+ local length_code_with_extra_count = 0
+ local dist_code_with_extra_count = 0
+ for i=1, #lcodes do
+ local deflate_code = lcodes[i]
+ local huffman_code = _fix_block_literal_huffman_code[deflate_code]
+ local huffman_bitlen = _fix_block_literal_huffman_bitlen[deflate_code]
+ WriteBits(huffman_code, huffman_bitlen)
+ if deflate_code > 256 then -- Length code
+ length_code_count = length_code_count + 1
+ if deflate_code > 264 and deflate_code < 285 then
+ -- Length code with extra bits
+ length_code_with_extra_count = length_code_with_extra_count + 1
+ local extra_bits = lextra_bits[length_code_with_extra_count]
+ local extra_bits_bitlen =
+ _literal_deflate_code_to_extra_bitlen[deflate_code-256]
+ WriteBits(extra_bits, extra_bits_bitlen)
+ end
+ -- Write distance code
+ local dist_code = dcodes[length_code_count]
+ local dist_huffman_code = _fix_block_dist_huffman_code[dist_code]
+ WriteBits(dist_huffman_code, 5)
+
+ if dist_code > 3 then -- dist code with extra bits
+ dist_code_with_extra_count = dist_code_with_extra_count + 1
+ local dist_extra_bits = dextra_bits[dist_code_with_extra_count]
+ local dist_extra_bits_bitlen = (dist_code-dist_code%2)/2 - 1
+ WriteBits(dist_extra_bits, dist_extra_bits_bitlen)
+ end
+ end
+ end
+end
+
+-- Get the size of store block without writing any bits into the writer.
+-- @param block_start The start index of the origin input string
+-- @param block_end The end index of the origin input string
+-- @param Total bit lens had been written into the compressed result before,
+-- because store block needs to shift to byte boundary.
+-- @return the bit length of the fixed block
+local function GetStoreBlockSize(block_start, block_end, total_bitlen)
+ assert(block_end-block_start+1 <= 65535)
+ local block_bitlen = 3
+ total_bitlen = total_bitlen + 3
+ local padding_bitlen = (8-total_bitlen%8)%8
+ block_bitlen = block_bitlen + padding_bitlen
+ block_bitlen = block_bitlen + 32
+ block_bitlen = block_bitlen + (block_end - block_start + 1) * 8
+ return block_bitlen
+end
+
+-- Write the store block.
+-- @param ... lots of stuffs
+-- @return nil
+local function CompressStoreBlock(WriteBits, WriteString, is_last_block, str
+ , block_start, block_end, total_bitlen)
+ assert(block_end-block_start+1 <= 65535)
+ WriteBits(is_last_block and 1 or 0, 1) -- Last block identifer.
+ WriteBits(0, 2) -- Store block identifier.
+ total_bitlen = total_bitlen + 3
+ local padding_bitlen = (8-total_bitlen%8)%8
+ if padding_bitlen > 0 then
+ WriteBits(_pow2[padding_bitlen]-1, padding_bitlen)
+ end
+ local size = block_end - block_start + 1
+ WriteBits(size, 16)
+
+ -- Write size's one's complement
+ local comp = (255 - size % 256) + (255 - (size-size%256)/256)*256
+ WriteBits(comp, 16)
+
+ WriteString(str:sub(block_start, block_end))
+end
+
+-- Do the deflate
+-- Currently using a simple way to determine the block size
+-- (This is why the compression ratio is little bit worse than zlib when
+-- the input size is very large
+-- The first block is 64KB, the following block is 32KB.
+-- After each block, there is a memory cleanup operation.
+-- This is not a fast operation, but it is needed to save memory usage, so
+-- the memory usage does not grow unboundly. If the data size is less than
+-- 64KB, then memory cleanup won't happen.
+-- This function determines whether to use store/fixed/dynamic blocks by
+-- calculating the block size of each block type and chooses the smallest one.
+local function Deflate(configs, WriteBits, WriteString, FlushWriter, str
+ , dictionary)
+ local string_table = {}
+ local hash_tables = {}
+ local is_last_block = nil
+ local block_start
+ local block_end
+ local bitlen_written
+ local total_bitlen = FlushWriter(_FLUSH_MODE_NO_FLUSH)
+ local strlen = #str
+ local offset
+
+ local level
+ local strategy
+ if configs then
+ if configs.level then
+ level = configs.level
+ end
+ if configs.strategy then
+ strategy = configs.strategy
+ end
+ end
+
+ if not level then
+ if strlen < 2048 then
+ level = 7
+ elseif strlen > 65536 then
+ level = 3
+ else
+ level = 5
+ end
+ end
+
+ while not is_last_block do
+ if not block_start then
+ block_start = 1
+ block_end = 64*1024 - 1
+ offset = 0
+ else
+ block_start = block_end + 1
+ block_end = block_end + 32*1024
+ offset = block_start - 32*1024 - 1
+ end
+
+ if block_end >= strlen then
+ block_end = strlen
+ is_last_block = true
+ else
+ is_last_block = false
+ end
+
+ local lcodes, lextra_bits, lcodes_counts, dcodes, dextra_bits
+ , dcodes_counts
+
+ local HLIT, HDIST, HCLEN, rle_codes_huffman_bitlens
+ , rle_codes_huffman_codes, rle_deflate_codes
+ , rle_extra_bits, lcodes_huffman_bitlens, lcodes_huffman_codes
+ , dcodes_huffman_bitlens, dcodes_huffman_codes
+
+ local dynamic_block_bitlen
+ local fixed_block_bitlen
+ local store_block_bitlen
+
+ if level ~= 0 then
+
+ -- GetBlockLZ77 needs block_start to block_end+3 to be loaded.
+ LoadStringToTable(str, string_table, block_start, block_end + 3
+ , offset)
+ if block_start == 1 and dictionary then
+ local dict_string_table = dictionary.string_table
+ local dict_strlen = dictionary.strlen
+ for i=0, (-dict_strlen+1)<-257
+ and -257 or (-dict_strlen+1), -1 do
+ string_table[i] = dict_string_table[dict_strlen+i]
+ end
+ end
+
+ if strategy == "huffman_only" then
+ lcodes = {}
+ LoadStringToTable(str, lcodes, block_start, block_end
+ , block_start-1)
+ lextra_bits = {}
+ lcodes_counts = {}
+ lcodes[block_end - block_start+2] = 256 -- end of block
+ for i=1, block_end - block_start+2 do
+ local code = lcodes[i]
+ lcodes_counts[code] = (lcodes_counts[code] or 0) + 1
+ end
+ dcodes = {}
+ dextra_bits = {}
+ dcodes_counts = {}
+ else
+ lcodes, lextra_bits, lcodes_counts, dcodes, dextra_bits
+ , dcodes_counts = GetBlockLZ77Result(level, string_table
+ , hash_tables, block_start, block_end, offset, dictionary
+ )
+ end
+
+ HLIT, HDIST, HCLEN, rle_codes_huffman_bitlens
+ , rle_codes_huffman_codes, rle_deflate_codes
+ , rle_extra_bits, lcodes_huffman_bitlens, lcodes_huffman_codes
+ , dcodes_huffman_bitlens, dcodes_huffman_codes =
+ GetBlockDynamicHuffmanHeader(lcodes_counts, dcodes_counts)
+ dynamic_block_bitlen = GetDynamicHuffmanBlockSize(
+ lcodes, dcodes, HCLEN, rle_codes_huffman_bitlens
+ , rle_deflate_codes, lcodes_huffman_bitlens
+ , dcodes_huffman_bitlens)
+ fixed_block_bitlen = GetFixedHuffmanBlockSize(lcodes, dcodes)
+ end
+
+ store_block_bitlen = GetStoreBlockSize(block_start, block_end
+ , total_bitlen)
+
+ local min_bitlen = store_block_bitlen
+ min_bitlen = (fixed_block_bitlen and fixed_block_bitlen < min_bitlen)
+ and fixed_block_bitlen or min_bitlen
+ min_bitlen = (dynamic_block_bitlen
+ and dynamic_block_bitlen < min_bitlen)
+ and dynamic_block_bitlen or min_bitlen
+
+ if level == 0 or (strategy ~= "fixed" and strategy ~= "dynamic" and
+ store_block_bitlen == min_bitlen) then
+ CompressStoreBlock(WriteBits, WriteString, is_last_block
+ , str, block_start, block_end, total_bitlen)
+ total_bitlen = total_bitlen + store_block_bitlen
+ elseif strategy ~= "dynamic" and (
+ strategy == "fixed" or fixed_block_bitlen == min_bitlen) then
+ CompressFixedHuffmanBlock(WriteBits, is_last_block,
+ lcodes, lextra_bits, dcodes, dextra_bits)
+ total_bitlen = total_bitlen + fixed_block_bitlen
+ elseif strategy == "dynamic" or dynamic_block_bitlen == min_bitlen then
+ CompressDynamicHuffmanBlock(WriteBits, is_last_block, lcodes
+ , lextra_bits, dcodes, dextra_bits, HLIT, HDIST, HCLEN
+ , rle_codes_huffman_bitlens, rle_codes_huffman_codes
+ , rle_deflate_codes, rle_extra_bits
+ , lcodes_huffman_bitlens, lcodes_huffman_codes
+ , dcodes_huffman_bitlens, dcodes_huffman_codes)
+ total_bitlen = total_bitlen + dynamic_block_bitlen
+ end
+
+ if is_last_block then
+ bitlen_written = FlushWriter(_FLUSH_MODE_NO_FLUSH)
+ else
+ bitlen_written = FlushWriter(_FLUSH_MODE_MEMORY_CLEANUP)
+ end
+
+ assert(bitlen_written == total_bitlen)
+
+ -- Memory clean up, so memory consumption does not always grow linearly
+ -- , even if input string is > 64K.
+ -- Not a very efficient operation, but this operation won't happen
+ -- when the input data size is less than 64K.
+ if not is_last_block then
+ local j
+ if dictionary and block_start == 1 then
+ j = 0
+ while (string_table[j]) do
+ string_table[j] = nil
+ j = j - 1
+ end
+ end
+ dictionary = nil
+ j = 1
+ for i = block_end-32767, block_end do
+ string_table[j] = string_table[i-offset]
+ j = j + 1
+ end
+
+ for k, t in pairs(hash_tables) do
+ local tSize = #t
+ if tSize > 0 and block_end+1 - t[1] > 32768 then
+ if tSize == 1 then
+ hash_tables[k] = nil
+ else
+ local new = {}
+ local newSize = 0
+ for i = 2, tSize do
+ j = t[i]
+ if block_end+1 - j <= 32768 then
+ newSize = newSize + 1
+ new[newSize] = j
+ end
+ end
+ hash_tables[k] = new
+ end
+ end
+ end
+ end
+ end
+end
+
+--- The description to compression configuration table.
+-- Any field can be nil to use its default.
+-- Table with keys other than those below is an invalid table.
+-- @class table
+-- @name compression_configs
+-- @field level The compression level ranged from 0 to 9. 0 is no compression.
+-- 9 is the slowest but best compression. Use nil for default level.
+-- @field strategy The compression strategy. "fixed" to only use fixed deflate
+-- compression block. "dynamic" to only use dynamic block. "huffman_only" to
+-- do no LZ77 compression. Only do huffman compression.
+
+
+-- @see LibDeflate:CompressDeflate(str, configs)
+-- @see LibDeflate:CompressDeflateWithDict(str, dictionary, configs)
+local function CompressDeflateInternal(str, dictionary, configs)
+ local WriteBits, WriteString, FlushWriter = CreateWriter()
+ Deflate(configs, WriteBits, WriteString, FlushWriter, str, dictionary)
+ local total_bitlen, result = FlushWriter(_FLUSH_MODE_OUTPUT)
+ local padding_bitlen = (8-total_bitlen%8)%8
+ return result, padding_bitlen
+end
+
+-- @see LibDeflate:CompressZlib
+-- @see LibDeflate:CompressZlibWithDict
+local function CompressZlibInternal(str, dictionary, configs)
+ local WriteBits, WriteString, FlushWriter = CreateWriter()
+
+ local CM = 8 -- Compression method
+ local CINFO = 7 --Window Size = 32K
+ local CMF = CINFO*16+CM
+ WriteBits(CMF, 8)
+
+ local FDIST = dictionary and 1 or 0
+ local FLEVEL = 2 -- Default compression
+ local FLG = FLEVEL*64+FDIST*32
+ local FCHECK = (31-(CMF*256+FLG)%31)
+ -- The FCHECK value must be such that CMF and FLG,
+ -- when viewed as a 16-bit unsigned integer stored
+ -- in MSB order (CMF*256 + FLG), is a multiple of 31.
+ FLG = FLG + FCHECK
+ WriteBits(FLG, 8)
+
+ if FDIST == 1 then
+ local adler32 = dictionary.adler32
+ local byte0 = adler32 % 256
+ adler32 = (adler32 - byte0) / 256
+ local byte1 = adler32 % 256
+ adler32 = (adler32 - byte1) / 256
+ local byte2 = adler32 % 256
+ adler32 = (adler32 - byte2) / 256
+ local byte3 = adler32 % 256
+ WriteBits(byte3, 8)
+ WriteBits(byte2, 8)
+ WriteBits(byte1, 8)
+ WriteBits(byte0, 8)
+ end
+
+ Deflate(configs, WriteBits, WriteString, FlushWriter, str, dictionary)
+ FlushWriter(_FLUSH_MODE_BYTE_BOUNDARY)
+
+ local adler32 = LibDeflate:Adler32(str)
+
+ -- Most significant byte first
+ local byte3 = adler32%256
+ adler32 = (adler32 - byte3) / 256
+ local byte2 = adler32%256
+ adler32 = (adler32 - byte2) / 256
+ local byte1 = adler32%256
+ adler32 = (adler32 - byte1) / 256
+ local byte0 = adler32%256
+
+ WriteBits(byte0, 8)
+ WriteBits(byte1, 8)
+ WriteBits(byte2, 8)
+ WriteBits(byte3, 8)
+ local total_bitlen, result = FlushWriter(_FLUSH_MODE_OUTPUT)
+ local padding_bitlen = (8-total_bitlen%8)%8
+ return result, padding_bitlen
+end
+
+--- Compress using the raw deflate format.
+-- @param str [string] The data to be compressed.
+-- @param configs [table/nil] The configuration table to control the compression
+-- . If nil, use the default configuration.
+-- @return [string] The compressed data.
+-- @return [integer] The number of bits padded at the end of output.
+-- 0 <= bits < 8
+-- This means the most significant "bits" of the last byte of the returned
+-- compressed data are padding bits and they don't affect decompression.
+-- You don't need to use this value unless you want to do some postprocessing
+-- to the compressed data.
+-- @see compression_configs
+-- @see LibDeflate:DecompressDeflate
+function LibDeflate:CompressDeflate(str, configs)
+ local arg_valid, arg_err = IsValidArguments(str, false, nil, true, configs)
+ if not arg_valid then
+ error(("Usage: LibDeflate:CompressDeflate(str, configs): "
+ ..arg_err), 2)
+ end
+ return CompressDeflateInternal(str, nil, configs)
+end
+
+--- Compress using the raw deflate format with a preset dictionary.
+-- @param str [string] The data to be compressed.
+-- @param dictionary [table] The preset dictionary produced by
+-- LibDeflate:CreateDictionary
+-- @param configs [table/nil] The configuration table to control the compression
+-- . If nil, use the default configuration.
+-- @return [string] The compressed data.
+-- @return [integer] The number of bits padded at the end of output.
+-- 0 <= bits < 8
+-- This means the most significant "bits" of the last byte of the returned
+-- compressed data are padding bits and they don't affect decompression.
+-- You don't need to use this value unless you want to do some postprocessing
+-- to the compressed data.
+-- @see compression_configs
+-- @see LibDeflate:CreateDictionary
+-- @see LibDeflate:DecompressDeflateWithDict
+function LibDeflate:CompressDeflateWithDict(str, dictionary, configs)
+ local arg_valid, arg_err = IsValidArguments(str, true, dictionary
+ , true, configs)
+ if not arg_valid then
+ error(("Usage: LibDeflate:CompressDeflateWithDict"
+ .."(str, dictionary, configs): "
+ ..arg_err), 2)
+ end
+ return CompressDeflateInternal(str, dictionary, configs)
+end
+
+--- Compress using the zlib format.
+-- @param str [string] the data to be compressed.
+-- @param configs [table/nil] The configuration table to control the compression
+-- . If nil, use the default configuration.
+-- @return [string] The compressed data.
+-- @return [integer] The number of bits padded at the end of output.
+-- Should always be 0.
+-- Zlib formatted compressed data never has padding bits at the end.
+-- @see compression_configs
+-- @see LibDeflate:DecompressZlib
+function LibDeflate:CompressZlib(str, configs)
+ local arg_valid, arg_err = IsValidArguments(str, false, nil, true, configs)
+ if not arg_valid then
+ error(("Usage: LibDeflate:CompressZlib(str, configs): "
+ ..arg_err), 2)
+ end
+ return CompressZlibInternal(str, nil, configs)
+end
+
+--- Compress using the zlib format with a preset dictionary.
+-- @param str [string] the data to be compressed.
+-- @param dictionary [table] A preset dictionary produced
+-- by LibDeflate:CreateDictionary()
+-- @param configs [table/nil] The configuration table to control the compression
+-- . If nil, use the default configuration.
+-- @return [string] The compressed data.
+-- @return [integer] The number of bits padded at the end of output.
+-- Should always be 0.
+-- Zlib formatted compressed data never has padding bits at the end.
+-- @see compression_configs
+-- @see LibDeflate:CreateDictionary
+-- @see LibDeflate:DecompressZlibWithDict
+function LibDeflate:CompressZlibWithDict(str, dictionary, configs)
+ local arg_valid, arg_err = IsValidArguments(str, true, dictionary
+ , true, configs)
+ if not arg_valid then
+ error(("Usage: LibDeflate:CompressZlibWithDict"
+ .."(str, dictionary, configs): "
+ ..arg_err), 2)
+ end
+ return CompressZlibInternal(str, dictionary, configs)
+end
+
+--[[ --------------------------------------------------------------------------
+ Decompress code
+--]] --------------------------------------------------------------------------
+
+--[[
+ Create a reader to easily reader stuffs as the unit of bits.
+ Return values:
+ 1. ReadBits(bitlen)
+ 2. ReadBytes(bytelen, buffer, buffer_size)
+ 3. Decode(huffman_bitlen_count, huffman_symbol, min_bitlen)
+ 4. ReaderBitlenLeft()
+ 5. SkipToByteBoundary()
+--]]
+local function CreateReader(input_string)
+ local input = input_string
+ local input_strlen = #input_string
+ local input_next_byte_pos = 1
+ local cache_bitlen = 0
+ local cache = 0
+
+ -- Read some bits.
+ -- To improve speed, this function does not
+ -- check if the input has been exhausted.
+ -- Use ReaderBitlenLeft() < 0 to check it.
+ -- @param bitlen the number of bits to read
+ -- @return the data is read.
+ local function ReadBits(bitlen)
+ local rshift_mask = _pow2[bitlen]
+ local code
+ if bitlen <= cache_bitlen then
+ code = cache % rshift_mask
+ cache = (cache - code) / rshift_mask
+ cache_bitlen = cache_bitlen - bitlen
+ else -- Whether input has been exhausted is not checked.
+ local lshift_mask = _pow2[cache_bitlen]
+ local byte1, byte2, byte3, byte4 = string_byte(input
+ , input_next_byte_pos, input_next_byte_pos+3)
+ -- This requires lua number to be at least double ()
+ cache = cache + ((byte1 or 0)+(byte2 or 0)*256
+ + (byte3 or 0)*65536+(byte4 or 0)*16777216)*lshift_mask
+ input_next_byte_pos = input_next_byte_pos + 4
+ cache_bitlen = cache_bitlen + 32 - bitlen
+ code = cache % rshift_mask
+ cache = (cache - code) / rshift_mask
+ end
+ return code
+ end
+
+ -- Read some bytes from the reader.
+ -- Assume reader is on the byte boundary.
+ -- @param bytelen The number of bytes to be read.
+ -- @param buffer The byte read will be stored into this buffer.
+ -- @param buffer_size The buffer will be modified starting from
+ -- buffer[buffer_size+1], ending at buffer[buffer_size+bytelen-1]
+ -- @return the new buffer_size
+ local function ReadBytes(bytelen, buffer, buffer_size)
+ assert(cache_bitlen % 8 == 0)
+
+ local byte_from_cache = (cache_bitlen/8 < bytelen)
+ and (cache_bitlen/8) or bytelen
+ for _=1, byte_from_cache do
+ local byte = cache % 256
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = string_char(byte)
+ cache = (cache - byte) / 256
+ end
+ cache_bitlen = cache_bitlen - byte_from_cache*8
+ bytelen = bytelen - byte_from_cache
+ if (input_strlen - input_next_byte_pos - bytelen + 1) * 8
+ + cache_bitlen < 0 then
+ return -1 -- out of input
+ end
+ for i=input_next_byte_pos, input_next_byte_pos+bytelen-1 do
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = string_sub(input, i, i)
+ end
+
+ input_next_byte_pos = input_next_byte_pos + bytelen
+ return buffer_size
+ end
+
+ -- Decode huffman code
+ -- To improve speed, this function does not check
+ -- if the input has been exhausted.
+ -- Use ReaderBitlenLeft() < 0 to check it.
+ -- Credits for Mark Adler. This code is from puff:Decode()
+ -- @see puff:Decode(...)
+ -- @param huffman_bitlen_count
+ -- @param huffman_symbol
+ -- @param min_bitlen The minimum huffman bit length of all symbols
+ -- @return The decoded deflate code.
+ -- Negative value is returned if decoding fails.
+ local function Decode(huffman_bitlen_counts, huffman_symbols, min_bitlen)
+ local code = 0
+ local first = 0
+ local index = 0
+ local count
+ if min_bitlen > 0 then
+ if cache_bitlen < 15 and input then
+ local lshift_mask = _pow2[cache_bitlen]
+ local byte1, byte2, byte3, byte4 =
+ string_byte(input, input_next_byte_pos
+ , input_next_byte_pos+3)
+ -- This requires lua number to be at least double ()
+ cache = cache + ((byte1 or 0)+(byte2 or 0)*256
+ +(byte3 or 0)*65536+(byte4 or 0)*16777216)*lshift_mask
+ input_next_byte_pos = input_next_byte_pos + 4
+ cache_bitlen = cache_bitlen + 32
+ end
+
+ local rshift_mask = _pow2[min_bitlen]
+ cache_bitlen = cache_bitlen - min_bitlen
+ code = cache % rshift_mask
+ cache = (cache - code) / rshift_mask
+ -- Reverse the bits
+ code = _reverse_bits_tbl[min_bitlen][code]
+
+ count = huffman_bitlen_counts[min_bitlen]
+ if code < count then
+ return huffman_symbols[code]
+ end
+ index = count
+ first = count * 2
+ code = code * 2
+ end
+
+ for bitlen = min_bitlen+1, 15 do
+ local bit
+ bit = cache % 2
+ cache = (cache - bit) / 2
+ cache_bitlen = cache_bitlen - 1
+
+ code = (bit==1) and (code + 1 - code % 2) or code
+ count = huffman_bitlen_counts[bitlen] or 0
+ local diff = code - first
+ if diff < count then
+ return huffman_symbols[index + diff]
+ end
+ index = index + count
+ first = first + count
+ first = first * 2
+ code = code * 2
+ end
+ -- invalid literal/length or distance code
+ -- in fixed or dynamic block (run out of code)
+ return -10
+ end
+
+ local function ReaderBitlenLeft()
+ return (input_strlen - input_next_byte_pos + 1) * 8 + cache_bitlen
+ end
+
+ local function SkipToByteBoundary()
+ local skipped_bitlen = cache_bitlen%8
+ local rshift_mask = _pow2[skipped_bitlen]
+ cache_bitlen = cache_bitlen - skipped_bitlen
+ cache = (cache - cache % rshift_mask) / rshift_mask
+ end
+
+ return ReadBits, ReadBytes, Decode, ReaderBitlenLeft, SkipToByteBoundary
+end
+
+-- Create a deflate state, so I can pass in less arguments to functions.
+-- @param str the whole string to be decompressed.
+-- @param dictionary The preset dictionary. nil if not provided.
+-- This dictionary should be produced by LibDeflate:CreateDictionary(str)
+-- @return The decomrpess state.
+local function CreateDecompressState(str, dictionary)
+ local ReadBits, ReadBytes, Decode, ReaderBitlenLeft
+ , SkipToByteBoundary = CreateReader(str)
+ local state =
+ {
+ ReadBits = ReadBits,
+ ReadBytes = ReadBytes,
+ Decode = Decode,
+ ReaderBitlenLeft = ReaderBitlenLeft,
+ SkipToByteBoundary = SkipToByteBoundary,
+ buffer_size = 0,
+ buffer = {},
+ result_buffer = {},
+ dictionary = dictionary,
+ }
+ return state
+end
+
+-- Get the stuffs needed to decode huffman codes
+-- @see puff.c:construct(...)
+-- @param huffman_bitlen The huffman bit length of the huffman codes.
+-- @param max_symbol The maximum symbol
+-- @param max_bitlen The min huffman bit length of all codes
+-- @return zero or positive for success, negative for failure.
+-- @return The count of each huffman bit length.
+-- @return A table to convert huffman codes to deflate codes.
+-- @return The minimum huffman bit length.
+local function GetHuffmanForDecode(huffman_bitlens, max_symbol, max_bitlen)
+ local huffman_bitlen_counts = {}
+ local min_bitlen = max_bitlen
+ for symbol = 0, max_symbol do
+ local bitlen = huffman_bitlens[symbol] or 0
+ min_bitlen = (bitlen > 0 and bitlen < min_bitlen)
+ and bitlen or min_bitlen
+ huffman_bitlen_counts[bitlen] = (huffman_bitlen_counts[bitlen] or 0)+1
+ end
+
+ if huffman_bitlen_counts[0] == max_symbol+1 then -- No Codes
+ return 0, huffman_bitlen_counts, {}, 0 -- Complete, but decode will fail
+ end
+
+ local left = 1
+ for len = 1, max_bitlen do
+ left = left * 2
+ left = left - (huffman_bitlen_counts[len] or 0)
+ if left < 0 then
+ return left -- Over-subscribed, return negative
+ end
+ end
+
+ -- Generate offsets info symbol table for each length for sorting
+ local offsets = {}
+ offsets[1] = 0
+ for len = 1, max_bitlen-1 do
+ offsets[len + 1] = offsets[len] + (huffman_bitlen_counts[len] or 0)
+ end
+
+ local huffman_symbols = {}
+ for symbol = 0, max_symbol do
+ local bitlen = huffman_bitlens[symbol] or 0
+ if bitlen ~= 0 then
+ local offset = offsets[bitlen]
+ huffman_symbols[offset] = symbol
+ offsets[bitlen] = offsets[bitlen] + 1
+ end
+ end
+
+ -- Return zero for complete set, positive for incomplete set.
+ return left, huffman_bitlen_counts, huffman_symbols, min_bitlen
+end
+
+-- Decode a fixed or dynamic huffman blocks, excluding last block identifier
+-- and block type identifer.
+-- @see puff.c:codes()
+-- @param state decompression state that will be modified by this function.
+-- @see CreateDecompressState
+-- @param ... Read the source code
+-- @return 0 on success, other value on failure.
+local function DecodeUntilEndOfBlock(state, lcodes_huffman_bitlens
+ , lcodes_huffman_symbols, lcodes_huffman_min_bitlen
+ , dcodes_huffman_bitlens, dcodes_huffman_symbols
+ , dcodes_huffman_min_bitlen)
+ local buffer, buffer_size, ReadBits, Decode, ReaderBitlenLeft
+ , result_buffer =
+ state.buffer, state.buffer_size, state.ReadBits, state.Decode
+ , state.ReaderBitlenLeft, state.result_buffer
+ local dictionary = state.dictionary
+ local dict_string_table
+ local dict_strlen
+
+ local buffer_end = 1
+ if dictionary and not buffer[0] then
+ -- If there is a dictionary, copy the last 258 bytes into
+ -- the string_table to make the copy in the main loop quicker.
+ -- This is done only once per decompression.
+ dict_string_table = dictionary.string_table
+ dict_strlen = dictionary.strlen
+ buffer_end = -dict_strlen + 1
+ for i=0, (-dict_strlen+1)<-257 and -257 or (-dict_strlen+1), -1 do
+ buffer[i] = _byte_to_char[dict_string_table[dict_strlen+i]]
+ end
+ end
+
+ repeat
+ local symbol = Decode(lcodes_huffman_bitlens
+ , lcodes_huffman_symbols, lcodes_huffman_min_bitlen)
+ if symbol < 0 or symbol > 285 then
+ -- invalid literal/length or distance code in fixed or dynamic block
+ return -10
+ elseif symbol < 256 then -- Literal
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = _byte_to_char[symbol]
+ elseif symbol > 256 then -- Length code
+ symbol = symbol - 256
+ local bitlen = _literal_deflate_code_to_base_len[symbol]
+ bitlen = (symbol >= 8)
+ and (bitlen
+ + ReadBits(_literal_deflate_code_to_extra_bitlen[symbol]))
+ or bitlen
+ symbol = Decode(dcodes_huffman_bitlens, dcodes_huffman_symbols
+ , dcodes_huffman_min_bitlen)
+ if symbol < 0 or symbol > 29 then
+ -- invalid literal/length or distance code in fixed or dynamic block
+ return -10
+ end
+ local dist = _dist_deflate_code_to_base_dist[symbol]
+ dist = (dist > 4) and (dist
+ + ReadBits(_dist_deflate_code_to_extra_bitlen[symbol])) or dist
+
+ local char_buffer_index = buffer_size-dist+1
+ if char_buffer_index < buffer_end then
+ -- distance is too far back in fixed or dynamic block
+ return -11
+ end
+ if char_buffer_index >= -257 then
+ for _=1, bitlen do
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = buffer[char_buffer_index]
+ char_buffer_index = char_buffer_index + 1
+ end
+ else
+ char_buffer_index = dict_strlen + char_buffer_index
+ for _=1, bitlen do
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] =
+ _byte_to_char[dict_string_table[char_buffer_index]]
+ char_buffer_index = char_buffer_index + 1
+ end
+ end
+ end
+
+ if ReaderBitlenLeft() < 0 then
+ return 2 -- available inflate data did not terminate
+ end
+
+ if buffer_size >= 65536 then
+ result_buffer[#result_buffer+1] =
+ table_concat(buffer, "", 1, 32768)
+ for i=32769, buffer_size do
+ buffer[i-32768] = buffer[i]
+ end
+ buffer_size = buffer_size - 32768
+ buffer[buffer_size+1] = nil
+ -- NOTE: buffer[32769..end] and buffer[-257..0] are not cleared.
+ -- This is why "buffer_size" variable is needed.
+ end
+ until symbol == 256
+
+ state.buffer_size = buffer_size
+
+ return 0
+end
+
+-- Decompress a store block
+-- @param state decompression state that will be modified by this function.
+-- @return 0 if succeeds, other value if fails.
+local function DecompressStoreBlock(state)
+ local buffer, buffer_size, ReadBits, ReadBytes, ReaderBitlenLeft
+ , SkipToByteBoundary, result_buffer =
+ state.buffer, state.buffer_size, state.ReadBits, state.ReadBytes
+ , state.ReaderBitlenLeft, state.SkipToByteBoundary, state.result_buffer
+
+ SkipToByteBoundary()
+ local bytelen = ReadBits(16)
+ if ReaderBitlenLeft() < 0 then
+ return 2 -- available inflate data did not terminate
+ end
+ local bytelenComp = ReadBits(16)
+ if ReaderBitlenLeft() < 0 then
+ return 2 -- available inflate data did not terminate
+ end
+
+ if bytelen % 256 + bytelenComp % 256 ~= 255 then
+ return -2 -- Not one's complement
+ end
+ if (bytelen-bytelen % 256)/256
+ + (bytelenComp-bytelenComp % 256)/256 ~= 255 then
+ return -2 -- Not one's complement
+ end
+
+ -- Note that ReadBytes will skip to the next byte boundary first.
+ buffer_size = ReadBytes(bytelen, buffer, buffer_size)
+ if buffer_size < 0 then
+ return 2 -- available inflate data did not terminate
+ end
+
+ -- memory clean up when there are enough bytes in the buffer.
+ if buffer_size >= 65536 then
+ result_buffer[#result_buffer+1] = table_concat(buffer, "", 1, 32768)
+ for i=32769, buffer_size do
+ buffer[i-32768] = buffer[i]
+ end
+ buffer_size = buffer_size - 32768
+ buffer[buffer_size+1] = nil
+ end
+ state.buffer_size = buffer_size
+ return 0
+end
+
+-- Decompress a fixed block
+-- @param state decompression state that will be modified by this function.
+-- @return 0 if succeeds other value if fails.
+local function DecompressFixBlock(state)
+ return DecodeUntilEndOfBlock(state
+ , _fix_block_literal_huffman_bitlen_count
+ , _fix_block_literal_huffman_to_deflate_code, 7
+ , _fix_block_dist_huffman_bitlen_count
+ , _fix_block_dist_huffman_to_deflate_code, 5)
+end
+
+-- Decompress a dynamic block
+-- @param state decompression state that will be modified by this function.
+-- @return 0 if success, other value if fails.
+local function DecompressDynamicBlock(state)
+ local ReadBits, Decode = state.ReadBits, state.Decode
+ local nlen = ReadBits(5) + 257
+ local ndist = ReadBits(5) + 1
+ local ncode = ReadBits(4) + 4
+ if nlen > 286 or ndist > 30 then
+ -- dynamic block code description: too many length or distance codes
+ return -3
+ end
+
+ local rle_codes_huffman_bitlens = {}
+
+ for i = 1, ncode do
+ rle_codes_huffman_bitlens[_rle_codes_huffman_bitlen_order[i]] =
+ ReadBits(3)
+ end
+
+ local rle_codes_err, rle_codes_huffman_bitlen_counts,
+ rle_codes_huffman_symbols, rle_codes_huffman_min_bitlen =
+ GetHuffmanForDecode(rle_codes_huffman_bitlens, 18, 7)
+ if rle_codes_err ~= 0 then -- Require complete code set here
+ -- dynamic block code description: code lengths codes incomplete
+ return -4
+ end
+
+ local lcodes_huffman_bitlens = {}
+ local dcodes_huffman_bitlens = {}
+ -- Read length/literal and distance code length tables
+ local index = 0
+ while index < nlen + ndist do
+ local symbol -- Decoded value
+ local bitlen -- Last length to repeat
+
+ symbol = Decode(rle_codes_huffman_bitlen_counts
+ , rle_codes_huffman_symbols, rle_codes_huffman_min_bitlen)
+
+ if symbol < 0 then
+ return symbol -- Invalid symbol
+ elseif symbol < 16 then
+ if index < nlen then
+ lcodes_huffman_bitlens[index] = symbol
+ else
+ dcodes_huffman_bitlens[index-nlen] = symbol
+ end
+ index = index + 1
+ else
+ bitlen = 0
+ if symbol == 16 then
+ if index == 0 then
+ -- dynamic block code description: repeat lengths
+ -- with no first length
+ return -5
+ end
+ if index-1 < nlen then
+ bitlen = lcodes_huffman_bitlens[index-1]
+ else
+ bitlen = dcodes_huffman_bitlens[index-nlen-1]
+ end
+ symbol = 3 + ReadBits(2)
+ elseif symbol == 17 then -- Repeat zero 3..10 times
+ symbol = 3 + ReadBits(3)
+ else -- == 18, repeat zero 11.138 times
+ symbol = 11 + ReadBits(7)
+ end
+ if index + symbol > nlen + ndist then
+ -- dynamic block code description:
+ -- repeat more than specified lengths
+ return -6
+ end
+ while symbol > 0 do -- Repeat last or zero symbol times
+ symbol = symbol - 1
+ if index < nlen then
+ lcodes_huffman_bitlens[index] = bitlen
+ else
+ dcodes_huffman_bitlens[index-nlen] = bitlen
+ end
+ index = index + 1
+ end
+ end
+ end
+
+ if (lcodes_huffman_bitlens[256] or 0) == 0 then
+ -- dynamic block code description: missing end-of-block code
+ return -9
+ end
+
+ local lcodes_err, lcodes_huffman_bitlen_counts
+ , lcodes_huffman_symbols, lcodes_huffman_min_bitlen =
+ GetHuffmanForDecode(lcodes_huffman_bitlens, nlen-1, 15)
+ --dynamic block code description: invalid literal/length code lengths,
+ -- Incomplete code ok only for single length 1 code
+ if (lcodes_err ~=0 and (lcodes_err < 0
+ or nlen ~= (lcodes_huffman_bitlen_counts[0] or 0)
+ +(lcodes_huffman_bitlen_counts[1] or 0))) then
+ return -7
+ end
+
+ local dcodes_err, dcodes_huffman_bitlen_counts
+ , dcodes_huffman_symbols, dcodes_huffman_min_bitlen =
+ GetHuffmanForDecode(dcodes_huffman_bitlens, ndist-1, 15)
+ -- dynamic block code description: invalid distance code lengths,
+ -- Incomplete code ok only for single length 1 code
+ if (dcodes_err ~=0 and (dcodes_err < 0
+ or ndist ~= (dcodes_huffman_bitlen_counts[0] or 0)
+ + (dcodes_huffman_bitlen_counts[1] or 0))) then
+ return -8
+ end
+
+ -- Build buffman table for literal/length codes
+ return DecodeUntilEndOfBlock(state, lcodes_huffman_bitlen_counts
+ , lcodes_huffman_symbols, lcodes_huffman_min_bitlen
+ , dcodes_huffman_bitlen_counts, dcodes_huffman_symbols
+ , dcodes_huffman_min_bitlen)
+end
+
+-- Decompress a deflate stream
+-- @param state: a decompression state
+-- @return the decompressed string if succeeds. nil if fails.
+local function Inflate(state)
+ local ReadBits = state.ReadBits
+
+ local is_last_block
+ while not is_last_block do
+ is_last_block = (ReadBits(1) == 1)
+ local block_type = ReadBits(2)
+ local status
+ if block_type == 0 then
+ status = DecompressStoreBlock(state)
+ elseif block_type == 1 then
+ status = DecompressFixBlock(state)
+ elseif block_type == 2 then
+ status = DecompressDynamicBlock(state)
+ else
+ return nil, -1 -- invalid block type (type == 3)
+ end
+ if status ~= 0 then
+ return nil, status
+ end
+ end
+
+ state.result_buffer[#state.result_buffer+1] =
+ table_concat(state.buffer, "", 1, state.buffer_size)
+ local result = table_concat(state.result_buffer)
+ return result
+end
+
+-- @see LibDeflate:DecompressDeflate(str)
+-- @see LibDeflate:DecompressDeflateWithDict(str, dictionary)
+local function DecompressDeflateInternal(str, dictionary)
+ local state = CreateDecompressState(str, dictionary)
+ local result, status = Inflate(state)
+ if not result then
+ return nil, status
+ end
+
+ local bitlen_left = state.ReaderBitlenLeft()
+ local bytelen_left = (bitlen_left - bitlen_left % 8) / 8
+ return result, bytelen_left
+end
+
+-- @see LibDeflate:DecompressZlib(str)
+-- @see LibDeflate:DecompressZlibWithDict(str)
+local function DecompressZlibInternal(str, dictionary)
+ local state = CreateDecompressState(str, dictionary)
+ local ReadBits = state.ReadBits
+
+ local CMF = ReadBits(8)
+ if state.ReaderBitlenLeft() < 0 then
+ return nil, 2 -- available inflate data did not terminate
+ end
+ local CM = CMF % 16
+ local CINFO = (CMF - CM) / 16
+ if CM ~= 8 then
+ return nil, -12 -- invalid compression method
+ end
+ if CINFO > 7 then
+ return nil, -13 -- invalid window size
+ end
+
+ local FLG = ReadBits(8)
+ if state.ReaderBitlenLeft() < 0 then
+ return nil, 2 -- available inflate data did not terminate
+ end
+ if (CMF*256+FLG)%31 ~= 0 then
+ return nil, -14 -- invalid header checksum
+ end
+
+ local FDIST = ((FLG-FLG%32)/32 % 2)
+ local FLEVEL = ((FLG-FLG%64)/64 % 4) -- luacheck: ignore FLEVEL
+
+ if FDIST == 1 then
+ if not dictionary then
+ return nil, -16 -- need dictonary, but dictionary is not provided.
+ end
+ local byte3 = ReadBits(8)
+ local byte2 = ReadBits(8)
+ local byte1 = ReadBits(8)
+ local byte0 = ReadBits(8)
+ local actual_adler32 = byte3*16777216+byte2*65536+byte1*256+byte0
+ if state.ReaderBitlenLeft() < 0 then
+ return nil, 2 -- available inflate data did not terminate
+ end
+ if not IsEqualAdler32(actual_adler32, dictionary.adler32) then
+ return nil, -17 -- dictionary adler32 does not match
+ end
+ end
+ local result, status = Inflate(state)
+ if not result then
+ return nil, status
+ end
+ state.SkipToByteBoundary()
+
+ local adler_byte0 = ReadBits(8)
+ local adler_byte1 = ReadBits(8)
+ local adler_byte2 = ReadBits(8)
+ local adler_byte3 = ReadBits(8)
+ if state.ReaderBitlenLeft() < 0 then
+ return nil, 2 -- available inflate data did not terminate
+ end
+
+ local adler32_expected = adler_byte0*16777216
+ + adler_byte1*65536 + adler_byte2*256 + adler_byte3
+ local adler32_actual = LibDeflate:Adler32(result)
+ if not IsEqualAdler32(adler32_expected, adler32_actual) then
+ return nil, -15 -- Adler32 checksum does not match
+ end
+
+ local bitlen_left = state.ReaderBitlenLeft()
+ local bytelen_left = (bitlen_left - bitlen_left % 8) / 8
+ return result, bytelen_left
+end
+
+--- Decompress a raw deflate compressed data.
+-- @param str [string] The data to be decompressed.
+-- @return [string/nil] If the decompression succeeds, return the decompressed
+-- data. If the decompression fails, return nil. You should check if this return
+-- value is non-nil to know if the decompression succeeds.
+-- @return [integer] If the decompression succeeds, return the number of
+-- unprocessed bytes in the input compressed data. This return value is a
+-- positive integer if the input data is a valid compressed data appended by an
+-- arbitary non-empty string. This return value is 0 if the input data does not
+-- contain any extra bytes.
+-- If the decompression fails (The first return value of this function is nil),
+-- this return value is undefined.
+-- @see LibDeflate:CompressDeflate
+function LibDeflate:DecompressDeflate(str)
+ local arg_valid, arg_err = IsValidArguments(str)
+ if not arg_valid then
+ error(("Usage: LibDeflate:DecompressDeflate(str): "
+ ..arg_err), 2)
+ end
+ return DecompressDeflateInternal(str)
+end
+
+--- Decompress a raw deflate compressed data with a preset dictionary.
+-- @param str [string] The data to be decompressed.
+-- @param dictionary [table] The preset dictionary used by
+-- LibDeflate:CompressDeflateWithDict when the compressed data is produced.
+-- Decompression and compression must use the same dictionary.
+-- Otherwise wrong decompressed data could be produced without generating any
+-- error.
+-- @return [string/nil] If the decompression succeeds, return the decompressed
+-- data. If the decompression fails, return nil. You should check if this return
+-- value is non-nil to know if the decompression succeeds.
+-- @return [integer] If the decompression succeeds, return the number of
+-- unprocessed bytes in the input compressed data. This return value is a
+-- positive integer if the input data is a valid compressed data appended by an
+-- arbitary non-empty string. This return value is 0 if the input data does not
+-- contain any extra bytes.
+-- If the decompression fails (The first return value of this function is nil),
+-- this return value is undefined.
+-- @see LibDeflate:CompressDeflateWithDict
+function LibDeflate:DecompressDeflateWithDict(str, dictionary)
+ local arg_valid, arg_err = IsValidArguments(str, true, dictionary)
+ if not arg_valid then
+ error(("Usage: LibDeflate:DecompressDeflateWithDict(str, dictionary): "
+ ..arg_err), 2)
+ end
+ return DecompressDeflateInternal(str, dictionary)
+end
+
+--- Decompress a zlib compressed data.
+-- @param str [string] The data to be decompressed
+-- @return [string/nil] If the decompression succeeds, return the decompressed
+-- data. If the decompression fails, return nil. You should check if this return
+-- value is non-nil to know if the decompression succeeds.
+-- @return [integer] If the decompression succeeds, return the number of
+-- unprocessed bytes in the input compressed data. This return value is a
+-- positive integer if the input data is a valid compressed data appended by an
+-- arbitary non-empty string. This return value is 0 if the input data does not
+-- contain any extra bytes.
+-- If the decompression fails (The first return value of this function is nil),
+-- this return value is undefined.
+-- @see LibDeflate:CompressZlib
+function LibDeflate:DecompressZlib(str)
+ local arg_valid, arg_err = IsValidArguments(str)
+ if not arg_valid then
+ error(("Usage: LibDeflate:DecompressZlib(str): "
+ ..arg_err), 2)
+ end
+ return DecompressZlibInternal(str)
+end
+
+--- Decompress a zlib compressed data with a preset dictionary.
+-- @param str [string] The data to be decompressed
+-- @param dictionary [table] The preset dictionary used by
+-- LibDeflate:CompressDeflateWithDict when the compressed data is produced.
+-- Decompression and compression must use the same dictionary.
+-- Otherwise wrong decompressed data could be produced without generating any
+-- error.
+-- @return [string/nil] If the decompression succeeds, return the decompressed
+-- data. If the decompression fails, return nil. You should check if this return
+-- value is non-nil to know if the decompression succeeds.
+-- @return [integer] If the decompression succeeds, return the number of
+-- unprocessed bytes in the input compressed data. This return value is a
+-- positive integer if the input data is a valid compressed data appended by an
+-- arbitary non-empty string. This return value is 0 if the input data does not
+-- contain any extra bytes.
+-- If the decompression fails (The first return value of this function is nil),
+-- this return value is undefined.
+-- @see LibDeflate:CompressZlibWithDict
+function LibDeflate:DecompressZlibWithDict(str, dictionary)
+ local arg_valid, arg_err = IsValidArguments(str, true, dictionary)
+ if not arg_valid then
+ error(("Usage: LibDeflate:DecompressZlibWithDict(str, dictionary): "
+ ..arg_err), 2)
+ end
+ return DecompressZlibInternal(str, dictionary)
+end
+
+-- Calculate the huffman code of fixed block
+do
+ _fix_block_literal_huffman_bitlen = {}
+ for sym=0, 143 do
+ _fix_block_literal_huffman_bitlen[sym] = 8
+ end
+ for sym=144, 255 do
+ _fix_block_literal_huffman_bitlen[sym] = 9
+ end
+ for sym=256, 279 do
+ _fix_block_literal_huffman_bitlen[sym] = 7
+ end
+ for sym=280, 287 do
+ _fix_block_literal_huffman_bitlen[sym] = 8
+ end
+
+ _fix_block_dist_huffman_bitlen = {}
+ for dist=0, 31 do
+ _fix_block_dist_huffman_bitlen[dist] = 5
+ end
+ local status
+ status, _fix_block_literal_huffman_bitlen_count
+ , _fix_block_literal_huffman_to_deflate_code =
+ GetHuffmanForDecode(_fix_block_literal_huffman_bitlen, 287, 9)
+ assert(status == 0)
+ status, _fix_block_dist_huffman_bitlen_count,
+ _fix_block_dist_huffman_to_deflate_code =
+ GetHuffmanForDecode(_fix_block_dist_huffman_bitlen, 31, 5)
+ assert(status == 0)
+
+ _fix_block_literal_huffman_code =
+ GetHuffmanCodeFromBitlen(_fix_block_literal_huffman_bitlen_count
+ , _fix_block_literal_huffman_bitlen, 287, 9)
+ _fix_block_dist_huffman_code =
+ GetHuffmanCodeFromBitlen(_fix_block_dist_huffman_bitlen_count
+ , _fix_block_dist_huffman_bitlen, 31, 5)
+end
+
+-- Encoding algorithms
+-- Prefix encoding algorithm
+-- implemented by Galmok of European Stormrage (Horde), galmok@gmail.com
+-- From LibCompress ,
+-- which is licensed under GPLv2
+-- The code has been modified by the author of LibDeflate.
+------------------------------------------------------------------------------
+
+-- to be able to match any requested byte value, the search
+-- string must be preprocessed characters to escape with %:
+-- ( ) . % + - * ? [ ] ^ $
+-- "illegal" byte values:
+-- 0 is replaces %z
+local _gsub_escape_table = {
+ ["\000"] = "%z", ["("] = "%(", [")"] = "%)", ["."] = "%.",
+ ["%"] = "%%", ["+"] = "%+", ["-"] = "%-", ["*"] = "%*",
+ ["?"] = "%?", ["["] = "%[", ["]"] = "%]", ["^"] = "%^",
+ ["$"] = "%$",
+}
+
+local function escape_for_gsub(str)
+ return str:gsub("([%z%(%)%.%%%+%-%*%?%[%]%^%$])", _gsub_escape_table)
+end
+
+--- Create a custom codec with encoder and decoder.
+-- This codec is used to convert an input string to make it not contain
+-- some specific bytes.
+-- This created codec and the parameters of this function do NOT take
+-- localization into account. One byte (0-255) in the string is exactly one
+-- character (0-255).
+-- Credits to LibCompress.
+-- @param reserved_chars [string] The created encoder will ensure encoded
+-- data does not contain any single character in reserved_chars. This parameter
+-- should be non-empty.
+-- @param escape_chars [string] The escape character(s) used in the created
+-- codec. The codec converts any character included in reserved\_chars /
+-- escape\_chars / map\_chars to (one escape char + one character not in
+-- reserved\_chars / escape\_chars / map\_chars).
+-- You usually only need to provide a length-1 string for this parameter.
+-- Length-2 string is only needed when
+-- reserved\_chars + escape\_chars + map\_chars is longer than 127.
+-- This parameter should be non-empty.
+-- @param map_chars [string] The created encoder will map every
+-- reserved\_chars:sub(i, i) (1 <= i <= #map\_chars) to map\_chars:sub(i, i).
+-- This parameter CAN be empty string.
+-- @return [table/nil] If the codec cannot be created, return nil.
+-- If the codec can be created according to the given
+-- parameters, return the codec, which is a encode/decode table.
+-- The table contains two functions:
+-- t:Encode(str) returns the encoded string.
+-- t:Decode(str) returns the decoded string if succeeds. nil if fails.
+-- @return [nil/string] If the codec is successfully created, return nil.
+-- If not, return a string that describes the reason why the codec cannot be
+-- created.
+-- @usage
+-- -- Create an encoder/decoder that maps all "\000" to "\003",
+-- -- and escape "\001" (and "\002" and "\003") properly
+-- local codec = LibDeflate:CreateCodec("\000\001", "\002", "\003")
+--
+-- local encoded = codec:Encode(SOME_STRING)
+-- -- "encoded" does not contain "\000" or "\001"
+-- local decoded = codec:Decode(encoded)
+-- -- assert(decoded == SOME_STRING)
+function LibDeflate:CreateCodec(reserved_chars, escape_chars
+ , map_chars)
+ -- select a default escape character
+ if type(reserved_chars) ~= "string"
+ or type(escape_chars) ~= "string"
+ or type(map_chars) ~= "string" then
+ error(
+ "Usage: LibDeflate:CreateCodec(reserved_chars,"
+ .." escape_chars, map_chars):"
+ .." All arguments must be string.", 2)
+ end
+
+ if escape_chars == "" then
+ return nil, "No escape characters supplied."
+ end
+ if #reserved_chars < #map_chars then
+ return nil, "The number of reserved characters must be"
+ .." at least as many as the number of mapped chars."
+ end
+ if reserved_chars == "" then
+ return nil, "No characters to encode."
+ end
+
+ local encode_bytes = reserved_chars..escape_chars..map_chars
+ -- build list of bytes not available as a suffix to a prefix byte
+ local taken = {}
+ for i = 1, #encode_bytes do
+ local byte = string_byte(encode_bytes, i, i)
+ if taken[byte] then -- Modified by LibDeflate:
+ return nil, "There must be no duplicate characters in the"
+ .." concatenation of reserved_chars, escape_chars and"
+ .." map_chars."
+ end
+ taken[byte] = true
+ end
+
+ -- Modified by LibDeflate:
+ -- Store the patterns and replacement in tables for later use.
+ -- This function is modified that loadstring() lua api is no longer used.
+ local decode_patterns = {}
+ local decode_repls = {}
+
+ -- the encoding can be a single gsub
+ -- , but the decoding can require multiple gsubs
+ local encode_search = {}
+ local encode_translate = {}
+
+ -- map single byte to single byte
+ if #map_chars > 0 then
+ local decode_search = {}
+ local decode_translate = {}
+ for i = 1, #map_chars do
+ local from = string_sub(reserved_chars, i, i)
+ local to = string_sub(map_chars, i, i)
+ encode_translate[from] = to
+ encode_search[#encode_search+1] = from
+ decode_translate[to] = from
+ decode_search[#decode_search+1] = to
+ end
+ decode_patterns[#decode_patterns+1] =
+ "([".. escape_for_gsub(table_concat(decode_search)).."])"
+ decode_repls[#decode_repls+1] = decode_translate
+ end
+
+ local escape_char_index = 1
+ local escape_char = string_sub(escape_chars
+ , escape_char_index, escape_char_index)
+ -- map single byte to double-byte
+ local r = 0 -- suffix char value to the escapeChar
+
+ local decode_search = {}
+ local decode_translate = {}
+ for i = 1, #encode_bytes do
+ local c = string_sub(encode_bytes, i, i)
+ if not encode_translate[c] then
+ -- this loop will update escapeChar and r
+ while r >= 256 or taken[r] do
+ -- Bug in LibCompress r81
+ -- while r < 256 and taken[r] do
+ r = r + 1
+ if r > 255 then -- switch to next escapeChar
+ decode_patterns[#decode_patterns+1] =
+ escape_for_gsub(escape_char)
+ .."(["
+ .. escape_for_gsub(table_concat(decode_search)).."])"
+ decode_repls[#decode_repls+1] = decode_translate
+
+ escape_char_index = escape_char_index + 1
+ escape_char = string_sub(escape_chars, escape_char_index
+ , escape_char_index)
+ r = 0
+ decode_search = {}
+ decode_translate = {}
+
+ -- Fixes Another bug in LibCompress r82.
+ -- LibCompress checks this error condition
+ -- right after "if r > 255 then"
+ -- This is why error case should also be tested.
+ if not escape_char or escape_char == "" then
+ -- actually I don't need to check
+ -- "not ecape_char", but what if Lua changes
+ -- the behavior of string.sub() in the future?
+ -- we are out of escape chars and we need more!
+ return nil, "Out of escape characters."
+ end
+ end
+ end
+
+ local char_r = _byte_to_char[r]
+ encode_translate[c] = escape_char..char_r
+ encode_search[#encode_search+1] = c
+ decode_translate[char_r] = c
+ decode_search[#decode_search+1] = char_r
+ r = r + 1
+ end
+ if i == #encode_bytes then
+ decode_patterns[#decode_patterns+1] =
+ escape_for_gsub(escape_char).."(["
+ .. escape_for_gsub(table_concat(decode_search)).."])"
+ decode_repls[#decode_repls+1] = decode_translate
+ end
+ end
+
+ local codec = {}
+
+ local encode_pattern = "(["
+ .. escape_for_gsub(table_concat(encode_search)).."])"
+ local encode_repl = encode_translate
+
+ function codec:Encode(str)
+ if type(str) ~= "string" then
+ error(("Usage: codec:Encode(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ return string_gsub(str, encode_pattern, encode_repl)
+ end
+
+ local decode_tblsize = #decode_patterns
+ local decode_fail_pattern = "(["
+ .. escape_for_gsub(reserved_chars).."])"
+
+ function codec:Decode(str)
+ if type(str) ~= "string" then
+ error(("Usage: codec:Decode(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ if string_find(str, decode_fail_pattern) then
+ return nil
+ end
+ for i = 1, decode_tblsize do
+ str = string_gsub(str, decode_patterns[i], decode_repls[i])
+ end
+ return str
+ end
+
+ return codec
+end
+
+local _addon_channel_codec
+
+local function GenerateWoWAddonChannelCodec()
+ return LibDeflate:CreateCodec("\000\124", "\001", "")
+end
+
+--- Encode the string to make it ready to be transmitted in World of
+-- Warcraft addon channel.
+-- The encoded string is guaranteed to contain no NULL ("\000") character.
+-- @param str [string] The string to be encoded.
+-- @return The encoded string.
+-- @see LibDeflate:DecodeForWoWAddonChannel
+function LibDeflate:EncodeForWoWAddonChannel(str)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:EncodeForWoWAddonChannel(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ if not _addon_channel_codec then
+ _addon_channel_codec = GenerateWoWAddonChannelCodec()
+ end
+ return _addon_channel_codec:Encode(str)
+end
+
+--- Decode the string produced by LibDeflate:EncodeForWoWAddonChannel
+-- @param str [string] The string to be decoded.
+-- @return [string/nil] The decoded string if succeeds. nil if fails.
+-- @see LibDeflate:EncodeForWoWAddonChannel
+function LibDeflate:DecodeForWoWAddonChannel(str)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:DecodeForWoWAddonChannel(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ if not _addon_channel_codec then
+ _addon_channel_codec = GenerateWoWAddonChannelCodec()
+ end
+ return _addon_channel_codec:Decode(str)
+end
+
+-- For World of Warcraft Chat Channel Encoding
+-- implemented by Galmok of European Stormrage (Horde), galmok@gmail.com
+-- From LibCompress ,
+-- which is licensed under GPLv2
+-- The code has been modified by the author of LibDeflate.
+-- Following byte values are not allowed:
+-- \000, s, S, \010, \013, \124, %
+-- Because SendChatMessage will error
+-- if an UTF8 multibyte character is incomplete,
+-- all character values above 127 have to be encoded to avoid this.
+-- This costs quite a bit of bandwidth (about 13-14%)
+-- Also, because drunken status is unknown for the received
+-- , strings used with SendChatMessage should be terminated with
+-- an identifying byte value, after which the server MAY add "...hic!"
+-- or as much as it can fit(!).
+-- Pass the identifying byte as a reserved character to this function
+-- to ensure the encoding doesn't contain that value.
+-- or use this: local message, match = arg1:gsub("^(.*)\029.-$", "%1")
+-- arg1 is message from channel, \029 is the string terminator
+-- , but may be used in the encoded datastream as well. :-)
+-- This encoding will expand data anywhere from:
+-- 0% (average with pure ascii text)
+-- 53.5% (average with random data valued zero to 255)
+-- 100% (only encoding data that encodes to two bytes)
+local function GenerateWoWChatChannelCodec()
+ local r = {}
+ for i = 128, 255 do
+ r[#r+1] = _byte_to_char[i]
+ end
+
+ local reserved_chars = "sS\000\010\013\124%"..table_concat(r)
+ return LibDeflate:CreateCodec(reserved_chars
+ , "\029\031", "\015\020")
+end
+
+local _chat_channel_codec
+
+--- Encode the string to make it ready to be transmitted in World of
+-- Warcraft chat channel.
+-- See also https://wow.gamepedia.com/ValidChatMessageCharacters
+-- @param str [string] The string to be encoded.
+-- @return [string] The encoded string.
+-- @see LibDeflate:DecodeForWoWChatChannel
+function LibDeflate:EncodeForWoWChatChannel(str)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:EncodeForWoWChatChannel(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ if not _chat_channel_codec then
+ _chat_channel_codec = GenerateWoWChatChannelCodec()
+ end
+ return _chat_channel_codec:Encode(str)
+end
+
+--- Decode the string produced by LibDeflate:EncodeForWoWChatChannel.
+-- @param str [string] The string to be decoded.
+-- @return [string/nil] The decoded string if succeeds. nil if fails.
+-- @see LibDeflate:EncodeForWoWChatChannel
+function LibDeflate:DecodeForWoWChatChannel(str)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:DecodeForWoWChatChannel(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ if not _chat_channel_codec then
+ _chat_channel_codec = GenerateWoWChatChannelCodec()
+ end
+ return _chat_channel_codec:Decode(str)
+end
+
+-- Credits to WeakAuras ,
+-- and Galmok (galmok@gmail.com) for the 6 bit encoding algorithm.
+-- The result of encoding will be 25% larger than the
+-- origin string, but every single byte of the encoding result will be
+-- printable characters as the following.
+local _byte_to_6bit_char = {
+ [0]="a", "b", "c", "d", "e", "f", "g", "h",
+ "i", "j", "k", "l", "m", "n", "o", "p",
+ "q", "r", "s", "t", "u", "v", "w", "x",
+ "y", "z", "A", "B", "C", "D", "E", "F",
+ "G", "H", "I", "J", "K", "L", "M", "N",
+ "O", "P", "Q", "R", "S", "T", "U", "V",
+ "W", "X", "Y", "Z", "0", "1", "2", "3",
+ "4", "5", "6", "7", "8", "9", "(", ")",
+}
+
+local _6bit_to_byte = {
+ [97]=0,[98]=1,[99]=2,[100]=3,[101]=4,[102]=5,[103]=6,[104]=7,
+ [105]=8,[106]=9,[107]=10,[108]=11,[109]=12,[110]=13,[111]=14,[112]=15,
+ [113]=16,[114]=17,[115]=18,[116]=19,[117]=20,[118]=21,[119]=22,[120]=23,
+ [121]=24,[122]=25,[65]=26,[66]=27,[67]=28,[68]=29,[69]=30,[70]=31,
+ [71]=32,[72]=33,[73]=34,[74]=35,[75]=36,[76]=37,[77]=38,[78]=39,
+ [79]=40,[80]=41,[81]=42,[82]=43,[83]=44,[84]=45,[85]=46,[86]=47,
+ [87]=48,[88]=49,[89]=50,[90]=51,[48]=52,[49]=53,[50]=54,[51]=55,
+ [52]=56,[53]=57,[54]=58,[55]=59,[56]=60,[57]=61,[40]=62,[41]=63,
+}
+
+--- Encode the string to make it printable.
+--
+-- Credis to WeakAuras2, this function is equivalant to the implementation
+-- it is using right now.
+-- The encoded string will be 25% larger than the origin string. However, every
+-- single byte of the encoded string will be one of 64 printable ASCII
+-- characters, which are can be easier copied, pasted and displayed.
+-- (26 lowercase letters, 26 uppercase letters, 10 numbers digits,
+-- left parenthese, or right parenthese)
+-- @param str [string] The string to be encoded.
+-- @return [string] The encoded string.
+function LibDeflate:EncodeForPrint(str)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:EncodeForPrint(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ local strlen = #str
+ local strlenMinus2 = strlen - 2
+ local i = 1
+ local buffer = {}
+ local buffer_size = 0
+ while i <= strlenMinus2 do
+ local x1, x2, x3 = string_byte(str, i, i+2)
+ i = i + 3
+ local cache = x1+x2*256+x3*65536
+ local b1 = cache % 64
+ cache = (cache - b1) / 64
+ local b2 = cache % 64
+ cache = (cache - b2) / 64
+ local b3 = cache % 64
+ local b4 = (cache - b3) / 64
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] =
+ _byte_to_6bit_char[b1].._byte_to_6bit_char[b2]
+ .._byte_to_6bit_char[b3].._byte_to_6bit_char[b4]
+ end
+
+ local cache = 0
+ local cache_bitlen = 0
+ while i <= strlen do
+ local x = string_byte(str, i, i)
+ cache = cache + x * _pow2[cache_bitlen]
+ cache_bitlen = cache_bitlen + 8
+ i = i + 1
+ end
+ while cache_bitlen > 0 do
+ local bit6 = cache % 64
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = _byte_to_6bit_char[bit6]
+ cache = (cache - bit6) / 64
+ cache_bitlen = cache_bitlen - 6
+ end
+
+ return table_concat(buffer)
+end
+
+--- Decode the printable string produced by LibDeflate:EncodeForPrint.
+-- "str" will have its prefixed and trailing control characters or space
+-- removed before it is decoded, so it is easier to use if "str" comes form
+-- user copy and paste with some prefixed or trailing spaces.
+-- Then decode fails if the string contains any characters cant be produced by
+-- LibDeflate:EncodeForPrint. That means, decode fails if the string contains a
+-- characters NOT one of 26 lowercase letters, 26 uppercase letters,
+-- 10 numbers digits, left parenthese, or right parenthese.
+-- @param str [string] The string to be decoded
+-- @return [string/nil] The decoded string if succeeds. nil if fails.
+function LibDeflate:DecodeForPrint(str)
+ if type(str) ~= "string" then
+ error(("Usage: LibDeflate:DecodeForPrint(str):"
+ .." 'str' - string expected got '%s'."):format(type(str)), 2)
+ end
+ str = str:gsub("^[%c ]+", "")
+ str = str:gsub("[%c ]+$", "")
+
+ local strlen = #str
+ if strlen == 1 then
+ return nil
+ end
+ local strlenMinus3 = strlen - 3
+ local i = 1
+ local buffer = {}
+ local buffer_size = 0
+ while i <= strlenMinus3 do
+ local x1, x2, x3, x4 = string_byte(str, i, i+3)
+ x1 = _6bit_to_byte[x1]
+ x2 = _6bit_to_byte[x2]
+ x3 = _6bit_to_byte[x3]
+ x4 = _6bit_to_byte[x4]
+ if not (x1 and x2 and x3 and x4) then
+ return nil
+ end
+ i = i + 4
+ local cache = x1+x2*64+x3*4096+x4*262144
+ local b1 = cache % 256
+ cache = (cache - b1) / 256
+ local b2 = cache % 256
+ local b3 = (cache - b2) / 256
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] =
+ _byte_to_char[b1].._byte_to_char[b2].._byte_to_char[b3]
+ end
+
+ local cache = 0
+ local cache_bitlen = 0
+ while i <= strlen do
+ local x = string_byte(str, i, i)
+ x = _6bit_to_byte[x]
+ if not x then
+ return nil
+ end
+ cache = cache + x * _pow2[cache_bitlen]
+ cache_bitlen = cache_bitlen + 6
+ i = i + 1
+ end
+
+ while cache_bitlen >= 8 do
+ local byte = cache % 256
+ buffer_size = buffer_size + 1
+ buffer[buffer_size] = _byte_to_char[byte]
+ cache = (cache - byte) / 256
+ cache_bitlen = cache_bitlen - 8
+ end
+
+ return table_concat(buffer)
+end
+
+local function InternalClearCache()
+ _chat_channel_codec = nil
+ _addon_channel_codec = nil
+end
+
+-- For test. Don't use the functions in this table for real application.
+-- Stuffs in this table is subject to change.
+LibDeflate.internals = {
+ LoadStringToTable = LoadStringToTable,
+ IsValidDictionary = IsValidDictionary,
+ IsEqualAdler32 = IsEqualAdler32,
+ _byte_to_6bit_char = _byte_to_6bit_char,
+ _6bit_to_byte = _6bit_to_byte,
+ InternalClearCache = InternalClearCache,
+}
+
+--[[-- Commandline options
+@class table
+@name CommandlineOptions
+@usage lua LibDeflate.lua [OPTION] [INPUT] [OUTPUT]
+\-0 store only. no compression.
+\-1 fastest compression.
+\-9 slowest and best compression.
+\-d do decompression instead of compression.
+\--dict specify the file that contains
+the entire preset dictionary.
+\-h give this help.
+\--strategy specify a special compression strategy.
+\-v print the version and copyright info.
+\--zlib use zlib format instead of raw deflate.
+]]
+
+-- currently no plan to support stdin and stdout.
+-- Because Lua in Windows does not set stdout with binary mode.
+if io and os and debug and _G.arg then
+ local io = io
+ local os = os
+ local debug = debug
+ local arg = _G.arg
+ local debug_info = debug.getinfo(1)
+ if debug_info.source == arg[0]
+ or debug_info.short_src == arg[0] then
+ -- We are indeed runnning THIS file from the commandline.
+ local input
+ local output
+ local i = 1
+ local status
+ local is_zlib = false
+ local is_decompress = false
+ local level
+ local strategy
+ local dictionary
+ while (arg[i]) do
+ local a = arg[i]
+ if a == "-h" then
+ print(LibDeflate._COPYRIGHT
+ .."\nUsage: lua LibDeflate.lua [OPTION] [INPUT] [OUTPUT]\n"
+ .." -0 store only. no compression.\n"
+ .." -1 fastest compression.\n"
+ .." -9 slowest and best compression.\n"
+ .." -d do decompression instead of compression.\n"
+ .." --dict specify the file that contains"
+ .." the entire preset dictionary.\n"
+ .." -h give this help.\n"
+ .." --strategy "
+ .." specify a special compression strategy.\n"
+ .." -v print the version and copyright info.\n"
+ .." --zlib use zlib format instead of raw deflate.\n")
+ os.exit(0)
+ elseif a == "-v" then
+ print(LibDeflate._COPYRIGHT)
+ os.exit(0)
+ elseif a:find("^%-[0-9]$") then
+ level = tonumber(a:sub(2, 2))
+ elseif a == "-d" then
+ is_decompress = true
+ elseif a == "--dict" then
+ i = i + 1
+ local dict_filename = arg[i]
+ if not dict_filename then
+ io.stderr:write("You must speicify the dict filename")
+ os.exit(1)
+ end
+ local dict_file, dict_status = io.open(dict_filename, "rb")
+ if not dict_file then
+ io.stderr:write(
+ ("LibDeflate: Cannot read the dictionary file '%s': %s")
+ :format(dict_filename, dict_status))
+ os.exit(1)
+ end
+ local dict_str = dict_file:read("*all")
+ dict_file:close()
+ -- In your lua program, you should pass in adler32 as a CONSTANT
+ -- , so it actually prevent you from modifying dictionary
+ -- unintentionally during the program development. I do this
+ -- here just because no convenient way to verify in commandline.
+ dictionary = LibDeflate:CreateDictionary(dict_str,
+ #dict_str, LibDeflate:Adler32(dict_str))
+ elseif a == "--strategy" then
+ -- Not sure if I should check error here
+ -- If I do, redudant code.
+ i = i + 1
+ strategy = arg[i]
+ elseif a == "--zlib" then
+ is_zlib = true
+ elseif a:find("^%-") then
+ io.stderr:write(("LibDeflate: Invalid argument: %s")
+ :format(a))
+ os.exit(1)
+ else
+ if not input then
+ input, status = io.open(a, "rb")
+ if not input then
+ io.stderr:write(
+ ("LibDeflate: Cannot read the file '%s': %s")
+ :format(a, tostring(status)))
+ os.exit(1)
+ end
+ elseif not output then
+ output, status = io.open(a, "wb")
+ if not output then
+ io.stderr:write(
+ ("LibDeflate: Cannot write the file '%s': %s")
+ :format(a, tostring(status)))
+ os.exit(1)
+ end
+ end
+ end
+ i = i + 1
+ end -- while (arg[i])
+
+ if not input or not output then
+ io.stderr:write("LibDeflate:"
+ .." You must specify both input and output files.")
+ os.exit(1)
+ end
+
+ local input_data = input:read("*all")
+ local configs = {
+ level = level,
+ strategy = strategy,
+ }
+ local output_data
+ if not is_decompress then
+ if not is_zlib then
+ if not dictionary then
+ output_data =
+ LibDeflate:CompressDeflate(input_data, configs)
+ else
+ output_data =
+ LibDeflate:CompressDeflateWithDict(input_data, dictionary
+ , configs)
+ end
+ else
+ if not dictionary then
+ output_data =
+ LibDeflate:CompressZlib(input_data, configs)
+ else
+ output_data =
+ LibDeflate:CompressZlibWithDict(input_data, dictionary
+ , configs)
+ end
+ end
+ else
+ if not is_zlib then
+ if not dictionary then
+ output_data = LibDeflate:DecompressDeflate(input_data)
+ else
+ output_data = LibDeflate:DecompressDeflateWithDict(
+ input_data, dictionary)
+ end
+ else
+ if not dictionary then
+ output_data = LibDeflate:DecompressZlib(input_data)
+ else
+ output_data = LibDeflate:DecompressZlibWithDict(
+ input_data, dictionary)
+ end
+ end
+ end
+
+ if not output_data then
+ io.stderr:write("LibDeflate: Decompress fails.")
+ os.exit(1)
+ end
+
+ output:write(output_data)
+ if input and input ~= io.stdin then
+ input:close()
+ end
+ if output and output ~= io.stdout then
+ output:close()
+ end
+
+ io.stderr:write(("Successfully writes %d bytes"):format(
+ output_data:len()))
+ os.exit(0)
+ end
+end
+
+return LibDeflate
diff --git a/Skada/Libs/LibDualSpec-1.0/LibDualSpec-1.0.lua b/Skada/Libs/LibDualSpec-1.0/LibDualSpec-1.0.lua
new file mode 100644
index 0000000..086f3cd
--- /dev/null
+++ b/Skada/Libs/LibDualSpec-1.0/LibDualSpec-1.0.lua
@@ -0,0 +1,437 @@
+--[[
+LibDualSpec-1.0 - Adds dual spec support to individual AceDB-3.0 databases
+Copyright (C) 2009-2012 Adirelle
+
+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.
+ * Redistribution of a stand alone version is strictly prohibited without
+ prior written authorization from the LibDualSpec project manager.
+ * Neither the name of the LibDualSpec authors 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, MINOR = "LibDualSpec-1.0", 17
+assert(LibStub, MAJOR.." requires LibStub")
+local lib, minor = LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end
+
+-- ----------------------------------------------------------------------------
+-- Library data
+-- ----------------------------------------------------------------------------
+
+lib.eventFrame = lib.eventFrame or CreateFrame("Frame")
+
+lib.registry = lib.registry or {}
+lib.options = lib.options or {}
+lib.mixin = lib.mixin or {}
+lib.upgrades = lib.upgrades or {}
+lib.currentSpec = lib.currentSpec or 0
+
+if minor and minor < 15 then
+ lib.talentsLoaded, lib.talentGroup = nil, nil
+ lib.specLoaded, lib.specGroup = nil, nil
+ lib.eventFrame:UnregisterAllEvents()
+ wipe(lib.options)
+end
+
+-- ----------------------------------------------------------------------------
+-- Locals
+-- ----------------------------------------------------------------------------
+
+local registry = lib.registry
+local options = lib.options
+local mixin = lib.mixin
+local upgrades = lib.upgrades
+
+-- "Externals"
+local AceDB3 = LibStub('AceDB-3.0', true)
+local AceDBOptions3 = LibStub('AceDBOptions-3.0', true)
+local AceConfigRegistry3 = LibStub('AceConfigRegistry-3.0', true)
+
+-- classId specialization functions don't require player data to be loaded
+local _, _, classId = UnitClass("player")
+local numSpecs = GetNumSpecializationsForClassID(classId)
+
+-- ----------------------------------------------------------------------------
+-- Localization
+-- ----------------------------------------------------------------------------
+
+local L_ENABLED = "Enable spec profiles"
+local L_ENABLED_DESC = "When enabled, your profile will be set to the specified profile when you change specialization."
+local L_CURRENT = "%s (Current)" -- maybe something like >> %s << and/or coloring to avoid localization?
+
+do
+ local locale = GetLocale()
+ if locale == "frFR" then
+ -- L_ENABLED = "Enable spec profiles"
+ -- L_ENABLED_DESC = "When enabled, your profile will be set to the specified profile when you change specialization."
+ -- L_CURRENT = "%s (Current)"
+ elseif locale == "deDE" then
+ L_ENABLED = "Spezialisierungsprofile aktivieren"
+ L_ENABLED_DESC = "Falls diese Option aktiviert ist, wird dein Profil auf das angegebene Profil gesetzt, wenn du die Spezialisierung wechselst."
+ L_CURRENT = "%s (Momentan)"
+ elseif locale == "koKR" then
+ -- L_ENABLED = "Enable spec profiles"
+ -- L_ENABLED_DESC = "When enabled, your profile will be set to the specified profile when you change specialization."
+ -- L_CURRENT = "%s (Current)"
+ elseif locale == "ruRU" then
+ L_ENABLED = "Включить профили специализации"
+ L_ENABLED_DESC = "Если включено, ваш профиль будет зависеть от выбранной специализации."
+ L_CURRENT = "%s (Текущий)"
+ elseif locale == "zhCN" then
+ L_ENABLED = "启用专精配置文件"
+ L_ENABLED_DESC = "当启用后,当切换专精时配置文件将设置为专精配置文件。"
+ L_CURRENT = "%s(当前)"
+ elseif locale == "zhTW" then
+ L_ENABLED = "啟用專精設定檔"
+ L_ENABLED_DESC = "當啟用後,當你切換專精時設定檔會設定為專精設定檔。"
+ L_CURRENT = "%s (目前) "
+ elseif locale == "esES" or locale == "esMX" then
+ -- L_ENABLED = "Enable spec profiles"
+ -- L_ENABLED_DESC = "When enabled, your profile will be set to the specified profile when you change specialization."
+ -- L_CURRENT = "%s (Current)"
+ elseif locale == "ptBR" then
+ -- L_ENABLED = "Enable spec profiles"
+ -- L_ENABLED_DESC = "When enabled, your profile will be set to the specified profile when you change specialization."
+ -- L_CURRENT = "%s (Current)"
+ elseif locale == "itIT" then
+ -- L_ENABLED = "Enable spec profiles"
+ -- L_ENABLED_DESC = "When enabled, your profile will be set to the specified profile when you change specialization."
+ -- L_CURRENT = "%s (Current)"
+ end
+end
+
+-- ----------------------------------------------------------------------------
+-- Mixin
+-- ----------------------------------------------------------------------------
+
+--- Get dual spec feature status.
+-- @return (boolean) true is dual spec feature enabled.
+-- @name enhancedDB:IsDualSpecEnabled
+function mixin:IsDualSpecEnabled()
+ return registry[self].db.char.enabled
+end
+
+--- Enable/disabled dual spec feature.
+-- @param enabled (boolean) true to enable dual spec feature, false to disable it.
+-- @name enhancedDB:SetDualSpecEnabled
+function mixin:SetDualSpecEnabled(enabled)
+ local db = registry[self].db.char
+ db.enabled = not not enabled
+
+ local currentProfile = self:GetCurrentProfile()
+ for i = 1, numSpecs do
+ -- nil out entries on disable, set nil entries to the current profile on enable
+ db[i] = enabled and (db[i] or currentProfile) or nil
+ end
+
+ self:CheckDualSpecState()
+end
+
+--- Get the profile assigned to a specialization.
+-- Defaults to the current profile.
+-- @param spec (number) the specialization index.
+-- @return (string) the profile name.
+-- @name enhancedDB:GetDualSpecProfile
+function mixin:GetDualSpecProfile(spec)
+ return registry[self].db.char[spec or lib.currentSpec] or self:GetCurrentProfile()
+end
+
+--- Set the profile assigned to a specialization.
+-- No validation are done to ensure the profile is valid.
+-- @param profileName (string) the profile name to use.
+-- @param spec (number) the specialization index.
+-- @name enhancedDB:SetDualSpecProfile
+function mixin:SetDualSpecProfile(profileName, spec)
+ spec = spec or lib.currentSpec
+ if spec < 1 or spec > numSpecs then return end
+
+ registry[self].db.char[spec] = profileName
+ self:CheckDualSpecState()
+end
+
+--- Check if a profile swap should occur.
+-- There is normally no reason to call this method directly as LibDualSpec
+-- takes care of calling it at the appropriate time.
+-- @name enhancedDB:CheckDualSpecState
+function mixin:CheckDualSpecState()
+ if not registry[self].db.char.enabled then return end
+ if lib.currentSpec == 0 then return end
+
+ local profileName = self:GetDualSpecProfile()
+ if profileName ~= self:GetCurrentProfile() then
+ self:SetProfile(profileName)
+ end
+end
+
+-- ----------------------------------------------------------------------------
+-- AceDB-3.0 support
+-- ----------------------------------------------------------------------------
+
+local function EmbedMixin(target)
+ for k,v in next, mixin do
+ rawset(target, k, v)
+ end
+end
+
+-- Upgrade settings from current/alternate system.
+-- This sets the current profile as the profile for your current spec and your
+-- swapped profile as the profile for the rest of your specs.
+local function UpgradeDatabase(target)
+ if lib.currentSpec == 0 then
+ upgrades[target] = true
+ return
+ end
+
+ local db = target:GetNamespace(MAJOR, true)
+ if db and db.char.profile then
+ for i = 1, numSpecs do
+ if i == lib.currentSpec then
+ db.char[i] = target:GetCurrentProfile()
+ else
+ db.char[i] = db.char.profile
+ end
+ end
+ db.char.profile = nil
+ db.char.specGroup = nil
+ end
+end
+
+-- Reset a spec profile to the current one if its profile is deleted.
+function lib:OnProfileDeleted(event, target, profileName)
+ local db = registry[target].db.char
+ if not db.enabled then return end
+
+ for i = 1, numSpecs do
+ if db[i] == profileName then
+ db[i] = target:GetCurrentProfile()
+ end
+ end
+end
+
+-- Actually enhance the database
+-- This is used on first initialization and everytime the database is reset using :ResetDB
+function lib:_EnhanceDatabase(event, target)
+ registry[target].db = target:GetNamespace(MAJOR, true) or target:RegisterNamespace(MAJOR)
+ EmbedMixin(target)
+ target:CheckDualSpecState()
+end
+
+--- Embed dual spec feature into an existing AceDB-3.0 database.
+-- LibDualSpec specific methods are added to the instance.
+-- @name LibDualSpec:EnhanceDatabase
+-- @param target (table) the AceDB-3.0 instance.
+-- @param name (string) a user-friendly name of the database (best bet is the addon name).
+function lib:EnhanceDatabase(target, name)
+ AceDB3 = AceDB3 or LibStub('AceDB-3.0', true)
+ if type(target) ~= "table" then
+ error("Usage: LibDualSpec:EnhanceDatabase(target, name): target should be a table.", 2)
+ elseif type(name) ~= "string" then
+ error("Usage: LibDualSpec:EnhanceDatabase(target, name): name should be a string.", 2)
+ elseif not AceDB3 or not AceDB3.db_registry[target] then
+ error("Usage: LibDualSpec:EnhanceDatabase(target, name): target should be an AceDB-3.0 database.", 2)
+ elseif target.parent then
+ error("Usage: LibDualSpec:EnhanceDatabase(target, name): cannot enhance a namespace.", 2)
+ elseif registry[target] then
+ return
+ end
+ registry[target] = { name = name }
+ UpgradeDatabase(target)
+ lib:_EnhanceDatabase("EnhanceDatabase", target)
+ target.RegisterCallback(lib, "OnDatabaseReset", "_EnhanceDatabase")
+ target.RegisterCallback(lib, "OnProfileDeleted")
+end
+
+-- ----------------------------------------------------------------------------
+-- AceDBOptions-3.0 support
+-- ----------------------------------------------------------------------------
+
+local function NoDualSpec()
+ return UnitLevel("player") < 11
+end
+
+options.new = {
+ name = "New",
+ type = "input",
+ order = 30,
+ get = false,
+ set = function(info, value)
+ local db = info.handler.db
+ if db:IsDualSpecEnabled() then
+ db:SetDualSpecProfile(value, lib.currentSpec)
+ else
+ db:SetProfile(value)
+ end
+ end,
+}
+
+options.choose = {
+ name = "Existing Profiles",
+ type = "select",
+ order = 40,
+ get = "GetCurrentProfile",
+ set = "SetProfile",
+ values = "ListProfiles",
+ arg = "common",
+ disabled = function(info)
+ return info.handler.db:IsDualSpecEnabled()
+ end
+}
+
+options.enabled = {
+ name = "|cffffd200"..L_ENABLED.."|r",
+ desc = L_ENABLED_DESC,
+ descStyle = "inline",
+ type = "toggle",
+ order = 41,
+ width = "full",
+ get = function(info) return info.handler.db:IsDualSpecEnabled() end,
+ set = function(info, value) info.handler.db:SetDualSpecEnabled(value) end,
+ hidden = NoDualSpec,
+}
+
+for i = 1, numSpecs do
+ local _, specName = GetSpecializationInfoForClassID(classId, i)
+ options["specProfile" .. i] = {
+ type = "select",
+ name = function() return lib.currentSpec == i and L_CURRENT:format(specName) or specName end,
+ order = 42 + i,
+ get = function(info) return info.handler.db:GetDualSpecProfile(i) end,
+ set = function(info, value) info.handler.db:SetDualSpecProfile(value, i) end,
+ values = "ListProfiles",
+ arg = "common",
+ disabled = function(info) return not info.handler.db:IsDualSpecEnabled() end,
+ hidden = NoDualSpec,
+ }
+end
+
+--- Embed dual spec options into an existing AceDBOptions-3.0 option table.
+-- @name LibDualSpec:EnhanceOptions
+-- @param optionTable (table) The option table returned by AceDBOptions-3.0.
+-- @param target (table) The AceDB-3.0 the options operate on.
+function lib:EnhanceOptions(optionTable, target)
+ AceDBOptions3 = AceDBOptions3 or LibStub('AceDBOptions-3.0', true)
+ AceConfigRegistry3 = AceConfigRegistry3 or LibStub('AceConfigRegistry-3.0', true)
+ if type(optionTable) ~= "table" then
+ error("Usage: LibDualSpec:EnhanceOptions(optionTable, target): optionTable should be a table.", 2)
+ elseif type(target) ~= "table" then
+ error("Usage: LibDualSpec:EnhanceOptions(optionTable, target): target should be a table.", 2)
+ elseif not AceDBOptions3 or not AceDBOptions3.optionTables[target] then
+ error("Usage: LibDualSpec:EnhanceOptions(optionTable, target): optionTable is not an AceDBOptions-3.0 table.", 2)
+ elseif optionTable.handler.db ~= target then
+ error("Usage: LibDualSpec:EnhanceOptions(optionTable, target): optionTable must be the option table of target.", 2)
+ elseif not registry[target] then
+ error("Usage: LibDualSpec:EnhanceOptions(optionTable, target): EnhanceDatabase should be called before EnhanceOptions(optionTable, target).", 2)
+ end
+
+ -- localize our replacements
+ options.new.name = optionTable.args.new.name
+ options.new.desc = optionTable.args.new.desc
+ options.choose.name = optionTable.args.choose.name
+ options.choose.desc = optionTable.args.choose.desc
+
+ -- add our new options
+ if not optionTable.plugins then
+ optionTable.plugins = {}
+ end
+ optionTable.plugins[MAJOR] = options
+end
+
+-- ----------------------------------------------------------------------------
+-- Upgrade existing
+-- ----------------------------------------------------------------------------
+
+for target in next, registry do
+ UpgradeDatabase(target)
+ EmbedMixin(target)
+ target:CheckDualSpecState()
+ local optionTable = AceDBOptions3 and AceDBOptions3.optionTables[target]
+ if optionTable then
+ lib:EnhanceOptions(optionTable, target)
+ end
+end
+
+-- ----------------------------------------------------------------------------
+-- Inspection
+-- ----------------------------------------------------------------------------
+
+local function iterator(registry, key)
+ local data
+ key, data = next(registry, key)
+ if key then
+ return key, data.name
+ end
+end
+
+--- Iterate through enhanced AceDB3.0 instances.
+-- The iterator returns (instance, name) pairs where instance and name are the
+-- arguments that were provided to lib:EnhanceDatabase.
+-- @name LibDualSpec:IterateDatabases
+-- @return Values to be used in a for .. in .. do statement.
+function lib:IterateDatabases()
+ return iterator, lib.registry
+end
+
+-- ----------------------------------------------------------------------------
+-- Switching logic
+-- ----------------------------------------------------------------------------
+
+local function eventHandler(self, event)
+ lib.currentSpec = GetSpecialization() or 0
+
+ if event == "PLAYER_LOGIN" then
+ self:UnregisterEvent(event)
+ self:RegisterUnitEvent("PLAYER_SPECIALIZATION_CHANGED", "player")
+ end
+
+ if lib.currentSpec > 0 and next(upgrades) then
+ for target in next, upgrades do
+ UpgradeDatabase(target)
+ end
+ wipe(upgrades)
+ end
+
+ for target in next, registry do
+ target:CheckDualSpecState()
+ end
+
+ if AceConfigRegistry3 and next(registry) then
+ -- Update the "Current" text in options
+ -- We don't get the key for the actual registered options table, and we can't
+ -- really check for our enhanced options without walking every options table,
+ -- so just refresh anything.
+ for appName in AceConfigRegistry3:IterateOptionsTables() do
+ AceConfigRegistry3:NotifyChange(appName)
+ end
+ end
+end
+
+lib.eventFrame:SetScript("OnEvent", eventHandler)
+if IsLoggedIn() then
+ eventHandler(lib.eventFrame, "PLAYER_LOGIN")
+else
+ lib.eventFrame:RegisterEvent("PLAYER_LOGIN")
+end
+
+
diff --git a/Skada/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua b/Skada/Libs/LibSharedMedia-3.0/LibSharedMedia-3.0.lua
new file mode 100644
index 0000000..ce5ff14
--- /dev/null
+++ b/Skada/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/Skada/Libs/LibStub/LibStub.lua b/Skada/Libs/LibStub/LibStub.lua
new file mode 100644
index 0000000..0a41ac0
--- /dev/null
+++ b/Skada/Libs/LibStub/LibStub.lua
@@ -0,0 +1,30 @@
+-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info
+-- LibStub is hereby placed in the Public Domain Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke
+local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS!
+local LibStub = _G[LIBSTUB_MAJOR]
+
+if not LibStub or LibStub.minor < LIBSTUB_MINOR then
+ LibStub = LibStub or {libs = {}, minors = {} }
+ _G[LIBSTUB_MAJOR] = LibStub
+ LibStub.minor = LIBSTUB_MINOR
+
+ function LibStub:NewLibrary(major, minor)
+ assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)")
+ minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.")
+
+ local oldminor = self.minors[major]
+ if oldminor and oldminor >= minor then return nil end
+ self.minors[major], self.libs[major] = minor, self.libs[major] or {}
+ return self.libs[major], oldminor
+ end
+
+ function LibStub:GetLibrary(major, silent)
+ if not self.libs[major] and not silent then
+ error(("Cannot find a library instance of %q."):format(tostring(major)), 2)
+ end
+ return self.libs[major], self.minors[major]
+ end
+
+ function LibStub:IterateLibraries() return pairs(self.libs) end
+ setmetatable(LibStub, { __call = LibStub.GetLibrary })
+end
diff --git a/Skada/Libs/LibTranslit-1.0/LibTranslit-1.0.lua b/Skada/Libs/LibTranslit-1.0/LibTranslit-1.0.lua
new file mode 100644
index 0000000..f0793fb
--- /dev/null
+++ b/Skada/Libs/LibTranslit-1.0/LibTranslit-1.0.lua
@@ -0,0 +1,124 @@
+--[[
+Copyright (C) 2019-2022 Vardex
+This file is part of LibTranslit.
+LibTranslit is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+LibTranslit is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+You should have received a copy of the GNU Lesser General Public License along with LibTranslit. If not, see .
+--]]
+local MAJOR, MINOR = "LibTranslit-1.0", 4
+if not LibStub then
+ error(("%s requires LibStub."):format(MAJOR))
+end
+
+local lib = LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end
+
+local strlen = strlen or string.len
+local strsub = strsub or string.sub
+local strbyte = strbyte or string.byte
+local strchar = strchar or string.char
+local format = format or string.format
+
+local cyrToLat = {
+ ["А"] = "A",
+ ["а"] = "a",
+ ["Б"] = "B",
+ ["б"] = "b",
+ ["В"] = "V",
+ ["в"] = "v",
+ ["Г"] = "G",
+ ["г"] = "g",
+ ["Д"] = "D",
+ ["д"] = "d",
+ ["Е"] = "E",
+ ["е"] = "e",
+ ["Ё"] = "e",
+ ["ё"] = "e",
+ ["Ж"] = "Zh",
+ ["ж"] = "zh",
+ ["З"] = "Z",
+ ["з"] = "z",
+ ["И"] = "I",
+ ["и"] = "i",
+ ["Й"] = "Y",
+ ["й"] = "y",
+ ["К"] = "K",
+ ["к"] = "k",
+ ["Л"] = "L",
+ ["л"] = "l",
+ ["М"] = "M",
+ ["м"] = "m",
+ ["Н"] = "N",
+ ["н"] = "n",
+ ["О"] = "O",
+ ["о"] = "o",
+ ["П"] = "P",
+ ["п"] = "p",
+ ["Р"] = "R",
+ ["р"] = "r",
+ ["С"] = "S",
+ ["с"] = "s",
+ ["Т"] = "T",
+ ["т"] = "t",
+ ["У"] = "U",
+ ["у"] = "u",
+ ["Ф"] = "F",
+ ["ф"] = "f",
+ ["Х"] = "Kh",
+ ["х"] = "kh",
+ ["Ц"] = "Ts",
+ ["ц"] = "ts",
+ ["Ч"] = "Ch",
+ ["ч"] = "ch",
+ ["Ш"] = "Sh",
+ ["ш"] = "sh",
+ ["Щ"] = "Shch",
+ ["щ"] = "shch",
+ ["Ъ"] = "",
+ ["ъ"] = "",
+ ["Ы"] = "Y",
+ ["ы"] = "y",
+ ["Ь"] = "",
+ ["ь"] = "",
+ ["Э"] = "E",
+ ["э"] = "e",
+ ["Ю"] = "Yu",
+ ["ю"] = "yu",
+ ["Я"] = "Ya",
+ ["я"] = "ya"
+}
+
+function lib:Transliterate(str, mark)
+ if not str then return "" end
+
+ mark = mark or ""
+ local tstr = ""
+ local tword = ""
+ local mark_word = false
+ local i = 1
+
+ while i <= strlen(str) do
+ local c = strsub(str, i, i)
+ local b = strbyte(c)
+
+ if b == 208 or b == 209 then
+ mark_word = true
+ c = strsub(str, i + 1, i + 1)
+ tword = format("%s%s", tword, (cyrToLat[strchar(b, strbyte(c))] or strchar(b, strbyte(c))))
+
+ i = i + 2
+ else
+ tword = format("%s%s", tword, c)
+
+ if c == " " or c == "-" then
+ tstr = format("%s%s", tstr, (mark_word and format("%s%s", mark, tword) or tword))
+ tword = ""
+ mark_word = false
+ end
+
+ i = i + 1
+ end
+ end
+
+ return format("%s%s", tstr, (mark_word and format("%s%s", mark, tword) or tword))
+end
diff --git a/Skada/Libs/Load.xml b/Skada/Libs/Load.xml
new file mode 100644
index 0000000..71bc73f
--- /dev/null
+++ b/Skada/Libs/Load.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Skada/Libs/SpecializedLibBars-1.0/SpecializedLibBars-1.0.lua b/Skada/Libs/SpecializedLibBars-1.0/SpecializedLibBars-1.0.lua
new file mode 100644
index 0000000..d2afda3
--- /dev/null
+++ b/Skada/Libs/SpecializedLibBars-1.0/SpecializedLibBars-1.0.lua
@@ -0,0 +1,2464 @@
+-- LibBars-1.0 by Kader, all glory to him.
+-- Specialized ( = enhanced) for Skada
+-- Note to self: don't forget to notify original author of changes
+-- in the unlikely event they end up being usable outside of Skada.
+-- Renaming the library (MAJOR) might break few things.
+
+local MAJOR, MINOR = "SpecializedLibBars-1.0", 90026
+local lib, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end -- No Upgrade needed.
+local folder = ...
+
+-------------------------------------------------------------------------------
+-- library callbacks
+-------------------------------------------------------------------------------
+
+local CallbackHandler = LibStub("CallbackHandler-1.0")
+lib.callbacks = lib.callbacks or CallbackHandler:New(lib)
+local callbacks = lib.callbacks
+
+-------------------------------------------------------------------------------
+-- cache frequently used lua and game functions
+-------------------------------------------------------------------------------
+
+local GetTime = GetTime
+local min, max, floor = math.min, math.max, math.floor
+local tsort, tinsert, tremove, wipe = table.sort, table.insert, table.remove, wipe
+local next, pairs, error, type, format = next, pairs, error, type, string.format
+local CreateFrame = CreateFrame
+local GameTooltip = GameTooltip
+local setmetatable = setmetatable
+local GetScreenWidth = GetScreenWidth
+local GetScreenHeight = GetScreenHeight
+local IsAltKeyDown = IsAltKeyDown
+local IsControlKeyDown = IsControlKeyDown
+local IsShiftKeyDown = IsShiftKeyDown
+
+-------------------------------------------------------------------------------
+-- localization
+-------------------------------------------------------------------------------
+
+local L_RESIZE_HEADER = "Resize"
+local L_RESIZE_CLICK = "\124cff00ff00Click\124r to freely resize window."
+local L_RESIZE_SHIFT_CLICK = "\124cff00ff00Shift-Click\124r to change the width."
+local L_RESIZE_ALT_CLICK = "\124cff00ff00Alt-Click\124r to change the height."
+local L_LOCK_WINDOW = "Lock Window"
+local L_UNLOCK_WINDOW = "Unlock Window"
+
+if LOCALE_deDE then
+ L_RESIZE_HEADER = "Gr\195\182\195\159e \195\164ndern"
+ L_RESIZE_CLICK = "\124cff00ff00Klicken\124r, um die Fenstergr\195\182\195\159e frei zu \195\164ndern."
+ L_RESIZE_SHIFT_CLICK = "\124cff00ff00Umschalt-Klick\124r, um die Breite zu \195\164ndern."
+ L_RESIZE_ALT_CLICK = "\124cff00ff00Alt-Klick\124r, um die H\195\182he zu \195\164ndern."
+ L_LOCK_WINDOW = "Fenster sperren"
+ L_UNLOCK_WINDOW = "Fenster entsperren"
+elseif LOCALE_esES or LOCALE_esMX then
+ L_RESIZE_HEADER = "Redimensionar"
+ L_RESIZE_CLICK = "\124cff00ff00Haga clic\124r para cambiar el tama\195\177o de la ventana."
+ L_RESIZE_SHIFT_CLICK = "\124cff00ff00Shift-Click\124r para cambiar el ancho de la ventana."
+ L_RESIZE_ALT_CLICK = "\124cff00ff00Alt-Click\124r para cambiar la altura de la ventana."
+ L_LOCK_WINDOW = "Bloquear ventana"
+ L_UNLOCK_WINDOW = "Desbloquear ventana"
+elseif LOCALE_frFR then
+ L_RESIZE_HEADER = "Redimensionner"
+ L_RESIZE_CLICK = "\124cff00ff00Clic\124r pour redimensionner."
+ L_RESIZE_SHIFT_CLICK = "\124cff00ff00Shift clic\124r pour changer la largeur."
+ L_RESIZE_ALT_CLICK = "\124cff00ff00Alt clic\124r pour changer la hauteur."
+ L_LOCK_WINDOW = "Verrouiller la fen\195\170tre"
+ L_UNLOCK_WINDOW = "D\195\169verrouiller la fen\195\170tre"
+elseif LOCALE_koKR then
+ L_RESIZE_HEADER = "크기 조정"
+ L_RESIZE_CLICK = "\124cff00ff00클릭\124r하여 창 크기를 자유롭게 조정합니다."
+ L_RESIZE_SHIFT_CLICK = "너비를 변경하려면 \124cff00ff00Shift-클릭\124r하십시오."
+ L_RESIZE_ALT_CLICK = "높이를 변경하려면 \124cff00ff00Alt-클릭\124r하십시오"
+ L_LOCK_WINDOW = "잠금 창"
+ L_UNLOCK_WINDOW = "잠금 해제 창"
+elseif LOCALE_ruRU then
+ L_RESIZE_HEADER = "Изменение размера"
+ L_RESIZE_CLICK = "\124cff00ff00Щелкните\124r, чтобы изменить размер окна."
+ L_RESIZE_SHIFT_CLICK = "\124cff00ff00Shift-Click\124r, чтобы изменить ширину."
+ L_RESIZE_ALT_CLICK = "\124cff00ff00ALT-Click\124r, чтобы изменить высоту."
+ L_LOCK_WINDOW = "Заблокировать окно"
+ L_UNLOCK_WINDOW = "Разблокировать окно"
+elseif LOCALE_zhCN then
+ L_RESIZE_HEADER = "调整大小"
+ L_RESIZE_CLICK = "\124cff00ff00单击\124r以调整窗口大小。"
+ L_RESIZE_SHIFT_CLICK = "\124cff00ff00Shift-Click\124r改变窗口的宽度。"
+ L_RESIZE_ALT_CLICK = "\124cff00ff00Alt-Click\124r更改窗口高度。"
+ L_LOCK_WINDOW = "锁定窗口"
+ L_UNLOCK_WINDOW = "解锁窗口"
+elseif LOCALE_zhTW then
+ L_RESIZE_HEADER = "調整大小"
+ L_RESIZE_CLICK = "\124cff00ff00單擊\124r以調整窗口大小。"
+ L_RESIZE_SHIFT_CLICK = "\124cff00ff00Shift-Click\124r改變窗口的寬度。"
+ L_RESIZE_ALT_CLICK = "\124cff00ff00Alt-Click\124r更改窗口高度。"
+ L_LOCK_WINDOW = "鎖定窗口"
+ L_UNLOCK_WINDOW = "解鎖窗口"
+end
+
+-------------------------------------------------------------------------------
+-- frame and class creation
+-------------------------------------------------------------------------------
+
+-- manageable textures and fontstrings z level
+local createFrame
+do
+ local function setZLevel(self, level)
+ local parent = self._parent
+ if level <= 0 then
+ self:SetParent(parent)
+ else
+ local zlevels = parent._zlevels
+ if level > #zlevels then
+ for i = #zlevels + 1, level do
+ zlevels[i] = CreateFrame("Frame", nil, (zlevels[i - 1] or parent))
+ zlevels[i]:SetAllPoints(true)
+ end
+ end
+ self:SetParent(zlevels[level])
+ end
+ end
+
+ local function createTexture(self, ...)
+ local tx = self:_CreateTexture(...)
+ tx._parent = self
+ tx.SetZLevel = setZLevel
+ return tx
+ end
+
+ local function createFontString(self, ...)
+ local fs = self:_CreateFontString(...)
+ fs._parent = self
+ fs.SetZLevel = setZLevel
+ return fs
+ end
+
+ function createFrame(...)
+ local f = CreateFrame(...)
+ f._zlevels = f._zlevels or {}
+
+ f._CreateTexture = f.CreateTexture
+ f.CreateTexture = createTexture
+
+ f._CreateFontString = f.CreateFontString
+ f.CreateFontString = createFontString
+
+ return f
+ end
+end
+
+local function createClass(ftype, parent)
+ local class = (type(ftype) == "table") and ftype or CreateFrame(ftype)
+ class.mt = {__index = class}
+
+ if parent then
+ class = setmetatable(class, {__index = parent})
+ class.super = parent
+ end
+
+ class.Bind = function(self, o)
+ return setmetatable(o, self.mt)
+ end
+
+ return class
+end
+
+-------------------------------------------------------------------------------
+-- library variables.
+-------------------------------------------------------------------------------
+
+local framePrototype = createClass("Frame")
+lib.barPrototype = lib.barPrototype or createClass({}, framePrototype)
+lib.barListPrototype = lib.barListPrototype or createClass({}, framePrototype)
+
+local barPrototype = lib.barPrototype
+local barListPrototype = lib.barListPrototype
+
+local listOnEnter, listOnLeave
+local anchorOnEnter, anchorOnLeave
+local stretchOnMouseDown, stretchOnMouseUp
+
+lib.bars = lib.bars or {}
+lib.barLists = lib.barLists or {}
+lib.recycledBars = lib.recycledBars or {}
+lib.listPosition = lib.listPosition or {}
+
+local bars = lib.bars
+local barLists = lib.barLists
+local recycledBars = lib.recycledBars
+local posix = lib.listPosition
+
+local scrollspeed = 1
+local dummyTable = {}
+
+local ICON_LOCK = ([[Interface\AddOns\%s\Libs\%s\lock.tga]]):format(folder, MAJOR)
+local ICON_UNLOCK = ([[Interface\AddOns\%s\Libs\%s\unlock.tga]]):format(folder, MAJOR)
+local ICON_RESIZE = [[Interface\CHATFRAME\UI-ChatIM-SizeGrabber-Up]]
+local ICON_STRETCH = [[Interface\MINIMAP\ROTATING-MINIMAPGUIDEARROW.blp]]
+
+lib.LEFT_TO_RIGHT = 1
+lib.RIGHT_TO_LEFT = 2
+local LEFT_TO_RIGHT = lib.LEFT_TO_RIGHT
+local RIGHT_TO_LEFT = lib.RIGHT_TO_LEFT
+
+-------------------------------------------------------------------------------
+-- local functions
+-------------------------------------------------------------------------------
+
+-- table pool
+local new, del
+do
+ local table_pool = setmetatable({}, {__mode = "kv"})
+
+ function new()
+ local t = next(table_pool)
+ if t then table_pool[t] = nil end
+ return t or {}
+ end
+
+ function del(t)
+ if type(t) == "table" then
+ for k, v in pairs(t) do
+ t[k] = nil
+ end
+ table_pool[t] = true
+ end
+ return nil
+ end
+end
+
+-------------------------------------------------------------------------------
+-- library functions.
+-------------------------------------------------------------------------------
+
+-- lib:NewBarGroup - bar list creation
+do
+ local function anchorOnMouseDown(self, button)
+ local p = self:GetParent()
+ if (button == "LeftButton" and p.locked) or button == "MiddleButton" then
+ stretchOnMouseDown(p.stretcher, "LeftButton")
+ elseif button == "LeftButton" and not p.locked and not p.isMoving then
+ p.isMoving = true
+
+ self.startX = p:GetLeft()
+ self.startY = p:GetTop()
+ p:StartMoving()
+ callbacks:Fire("WindowMoveStart", p, self.startX, self.startY)
+ end
+ end
+
+ local function anchorOnMouseUp(self, button)
+ local p = self:GetParent()
+ if (button == "LeftButton" and p.locked) or button == "MiddleButton" then
+ stretchOnMouseUp(p.stretcher, "LeftButton")
+ elseif button == "LeftButton" and not p.locked and p.isMoving then
+ p.isMoving = nil
+ p:StopMovingOrSizing()
+
+ local endX = p:GetLeft()
+ local endY = p:GetTop()
+ if self.startX ~= endX or self.startY ~= endY then
+ callbacks:Fire("WindowMoveStop", p, endX, endY)
+ end
+ end
+ end
+
+ local function listOnMouseDown(self, button)
+ if self.locked or button ~= "LeftButton" then return end
+ anchorOnMouseDown(self.button, button)
+ end
+
+ local function listOnMouseUp(self, button)
+ if self.locked or button ~= "LeftButton" then return end
+ anchorOnMouseUp(self.button, button)
+ end
+
+ local function listOnSizeChanged(self, width)
+ self:SetLength(width)
+ self:GuessMaxBars()
+ self:SortBars()
+ callbacks:Fire("WindowResizing", self)
+ end
+
+ local function listOnMouseWheel(self, direction)
+ local maxbars = self:GetMaxBars()
+ local numbars = self:GetNumBars()
+ local offset = self:GetBarOffset()
+
+ if direction == 1 and offset > 0 then
+ self:SetBarOffset(IsShiftKeyDown() and 0 or max(0, offset - (IsControlKeyDown() and maxbars or scrollspeed)))
+ callbacks:Fire("WindowScroll", self, direction)
+ elseif direction == -1 and ((numbars - maxbars - offset) > 0) then
+ if IsShiftKeyDown() then
+ self:SetBarOffset(numbars - maxbars)
+ else
+ self:SetBarOffset(min(max(0, numbars - maxbars), offset + (IsControlKeyDown() and maxbars or scrollspeed)))
+ end
+ callbacks:Fire("WindowScroll", self, direction)
+ end
+ end
+
+ local DEFAULT_TEXTURE = [[Interface\TARGETINGFRAME\UI-StatusBar]]
+ local DEFAULT_BACKDROP = {
+ bgFile = [[Interface\Tooltips\UI-Tooltip-Background]],
+ edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]],
+ inset = 4,
+ edgeSize = 8,
+ tile = true,
+ insets = {left = 2, right = 2, top = 2, bottom = 2}
+ }
+
+ function lib:NewBarGroup(name, orientation, height, length, thickness, frameName)
+ if self == lib then
+ error("You may only call :NewBarGroup as an embedded function")
+ end
+
+ if barLists[self] and barLists[self][name] then
+ error(format("A bar list named %s already exists.", name))
+ end
+
+ barLists[self] = barLists[self] or {}
+
+ orientation = orientation or LEFT_TO_RIGHT
+ orientation = (orientation == "LEFT") and LEFT_TO_RIGHT or orientation
+ orientation = (orientation == "RIGHT") and RIGHT_TO_LEFT or orientation
+
+ frameName = frameName:gsub("%W","")
+ local list = barListPrototype:Bind(createFrame("Frame", frameName, UIParent))
+ list:SetFrameLevel(1)
+ list:SetResizable(true)
+ list:SetMovable(true)
+ list:SetScript("OnMouseDown", listOnMouseDown)
+ list:SetScript("OnMouseUp", listOnMouseUp)
+
+ list.name = name
+ barLists[self][name] = list
+
+ local myfont = lib.defaultFont or _G["SkadaRevTitleFont"]
+ if not myfont then
+ myfont = CreateFont("SkadaRevTitleFont")
+ myfont:CopyFontObject(ChatFontSmall)
+ lib.defaultFont = myfont
+ end
+
+ list.button = list.button or createFrame("Button", "$parentAnchor", list)
+ list.button:SetFrameLevel(list:GetFrameLevel() + 3)
+ list.button:SetText(name)
+ list.button:SetNormalFontObject(myfont)
+ list.button:SetBackdrop(DEFAULT_BACKDROP)
+ list.button:SetBackdropColor(0, 0, 0, 1)
+
+ list.button.text = list.button:GetFontString(nil, "ARTWORK")
+ list.button.text:SetWordWrap(false)
+
+ list.button.icon = list.button.icon or list.button:CreateTexture("$parentIcon", "ARTWORK")
+ list.button.icon:SetTexCoord(0.094, 0.906, 0.094, 0.906)
+ list.button.icon:SetPoint("LEFT", list.button, "LEFT", 5, 0)
+ list.button.icon:SetWidth(14)
+ list.button.icon:SetHeight(14)
+
+ list.length = length or 200
+ list.thickness = thickness or 15
+
+ list.button:SetScript("OnMouseDown", anchorOnMouseDown)
+ list.button:SetScript("OnMouseUp", anchorOnMouseUp)
+ list.button:RegisterForClicks("LeftButtonUp", "RightButtonUp", "MiddleButtonUp", "Button4Up", "Button5Up")
+
+ list.buttons = {}
+
+ list:SetPoint("TOPLEFT", UIParent, "CENTER")
+ list:SetMinResize(150, 60)
+ list:SetMaxResize(500, 500)
+
+ list.showIcon = true
+ list.showLabel = true
+ list.showTimerLabel = true
+
+ list.lastBar = list
+
+ list.texture = DEFAULT_TEXTURE
+ list.spacing = 0
+ list.startpoint = 0
+ list.offset = 0
+ list.numBars = 0
+
+ -- resize to the right
+ if not list.resizeright then
+ list.resizeright = CreateFrame("Button", "$parentRightResizer", list)
+ list.resizeright:SetFrameLevel(list:GetFrameLevel() + 3)
+ list.resizeright:SetWidth(12)
+ list.resizeright:SetHeight(12)
+ list.resizeright:SetAlpha(0)
+ list.resizeright.icon = list.resizeright:CreateTexture("$parentIcon", "OVERLAY")
+ list.resizeright.icon:SetAllPoints(list.resizeright)
+ list.resizeright.icon:SetTexture(ICON_RESIZE)
+ list.resizeright.icon:SetVertexColor(1, 1, 1, 0.65)
+ list.resizeright:Hide()
+ end
+
+ -- resize to the left
+ if not list.resizeleft then
+ list.resizeleft = CreateFrame("Button", "$parentLeftResizer", list)
+ list.resizeleft:SetFrameLevel(list:GetFrameLevel() + 3)
+ list.resizeleft:SetWidth(12)
+ list.resizeleft:SetHeight(12)
+ list.resizeleft:SetAlpha(0)
+ list.resizeleft.icon = list.resizeleft:CreateTexture("$parentIcon", "OVERLAY")
+ list.resizeleft.icon:SetAllPoints(list.resizeleft)
+ list.resizeleft.icon:SetTexture(ICON_RESIZE)
+ list.resizeleft.icon:SetVertexColor(1, 1, 1, 0.65)
+ list.resizeleft:Hide()
+ end
+
+ -- lock button
+ if not list.lockbutton then
+ list.lockbutton = CreateFrame("Button", "$parentLockButton", list)
+ list.lockbutton:SetPoint("BOTTOM", list, "BOTTOM", 0, 2)
+ list.lockbutton:SetFrameLevel(list:GetFrameLevel() + 3)
+ list.lockbutton:SetWidth(12)
+ list.lockbutton:SetHeight(12)
+ list.lockbutton:SetAlpha(0)
+ list.lockbutton.icon = list.lockbutton:CreateTexture("$parentIcon", "OVERLAY")
+ list.lockbutton.icon:SetAllPoints(list.lockbutton)
+ list.lockbutton.icon:SetTexture(ICON_LOCK)
+ list.lockbutton.icon:SetVertexColor(0.6, 0.6, 0.6, 0.7)
+ list.lockbutton:Hide()
+ end
+
+ -- stretch button
+ if not list.stretcher then
+ list.stretcher = CreateFrame("Button", "$parentStretcher", list)
+ list.stretcher:SetFrameLevel(list:GetFrameLevel() + 3)
+ list.stretcher:SetWidth(32)
+ list.stretcher:SetHeight(12)
+ list.stretcher:SetAlpha(0)
+ list.stretcher.bg = list.stretcher:CreateTexture("$parentBG", "BACKGROUND")
+ list.stretcher.bg:SetAllPoints(true)
+ list.stretcher.bg:SetTexture([[Interface\Buttons\WHITE8X8]])
+ list.stretcher.bg:SetVertexColor(0, 0, 0, 0.85)
+ list.stretcher.icon = list.stretcher:CreateTexture("$parentIcon", "ARTWORK")
+ list.stretcher.icon:SetWidth(12)
+ list.stretcher.icon:SetHeight(12)
+ list.stretcher.icon:SetPoint("CENTER")
+ list.stretcher.icon:SetTexture(ICON_STRETCH)
+ list.stretcher.icon:SetDesaturated(true)
+ list.stretcher:Hide()
+ end
+
+ list:SetDisableResize(nil)
+ list:SetDisableStretch(nil)
+ list:SetReverseStretch(nil)
+ list:SetAnchorMouseover(false)
+ list:SetScript("OnSizeChanged", listOnSizeChanged)
+
+ list:SetClickthrough(nil)
+ list:EnableMouseWheel(true)
+ list:SetScript("OnMouseWheel", listOnMouseWheel)
+
+ list:SetOrientation(orientation)
+ list:SetReverseGrowth(nil, true)
+ list:SetWidth(length)
+ list:SetHeight(height)
+
+ return list
+ end
+end
+
+-- retrieves a single bar list
+function lib:GetBarGroup(name)
+ return barLists[self] and barLists[self][name]
+end
+
+-- returns the list of all bar lists
+function lib:GetBarGroups()
+ return barLists[self]
+end
+
+-- individual bars functions
+
+-- lib:CreateBar - creates a new bar
+function lib:CreateBar(name, ...)
+ if self == lib then
+ error("You may only call :NewBar as an embedded function")
+ end
+
+ bars[self] = bars[self] or {}
+ local bar = bars[self][name]
+ local isNew = nil
+ if not bar then
+ self.numBars = self.numBars + 1
+ bar = tremove(recycledBars)
+ if not bar then
+ bar = barPrototype:Bind(createFrame("Frame"))
+ else
+ bar:Show()
+ end
+ isNew = true
+ end
+ bar.name = name
+ lib.Create(bar, ...)
+ bar:SetFont(self.font, self.fontSize, self.fontFlags, self.numfont, self.numfontSize, self.numfontFlags)
+
+ bars[self][name] = bar
+
+ return bar, isNew
+end
+
+-- retrieves a single bar by name
+function lib:GetBar(name)
+ return bars[self] and bars[self][name]
+end
+
+-- retrieves all bars for the given list
+function lib:GetBars(name)
+ return bars[self] or dummyTable
+end
+
+barListPrototype.GetBar = lib.GetBar
+barListPrototype.GetBars = lib.GetBars
+
+-- releases a bar
+function lib:ReleaseBar(name)
+ if not bars[self] then return end
+
+ local bar
+ if type(name) == "string" then
+ bar = bars[self][name]
+ elseif type(name) == "table" then
+ if name.name and bars[self][name.name] == name then
+ bar = name
+ end
+ end
+
+ if not bar then return end
+ bar:OnBarReleased()
+ bars[self][bar.name] = nil
+ recycledBars[#recycledBars + 1] = bar
+ self.numBars = self.numBars - 1
+ callbacks:Fire("BarReleased", bar, bar.name, self.numBars)
+end
+
+-- changes lists scroll speed
+function lib:SetScrollSpeed(speed)
+ scrollspeed = min(10, max(1, speed or 0))
+end
+
+local function SavePosition(self)
+ wipe(posix) -- always wipe
+ posix.width = self:GetWidth()
+ posix.height = self:GetHeight()
+
+ local xOfs, yOfs = self:GetCenter()
+ if not xOfs then return end
+
+ local scale = self:GetEffectiveScale()
+ local uiScale = UIParent:GetScale()
+
+ xOfs = (xOfs * scale) - (GetScreenWidth() * uiScale) / 2
+ yOfs = (yOfs * scale) - (GetScreenHeight() * uiScale) / 2
+ posix.xOfs = xOfs / uiScale
+ posix.yOfs = yOfs / uiScale
+end
+
+local function RestorePosition(self)
+ if self == lib then return end
+
+ if posix.xOfs and posix.yOfs then
+ local scale = self:GetEffectiveScale()
+ local uiScale = UIParent:GetScale()
+
+ self:ClearAllPoints()
+ self:SetPoint("CENTER", UIParent, "CENTER", posix.xOfs * uiScale / scale, posix.yOfs * uiScale / scale)
+ end
+
+ if posix.width then
+ self:SetWidth(posix.width)
+ end
+
+ if posix.height then
+ self:SetHeight(posix.height)
+ end
+
+ wipe(posix) -- always wipe
+end
+
+barListPrototype.SavePosition = SavePosition
+barListPrototype.RestorePosition = RestorePosition
+
+-- returns bar(s) height
+function barListPrototype:GetThickness()
+ return self.thickness
+end
+barPrototype.GetThickness = barListPrototype.GetThickness
+
+-- returns bar's length/group width
+function barListPrototype:GetLength()
+ return self.length
+end
+barPrototype.GetLength = barListPrototype.GetLength
+
+-- changes size
+function barListPrototype:SetSize(width, height)
+ self:SetWidth(width)
+ self:SetHeight(height)
+end
+barPrototype.SetSize = barListPrototype.SetSize
+
+-- handles bar/group show/hide
+function barListPrototype:SetShown(show)
+ if show and not self:IsShown() then
+ self:Show()
+ elseif not show and self:IsShown() then
+ self:Hide()
+ end
+end
+barPrototype.SetShown = barListPrototype.SetShown
+
+-------------------------------------------------------------------------------
+-- bar lists/groups functions
+-------------------------------------------------------------------------------
+
+-- locks the bar group
+function barListPrototype:Lock(fireevent)
+ self.locked = true
+ self.lockbutton.icon:SetTexture(ICON_UNLOCK)
+
+ if not self.noresize then
+ self.resizeright:Hide()
+ self.resizeleft:Hide()
+ end
+
+ if fireevent then
+ callbacks:Fire("WindowLocked", self, self.locked)
+ end
+end
+
+-- unlocks the bar group
+function barListPrototype:Unlock(fireevent)
+ self.locked = nil
+ self.lockbutton.icon:SetTexture(ICON_LOCK)
+
+ if not self.noresize then
+ self.resizeright:Show()
+ self.resizeleft:Show()
+ end
+
+ if fireevent then
+ callbacks:Fire("WindowLocked", self, self.locked)
+ end
+end
+
+-- toggle lock state
+function barListPrototype:SetLocked(lock, fireevent)
+ if lock then
+ self:Lock(fireevent)
+ else
+ self:Unlock(fireevent)
+ end
+end
+
+-- changes bars height
+function barListPrototype:SetThickness(thickness)
+ if not thickness or self.thickness == thickness then return end
+
+ self.thickness = thickness
+ if bars[self] then
+ for _, bar in pairs(bars[self]) do
+ bar:SetThickness(self.thickness)
+ end
+ end
+ self:UpdateOrientationLayout()
+end
+barListPrototype.SetBarHeight = barListPrototype.SetThickness
+
+-- changes spacing between bars
+function barListPrototype:SetSpacing(spacing)
+ if not spacing or self.spacing == spacing then return end
+
+ self.spacing = spacing
+ self:SortBars()
+end
+
+-- returns the spacing between bars
+function barListPrototype:GetSpacing()
+ return self.spacing
+end
+
+-- changes bars orientation
+function barListPrototype:SetOrientation(o)
+ if not o or self.orientation == 0 then return end
+
+ if o ~= LEFT_TO_RIGHT and o ~= RIGHT_TO_LEFT then
+ error(format("orientation must be %s or %s.", LEFT_TO_RIGHT, RIGHT_TO_LEFT))
+ end
+
+ self.orientation = o
+ if bars[self] then
+ for _, bar in pairs(bars[self]) do
+ bar:SetOrientation(self.orientation)
+ end
+ end
+ self:UpdateOrientationLayout()
+end
+
+-- returns bars orientation
+function barListPrototype:GetOrientation()
+ return self.ownerGroup and self.ownerGroup.orientation or self.orientation
+end
+barPrototype.GetOrientation = barListPrototype.GetOrientation
+
+-- updates orientation layout
+function barListPrototype:UpdateOrientationLayout()
+ barListPrototype.super.SetWidth(self, self.length)
+ self.button:SetWidth(self.length)
+ self:SetReverseGrowth(self.growup, true)
+end
+
+-- barListPrototype:SetSmoothing - bars animation
+function barListPrototype:SetSmoothing(smoothing)
+ self.smoothing = smoothing or nil
+end
+
+-- changes group grow direction
+function barListPrototype:SetReverseGrowth(reverse, update)
+ if (self.growup == reverse) and update then return end -- only update if necessary
+
+ self.growup = reverse or nil
+
+ self.button:ClearAllPoints()
+ self.resizeright:ClearAllPoints()
+ self.resizeleft:ClearAllPoints()
+ self.lockbutton:ClearAllPoints()
+
+ if self.growup then
+ self.button:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT")
+ self.button:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
+ self.resizeright.icon:SetTexCoord(0, 1, 1, 0)
+ self.resizeright:SetPoint("TOPRIGHT", self, "TOPRIGHT")
+ self.resizeleft.icon:SetTexCoord(1, 0, 1, 0)
+ self.resizeleft:SetPoint("TOPLEFT", self, "TOPLEFT")
+ self.lockbutton:SetPoint("TOP", self, "TOP", 0, -2)
+ self:SortBars()
+
+ return
+ end
+
+ self.button:SetPoint("TOPLEFT", self, "TOPLEFT")
+ self.button:SetPoint("TOPRIGHT", self, "TOPRIGHT")
+ self.resizeright.icon:SetTexCoord(0, 1, 0, 1)
+ self.resizeright:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
+ self.resizeleft.icon:SetTexCoord(1, 0, 0, 1)
+ self.resizeleft:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT")
+ self.lockbutton:SetPoint("BOTTOM", self, "BOTTOM", 0, 2)
+ self:SortBars()
+end
+
+-- returns true if the group is reversed
+function barListPrototype:GetReverseGrowth()
+ return self.growup
+end
+
+-- makes bars (un)clickable
+function barListPrototype:SetClickthrough(clickthrough)
+ if self.clickthrough == clickthrough then return end
+
+ self.clickthrough = clickthrough or nil
+ if not bars[self] then return end
+
+ for _, bar in pairs(bars[self]) do
+ bar:EnableMouse(not self.clickthrough)
+ end
+end
+
+-- barListPrototype:AddButton - adds buttons to anchor
+do
+ local function buttonOnEnter(self)
+ GameTooltip_SetDefaultAnchor(GameTooltip, self)
+ GameTooltip:SetText(self.title)
+ GameTooltip:AddLine(self.description, 1, 1, 1, true)
+ GameTooltip:Show()
+ anchorOnEnter(self:GetParent())
+ end
+
+ local function buttonOnLeave(self)
+ GameTooltip:Hide()
+ anchorOnLeave(self:GetParent())
+ end
+
+ function barListPrototype:AddButton(index, title, description, normaltex, highlighttex, clickfunc)
+ if index and not title then
+ title = index
+ elseif title and not index then
+ index = title
+ end
+
+ -- Create button frame.
+ local btn = CreateFrame("Button", format("$parent%s", (index:gsub("^%l", string.upper)):gsub("%s+", "")), self.button)
+ btn:SetFrameLevel(self.button:GetFrameLevel() + 1)
+ btn:SetWidth(14)
+ btn:SetHeight(14)
+
+ btn:SetNormalTexture(normaltex)
+ btn:SetHighlightTexture(highlighttex or normaltex, "ADD")
+ btn.normalTex = btn:GetNormalTexture()
+ btn.highlightTex = btn:GetHighlightTexture()
+
+ btn:RegisterForClicks("AnyUp")
+ btn:SetScript("OnClick", clickfunc)
+
+ btn.list = self
+ btn.index = index
+ btn.title = title
+ btn.description = description
+
+ btn:SetScript("OnEnter", buttonOnEnter)
+ btn:SetScript("OnLeave", buttonOnLeave)
+
+ btn:Hide()
+ self.buttons[#self.buttons + 1] = btn
+ self:AdjustButtons()
+
+ return btn
+ end
+end
+
+-- handles anchor buttons show/hide
+function barListPrototype:ShowButton(title, visible)
+ for i = 1, #self.buttons do
+ local b = self.buttons[i]
+ if b and b.title == title then
+ b.visible = visible or nil
+ break
+ end
+ end
+ self:AdjustButtons()
+end
+
+-- shows anchor
+function barListPrototype:ShowAnchor()
+ self.button:Show()
+ self:GuessMaxBars()
+ self:SortBars()
+end
+
+-- hides anchor
+function barListPrototype:HideAnchor()
+ self.button:Hide()
+ self:GuessMaxBars()
+ self:SortBars()
+end
+
+-- shows anchor icon
+function barListPrototype:ShowAnchorIcon(icon)
+ if not self.showAnchorIcon then
+ self.showAnchorIcon = true
+ self.button.icon:Show()
+ self:AdjustTitle()
+ end
+ if icon then
+ self.button.icon:SetTexture(icon)
+ end
+end
+
+-- hides anchor icon
+function barListPrototype:HideAnchorIcon()
+ if not self.showAnchorIcon then return end
+
+ self.showAnchorIcon = nil
+ self.button.icon:SetTexture(nil)
+ self.button.icon:Hide()
+ self:AdjustTitle()
+end
+
+-- adds an offset to bars starting point.
+function barListPrototype:SetDisplacement(startpoint)
+ if not startpoint or self.startpoint == startpoint then return end
+
+ self.startpoint = startpoint
+ self:GuessMaxBars()
+ self:SortBars()
+end
+
+-- barListPrototype:SetAnchorMouseover - handles anchor mouseover
+do
+ function anchorOnEnter(self)
+ local p = self:GetParent()
+ listOnEnter(p)
+
+ if not p.mouseover then return end
+
+ p:AdjustTitle(true)
+ for i = 1, #p.buttons do
+ local b = p.buttons[i]
+ if b and b.visible then
+ b:Show()
+ end
+ end
+ end
+
+ function anchorOnLeave(self)
+ local p = self:GetParent()
+ listOnLeave(p)
+
+ if not p.mouseover then return end
+
+ p:AdjustTitle()
+ for i = 1, #p.buttons do
+ local b = p.buttons[i]
+ if b and b.visible then
+ b:Hide()
+ end
+ end
+ end
+
+ function barListPrototype:SetAnchorMouseover(mouseover)
+ self.mouseover = mouseover or nil
+ self.button:SetScript("OnEnter", anchorOnEnter)
+ self.button:SetScript("OnLeave", anchorOnLeave)
+ self:AdjustButtons()
+ end
+end
+
+-- adjusts anchor text
+function barListPrototype:AdjustTitle(nomouseover)
+ self.button.text:SetJustifyH(self.orientation == RIGHT_TO_LEFT and "RIGHT" or "LEFT")
+ self.button.text:SetJustifyV("MIDDLE")
+
+ self.button.icon:ClearAllPoints()
+ self.button.text:ClearAllPoints()
+
+ if self.lastbtn and self.orientation == RIGHT_TO_LEFT then
+ if self.mouseover and not nomouseover then
+ self.button.text:SetPoint("LEFT", self.button, "LEFT", 5, 1)
+ else
+ self.button.text:SetPoint("LEFT", self.lastbtn, "RIGHT")
+ end
+ self.button.icon:SetPoint("RIGHT", self.button, "RIGHT", -5, -1)
+ self.button.text:SetPoint("RIGHT", self.button, "RIGHT", self.showAnchorIcon and -23 or -5, 0)
+ elseif self.lastbtn then
+ self.button.icon:SetPoint("LEFT", self.button, "LEFT", 5, -1)
+ self.button.text:SetPoint("LEFT", self.button, "LEFT", self.showAnchorIcon and 23 or 5, 0)
+ if self.mouseover and not nomouseover then
+ self.button.text:SetPoint("RIGHT", self.button, "RIGHT", -5, 1)
+ else
+ self.button.text:SetPoint("RIGHT", self.lastbtn, "LEFT")
+ end
+ else
+ self.button.icon:SetPoint("LEFT", self.button, "LEFT", 5, -1)
+ self.button.text:SetPoint("LEFT", self.button, "LEFT", self.showAnchorIcon and 23 or 5, 0)
+ self.button.text:SetPoint("RIGHT", self.button, "RIGHT", -5, 0)
+ end
+end
+
+-- adjusts anchor buttons
+function barListPrototype:AdjustButtons()
+ self.lastbtn = nil
+ local height = self.button:GetHeight()
+ local spacing = self.btnspacing or 1
+ local nr = 0
+
+ for i = 1, #self.buttons do
+ local btn = self.buttons[i]
+ if btn then
+ btn:ClearAllPoints()
+
+ if btn.visible then
+ if nr == 0 and self.orientation == RIGHT_TO_LEFT then
+ btn:SetPoint("TOPLEFT", self.button, "TOPLEFT", 5, -(max(height - btn:GetHeight(), 0) / 2))
+ elseif nr == 0 then
+ btn:SetPoint("TOPRIGHT", self.button, "TOPRIGHT", -5, -(max(height - btn:GetHeight(), 0) / 2))
+ elseif self.orientation == RIGHT_TO_LEFT then
+ btn:SetPoint("TOPLEFT", self.lastbtn, "TOPRIGHT", spacing, 0)
+ else
+ btn:SetPoint("TOPRIGHT", self.lastbtn, "TOPLEFT", -spacing, 0)
+ end
+ self.lastbtn = btn
+ nr = nr + 1
+
+ if self.mouseover then
+ btn:Hide()
+ else
+ btn:Show()
+ end
+ else
+ btn:Hide()
+ end
+ end
+ end
+
+ self:AdjustTitle()
+end
+
+-- changes spacing between anchor buttons
+function barListPrototype:SetButtonsSpacing(spacing)
+ if self.btnspacing == spacing then return end
+ self.btnspacing = spacing or 1
+ self:AdjustButtons()
+end
+
+-- changes anchor buttons opacity
+function barListPrototype:SetButtonsOpacity(opacity)
+ if not opacity or self.buttonsOpacity == opacity then return end
+
+ self.buttonsOpacity = opacity
+ for i = 1, #self.buttons do
+ local btn = self.buttons[i]
+ if btn then
+ btn:SetAlpha(opacity)
+ end
+ end
+end
+
+-- creates a new bar from prototype
+function barListPrototype:CreateBar(...)
+ local bar, isNew = lib.CreateBar(self, ...)
+ bar:SetTexture(self.texture)
+
+ if self.showIcon then
+ bar:ShowIcon()
+ else
+ bar:HideIcon(bar)
+ end
+ if self.showLabel then
+ bar:ShowLabel()
+ else
+ bar:HideLabel(bar)
+ end
+ if self.showTimerLabel then
+ bar:ShowTimerLabel()
+ else
+ bar:HideTimerLabel(bar)
+ end
+ self:SortBars()
+ bar.ownerGroup = self
+ bar:SetParent(self)
+
+ bar:EnableMouse(not self.clickthrough)
+ return bar, isNew
+end
+
+-- creates a new bar
+function barListPrototype:NewBar(name, text, value, maxVal, icon)
+ local bar, isNew = self:CreateBar(name, text, value, maxVal, icon, self.orientation, self.length, self.thickness)
+
+ if self.bgcolor then
+ bar.bg:SetVertexColor(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3], self.bgcolor[4])
+ else
+ bar.bg:SetVertexColor(0.3, 0.3, 0.3, 0.6)
+ end
+
+ return bar, isNew
+end
+
+-- removes the given bar
+function barListPrototype:RemoveBar(bar)
+ lib.ReleaseBar(self, bar)
+end
+
+function barListPrototype:SetDisableHighlight(disable)
+ self.barhighlight = (disable ~= true) and true or nil
+end
+
+-- changes bars background color
+function barListPrototype:SetBarBackgroundColor(r, g, b, a)
+ if not self.bgcolor or self.bgcolor[1] ~= r or self.bgcolor[2] ~= g or self.bgcolor[3] ~= b or self.bgcolor[4] ~= a then
+ self.bgcolor = self.bgcolor or new()
+ self.bgcolor[1] = r
+ self.bgcolor[2] = g
+ self.bgcolor[3] = b
+ self.bgcolor[4] = a or 1
+
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar.bg:SetVertexColor(self.bgcolor[1], self.bgcolor[2], self.bgcolor[3], self.bgcolor[4])
+ end
+ end
+end
+
+-- barListPrototype:SetDisableResize - disable group resize
+do
+ function listOnEnter(self)
+ if self.lockbutton then
+ self.lockbutton:SetAlpha(1)
+ end
+ if self.stretcher then
+ self.stretcher:SetAlpha(1)
+ end
+ if self.resizeright then
+ self.resizeright:SetAlpha(1)
+ self.resizeleft:SetAlpha(1)
+ end
+ end
+
+ function listOnLeave(self)
+ GameTooltip:Hide()
+ if self.lockbutton then
+ self.lockbutton:SetAlpha(0)
+ end
+ if self.stretcher then
+ self.stretcher:SetAlpha(0)
+ end
+ if self.resizeright then
+ self.resizeright:SetAlpha(0)
+ self.resizeleft:SetAlpha(0)
+ end
+ end
+
+ local strfind = strfind or string.find
+ local function sizerOnMouseDown(self, button)
+ local p = self:GetParent()
+ if p.isResizing or button ~= "LeftButton" then return end
+
+ p.isResizing = true
+ self.direction = self.direction or strfind(self:GetName(), "Left") and "LEFT" or "RIGHT"
+
+ if IsShiftKeyDown() then
+ p:StartSizing(self.direction)
+ elseif IsAltKeyDown() then
+ p:StartSizing(p.growup and "TOP" or "BOTTOM")
+ else
+ p:StartSizing(format("%s%s", (p.growup and "TOP" or "BOTTOM"), self.direction))
+ end
+ end
+
+ local function sizerOnMouseUp(self, button)
+ local p = self:GetParent()
+ if button ~= "LeftButton" or not p.isResizing then return end
+
+ p.isResizing = nil
+ local top, left = p:GetTop(), p:GetLeft()
+ p:StopMovingOrSizing()
+ p:SetLength(p:GetLength())
+ p:GuessMaxBars()
+ p:SortBars()
+ callbacks:Fire("WindowResized", p)
+ end
+
+ local function sizerOnEnter(self)
+ GameTooltip:SetOwner(self, "ANCHOR_NONE")
+ GameTooltip:SetPoint("BOTTOM", self, "TOP")
+ GameTooltip:ClearLines()
+ GameTooltip:AddLine(L_RESIZE_HEADER)
+ GameTooltip:AddLine(L_RESIZE_CLICK, 1, 1, 1)
+ GameTooltip:AddLine(L_RESIZE_SHIFT_CLICK, 1, 1, 1)
+ GameTooltip:AddLine(L_RESIZE_ALT_CLICK, 1, 1, 1)
+ GameTooltip:Show()
+ listOnEnter(self:GetParent())
+ self.icon:SetVertexColor(1, 1, 1, 1)
+ end
+
+ local function sizerOnLeave(self)
+ listOnLeave(self:GetParent())
+ self.icon:SetVertexColor(1, 1, 1, 0.65)
+ end
+
+ local function lockOnEnter(self)
+ local p = self:GetParent()
+ GameTooltip:SetOwner(self, "ANCHOR_NONE")
+ GameTooltip:SetPoint("BOTTOM", self, "TOP")
+ GameTooltip:ClearLines()
+ GameTooltip:AddLine(p.name)
+ GameTooltip:AddLine(p.locked and L_UNLOCK_WINDOW or L_LOCK_WINDOW, 1, 1, 1)
+ GameTooltip:Show()
+ listOnEnter(self:GetParent())
+ self.icon:SetVertexColor(1, 1, 1, 0.7)
+ end
+
+ local function lockOnLeave(self)
+ listOnLeave(self:GetParent())
+ self.icon:SetVertexColor(0.6, 0.6, 0.6, 0.7)
+ end
+
+ local function lockOnClick(self)
+ local p = self:GetParent()
+ if p.locked then
+ p:Unlock(true)
+ else
+ p:Lock(true)
+ end
+ lockOnEnter(self)
+ end
+
+ function barListPrototype:SetDisableResize(disable)
+ self.noresize = disable or nil
+
+ if self.noresize then
+ -- window
+ self:SetScript("OnEnter", nil)
+ self:SetScript("OnLeave", nil)
+
+ -- lock button
+ self.lockbutton:SetScript("OnClick", nil)
+ self.lockbutton:SetScript("OnEnter", nil)
+ self.lockbutton:SetScript("OnLeave", nil)
+ self.lockbutton:Hide()
+
+ -- left resizer
+ self.resizeleft:SetScript("OnMouseDown", nil)
+ self.resizeleft:SetScript("OnMouseUp", nil)
+ self.resizeleft:SetScript("OnEnter", nil)
+ self.resizeleft:SetScript("OnLeave", nil)
+ self.resizeleft:Hide()
+
+ -- right resizer
+ self.resizeright:SetScript("OnMouseDown", nil)
+ self.resizeright:SetScript("OnMouseUp", nil)
+ self.resizeright:SetScript("OnEnter", nil)
+ self.resizeright:SetScript("OnLeave", nil)
+ self.resizeright:Hide()
+
+ return
+ end
+
+ -- window
+ self:SetScript("OnEnter", listOnEnter)
+ self:SetScript("OnLeave", listOnLeave)
+
+ -- lock button
+ self.lockbutton:SetScript("OnClick", lockOnClick)
+ self.lockbutton:SetScript("OnEnter", lockOnEnter)
+ self.lockbutton:SetScript("OnLeave", lockOnLeave)
+ self.lockbutton:Show()
+
+ -- left resizer
+ self.resizeleft:SetScript("OnMouseDown", sizerOnMouseDown)
+ self.resizeleft:SetScript("OnMouseUp", sizerOnMouseUp)
+ self.resizeleft:SetScript("OnEnter", sizerOnEnter)
+ self.resizeleft:SetScript("OnLeave", sizerOnLeave)
+ self.resizeleft:Show()
+
+ -- right resizer
+ self.resizeright:SetScript("OnMouseDown", sizerOnMouseDown)
+ self.resizeright:SetScript("OnMouseUp", sizerOnMouseUp)
+ self.resizeright:SetScript("OnEnter", sizerOnEnter)
+ self.resizeright:SetScript("OnLeave", sizerOnLeave)
+ self.resizeright:Show()
+ end
+end
+
+-- barListPrototype:SetDisableStretch - disable group stretch
+do
+ local function listOnStretch(self, elapsed)
+ if self.stretch_off then
+ self.stretch_on = nil
+ self.stretch_off = nil
+ callbacks:Fire("WindowStretchStop", self)
+ elseif self.stretch_on then
+ if not self.isStretching then
+ self.isStretching = true
+ self:SavePosition()
+ self:StartSizing(self.stretchdown and "BOTTOM" or "TOP")
+ callbacks:Fire("WindowStretchStart", self)
+ else
+ self:SortBars()
+ callbacks:Fire("WindowStretching", self)
+ end
+ else
+ self.isStretching = nil
+ self:StopMovingOrSizing()
+ self:RestorePosition()
+ self:RemoveOnUpdate(listOnStretch)
+ end
+ end
+
+ function stretchOnMouseDown(self, button)
+ local p = self:GetParent()
+ if not p or button ~= "LeftButton" then return end
+ p.stretch_on = true
+ p:AddOnUpdate(listOnStretch)
+ end
+
+ function stretchOnMouseUp(self, button)
+ local p = self:GetParent()
+ if p and p.stretch_on and button == "LeftButton" then
+ p.stretch_off = true
+ end
+ end
+
+ local function stretchOnEnter(self)
+ self.icon:SetDesaturated(false)
+ listOnEnter(self:GetParent())
+ end
+
+ local function stretchOnLeave(self)
+ self.icon:SetDesaturated(true)
+ listOnLeave(self:GetParent())
+ end
+
+ function barListPrototype:SetDisableStretch(disable)
+ self.nostrech = disable or nil
+
+ if self.nostrech then
+ self.stretcher:SetScript("OnMouseDown", nil)
+ self.stretcher:SetScript("OnMouseUp", nil)
+ self.stretcher:SetScript("OnEnter", nil)
+ self.stretcher:SetScript("OnLeave", nil)
+ self.stretcher:Hide()
+ return
+ end
+
+ self.stretcher:SetScript("OnMouseDown", stretchOnMouseDown)
+ self.stretcher:SetScript("OnMouseUp", stretchOnMouseUp)
+ self.stretcher:SetScript("OnEnter", stretchOnEnter)
+ self.stretcher:SetScript("OnLeave", stretchOnLeave)
+ self.stretcher:Show()
+ end
+end
+
+-- reverse group's stretch direction
+function barListPrototype:SetReverseStretch(stretchdown)
+ self.stretchdown = stretchdown or nil
+ if not self.stretcher:IsShown() then return end
+
+ self.stretcher:ClearAllPoints()
+ if self.stretchdown then
+ self.stretcher:SetPoint("TOP", self, "BOTTOM")
+ self.stretcher.icon:SetTexCoord(0.219, 0.781, 0.781, 0)
+ else
+ self.stretcher:SetPoint("BOTTOMRIGHT", self, "TOPRIGHT")
+ self.stretcher.icon:SetTexCoord(0.219, 0.781, 0, 0.781)
+ end
+end
+
+-- changes bars offset
+function barListPrototype:SetBarOffset(offset)
+ if self.offset == offset then return end
+ self.offset = offset
+ self:SortBars()
+end
+
+-- returns bars offset
+function barListPrototype:GetBarOffset()
+ return self.offset
+end
+
+-- changes group width
+function barListPrototype:SetLength(length)
+ self.length = length
+ if bars[self] then
+ for _, bar in pairs(bars[self]) do
+ bar:SetLength(length)
+ end
+ end
+ self:UpdateOrientationLayout()
+end
+barListPrototype.SetBarWidth = barListPrototype.SetLength
+
+-- changes group height
+function barListPrototype:SetHeight(height)
+ self.super.SetHeight(self, height)
+ self:GuessMaxBars()
+end
+
+-- sets bars sort function
+function barListPrototype:SetSortFunction(func)
+ if self.sortFunc ~= func then
+ if func and type(func) ~= "function" then
+ error(":SetSortFunction requires a valid function.")
+ end
+
+ self.sortFunc = func
+ end
+end
+
+-- returns bars sort function
+function barListPrototype:GetSortFunction(func)
+ return self.sortFunc
+end
+
+-- sets max bars
+function barListPrototype:SetMaxBars(num)
+ if not num or self.maxBars == num then return end
+ self.maxBars = floor(num)
+ self:SortBars()
+end
+
+-- returns max bars
+function barListPrototype:GetMaxBars()
+ return self.maxBars
+end
+
+-- guesses max bars to display depending on the group's height
+function barListPrototype:GuessMaxBars()
+ local maxbars = self:GetHeight() / (self.thickness + self.spacing)
+
+ if self.button:IsVisible() then
+ local height = self:GetHeight() + self.spacing
+ local height2 = self.button:GetHeight() + self.startpoint
+ maxbars = ((maxbars - 1) * ((height - height2) / height)) + 1
+ end
+
+ self.maxBars = floor(maxbars)
+end
+
+-- returns the number of bars
+function barListPrototype:GetNumBars()
+ return self.numBars or 0
+end
+
+-- changes bars texture
+function barListPrototype:SetTexture(tex)
+ if self.texture == tex then return end
+ self.texture = tex
+
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar.fg:SetTexture(self.texture)
+ bar.bg:SetTexture(self.texture)
+ end
+end
+barPrototype.SetTexture = barListPrototype.SetTexture
+
+-- changes labels and timerLabels fonts
+function barListPrototype:SetFont(font, size, outline, numFont, numSize, numOutline)
+ local changed = false
+
+ -- label
+ if font and self.font ~= font then
+ self.font = font
+ changed = true
+ end
+ if size and self.fontSize ~= size then
+ self.fontSize = size
+ changed = true
+ end
+ if outline and self.fontFlags ~= outline then
+ self.fontFlags = outline
+ changed = true
+ end
+
+ -- timer
+ if numFont and self.numfont ~= numFont then
+ self.numfont = numFont
+ changed = true
+ end
+ if numSize and self.numfontSize ~= numSize then
+ self.numfontSize = numSize
+ changed = true
+ end
+ if numOutline and self.numfontFlags ~= numOutline then
+ self.numfontFlags = numOutline
+ changed = true
+ end
+
+ if changed and bars[self] then
+ for _, bar in pairs(bars[self]) do
+ bar:SetFont(font, size, outline, numFont, numSize, numOutline)
+ end
+ end
+end
+
+-- show bar icons
+function barListPrototype:ShowBarIcons()
+ self.showIcon = true
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar:ShowIcon()
+ end
+end
+
+-- hide bar icons
+function barListPrototype:HideBarIcons()
+ self.showIcon = nil
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar:HideIcon()
+ end
+end
+
+-- returns true if bar icons are shown
+function barListPrototype:IsIconShown()
+ return self.showIcon
+end
+barPrototype.IsIconShown = barListPrototype.IsIconShown
+
+-- shows bar labels
+function barListPrototype:ShowLabel()
+ self.showLabel = true
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar:ShowLabel()
+ end
+end
+
+-- hides bar labesl
+function barListPrototype:HideLabel()
+ self.showLabel = nil
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar:HideLabel()
+ end
+end
+
+-- shows bars timer labels
+function barListPrototype:ShowTimerLabel()
+ self.showTimerLabel = true
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar:ShowTimerLabel()
+ end
+end
+
+-- hides bars timer labels
+function barListPrototype:HideTimerLabel()
+ self.showTimerLabel = nil
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar:HideTimerLabel()
+ end
+end
+
+-- changes bars text color
+function barListPrototype:SetTextColor(r, g, b, a)
+ if not self.textcolor or self.textcolor[1] ~= r or self.textcolor[2] ~= g or self.textcolor[3] ~= b or self.textcolor[4] ~= a then
+ self.textcolor = self.textcolor or new()
+ self.textcolor[1] = r or 1
+ self.textcolor[2] = g or 1
+ self.textcolor[3] = b or 1
+ self.textcolor[4] = a or 1
+
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ bar.label:SetTextColor(self.textcolor[1], self.textcolor[2], self.textcolor[3], self.textcolor[4])
+ bar.timerLabel:SetTextColor(self.textcolor[1], self.textcolor[2], self.textcolor[3], self.textcolor[4])
+ end
+ end
+end
+
+-- changes bar default color
+function barListPrototype:SetColor(r, g, b, a)
+ if not self.colors or self.colors[1] ~= r or self.colors[2] ~= g or self.colors[3] ~= b or self.colors[4] ~= a then
+ self.colors = self.colors or new()
+ local alpha = (a and self.colors[4] ~= a)
+
+ self.colors[1] = r
+ self.colors[2] = g
+ self.colors[3] = b
+ self.colors[4] = a
+
+ if not bars[self] then return end
+ for _, bar in pairs(bars[self]) do
+ if bar.lockColor and alpha then
+ bar:SetColor(nil, nil, nil, a, bar.lockColor)
+ elseif bar.lockColor then
+ bar:UpdateColor()
+ else
+ bar:SetColor(r, g, b, a, bar.lockColor)
+ end
+ end
+ end
+end
+
+-- enables or disabled spark icon
+function barListPrototype:SetUseSpark(usespark)
+ if self.usespark == usespark then return end
+
+ self.usespark = usespark or nil
+ if not bars[self] then return end
+
+ for _, bar in pairs(bars[self]) do
+ if self.usespark and not bar.spark:IsShown() then
+ bar.spark:Show()
+ elseif not self.usespark and bar.spark:IsShown() then
+ bar.spark:Hide()
+ end
+ end
+end
+
+-- barListPrototype:SortBars - sorts bars
+do
+ local values = {}
+
+ local tostring = tostring
+ local function sortFunc(a, b)
+ local apct, bpct = a.value / a.maxValue, b.value / b.maxValue
+ if apct == bpct then
+ if a.maxValue == b.maxValue then
+ return tostring(a.name) > tostring(b.name)
+ else
+ return a.maxValue > b.maxValue
+ end
+ else
+ return apct > bpct
+ end
+ end
+
+ function barListPrototype:SortBars()
+ local lastBar = self
+ local ct = 0
+ local has_fixed = nil
+
+ if not bars[self] then return end
+
+ for _, bar in pairs(bars[self]) do
+ ct = ct + 1
+ values[ct] = bar
+ bar:Hide()
+ has_fixed = has_fixed or bar.fixed
+ end
+
+ for i = ct + 1, #values do
+ values[i] = nil
+ end
+ if #values == 0 then
+ return
+ end
+
+ tsort(values, self.sortFunc or sortFunc)
+
+ local orientation = self.orientation
+ local growup = self.growup
+ local spacing = self.spacing
+ local startpoint = self.button:IsVisible() and (self.button:GetHeight() + self.startpoint) or 0
+
+ local from, to
+ local offset = self.offset
+ local y1, y2 = startpoint, startpoint
+ local maxbars = min(#values, self.maxBars)
+
+ local start, stop, step, fixnum
+ if growup then
+ from = "BOTTOM"
+ to = "TOP"
+ start = min(#values, maxbars + offset)
+ stop = min(#values, 1 + offset)
+ step = -1
+ fixnum = start
+ else
+ from = "TOP"
+ to = "BOTTOM"
+ start = min(1 + offset, #values)
+ stop = min(maxbars + offset, #values)
+ step = 1
+ fixnum = stop
+ end
+
+ -- Fixed bar replaces the last bar
+ if has_fixed and fixnum < #values then
+ for i = fixnum + 1, #values, 1 do
+ if values[i].fixed then
+ tinsert(values, fixnum, values[i])
+ break
+ end
+ end
+ end
+
+ local showIcon = self.showIcon
+ local thickness = self.thickness
+ local shown = 0
+
+ for i = start, stop, step do
+ local origTo = to
+ local v = values[i]
+ if lastBar == self then
+ to = from
+ if growup then
+ y1, y2 = startpoint, startpoint
+ else
+ y1, y2 = -startpoint, -startpoint
+ end
+ else
+ if growup then
+ y1, y2 = spacing, spacing
+ else
+ y1, y2 = -spacing, -spacing
+ end
+ end
+
+ local x1, x2 = 0, 0 -- TODO: find a better way
+ if showIcon and lastBar == self then
+ if orientation == LEFT_TO_RIGHT then
+ x1 = thickness
+ else
+ x2 = -thickness
+ end
+ end
+
+ if shown <= maxbars and v then
+ v:ClearAllPoints()
+ v:SetPoint(format("%sLEFT", from), lastBar, format("%sLEFT", to), x1, y1)
+ v:SetPoint(format("%sRIGHT", from), lastBar, format("%sRIGHT", to), x2, y2)
+ v:Show()
+
+ shown = shown + 1
+ lastBar = v
+ end
+
+ to = origTo
+ end
+
+ self.lastBar = lastBar
+ end
+end
+
+-- barListPrototype:AddOnUpdate
+do
+ -- handles OnUpdate
+ local function listOnUpdate(self, elapsed)
+ if not self.updateFuncs or next(self.updateFuncs) == nil then
+ self:SetScript("OnUpdate", nil)
+ return
+ end
+ for func in pairs(self.updateFuncs) do
+ func(self, elapsed)
+ end
+ end
+
+ -- adds OnUpdate function
+ function barListPrototype:AddOnUpdate(func)
+ if type(func) ~= "function" then return end
+ self.updateFuncs = self.updateFuncs or new()
+ self.updateFuncs[func] = true
+ self:SetScript("OnUpdate", listOnUpdate)
+ end
+ barPrototype.AddOnUpdate = barListPrototype.AddOnUpdate
+end
+
+-- removes OnUpdate function
+function barListPrototype:RemoveOnUpdate(func)
+ if not self.updateFuncs then return end
+ self.updateFuncs[func] = nil
+ if next(self.updateFuncs) == nil then
+ self.updateFuncs = del(self.updateFuncs)
+ end
+end
+barPrototype.RemoveOnUpdate = barListPrototype.RemoveOnUpdate
+
+-------------------------------------------------------------------------------
+-- bar functions
+-------------------------------------------------------------------------------
+
+-- barPrototype:Create - creates a new bar
+do
+ local function barOnMouseDown(self, button)
+ local p = self:GetParent()
+ if not p then return end
+ callbacks:Fire("BarClick", self, button)
+ end
+
+ local function barOnEnter(self, motion)
+ local p = self:GetParent()
+ listOnEnter(p)
+ if p.barhighlight then
+ self.hg:SetVertexColor(1, 1, 1, 0.1)
+ end
+ callbacks:Fire("BarEnter", self, motion)
+ end
+
+ local function barOnLeave(self, motion)
+ local p = self:GetParent()
+ listOnLeave(p)
+ if p.barhighlight then
+ self.hg:SetVertexColor(0, 0, 0, 0)
+ end
+ callbacks:Fire("BarLeave", self, motion)
+ end
+
+ local DEFAULT_ICON = [[Interface\ICONS\INV_Misc_QuestionMark]]
+ function lib.Create(self, text, value, maxVal, icon, orientation, length, thickness)
+ self:SetScript("OnMouseDown", barOnMouseDown)
+ self:SetScript("OnEnter", barOnEnter)
+ self:SetScript("OnLeave", barOnLeave)
+ self:SetScript("OnSizeChanged", self.OnSizeChanged)
+
+ self.bg = self.bg or self:CreateTexture(nil, "BACKGROUND")
+ self.bg:SetAllPoints()
+ self.bg:SetVertexColor(0.3, 0.3, 0.3, 0.6)
+
+ self.fg = self.fg or self:CreateTexture(nil, "BORDER")
+ self.fg:SetAllPoints()
+ self.fg.SetValue = self.fg.SetWidth
+ self.fg:SetValue(0)
+
+ self.hg = self.hg or self:CreateTexture(nil, "ARTWORK")
+ self.hg:SetAllPoints()
+ self.hg:SetTexture([[Interface\Buttons\WHITE8X8]])
+ self.hg:SetVertexColor(0, 0, 0, 0)
+
+ self.spark = self.spark or self:CreateTexture(nil, "OVERLAY")
+ self.spark:SetTexture([[Interface\CastingBar\UI-CastingBar-Spark]])
+ self.spark:SetWidth(10)
+ self.spark:SetHeight(10)
+ self.spark:SetBlendMode("ADD")
+ self.spark:Hide()
+
+ self.iconFrame = self.iconFrame or CreateFrame("Frame", nil, self)
+ self.iconFrame:SetPoint("LEFT", self, "LEFT")
+ self.iconFrame:SetFrameLevel(self:GetFrameLevel() + 1)
+ self.iconFrame.bar = self
+
+ self.icon = self.icon or self.iconFrame:CreateTexture(nil, "OVERLAY")
+ self.icon:SetAllPoints(self.iconFrame)
+ self:SetIcon(icon or DEFAULT_ICON)
+ if icon then
+ self:ShowIcon()
+ end
+ self.icon:SetTexCoord(0.094, 0.906, 0.094, 0.906)
+
+ self.label = self.label or self:CreateFontString(nil, "OVERLAY", "ChatFontNormal")
+ self.label:SetWordWrap(false)
+ self.label:SetText(text)
+ self.label:ClearAllPoints()
+ self.label:SetPoint("LEFT", self, "LEFT", 3, 0)
+ self:ShowLabel()
+
+ self.timerLabel = self.timerLabel or self:CreateFontString(nil, "OVERLAY", "ChatFontNormal")
+ self.timerLabel:ClearAllPoints()
+ self.timerLabel:SetPoint("RIGHT", self, "RIGHT", -3, 0)
+ self:SetTimerLabel("")
+ self:HideTimerLabel()
+
+ local f, s, m = self.label:GetFont()
+ self.label:SetFont(f, s or 10, m)
+
+ f, s, m = self.timerLabel:GetFont()
+ self.timerLabel:SetFont(f, s or 10, m)
+
+ self:SetScale(1)
+ self:SetAlpha(1)
+
+ self.length = length or 200
+ self.thickness = thickness or 15
+ self:SetOrientation(orientation or LEFT_TO_RIGHT)
+
+ self.value = value or 1
+ self.maxValue = maxVal or self.value
+ self:SetMaxValue(self.maxValue)
+ self:SetValue(self.value)
+ end
+end
+
+-- releases a bar that's no longer in use
+function barPrototype:OnBarReleased()
+ self.ownerGroup = nil
+ self.colors = del(self.colors)
+
+ self.fg:SetVertexColor(1, 1, 1, 0)
+ self:SetScript("OnEnter", nil)
+ self:SetScript("OnLeave", nil)
+ self:SetScript("OnUpdate", nil)
+ self:SetParent(UIParent)
+ self:ClearAllPoints()
+ self:Hide()
+
+ local f, s, m = ChatFontNormal:GetFont()
+ self.label:SetFont(f, s or 10, m)
+ self.timerLabel:SetFont(f, s or 10, m)
+end
+
+-- handles size change
+function barPrototype:OnSizeChanged()
+ self:SetValue(self.value)
+end
+
+-- changes label and timer fonts
+function barPrototype:SetFont(font, size, outline, numFont, numSize, numOutline)
+ local f, s, o = self.label:GetFont()
+ outline = outline or o
+ self.label:SetFont(font or f, size or s, outline)
+ self.label:SetShadowColor(0, 0, 0, outline == "" and 0 or 1)
+
+ f, s, o = self.timerLabel:GetFont()
+ numOutline = numOutline or o
+ self.timerLabel:SetFont(numFont or f, numSize or s, numOutline)
+ self.timerLabel:SetShadowColor(0, 0, 0, numOutline == "" and 0 or 1)
+end
+
+-- changes bar icon texture
+function barPrototype:SetIcon(icon, ...)
+ if not icon then
+ self.iconFrame:Hide()
+ return
+ end
+
+ self.icon:SetTexture(icon)
+ if self.showIcon then
+ self.iconFrame:Show()
+ end
+ if ... then
+ self.icon:SetTexCoord(...)
+ end
+end
+
+-- shows bar's icon
+function barPrototype:ShowIcon()
+ self.showIcon = true
+ if self.icon then
+ self.iconFrame:Show()
+ end
+end
+
+-- hides bar's icon
+function barPrototype:HideIcon()
+ self.showIcon = nil
+ if self.icon then
+ self.iconFrame:Hide()
+ end
+end
+
+-- changes bar's label text
+function barPrototype:SetLabel(text)
+ self.label:SetText(text)
+end
+
+-- returns bar's label text
+function barPrototype:GetLabel()
+ return self.label:GetText()
+end
+
+barPrototype.SetText = barPrototype.SetLabel -- for API compatibility
+barPrototype.GetText = barPrototype.GetLabel -- for API compatibility
+
+-- shows bar's label
+function barPrototype:ShowLabel()
+ if not self.label:IsShown() then
+ self.label:Show()
+ end
+end
+
+-- hides bar's label
+function barPrototype:HideLabel()
+ if self.label:IsShown() then
+ self.label:Hide()
+ end
+end
+
+-- changes timer's text
+function barPrototype:SetTimerLabel(text)
+ self.timerLabel:SetText(text)
+end
+
+-- returns timer's text
+function barPrototype:GetTimerLabel()
+ return self.timerLabel:GetText()
+end
+
+-- shows bar's timer label
+function barPrototype:ShowTimerLabel()
+ if not self.timerLabel:IsShown() then
+ self.timerLabel:Show()
+ end
+end
+
+-- hides bar's timer label
+function barPrototype:HideTimerLabel()
+ if self.timerLabel:IsShown() then
+ self.timerLabel:Hide()
+ end
+end
+
+-- changes bar's foreground and background textures
+function barPrototype:SetTexture(texture)
+ self.fg:SetTexture(texture)
+ self.bg:SetTexture(texture)
+end
+
+-- changes bar's color
+function barPrototype:SetColor(r, g, b, a, locked)
+ if not self.colors or self.colors[1] ~= r or self.colors[2] ~= g or self.colors[3] ~= b or self.colors[4] ~= a then
+ self.colors = self.colors or new()
+
+ self.colors[1] = r or self.colors[1]
+ self.colors[2] = g or self.colors[2]
+ self.colors[3] = b or self.colors[3]
+ self.colors[4] = a or self.colors[4]
+ self.lockColor = locked or nil
+
+ self:UpdateColor()
+ end
+end
+
+-- unsets bar color
+function barPrototype:UnsetColor()
+ self.colors = del(self.colors)
+end
+
+-- updates bar's foreground color
+function barPrototype:UpdateColor()
+ if not self.colors then return end
+ self.fg:SetVertexColor(self.colors[1], self.colors[2], self.colors[3], self.colors[4] or 1)
+end
+
+-- barPrototype:SetLength -- changes bar's width
+-- barPrototype:SetThickness -- changes bar's heght
+do
+ barPrototype.SetWidth = barPrototype.super.SetWidth
+ barPrototype.SetHeight = barPrototype.super.SetHeight
+
+ local function updateSize(self)
+ local iconSize = self.showIcon and self.thickness or 0
+ local width = max(0.0001, self.length - iconSize)
+ local height = self.thickness
+
+ self:SetWidth(width)
+ self:SetHeight(height)
+ self.iconFrame:SetWidth(height)
+ self.iconFrame:SetHeight(height)
+ end
+
+ function barPrototype:SetLength(length)
+ self.length = length
+ updateSize(self)
+ end
+
+ function barPrototype:SetThickness(thickness)
+ self.thickness = thickness
+ updateSize(self)
+ end
+end
+
+-- changes bar's orientation
+function barPrototype:SetOrientation(o)
+ self:UpdateOrientationLayout(o)
+ self:SetThickness(self.thickness)
+end
+
+-- updates bar's orientation
+function barPrototype:UpdateOrientationLayout(orientation)
+ if orientation == LEFT_TO_RIGHT then
+ local t = self.iconFrame
+ t:ClearAllPoints()
+ t:SetPoint("RIGHT", self, "LEFT")
+
+ t = self.fg
+ t.SetValue = t.SetWidth
+ t:ClearAllPoints()
+ t:SetPoint("TOPLEFT", self, "TOPLEFT")
+ t:SetPoint("BOTTOMLEFT", self, "BOTTOMLEFT")
+
+ t = self.spark
+ t:ClearAllPoints()
+ t:SetPoint("TOP", self.fg, "TOPRIGHT", 0, 7)
+ t:SetPoint("BOTTOM", self.fg, "BOTTOMRIGHT", 0, -7)
+ t:SetTexCoord(0, 1, 0, 1)
+
+ t = self.timerLabel
+ t:ClearAllPoints()
+ t:SetPoint("RIGHT", self, "RIGHT", -5, 0)
+ t:SetJustifyH("RIGHT")
+ t:SetJustifyV("MIDDLE")
+
+ t = self.label
+ t:ClearAllPoints()
+ t:SetPoint("LEFT", self, "LEFT", 5, 0)
+ t:SetPoint("RIGHT", self.timerLabel, "LEFT")
+ t:SetJustifyH("LEFT")
+ t:SetJustifyV("MIDDLE")
+
+ self.bg:SetTexCoord(0, 1, 0, 1)
+ elseif orientation == RIGHT_TO_LEFT then
+ local t = self.iconFrame
+ t:ClearAllPoints()
+ t:SetPoint("LEFT", self, "RIGHT")
+
+ t = self.fg
+ t.SetValue = t.SetWidth
+ t:ClearAllPoints()
+ t:SetPoint("TOPRIGHT", self, "TOPRIGHT")
+ t:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT")
+
+ t = self.spark
+ t:ClearAllPoints()
+ t:SetPoint("TOP", self.fg, "TOPLEFT", 0, 7)
+ t:SetPoint("BOTTOM", self.fg, "BOTTOMLEFT", 0, -7)
+ t:SetTexCoord(0, 1, 0, 1)
+
+ t = self.timerLabel
+ t:ClearAllPoints()
+ t:SetPoint("LEFT", self, "LEFT", 5, 0)
+ t:SetJustifyH("LEFT")
+ t:SetJustifyV("MIDDLE")
+
+ t = self.label
+ t:ClearAllPoints()
+ t:SetPoint("RIGHT", self, "RIGHT", -5, 0)
+ t:SetPoint("LEFT", self.timerLabel, "RIGHT")
+ t:SetJustifyH("RIGHT")
+ t:SetJustifyV("MIDDLE")
+
+ self.bg:SetTexCoord(0, 1, 0, 1)
+ end
+ self:SetValue(self.value or 0)
+end
+
+-- barPrototype:SetValue - changes bar's value
+do
+ local function SetTextureValue(self, amt, dist)
+ dist = max(0.0001, dist - (self.showIcon and self.thickness or 0))
+ self.fg:SetValue(amt * dist)
+
+ if self.ownerGroup.orientation == LEFT_TO_RIGHT then
+ self.fg:SetTexCoord(0, amt, 0, 1)
+ elseif self.ownerGroup.orientation == RIGHT_TO_LEFT then
+ self.fg:SetTexCoord(1 - amt, 1, 0, 1)
+ end
+ end
+
+ local function calc_last_amt(targetamt, lastamt)
+ if targetamt > lastamt then
+ return min(((targetamt - lastamt) / 4) + lastamt, targetamt)
+ end
+ return max(lastamt - ((lastamt - targetamt) / 4), targetamt)
+ end
+
+ local function animate(self, elapsed)
+ local t = self.lastanimated + elapsed
+ if t >= 0.25 then
+ SetTextureValue(self, self.targetamt, self.targetdist)
+ self.lastamt = self.targetamt
+ self:SetScript("OnUpdate", nil)
+ t = 0
+ else
+ self.lastamt = calc_last_amt(self.targetamt, self.lastamt)
+ SetTextureValue(self, self.lastamt, self.targetdist)
+ end
+ self.lastanimated = t
+ end
+
+ local function SetTextureTarget(self, amt, dist)
+ self.targetamt = amt
+ self.targetdist = dist
+
+ self.lastanimated = 0
+ self:SetScript("OnUpdate", animate)
+ end
+
+ function barPrototype:SetValue(val)
+ if not val then
+ error("value cannot be nil!")
+ end
+
+ self.value = val
+ if not self.maxValue or val > self.maxValue then
+ self.maxValue = val
+ end
+
+ local ownerGroup = self.ownerGroup
+ if not ownerGroup then return end
+
+ local amt = max(0.000001, min(1, val / max(self.maxValue, 0.000001)))
+ local dist = ownerGroup:GetLength()
+
+ -- smoothing
+ if ownerGroup.smoothing and self.lastamt then
+ SetTextureTarget(self, amt, dist)
+ else
+ self.lastamt = amt
+ SetTextureValue(self, amt, dist)
+ end
+
+ -- spark
+ if ownerGroup.usespark and self.spark then
+ if amt == 1 or amt <= 0.000001 then
+ self.spark:Hide()
+ else
+ self.spark:Show()
+ end
+ end
+
+ self:UpdateColor()
+ end
+end
+
+-- sets bar's max value
+function barPrototype:SetMaxValue(val)
+ self.maxValue = val
+ self:SetValue(self.value)
+end
+
+-------------------------------------------------------------------------------
+-- sticky frames | credits: Jason Greer - LibFlyPaper-1.1
+-------------------------------------------------------------------------------
+do
+ local math_huge, unpack = math.huge, unpack
+ local DEFAULT_STICKY_TOLERANCE = 16
+ local FRAME_STRATAS = {BACKGROUND = 1, LOW = 2, MEDIUM = 3, HIGH = 4, DIALOG = 5, FULLSCREEN = 6, FULLSCREEN_DIALOG = 7, TOOLTIP = 8}
+ local FRAME_ANCHORS = {"TL", "TR", "TC", "BL", "BR", "BC", "LT", "LB", "LC", "RT", "RB", "RC"}
+ local FRAME_ANCHOR_POINTS = {
+ -- bottom to top
+ TL = {"BOTTOMLEFT", "TOPLEFT", 0, 1},
+ TR = {"BOTTOMRIGHT", "TOPRIGHT", 0, 1},
+ TC = {"BOTTOM", "TOP", 0, 1},
+ -- top to bottom
+ BL = {"TOPLEFT", "BOTTOMLEFT", 0, -1},
+ BR = {"TOPRIGHT", "BOTTOMRIGHT", 0, -1},
+ BC = {"TOP", "BOTTOM", 0, -1},
+ -- right to left
+ LT = {"TOPRIGHT", "TOPLEFT", -1, 0},
+ LB = {"BOTTOMRIGHT", "BOTTOMLEFT", -1, 0},
+ LC = {"RIGHT", "LEFT", -1, 0},
+ -- left to right
+ RT = {"TOPLEFT", "TOPRIGHT", 1, 0},
+ RB = {"BOTTOMLEFT", "BOTTOMRIGHT", 1, 0},
+ RC = {"LEFT", "RIGHT", 1, 0}
+ }
+ local COORDS = {
+ TOP = function(left, bottom, width, height)
+ return left + width * 0.5, bottom + height
+ end,
+ TOPLEFT = function(left, bottom, width, height)
+ return left, bottom + height
+ end,
+ TOPRIGHT = function(left, bottom, width, height)
+ return left + width, bottom + height
+ end,
+ BOTTOM = function(left, bottom, width, height)
+ return left + width * 0.5, bottom
+ end,
+ BOTTOMLEFT = function(left, bottom, width, height)
+ return left, bottom
+ end,
+ BOTTOMRIGHT = function(left, bottom, width, height)
+ return left + width, bottom
+ end,
+ LEFT = function(left, bottom, width, height)
+ return left, bottom + height * 0.5
+ end,
+ CENTER = function(left, bottom, width, height)
+ return left + width * 0.5, bottom + height * 0.5
+ end,
+ RIGHT = function(left, bottom, width, height)
+ return left + width, bottom + height * 0.5
+ end
+ }
+
+ local function getScaledRect(self)
+ if self.GetScaledRect then
+ return self:GetScaledRect()
+ end
+
+ local left, bottom, width, height = self:GetRect()
+ local scale = self:GetEffectiveScale()
+ return left * scale, bottom * scale, width * scale, height * scale
+ end
+
+ -- two dimensional distance
+ local function getSquaredDistance(x1, y1, x2, y2)
+ return (x1 - x2) ^ 2 + (y1 - y2) ^ 2
+ end
+
+ -- returns true if or one of the frames that
+ -- is dependent on is anchored to and nil otherwise
+ local function isFrameDependentOn(self, frame)
+ if self and frame then
+ if self == frame then
+ return true
+ end
+
+ local points = self:GetNumPoints()
+ for i = 1, points do
+ local _, parent = self:GetPoint(i)
+ if isFrameDependentOn(parent, frame) then
+ return true
+ end
+ end
+ end
+ end
+
+ -- returns true if its actually possible to attach
+ -- the two frames without error
+ local function canAttach(self, frame)
+ return self and frame and not isFrameDependentOn(frame, self)
+ end
+
+ -- returns the addon id and addonName associated with
+ -- the specified frame
+ local function getFrameGroup(self)
+ local sticky = lib._sticky
+ if not sticky then return end
+
+ for name, group in pairs(sticky) do
+ for groupId, groupFrame in pairs(group) do
+ if groupFrame == self then
+ return name, groupId
+ end
+ end
+ end
+ end
+
+ -- returns 0 if a frame is in the same group as another frame
+ -- and 1 otherwise
+ local function getGroupDistance(self, frame)
+ return (self == frame or getFrameGroup(self) == getFrameGroup(frame)) and 0 or 1
+ end
+
+ local function getZDistance(self, frame)
+ if self == frame then
+ return 0
+ end
+
+ local s1 = FRAME_STRATAS[self:GetFrameStrata()]
+ local s2 = FRAME_STRATAS[frame:GetFrameStrata()]
+ local l1 = self:GetFrameLevel()
+ local l2 = frame:GetFrameLevel()
+
+ return getSquaredDistance(s1, l1, s2, l2)
+ end
+
+ -- iterate through all anchor points
+ -- return the one with the shortest distance
+ local function getClosestAnchor(self, frame)
+ if self == frame then return end
+
+ local bestDistance = math_huge
+ local bestAnchor = false
+ local l1, b1, w1, h1 = getScaledRect(self)
+ local l2, b2, w2, h2 = getScaledRect(frame)
+
+ for i = 1, #FRAME_ANCHORS do
+ local anchor = FRAME_ANCHORS[i]
+ local point, relPoint = unpack(FRAME_ANCHOR_POINTS[anchor])
+ local x1, y1 = COORDS[point](l1, b1, w1, h1)
+ local x2, y2 = COORDS[relPoint](l2, b2, w2, h2)
+ local distance = getSquaredDistance(x1, y1, x2, y2)
+
+ if distance < bestDistance then
+ bestDistance = distance
+ bestAnchor = anchor
+ end
+ end
+
+ return bestAnchor, bestDistance
+ end
+
+ local function getClosestFrame(self, sticky, tolerance)
+ local maxDistance = (tonumber(tolerance) or DEFAULT_STICKY_TOLERANCE) ^ 2
+ local bestDistance = math_huge
+ local bestAnchor, bestFrame, bestId
+
+ for id, frame in pairs(sticky) do
+ if canAttach(self, frame) then
+ local anchor, distance = getClosestAnchor(self, frame)
+
+ if distance <= maxDistance then
+ -- prioritize frames on the same layer
+ distance = distance + getZDistance(self, frame)
+
+ -- prioritize frames from the same addon
+ distance = distance + getGroupDistance(self, frame)
+
+ if distance < bestDistance then
+ bestAnchor = anchor
+ bestDistance = distance
+ bestFrame = frame
+ bestId = id
+ end
+ end
+ end
+ end
+
+ return bestFrame, bestAnchor, bestId, bestDistance
+ end
+
+ local function anchorFrame(self, frame, anchor, xOfs, yOfs)
+ local point, relPoint, xMult, yMult = unpack(FRAME_ANCHOR_POINTS[anchor])
+ local s = self:GetEffectiveScale()
+ local x = ((tonumber(xOfs) or 0) * xMult) / s
+ local y = ((tonumber(yOfs) or 0) * yMult) / s
+
+ self:ClearAllPoints()
+ self:SetPoint(point, frame, relPoint, x, y)
+
+ callbacks:Fire("OnAnchorFrame", self, frame, anchor, x, y)
+ end
+
+ -- attempts to anchor to a specific anchor point on
+ function barListPrototype:Stick(frame, tolerance, xOfs, yOfs)
+ if not canAttach(self, frame) then return end
+
+ local anchor, distance = getClosestAnchor(self, frame)
+ local maxDistance = (tonumber(tolerance) or DEFAULT_STICKY_TOLERANCE) ^ 2
+ if distance > maxDistance then return end
+
+ anchorFrame(self, frame, anchor, xOfs, yOfs)
+ return anchor, distance
+ end
+
+ -- iterate through all registered frames, and try to stick to the nearest one
+ function barListPrototype:StickToClosestFrameInGroup(groupName, tolerance, xOfs, yOfs)
+ local group = lib._sticky and lib._sticky[groupName]
+ if not group then return end
+
+ local frame, anchor, id = getClosestFrame(self, group, tolerance)
+ if not frame then return end
+
+ anchorFrame(self, frame, anchor, xOfs, yOfs)
+ return anchor, id, frame
+ end
+
+ local function addFrame(groupName, id, frame)
+ local group = lib._sticky and lib._sticky[groupName]
+ if not group then
+ lib._sticky = lib._sticky or new()
+ lib._sticky[groupName] = new()
+ group = lib._sticky[groupName]
+ end
+
+ if group[id] then return end
+ group[id] = frame
+ callbacks:Fire("OnAddFrame", frame, groupName, id)
+ return true
+ end
+
+ local function removeFrame(groupName, id)
+ local group = lib._sticky and lib._sticky[groupName]
+ if not group then return end
+
+ local frame = group[id]
+ if not frame then return end
+
+ group[id] = nil
+ callbacks:Fire("OnRemoveFrame", frame, groupName, id)
+
+ -- free tables
+ if next(group) == nil then
+ lib._sticky[groupName] = del(group)
+ end
+ if next(lib._sticky) == nil then
+ lib._sticky = del(lib._sticky)
+ end
+
+ return true
+ end
+
+ function barListPrototype:SetSticky(sticky, groupName)
+ return sticky and addFrame(groupName, self.name, self) or removeFrame(groupName, self.name)
+ end
+end
+
+-------------------------------------------------------------------------------
+-- library embeds
+-------------------------------------------------------------------------------
+
+-- lib:Embed - library embed
+do
+ lib.embeds = lib.embeds or {}
+
+ local mixins = {
+ "NewBar",
+ "GetBar",
+ "ReleaseBar",
+ "GetBars",
+ "NewBarGroup",
+ "GetBarGroup",
+ "GetBarGroups",
+ "SetScrollSpeed",
+ "RegisterCallback",
+ "callbacks",
+ "LEFT_TO_RIGHT",
+ "RIGHT_TO_LEFT"
+ }
+
+ function lib:Embed(target)
+ for k, v in pairs(mixins) do
+ target[v] = self[v]
+ end
+ lib.embeds[target] = true
+ return target
+ end
+end
+
+--- Finally: upgrade our old embeds
+for target, v in pairs(lib.embeds) do
+ lib:Embed(target)
+end
diff --git a/Skada/Libs/SpecializedLibBars-1.0/lock.tga b/Skada/Libs/SpecializedLibBars-1.0/lock.tga
new file mode 100644
index 0000000..8f8f99e
Binary files /dev/null and b/Skada/Libs/SpecializedLibBars-1.0/lock.tga differ
diff --git a/Skada/Libs/SpecializedLibBars-1.0/unlock.tga b/Skada/Libs/SpecializedLibBars-1.0/unlock.tga
new file mode 100644
index 0000000..721d2ac
Binary files /dev/null and b/Skada/Libs/SpecializedLibBars-1.0/unlock.tga differ
diff --git a/Skada/Libs/SpecializedLibToast-1.0/SpecializedLibToast-1.0.lua b/Skada/Libs/SpecializedLibToast-1.0/SpecializedLibToast-1.0.lua
new file mode 100644
index 0000000..5241a46
--- /dev/null
+++ b/Skada/Libs/SpecializedLibToast-1.0/SpecializedLibToast-1.0.lua
@@ -0,0 +1,691 @@
+-- LibToast-1.0 modified by Kader
+-- Specialized ( = enhanced) for Skada
+
+local MAJOR, MINOR = "SpecializedLibToast-1.0", 3
+
+local LibStub = LibStub
+assert(LibStub, MAJOR .. " requires LibStub")
+
+local lib, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+if not lib then return end -- No upgrade needed
+local folder = ...
+
+-----------------------------------------------------------------------
+-- Upvalued Lua API.
+-----------------------------------------------------------------------
+-- Functions
+local pairs, type, error = pairs, type, error
+local tremove, unpack = table.remove, unpack
+local min, max = math.min, math.max
+local find, lower, format = string.find, string.lower, string.format
+local CreateFrame, UIFrameFade = CreateFrame, UIFrameFade
+local UIFrameFadeRemoveFrame = UIFrameFadeRemoveFrame
+
+-----------------------------------------------------------------------
+-- Migrations.
+-----------------------------------------------------------------------
+lib.templates = lib.templates or {}
+lib.unique_templates = lib.unique_templates or {}
+lib.active_toasts = lib.active_toasts or {}
+lib.toast_heap = lib.toast_heap or {}
+lib.button_heap = lib.button_heap or {}
+
+-----------------------------------------------------------------------
+-- Variables.
+-----------------------------------------------------------------------
+local current_toast
+
+-----------------------------------------------------------------------
+-- Constants.
+-----------------------------------------------------------------------
+local active_toasts = lib.active_toasts
+local toast_heap = lib.toast_heap
+local button_heap = lib.button_heap
+
+local toast_proxy = {}
+
+local METHOD_USAGE_FORMAT = MAJOR .. ":%s() - %s."
+
+local DEFAULT_FADE_HOLD_TIME = 5
+local DEFAULT_FADE_IN_TIME = 0.5
+local DEFAULT_FADE_OUT_TIME = 1
+local DEFAULT_TOAST_WIDTH = 275
+local DEFAULT_TOAST_HEIGHT = 50
+local DEFAULT_ICON_SIZE = 28
+
+local DEFAULT_TOAST_BACKDROP = {
+ bgFile = [[Interface\ChatFrame\ChatFrameBackground]],
+ edgeFile = [[Interface\ChatFrame\ChatFrameBackground]],
+ edgeSize = 1,
+ insets = {left = 0, right = 0, top = 0, bottom = 0}
+}
+
+local DEFAULT_BACKGROUND_COLORS = {r = 0, g = 0, b = 0}
+
+local DEFAULT_TITLE_COLORS = {r = 0.510, g = 0.773, b = 1}
+
+local DEFAULT_TEXT_COLORS = {r = 1, g = 1, b = 1}
+
+local TOAST_BUTTONS = {
+ primary_button = true,
+ secondary_button = true,
+ tertiary_button = true
+}
+
+local TOAST_BUTTON_HEIGHT = 18
+
+local SIBLING_ANCHORS = {
+ TOPRIGHT = "BOTTOMRIGHT",
+ TOPLEFT = "BOTTOMLEFT",
+ BOTTOMRIGHT = "TOPRIGHT",
+ BOTTOMLEFT = "TOPLEFT",
+ TOP = "BOTTOM",
+ BOTTOM = "TOP",
+ LEFT = "RIGHT",
+ RIGHT = "LEFT"
+}
+
+local OFFSET_X = {
+ TOPRIGHT = -90,
+ TOPLEFT = 90,
+ BOTTOMRIGHT = -90,
+ BOTTOMLEFT = 90,
+ TOP = 0,
+ BOTTOM = 0,
+ LEFT = 90,
+ RIGHT = -90
+}
+
+local OFFSET_Y = {
+ TOPRIGHT = -60,
+ TOPLEFT = -60,
+ BOTTOMRIGHT = 60,
+ BOTTOMLEFT = 60,
+ TOP = -60,
+ BOTTOM = 180,
+ LEFT = 0,
+ RIGHT = 0
+}
+
+local SIBLING_OFFSET_X = {
+ TOPRIGHT = 0,
+ TOPLEFT = 0,
+ BOTTOMRIGHT = 0,
+ BOTTOMLEFT = 0,
+ TOP = 0,
+ BOTTOM = 0,
+ LEFT = 10,
+ RIGHT = -10
+}
+
+local SIBLING_OFFSET_Y = {
+ TOPRIGHT = -10,
+ TOPLEFT = -10,
+ BOTTOMRIGHT = 10,
+ BOTTOMLEFT = 10,
+ TOP = -10,
+ BOTTOM = 10,
+ LEFT = 0,
+ RIGHT = 0
+}
+
+lib.config = {
+ hide_toasts = false,
+ spawn_point = "BOTTOMRIGHT",
+ duration = DEFAULT_FADE_HOLD_TIME,
+ floating_icon = false,
+ opacity = 0.75,
+ width = DEFAULT_TOAST_WIDTH,
+ height = DEFAULT_TOAST_HEIGHT,
+ -- colors:
+ title = {
+ very_low = DEFAULT_TITLE_COLORS,
+ moderate = DEFAULT_TITLE_COLORS,
+ normal = DEFAULT_TITLE_COLORS,
+ high = DEFAULT_TITLE_COLORS,
+ emergency = DEFAULT_TITLE_COLORS
+ },
+ text = {
+ very_low = DEFAULT_TEXT_COLORS,
+ moderate = DEFAULT_TEXT_COLORS,
+ normal = DEFAULT_TEXT_COLORS,
+ high = DEFAULT_TEXT_COLORS,
+ emergency = DEFAULT_TEXT_COLORS
+ },
+ background = {
+ very_low = DEFAULT_BACKGROUND_COLORS,
+ moderate = DEFAULT_BACKGROUND_COLORS,
+ normal = DEFAULT_BACKGROUND_COLORS,
+ high = DEFAULT_BACKGROUND_COLORS,
+ emergency = DEFAULT_BACKGROUND_COLORS
+ }
+}
+
+function lib:SetWidth(width)
+ lib.config.width = width
+end
+
+function lib:SetHeight(height)
+ lib.config.height = height
+end
+
+function lib:SetShown(show)
+ lib.config.hide_toasts = not show
+end
+
+function lib:SetSpawnPoint(point)
+ lib.config.spawn_point = point
+end
+
+function lib:GetDuration()
+ return lib.config.duration
+end
+
+function lib:SetDuration(duration)
+ lib.config.duration = max(0, min(10, duration or 0))
+end
+
+function lib:SetFloatingIcon(enable)
+ lib.config.floating_icon = enable
+end
+
+function lib:SetOpacity(opacity)
+ lib.config.opacity = opacity
+end
+
+function lib:SetTitleColors(urgency, r, g, b)
+ lib.config.title[urgency] = {r = r or 1, g = g or 1, b = b or 1}
+end
+
+function lib:SetTextColors(urgency, r, g, b)
+ lib.config.text[urgency] = {r = r or 1, g = g or 1, b = b or 1}
+end
+
+function lib:SetBackgroundColors(urgency, r, g, b)
+ lib.config.background[urgency] = {r = r or 1, g = g or 1, b = b or 1}
+end
+
+-----------------------------------------------------------------------
+-- Settings functions.
+-----------------------------------------------------------------------
+function lib:GetSpawnPoint()
+ return self.config.spawn_point
+end
+
+function lib:GetTitleColors(urgency)
+ return self.config.title[urgency].r, self.config.title[urgency].g, self.config.title[urgency].b
+end
+
+function lib:GetTextColors(urgency)
+ return self.config.text[urgency].r, self.config.text[urgency].g, self.config.text[urgency].b
+end
+
+function lib:GetBackgroundColors(urgency)
+ return self.config.background[urgency].r, self.config.background[urgency].g, self.config.background[urgency].b
+end
+
+function lib:GetDuration()
+ return self.config.duration
+end
+
+function lib:GetOpacity()
+ return self.config.opacity
+end
+
+function lib:HasFloatingIcon()
+ return self.config.floating_icon
+end
+
+local function ToastsAreSuppressed()
+ return lib.config.hide_toasts
+end
+
+-----------------------------------------------------------------------
+-- Helper functions.
+-----------------------------------------------------------------------
+local function _reclaimButton(button)
+ button:Hide()
+ button:ClearAllPoints()
+ button:SetParent(nil)
+ button:SetText(nil)
+ button_heap[#button_heap + 1] = button
+end
+
+local function _reclaimToast(toast)
+ for button_name in pairs(TOAST_BUTTONS) do
+ local button = toast[button_name]
+
+ if button then
+ toast[button_name] = nil
+ _reclaimButton(button)
+ end
+ end
+ toast.is_persistent = nil
+ toast.template_name = nil
+ toast.payload = nil
+ toast:Hide()
+
+ UIFrameFadeRemoveFrame(toast)
+ toast_heap[#toast_heap + 1] = toast
+
+ local remove_index
+ for index = 1, #active_toasts do
+ if active_toasts[index] == toast then
+ remove_index = index
+ break
+ end
+ end
+
+ if remove_index then
+ tremove(active_toasts, remove_index):ClearAllPoints()
+ end
+ local spawn_point = lib:GetSpawnPoint()
+ local lower_point = lower(spawn_point)
+ local floating_icon = lib:HasFloatingIcon()
+
+ for index = 1, #active_toasts do
+ local indexed_toast = active_toasts[index]
+ indexed_toast:ClearAllPoints()
+ indexed_toast.icon:ClearAllPoints()
+
+ if floating_icon then
+ if find(lower_point, "right") then
+ indexed_toast.icon:SetPoint("TOPRIGHT", indexed_toast, "TOPLEFT", -5, -10)
+ elseif find(lower_point, "left") then
+ indexed_toast.icon:SetPoint("TOPLEFT", indexed_toast, "TOPRIGHT", 5, -10)
+ else
+ indexed_toast.icon:SetPoint("TOPRIGHT", indexed_toast, "TOPLEFT", -5, -10)
+ end
+ else
+ indexed_toast.icon:SetPoint("TOPLEFT", indexed_toast, "TOPLEFT", 8, -10)
+ end
+
+ if index == 1 then
+ indexed_toast:SetPoint(spawn_point, UIParent, spawn_point, OFFSET_X[spawn_point], OFFSET_Y[spawn_point])
+ else
+ indexed_toast:SetPoint(spawn_point, active_toasts[index - 1], SIBLING_ANCHORS[spawn_point], SIBLING_OFFSET_X[spawn_point], SIBLING_OFFSET_Y[spawn_point])
+ end
+ end
+end
+
+local function _finishToastDisplay(toast)
+ local fade_info = toast.fade_out_info
+ fade_info.fadeTimer = 0
+ fade_info.finishedFunc = _reclaimToast
+ fade_info.finishedArg1 = toast
+
+ UIFrameFade(toast, fade_info)
+end
+
+local function _showDismissButton(frame, motion)
+ frame.dismiss_button:Show()
+end
+
+local function _hideDismissButton(frame, motion)
+ if not frame.dismiss_button:IsMouseOver() then
+ frame.dismiss_button:Hide()
+ end
+end
+
+local function _dismissToast(frame, button, down)
+ _reclaimToast(frame:GetParent())
+end
+
+local function _acquireToast()
+ local toast = tremove(toast_heap)
+
+ if not toast then
+ toast = CreateFrame("Button", nil, UIParent)
+ toast:SetFrameStrata("DIALOG")
+ toast:Hide()
+
+ local toast_icon = toast:CreateTexture(nil, "BORDER")
+ toast_icon:SetWidth(DEFAULT_ICON_SIZE)
+ toast_icon:SetHeight(DEFAULT_ICON_SIZE)
+ toast.icon = toast_icon
+
+ local title = toast:CreateFontString(nil, "BORDER", "FriendsFont_Normal")
+ title:SetJustifyH("LEFT")
+ title:SetJustifyV("MIDDLE")
+ title:SetWordWrap(true)
+ title:SetPoint("TOPLEFT", toast, "TOPLEFT", 44, -10)
+ title:SetPoint("RIGHT", toast, "RIGHT", -20, 10)
+ toast.title = title
+
+ local focus = CreateFrame("Frame", nil, toast)
+ focus:EnableMouse(true)
+ focus:SetAllPoints(toast)
+ focus:SetScript("OnEnter", _showDismissButton)
+ focus:SetScript("OnLeave", _hideDismissButton)
+ focus:SetScript("OnShow", _hideDismissButton)
+
+ local dismiss_button = CreateFrame("Button", nil, toast)
+ dismiss_button:SetWidth(18)
+ dismiss_button:SetHeight(18)
+ dismiss_button:SetPoint("TOPRIGHT", toast, "TOPRIGHT", -4, -4)
+ dismiss_button:SetFrameStrata("DIALOG")
+ dismiss_button:SetFrameLevel(toast:GetFrameLevel() + 2)
+ dismiss_button:SetNormalTexture(format([[Interface\AddOns\%s\Libs\%s\closebutton-up]], folder, MAJOR))
+ dismiss_button:SetPushedTexture(format([[Interface\AddOns\%s\Libs\%s\closebutton-down]], folder, MAJOR))
+ dismiss_button:SetHighlightTexture(format([[Interface\AddOns\%s\Libs\%s\closebutton-highlight]], folder, MAJOR))
+ dismiss_button:Hide()
+ dismiss_button:SetScript("OnClick", _dismissToast)
+
+ focus.dismiss_button = dismiss_button
+
+ local text = toast:CreateFontString(nil, "BORDER", "FriendsFont_Normal")
+ text:SetJustifyH("LEFT")
+ text:SetJustifyV("MIDDLE")
+ text:SetWordWrap(true)
+ text:SetPoint("TOPLEFT", title, "BOTTOMLEFT", 0, -4)
+ toast.text = text
+
+ toast.fade_in_info = {
+ timeToFade = DEFAULT_FADE_IN_TIME,
+ startAlpha = 0,
+ endAlpha = 1
+ }
+
+ toast.fade_out_info = {
+ timeToFade = DEFAULT_FADE_OUT_TIME,
+ finishedFunc = _reclaimToast,
+ finishedArg1 = toast,
+ startAlpha = 1,
+ endAlpha = 0
+ }
+ end
+ toast:SetWidth(lib.config.width)
+ toast:SetHeight(lib.config.height)
+
+ toast:SetBackdrop(DEFAULT_TOAST_BACKDROP)
+ toast:SetBackdropColor(0, 0, 0, 0.6)
+ toast:SetBackdropBorderColor(0, 0, 0, 1)
+
+ return toast
+end
+
+-----------------------------------------------------------------------
+-- Library methods.
+-----------------------------------------------------------------------
+function lib:Register(template_name, constructor, is_unique)
+ if type(template_name) ~= "string" or template_name == "" then
+ error(format(METHOD_USAGE_FORMAT, "Register", "template_name must be a non-empty string"), 2)
+ end
+
+ if type(constructor) ~= "function" then
+ error(format(METHOD_USAGE_FORMAT, "Register", "constructor must be a function"), 2)
+ end
+ self.templates[template_name] = constructor
+ self.unique_templates[template_name] = is_unique or nil
+end
+
+function lib:Spawn(template_name, ...)
+ if not template_name or type(template_name) ~= "string" or template_name == "" then
+ error(format(METHOD_USAGE_FORMAT, "Spawn", "template_name must be a non-empty string"), 2)
+ end
+
+ if not self.templates[template_name] then
+ error(format(METHOD_USAGE_FORMAT, "Spawn", format('"%s" does not match a registered template', template_name)), 2)
+ end
+
+ if ToastsAreSuppressed() then
+ return false
+ end
+
+ if self.unique_templates[template_name] then
+ for index = 1, #active_toasts do
+ if active_toasts[index].template_name == template_name then
+ return false
+ end
+ end
+ end
+ current_toast = _acquireToast()
+ current_toast.template_name = template_name
+
+ -----------------------------------------------------------------------
+ -- Reset defaults.
+ -----------------------------------------------------------------------
+ current_toast.title:SetText(nil)
+ current_toast.text:SetText(nil)
+ current_toast.icon:SetTexture(nil)
+ current_toast.icon:SetTexCoord(0.062, 0.938, 0.062, 0.938)
+
+ -----------------------------------------------------------------------
+ -- Run constructor.
+ -----------------------------------------------------------------------
+ self.templates[template_name](toast_proxy, ...)
+
+ if not current_toast.title:GetText() and not current_toast.text:GetText() and not current_toast.icon:GetTexture() then
+ _reclaimToast(current_toast)
+ return false
+ end
+
+ -----------------------------------------------------------------------
+ -- Finalize layout.
+ -----------------------------------------------------------------------
+ local urgency = current_toast.urgency_level
+ current_toast.title:SetTextColor(self:GetTitleColors(urgency))
+ current_toast.text:SetTextColor(self:GetTextColors(urgency))
+
+ local opacity = self:GetOpacity()
+ local r, g, b = self:GetBackgroundColors(urgency)
+ current_toast:SetBackdropColor(r, g, b, opacity)
+
+ r, g, b = current_toast:GetBackdropBorderColor()
+ current_toast:SetBackdropBorderColor(r, g, b, opacity)
+
+ local fade_in_info = current_toast.fade_in_info
+ fade_in_info.fadeTimer = 0
+ fade_in_info.fadeHoldTime = current_toast.is_persistent and 0 or self:GetDuration()
+
+ if fade_in_info.fadeHoldTime > 0 then
+ fade_in_info.finishedFunc = _finishToastDisplay
+ fade_in_info.finishedArg1 = current_toast
+ else
+ fade_in_info.finishedFunc = nil
+ fade_in_info.finishedArg1 = nil
+ end
+ local spawn_point = lib:GetSpawnPoint()
+ local lower_point = lower(spawn_point)
+ local floating_icon = self:HasFloatingIcon()
+
+ current_toast.icon:ClearAllPoints()
+
+ if floating_icon then
+ if find(lower_point, "right") then
+ current_toast.icon:SetPoint("TOPRIGHT", current_toast, "TOPLEFT", -5, -10)
+ elseif find(lower_point, "left") then
+ current_toast.icon:SetPoint("TOPLEFT", current_toast, "TOPRIGHT", 5, -10)
+ else
+ current_toast.icon:SetPoint("TOPRIGHT", current_toast, "TOPLEFT", -5, -10)
+ end
+ else
+ current_toast.icon:SetPoint("TOPLEFT", current_toast, "TOPLEFT", 8, -10)
+ end
+
+ if floating_icon or not current_toast.icon:GetTexture() then
+ current_toast.title:SetPoint("TOPLEFT", current_toast, "TOPLEFT", 10, -10)
+ else
+ current_toast.title:SetPoint("TOPLEFT", current_toast, "TOPLEFT", current_toast.icon:GetWidth() + 15, -10)
+ end
+
+ if current_toast.title:GetText() then
+ current_toast.title:SetWidth(current_toast:GetWidth() - current_toast.icon:GetWidth() - 20)
+ current_toast.title:Show()
+ else
+ current_toast.title:Hide()
+ end
+
+ if current_toast.text:GetText() then
+ current_toast.text:SetWidth(current_toast:GetWidth() - current_toast.icon:GetWidth() - 20)
+
+ current_toast.text:Show()
+ else
+ current_toast.text:Hide()
+ end
+ local button_height = (current_toast.primary_button or current_toast.secondary_button or current_toast.tertiary_button) and TOAST_BUTTON_HEIGHT or 0
+ current_toast:SetHeight(current_toast.text:GetStringHeight() + current_toast.title:GetStringHeight() + button_height + 25)
+
+ -----------------------------------------------------------------------
+ -- Anchor and spawn.
+ -----------------------------------------------------------------------
+ if #active_toasts > 0 then
+ current_toast:SetPoint(spawn_point, active_toasts[#active_toasts], SIBLING_ANCHORS[spawn_point], SIBLING_OFFSET_X[spawn_point], SIBLING_OFFSET_Y[spawn_point])
+ else
+ current_toast:SetPoint(spawn_point, UIParent, spawn_point, OFFSET_X[spawn_point], OFFSET_Y[spawn_point])
+ end
+ active_toasts[#active_toasts + 1] = current_toast
+ UIFrameFade(current_toast, fade_in_info)
+ return true
+end
+
+-----------------------------------------------------------------------
+-- Proxy methods.
+-----------------------------------------------------------------------
+local TOAST_URGENCIES = {
+ very_low = true,
+ moderate = true,
+ normal = true,
+ high = true,
+ emergency = true
+}
+
+function toast_proxy:SetUrgencyLevel(urgency)
+ urgency = lower(urgency:gsub(" ", "_"))
+
+ if not TOAST_URGENCIES[urgency] then
+ error(format('"%s" is not a valid toast urgency level', urgency), 2)
+ end
+ current_toast.urgency_level = urgency
+end
+
+function toast_proxy:UrgencyLevel()
+ return current_toast.urgency_level
+end
+
+function toast_proxy:SetTitle(title)
+ current_toast.title:SetText(title)
+end
+
+function toast_proxy:SetFormattedTitle(title, ...)
+ current_toast.title:SetFormattedText(title, ...)
+end
+
+function toast_proxy:SetText(text)
+ current_toast.text:SetText(text)
+end
+
+function toast_proxy:SetFormattedText(text, ...)
+ current_toast.text:SetFormattedText(text, ...)
+end
+
+function toast_proxy:SetIconTexture(texture)
+ current_toast.icon:SetTexture(texture)
+end
+
+local _initializedToastButton
+do
+ local BUTTON_NAME_FORMAT = "LibToast_Button%d"
+ local button_count = 0
+
+ local function _buttonCallbackHandler(button, mouse_button, is_down)
+ button.handler(button.id, mouse_button, is_down, button.toast.payload)
+ _reclaimToast(button.toast)
+ end
+
+ local function _acquireToastButton(toast)
+ local button = tremove(button_heap)
+
+ if not button then
+ button_count = button_count + 1
+
+ button = CreateFrame("Button", format(BUTTON_NAME_FORMAT, button_count), toast, "UIMenuButtonStretchTemplate")
+ button:SetHeight(TOAST_BUTTON_HEIGHT)
+ button:SetFrameStrata("DIALOG")
+ button:SetScript("OnClick", _buttonCallbackHandler)
+
+ local font_string = button:GetFontString()
+ font_string:SetJustifyH("CENTER")
+ font_string:SetJustifyV("CENTER")
+ end
+ button:SetParent(toast)
+ button:SetFrameLevel(toast:GetFrameLevel() + 2)
+ return button
+ end
+
+ function _initializedToastButton(button_id, label, handler)
+ if not label or not handler then
+ error("label and handler are required", 3)
+ return
+ end
+ local button = current_toast[button_id]
+
+ if not button then
+ button = _acquireToastButton(current_toast)
+ current_toast[button_id] = button
+ end
+ button.id = button_id:gsub("_button", "")
+ button.handler = handler
+ button.toast = current_toast
+
+ button:Show()
+ button:SetText(label)
+ button:SetWidth(button:GetFontString():GetStringWidth() + 15)
+
+ return button
+ end
+end -- do-block
+
+function toast_proxy:SetPrimaryCallback(label, handler)
+ local button = _initializedToastButton("primary_button", label, handler)
+ button:SetPoint("BOTTOMLEFT", current_toast, "BOTTOMLEFT", 3, 4)
+ button:SetPoint("BOTTOMRIGHT", current_toast, "BOTTOMRIGHT", -3, 4)
+
+ current_toast:SetHeight(current_toast:GetHeight() + button:GetHeight() + 5)
+
+ if button:GetWidth() > current_toast:GetWidth() then
+ current_toast:SetWidth(button:GetWidth() + 5)
+ end
+end
+
+function toast_proxy:SetSecondaryCallback(label, handler)
+ if not current_toast.primary_button then
+ error("primary button must be defined first", 2)
+ end
+ current_toast.primary_button:ClearAllPoints()
+ current_toast.primary_button:SetPoint("BOTTOMLEFT", current_toast, "BOTTOMLEFT", 3, 4)
+
+ local button = _initializedToastButton("secondary_button", label, handler)
+ button:SetPoint("BOTTOMRIGHT", current_toast, "BOTTOMRIGHT", -3, 4)
+
+ if button:GetWidth() + current_toast.primary_button:GetWidth() > current_toast:GetWidth() then
+ current_toast:SetWidth(button:GetWidth() + current_toast.primary_button:GetWidth() + 5)
+ end
+end
+
+function toast_proxy:SetTertiaryCallback(label, handler)
+ if not current_toast.primary_button or not current_toast.secondary_button then
+ error("primary and secondary buttons must be defined first", 2)
+ end
+ current_toast.secondary_button:ClearAllPoints()
+ current_toast.secondary_button:SetPoint("LEFT", current_toast.primary_button, "RIGHT", 0, 0)
+
+ local button = _initializedToastButton("tertiary_button", label, handler)
+ button:SetPoint("LEFT", current_toast.secondary_button, "RIGHT", 0, 0)
+
+ if button:GetWidth() + current_toast.primary_button:GetWidth() + current_toast.secondary_button:GetWidth() > current_toast:GetWidth() then
+ current_toast:SetWidth(button:GetWidth() + current_toast.primary_button:GetWidth() + current_toast.secondary_button:GetWidth() + 5)
+ end
+end
+
+function toast_proxy:SetPayload(...)
+ current_toast.payload = {...}
+end
+
+function toast_proxy:Payload()
+ return unpack(current_toast.payload)
+end
+
+function toast_proxy:MakePersistent()
+ current_toast.is_persistent = true
+end
diff --git a/Skada/Libs/SpecializedLibToast-1.0/closebutton-down.blp b/Skada/Libs/SpecializedLibToast-1.0/closebutton-down.blp
new file mode 100644
index 0000000..d817905
Binary files /dev/null and b/Skada/Libs/SpecializedLibToast-1.0/closebutton-down.blp differ
diff --git a/Skada/Libs/SpecializedLibToast-1.0/closebutton-highlight.blp b/Skada/Libs/SpecializedLibToast-1.0/closebutton-highlight.blp
new file mode 100644
index 0000000..011c672
Binary files /dev/null and b/Skada/Libs/SpecializedLibToast-1.0/closebutton-highlight.blp differ
diff --git a/Skada/Libs/SpecializedLibToast-1.0/closebutton-up.blp b/Skada/Libs/SpecializedLibToast-1.0/closebutton-up.blp
new file mode 100644
index 0000000..f98186c
Binary files /dev/null and b/Skada/Libs/SpecializedLibToast-1.0/closebutton-up.blp differ
diff --git a/Skada/Libs/TaintLess.xml b/Skada/Libs/TaintLess.xml
new file mode 100644
index 0000000..eb593e8
--- /dev/null
+++ b/Skada/Libs/TaintLess.xml
@@ -0,0 +1,63 @@
+
\ No newline at end of file
diff --git a/Skada/Locales/Load.xml b/Skada/Locales/Load.xml
new file mode 100644
index 0000000..6a3d269
--- /dev/null
+++ b/Skada/Locales/Load.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Skada/Locales/deDE.lua b/Skada/Locales/deDE.lua
new file mode 100644
index 0000000..f41706b
--- /dev/null
+++ b/Skada/Locales/deDE.lua
@@ -0,0 +1,755 @@
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "deDE")
+if not L then return end
+
+L["A damage meter."] = "Ein Damage-Meter."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "Die Speicherauslastung ist hoch. Du kannst Skada zur\195\188cksetzen und eine der Optionen zur automatischen Zur\195\188cksetzung aktivieren."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada ist nicht aktuell. Du kannst die neuste Version bei \124cffffbb00%s\124r herunterladen"
+L["Skada: Modes"] = "Skada: Modi"
+L["Skada: Fights"] = "Skada: K\195\164mpfe"
+L["Data Collection"] = "Datensammlung"
+L["ENABLED"] = "AKTIVIERT"
+L["DISABLED"] = "DEAKTIVIERT"
+L["Enable All"] = "Alle aktivieren"
+L["Disable All"] = "Alle deaktivieren"
+L["Stopping for wipe."] = "Stoppen wegen Wischen."
+L["Usage:"] = "Benutzen:"
+L["Commands:"] = "Befehle:"
+L["Import"] = "Importieren"
+L["Export"] = "Exportieren"
+L["Import/Export"] = "Importieren/Exportieren"
+-- profiles
+L["Profiles"] = "Profile"
+L["Profile Import/Export"] = "Profile Importieren/Exportieren"
+L["Import Profile"] = "Profil Importieren"
+L["Export Profile"] = "Profil Exportieren"
+L["Paste here a profile in text format."] = "F\195\188gen Sie hier ein Profil im Textformat ein."
+L["Press CTRL-V to paste the text from your clipboard."] = "Dr\195\188cke STRG-V um den Text aus Ihrer Zwischenablage einzuf\195\188gen."
+L["This is your current profile in text format."] = "Dies ist Dein aktuelles Profil im Textformat."
+L["Press CTRL-C to copy the text to your clipboard."] = "Dr\195\188cke STRG-C um die Text in die Zwischenablage zu kopieren."
+L["Network Sharing"] = "Netzwerkfreigabe"
+L["Player Name"] = "Name des Spielers"
+L["Send Profile"] = "Profil Senden"
+L["Accept profiles from other players."] = "Profile von anderen Spielern akzeptieren."
+L["opt_profile_received"] = "%s hat Dir eine Profil-Konfiguration gesendet. Willst Du das erhaltene Profil aktivieren?"
+L["Progress"] = "Fortschritt"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "Datengr\195\182\195\159e: \124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "Fortschritt der \195\156bertragung: %d%%"
+L["Transmission Completed"] = "\195\156bertragung Abgeschlossen"
+-- common lines
+L["Options"] = "Optionen"
+L["Options for %s."] = "Optionen von %s."
+L["General"] = "Allgemein"
+L["General options for %s."] = "Allgemeine Optionen von %s."
+L["Text"] = "Text"
+L["Text options for %s."] = "Textoptionen von %s."
+L["Format"] = "Format"
+L["Format options for %s."] = "Formatoptionen von %s."
+L["Appearance"] = "Aussehen"
+L["Appearance options for %s."] = "Darstellungsoptionen von %s."
+L["Advanced"] = "Erweitert"
+L["Advanced options for %s."] = "Erweiterte Optionen von %s."
+L["Position"] = "Position"
+L["Position settings for %s."] = "Positionseinstellungen von %s."
+L["Width"] = "Breite"
+L["The width of %s."] = "Die Breite von %s."
+L["Height"] = "H\195\182he"
+L["The height of %s."] = "Die H\195\182he von %s."
+L["Active Time"] = "Aktive Zeit"
+L["Segment Time"] = "Segmentzeit"
+L["Click for \124cff00ff00%s\124r"] = "Klick f\195\188r \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift-Klick f\195\188r \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Strg-Klick f\195\188r \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt-Klick f\195\188r \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "Nach Klasse filtern"
+L["Average"] = "Durchschnitt"
+L["Count"] = "Count"
+L["Refresh"] = "Aktualisieren"
+L["Percent"] = "Prozent"
+L["sPercent"] = "Prozent (unteransicht)"
+L["General Options"] = "Allgemeine Optionen"
+-- L["HoT"] = "HoT"
+-- L["DoT"] = "DoT"
+L["Hits"] = "Treffer"
+L["Normal Hits"] = "Normale Treffer"
+L["Critical"] = "Kritisch"
+L["Critical Hits"] = "Kritische Treffer"
+L["Crushing"] = "Schmetternd"
+L["Glancing"] = "Gestreift"
+L["ABSORB"] = "Absorbiert"
+L["BLOCK"] = "Blockiert"
+L["DEFLECT"] = "Abgewehrt"
+L["DODGE"] = "Ausgewichen"
+L["EVADE"] = "Entkommen"
+L["IMMUNE"] = "Immun"
+L["MISS"] = "Verfehlt"
+L["PARRY"] = "Pariert"
+L["REFLECT"] = "Reflektiert"
+L["RESIST"] = "Widerstanden"
+L["Only for bosses."] = "Only for boss fights."
+L["Enable this only against bosses."] = "Aktivieren Sie diese Option nur gegen Bosse."
+-- segment info
+L["Start"] = "Start"
+L["End"] = "Ende"
+-- windows section:
+L["Window"] = "Fenster"
+L["Windows"] = "Fenster"
+L["Create Window"] = "Fenster erstellen"
+L["Window Name"] = "Fenstername"
+L["Enter the name for the new window."] = "Gib den Namen f\195\188r das neue Fenster ein."
+L["Delete Window"] = "Fenster l\195\182schen"
+L["Choose the window to be deleted."] = "W\195\164hle das Fenster, welches gel\195\182scht werden soll."
+L["Are you sure you want to delete this window?"] = "M\195\182chten Sie dieses Fenster wirklich l\195\182schen?"
+L["Delete All Windows"] = "L\195\182schen Sie alle Fenster"
+L["Are you sure you want to delete all windows?"] = "M\195\182chten Sie wirklich alle Fenster l\195\182schen?"
+L["Rename Window"] = "Fenster umbenennen"
+L["Enter the name for the window."] = "Gib den Namen f\195\188r das Fenster ein."
+L["Test Mode"] = "Testmodus"
+L["Creates fake data to help you configure your windows."] = "Erstellt gef\195\164lschte Daten, um Ihnen bei der Konfiguration Ihrer Fenster zu helfen."
+L["Child Window"] = "Fenster sperren"
+L["A child window will replicate the parent window actions."] = "Ein untergeordnetes Fenster kopiert die \195\188bergeordneten Fensteraktionen. "
+L["Child Window Mode"] = "Kind Fenstermodus"
+L["Lock Window"] = "Sekund\195\164rfenster"
+L["Locks the bar window in place."] = "Sperrt das Fenster gegen unbeabsichtigtes Verschieben."
+L["Hide Window"] = "Fenster ausblenden"
+L["Hides the window."] = "Blendet das Fenster aus."
+L["Sticky Window"] = "Klebriges Fenster"
+L["Allows the window to stick to other Skada windows."] = "Erm\195\182glicht dem Fenster, an anderen Skada-Fenstern zu fangen. "
+L["Snap to best fit"] = "Auf beste Passform einrasten"
+L["Snaps the window size to best fit when resizing."] = "Passt die Fenstergr\195\182\195\159e an, damit sie beim \195\132ndern der Gr\195\182\195\159e am besten passt."
+L["Disable Resize Buttons"] = "Gr\195\182\195\159en\195\164nderungsschaltfl\195\164chen deaktivieren"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "Gr\195\182\195\159en\195\164nderungs und Sperr/Entsperr werden nicht angezeigt, wenn du mit der Maus \195\188ber das Fenster f\195\164hrst."
+L["Disable stretch button"] = "Ausweitungsschaltfläche deaktivieren"
+L["Stretch button won't show up when you hover over the window."] = "Die Streckschaltfl\195\164che wird nicht angezeigt, wenn Sie mit der Maus über das Fenster fahren."
+L["Reverse window stretch"] = "Umgekehrte Fensterstreckung"
+L["opt_botstretch_desc"] = "Platziert die Stretch-Schaltfl\195\164che am unteren Rand des Fensters und lässt letzteres nach unten strecken."
+L["Display System"] = "Anzeigesystem"
+L["Choose the system to be used for displaying data in this window."] = "W\195\164hle das System, das f\195\188r die Anzeige der Daten in diesem Fenster verwendet werden soll."
+L["Copy Settings"] = "Einstellungen kopieren"
+L["Choose the window from which you want to copy the settings."] = "W\195\164hlen Sie das Fenster, aus dem Sie die Einstellungen kopieren m\195\182chten. "
+-- bars
+L["Bars"] = "Leisten"
+L["Left Text"] = "Linker Text"
+L["Right Text"] = "Rechter Text"
+L["Font"] = "Schriftart"
+L["The font used by %s."] = "Die von %s verwendete Schriftart."
+L["Font Size"] = "Schriftgr\195\182\195\159e"
+L["The font size of %s."] = "Die Schriftgr\195\182\195\159e von %s."
+L["Font Outline"] = "Schriftumriss"
+L["Sets the font outline."] = "Legt den Schriftumriss fest."
+L["Outline"] = "Umrandung"
+L["Thick"] = "Dicke"
+L["Thick outline"] = "Dicke Umrandung"
+L["Monochrome"] = "Monochrom"
+L["Outlined monochrome"] = "Monochrome Umrandung"
+L["Bar Texture"] = "Leistentextur"
+L["The texture used by all bars."] = "Textur der Leisten."
+L["Spacing"] = "Abstand"
+L["Distance between %s."] = "Abstand zwischen %s."
+L["Displacement"] = "Verdr\195\164ngung"
+L["The distance between the edge of the window and the first bar."] = "Der Abstand zwischen dem Fensterrand und dem ersten Balken."
+L["Bar Orientation"] = "Leistenausrichtung"
+L["The direction the bars are drawn in."] = "Die Richtung in welche die Leisten erstellt werden."
+L["Left to right"] = "Links nach Rechts"
+L["Right to left"] = "Rechts nach Links"
+L["Reverse bar growth"] = "Umgekehrter Leistenanstieg"
+L["Bars will grow up instead of down."] = "Leisten wachsen nach oben, anstatt nach unten."
+L["Disable bar highlight"] = "Balkenhervorhebung deaktivieren"
+L["Hovering a bar won't make it brighter."] = "Aktiviert: Der Balken wird nicht heller, wenn der Mauszeiger dar\195\188berf\195\164hrt."
+L["Bar Color"] = "Leistenfarbe"
+L["Choose the default color of the bars."] = "W\195\164hle die Standard-Leistenfarbe aus."
+L["Background Color"] = "Hintergrundfarbe"
+L["The color of the background."] = "Die Farbe des Hintergrunds."
+L["Custom Color"] = "Benutzerdefinierte Farbe"
+L["Use a different color for my bar."] = "Verwenden Sie eine andere Farbe f\195\188r meinen Balken."
+L["My Color"] = "Meine farbe"
+L["Spell school colors"] = "Zauberartfarben"
+L["Use spell school colors where applicable."] = "Verwendet die Farben der Zauberart, falls anwendbar."
+L["When possible, bars will be colored according to player class."] = "Wenn m\195\182glich, werden die Leisten entsprechend der Klasse eingef\195\164rbt."
+L["When possible, bar text will be colored according to player class."] = "Wenn m\195\182glich, wird der Leistentext entsprechend der Klasse eingef\195\164rbt."
+L["Class Icons"] = "Klassensymbole"
+L["Use class icons where applicable."] = "Wenn m\195\182glich, wird ein Klassensymbol vor der Leiste angezeigt."
+L["Spec Icons"] = "Spezifikationssymbole"
+L["Use specialization icons where applicable."] = "Gegebenenfalls Spezialisierungssymbole verwenden."
+L["Role Icons"] = "Rollensymbole"
+L["Use role icons where applicable."] = "Rollensymbole verwenden, wenn dies m\195\182glich ist."
+L["Show Spark Effect"] = "Glanz Effekt anzeigen"
+L["Click Through"] = "Klicke hindurch"
+L["Disables mouse clicks on bars."] = "Deaktiviert Mausklicks auf Leisten."
+L["Smooth Bars"] = "Sanfte Leisten"
+L["Animate bar changes smoothly rather than immediately."] = "\195\132nderungen an Leisten werden sanft animiert anstatt sofort und sprunghaft dargestellt."
+-- title bar
+L["Title Bar"] = "Titelleiste"
+L["Enables the title bar."] = "Aktiviert die Titelleiste."
+L["Include set"] = "Segment anzeigen"
+L["Include set name in title bar"] = "Den Namen des Segments in der Titelleiste anzeigen"
+L["Encounter Timer"] = "Begegnungszeit"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "Aktiviert: Eine Stoppuhr wird links vom Text angezeigt."
+L["Mode Icon"] = "Modussymbol"
+L["Shows mode's icon in the title bar."] = "Zeigt das Symbol des Modus in der Titelleiste an."
+L["The texture used as the background of the title."] = "Die Hintergrundtextur der Titelleiste."
+L["Border texture"] = "Rahmentextur"
+L["The texture used for the borders."] = "Die f\195\188r die R\195\164nder verwendete Textur."
+L["Border Color"] = "Rahmenfarbe"
+L["The color used for the border."] = "Die f\195\188r den Rahmen verwendete Farbe."
+L["Buttons"] = "Buttons"
+L["Auto Hide Buttons"] = "Schaltfl\195\164chen automatisch verstecken"
+L["Show window buttons only if the cursor is over the title bar."] = "Fensterschaltfl\195\164chen nur anzeigen, wenn der Cursor \195\188ber der Titelleiste steht."
+L["Buttons Style"] = "Schaltfl\195\164chen-Stil"
+-- general window
+L["Background Texture"] = "Hintergrundtextur"
+L["The texture used as the background."] = "Die als Hintergrund verwendete Textur."
+L["Tile"] = "Kacheln"
+L["Tile the background texture."] = "Kachelt die Hintergrundtextur"
+L["Tile Size"] = "Kachelgr\195\182\195\159e"
+L["The size of the texture pattern."] = "Die Gr\195\182\195\159e der einzelnen Kacheln."
+L["Border"] = "Rahmen"
+L["Border Thickness"] = "Rahmenbreite"
+L["The thickness of the borders."] = "Die Breite der Rahmen."
+L["Border Insets"] = "Abstand der rahmen"
+L["The distance between the window and its border."] = "Der Abstand zwischen dem Fenster und seinem Rand."
+L["Scale"] = "Skalierung"
+L["Sets the scale of the window."] = "Legt die Skalierung des Fensters fest."
+L["Strata"] = "Schicht"
+L["This determines what other frames will be in front of the frame."] = "Dies bestimmt, welche anderen Rahmen vor dem Rahmen sein werden."
+L["Clamped To Screen"] = "Am Bildschirm fest machen"
+L["Toggle whether to permit movement out of screen."] = "ein-/ausschalten um das Fenster \195\188ber den Bildschirmrand hinaus zu bewegen"
+L["X Offset"] = "X-Versatz"
+L["Y Offset"] = "Y-Versatz"
+-- switching
+L["Mode Switching"] = "Moduswechsel"
+L["Combat Mode"] = "Kampfmodus"
+L["opt_combatmode_desc"] = "Bei Kampfbeginn automatisch auf das Segment des \124cffffbb00Momentaner Kampf\124r und den eingestellten Anzeigemodus wechseln."
+L["Wipe Mode"] = "Niederlagenanzeigemodus"
+L["opt_wipemode_desc"] = "Wechselt bei einer Niederlage automatisch auf das Segment des \124cffffbb00Momentaner Kampf\124r und den hier eingestellten Anzeigemodus ."
+L["Return after combat"] = "Zur\195\188ck nach Kampf"
+L["Return to the previous set and mode after combat ends."] = "Nach dem Kampf wieder zur vorherigen Ansicht wechseln."
+L["Auto switch to current"] = "Automatisch wechseln zu momentan"
+L["opt_autocurrent_desc"] = "Wenn ein Kampf beginnt, schaltet das Fenster automatisch zum \124cffffbb00Momentaner Kampf\124r."
+L["Auto Hide"] = "Automatisch Verbergen"
+L["While in combat"] = "Innerhalb eines Kampfes"
+L["While out of combat"] = "Au\195\159erhalb eines Kampfes"
+L["While not in a group"] = "Au\195\159erhalb einer Gruppe"
+L["While inside an instance"] = "Innerhalb einer Instanz"
+L["While not inside an instance"] = "Au\195\159erhalb einer Instanz"
+L["In Battlegrounds"] = "Einer Schlachtfelder"
+L["Inline Bar Display"] = "Einzeilige Leistenanzeige"
+L["mod_inline_desc"] = "Die einzeilige Anzeige ist ein horizontaler Fensterstil."
+L["Font Color"] = "Schriftfarbe"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "Schriftfarbe.\nKlicken Sie auf \"Klassenfarben\", um zu beginnen."
+L["opt_barwidth_desc"] = "Breite der Balken. Dies gilt nur, wenn die Option \"Feste Leistenbreite\" verwendet wird."
+L["Fixed bar width"] = "Feste Leistenbreite"
+L["opt_fixedbarwidth_desc"] = "Das Aktivieren dieser Option macht die Leistenbreite konstant. Andernfalls ist die Leistenbreite von der Textbreite abh\195\164ngig."
+L["Use class colors for %s."] = "Verwenden Sie Klassenfarben f\195\188r %s."
+L["opt_isusingclasscolors_desc"] = "Mit: %s - 5.71M (21.7K)\nOhne: %s - 5.71M (21.7K)"
+L["Put values on new line."] = "Setzen Sie Werte in eine neue Zeile."
+L["opt_isonnewline_desc"] = "Neue Zeile:\n%1$s\n5.71M (21.7K)\n\nTeiler:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = "Verwenden Sie ElvUI-Skin, falls verf\195\188gbar."
+L["opt_isusingelvuiskin_desc"] = "Aktivieren Sie diese Option, um stattdessen ElvUI-Skin zu verwenden.\nStandard: aktiviert"
+L["Use solid background."] = "Verwenden Sie soliden Hintergrund."
+L["Un-check this for an opaque background."] = "Deaktivieren Sie diese Option, um einen undurchsichtigen Hintergrund zu erhalten."
+L["Data Text"] = "Datentext"
+L["mod_broker_desc"] = "Der Datentext verh\195\164lt sich wie ein DataBroker-Plugin. Es kann in eine beliebige LDB-Anzeige wie Titan Panel, ChocolateBar, Bazooka etc. integriert werden. Skada kann diesen Datentext auch ohne ein solches, zus\195\164tzliches Addon anzeigen."
+-- L["Use frame"] = ""
+-- L["opt_useframe_desc"] = ""
+L["Text Color"] = "Schriftfarbe"
+L["The text color of %s."] = "Die Textfarbe von %s."
+L["Choose the default color."] = "W\195\164hle die Standardfarbe."
+L["Hint: Left-Click to set active mode."] = "Hinweis: Linksklick, um den aktiven Modus festzulegen."
+L["Right-Click to set active set."] = "Rechtsklick, um das aktive Segment festzulegen."
+L["Shift+Left-Click to open menu."] = "Shift-Linksklick, um das Optionsmen\195\188 zu \195\182ffnen."
+-- data resets
+L["Data Resets"] = "Daten zur\195\188cksetzen"
+L["Reset on entering instance"] = "Beim Betreten einer Instanz:"
+L["Controls if data is reset when you enter an instance."] = "Legt fest, ob die Daten zur\195\188ckgesetzt werden, wenn Du eine Instanz betrittst."
+L["Reset on joining a group"] = "Beim Beitritt in eine Gruppe:"
+L["Controls if data is reset when you join a group."] = "Legt fest, ob die Daten zur\195\188ckgesetzt werden, wenn Du einer Gruppe beitrittst."
+L["Reset on leaving a group"] = "Beim Verlassen einer Gruppe:"
+L["Controls if data is reset when you leave a group."] = "Legt fest, ob die Daten zur\195\188ckgesetzt werden, wenn Du eine Gruppe verl\195\164sst."
+L["Ask"] = "Abfragen"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "M\195\182chtest Du Skada zur\195\188cksetzen?\nHalten Sie SHIFT, um Reset alles."
+L["All data has been reset."] = "Alle Daten wurden zur\195\188ckgesetzt."
+L["There is no data to reset."] = "Keine Daten zum Zur\195\188cksetzen."
+L["Skip reset dialog"] = "Ignorieren Reset-Dialog"
+L["opt_skippopup_desc"] = "Aktivieren Sie diese Option, wenn Sie Skada m\195\182chten, ohne den Best\195\164tigungsdialog zur\195\188ckgesetzt."
+L["Are you sure you want to reinstall Skada?"] = "M\195\182chten Sie Skada wirklich neu installieren?"
+-- general options
+L["Show minimap button"] = "Minikartenbutton zeigen"
+L["Toggles showing the minimap button."] = "Zeigt oder versteckt den Minikartenbutton"
+L["Transliterate"] = "Transliterieren"
+L["Converts Cyrillic letters into Latin letters."] = "Wandelt kyrillische Buchstaben in lateinische Buchstaben um."
+L["Remove realm name"] = "Realmnamen entfernen"
+L["opt_realmless_desc"] = "Wenn aktiviert, werden Realmnamen von Charakteren ausgeblendet."
+L["Merge pets"] = "Begleiter zusammenf\195\188gen"
+L["Merges pets with their owners. Changing this only affects new data."] = "F\195\188gt Begleiter mit ihren Besitzern zusammen. Eine \195\132nderung wirkt sich hier nur auf neue Daten aus."
+L["Show totals"] = "Summen zeigen"
+L["Shows a extra row with a summary in certain modes."] = "Zeigt eine extra Zeile mit Zusammenfassungen in bestimmten Modi."
+L["Only keep boss fighs"] = "Nur Bossk\195\164mpfe"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "Nur Bossk\195\164mpfe werden gespeichert. Nicht-Bossk\195\164mpfe werden verworfen."
+L["Always save boss fights"] = "Bossk\195\164mpfe immer speichern"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "Bossk\195\164mpfe werden mit dieser Option gespeichert und sind vom Skada-Reset nicht betroffen."
+L["Hide when solo"] = "Verstecken, wenn Solo"
+L["Hides Skada's window when not in a party or raid."] = "Versteckt das Skada-Fenster, wenn Du in keiner Gruppe oder in keinem Schlachtzug bist."
+L["Hide in PvP"] = "Im PvP verstecken"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "Skada-Fenster in Schlachtfeldern/Arenen verstecken"
+L["Hide in combat"] = "Im Kampf verbergen"
+L["Hides Skada's window when in combat."] = "Das Skada-Fenster im Kampf verstecken."
+L["Show in combat"] = "Im Kampf zeigen"
+L["Shows Skada's window when in combat."] = "Zeigt Skada-Fenster im Kampf."
+L["Disable while hidden"] = "Deaktivieren wenn versteckt"
+L["Skada will not collect any data when automatically hidden."] = "Skada sammelt keine Daten, wenn automatisch versteckt."
+L["Sort modes by usage"] = "Modi nach Verwendung anordnen"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "Die Modusliste wird nach der Nutzung anstatt nach dem Alphabet angeordnet."
+L["Show rank numbers"] = "Platzierungen zeigen"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "Zeige relative Platzierungen f\195\188r Modis bei denen dies m\195\182glich ist."
+L["Aggressive combat detection"] = "Aggressive Kampferkennung"
+L["opt_tentativecombatstart_desc"] = [[Skada verwendet normalerweise ein sehr konservatives (simples) Kampferkennungsschema, welches am besten in Schlachtzügen funktioniert.
+Mithilfe dieser Option versucht Skada andere Damage-Meter zu emulieren.
+Sinnvoll für Dungeon-Runs, für Bosskämpfe bedeutungslos.]]
+L["Autostop"] = "Fr\195\188h Stoppen bei Wipe"
+L["opt_autostop_desc"] = "Stoppt automatisch das aktuelle Segment, nachdem die H\195\164lfte aller Schlachtzugsmitglieder gestorben sind."
+L["Always show self"] = "Mich immer anzeigen"
+L["opt_showself_desc"] = "Zeigt den Spieler immer im sichtbaren Bereich an, selbst wenn er eigentlich nicht sichtbar w\195\164re (nicht genug Platz)."
+L["Number format"] = "Zahlenformat"
+L["Controls the way large numbers are displayed."] = "Legt fest, wie gro\195\159e Zahlen angezeigt werden."
+L["Condensed"] = "Zusammengefasst"
+L["Detailed"] = "Detailliert"
+L["Combined"] = "Kombiniert"
+L["Comma"] = "Komma"
+L["Numeral system"] = "Zahlensystem"
+L["Select which numeral system to use."] = "W\195\164hle das zu benutzende Zahlensystem aus."
+L["Auto"] = "Automatik"
+L["Western"] = "Westlich"
+L["East Asia"] = "Ost-Asien"
+L["Brackets"] = "Einklammern"
+L["Choose which type of brackets to use."] = "W\195\164hlen Sie, welche Art von Klammern Sie verwenden m\195\182chten."
+L["Separator"] = "Trennzeichen"
+L["Choose which character is used to separator values between brackets."] = "W\195\164hlen Sie aus, welches Zeichen verwendet wird, um Werte zwischen Klammern zu trennen."
+L["Number of decimals"] = "Dezimalstellen"
+L["Controls the way percentages are displayed."] = "Steuert, wie Prozentsatz angezeigt werden."
+L["Data Feed"] = "Datenquelle"
+L["opt_feed_desc"] = "Ausw\195\164hlen welche Datensammlung in der DataBroker-Ansicht angezeigt werden soll. Dies erfordert ein LDB-Anzeige-Addon, wie zum Beispiel 'Titan Panel'."
+L["Time Measure"] = "Zeitmessung"
+L["Activity Time"] = "Aktivzeit"
+L["Effective Time"] = "Effektivzeit"
+L["opt_timemesure_desc"] = [=[|cffffff00Aktivität|r: Die Teilnehmer-Uhr stoppt, wenn er inaktiv ist, und läuft bei Aktivitäten weiter. Gewöhnliche Art zur Messung von DpS und HpS.
+|cffffff00Effektiv|r: gebräuchlich für Ranglisten. Diese Methode nutzt die Kampfzeit für DpS-/HpS-Messungen aller Schlachtzugteilnehmer.]=]
+L["Number set duplicates"] = "Anzahl der Duplikate"
+L["Append a count to set names with duplicate mob names."] = "F\195\188gt eine Anzahl hinzu, um Namen, mit doppelten Gegnernamen, festzulegen."
+L["Set Format"] = "Format setzen"
+L["Controls the way set names are displayed."] = "Bestimmt, wie Namen von Segmenten angezeigt werden."
+L["Links in reports"] = "Links in den Berichten"
+L["When possible, use links in the report messages."] = "Verwenden Sie nach M\195\182glichkeit Links in den Berichtsnachrichten."
+L["Segments to keep"] = "Zu behaltende Datensegmente"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "Die Anzahl der Kampfsegmente, die behalten werden sollen. St\195\164ndige Segmente sind hier nicht enthalten."
+L["Persistent segments"] = "Dauerhafte Segmente"
+L["The number of persistent fight segments to keep."] = "Die Anzahl der persistenten Segmente, die beibehalten werden sollen."
+L["Memory Check"] = "Speicherpr\195\188fung"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "Überpr\195\188ft die Speichernutzung und warnt Sie, wenn sie gr\195\182\195\159er oder gleich %d MB ist."
+L["Disable Comms"] = "Kommunikation deaktivieren"
+L["Minimum segment length"] = "Minimale Segmentl\195\164nge"
+L["The minimum length required in seconds for a segment to be saved."] = "Die erforderliche Mindestl\195\164nge in Sekunden, damit ein Segment gespeichert werden kann."
+L["Update frequency"] = "Aktualisierungsfrequenz"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "Wie oft die Fenster aktualisiert werden, k\195\188rzer f\195\188r schnellere Updates. Erh\195\182ht die CPU-Auslastung."
+-- columns
+L["Columns"] = "Spalten"
+-- tooltips
+L["Tooltips"] = "Tooltips"
+L["Show Tooltips"] = "Tooltips anzeigen"
+L["Shows tooltips with extra information in some modes."] = "Zeigt Tooltips mit zus\195\164tzlicher Information in einigen Modi."
+L["Informative Tooltips"] = "Informative Tooltips"
+L["Shows subview summaries in the tooltips."] = "Zeigt die Zusammenfassungen der Unteransichten in den Tooltips."
+L["Subview Rows"] = "Unteransicht Zeilen"
+L["The number of rows from each subview to show when using informative tooltips."] = "Die Anzahl der anzuzeigenden Zeilen von jeder Unteransicht, wenn mit informativen Tooltips gearbeitet wird."
+L["Tooltip Position"] = "Tooltip-Position"
+L["Position of the tooltips."] = "Position der QuickInfos."
+L["Top Right"] = "Oben rechts"
+L["Top Left"] = "Oben links"
+L["Bottom Right"] = "Unten rechts"
+L["Bottom Left"] = "Unten links"
+L["Smart"] = "Clever"
+L["Follow Cursor"] = "Follow Cursor"
+L["Top"] = "Oben"
+L["Bottom"] = "Unten"
+L["Right"] = "Rechts"
+L["Left"] = "Links"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00Ben\195\182tigt\124r: %s"
+L["Modules"] = "Module"
+L["Disabled Modules"] = "Deaktivierte Module"
+L["Modules Options"] = "Moduloptionen"
+L["Tick the modules you want to disable."] = "Hake die Module an, die du deaktivieren willst."
+L["This change requires a UI reload. Are you sure?"] = "Diese \195\132nderung erfordert ein Neuladen des UIs. Bist du sicher?"
+-- themes options
+L["Theme"] = "Oberfl\195\164che"
+L["Themes"] = "Oberfl\195\164chen"
+L["Manage Themes"] = "Oberfl\195\164chen verwalten"
+L["All Windows"] = "Alle Fenster"
+L["Apply Theme"] = "Übernimmt die Oberfl\195\164che"
+L["Theme applied!"] = "Oberfl\195\164che \195\188bernommen!"
+L["Name of your new theme."] = "Name deiner neuen Oberfl\195\164che"
+L["Save Theme"] = "Speichert die Oberfl\195\164che"
+L["Delete Theme"] = "L\195\182scht die Oberfl\195\164che"
+L["Are you sure you want to delete this theme?"] = "M\195\182chten Sie diesen Stil wirklich l\195\182schen?"
+L["Paste here a theme in text format."] = "F\195\188gen Sie hier ein oberfl\195\164che im Textformat ein."
+L["This is your current theme in text format."] = "Dies ist Dein aktuelles oberfl\195\164che im Textformat."
+-- scroll options
+L["Scroll"] = "Scroll"
+L["Wheel Speed"] = "Mausradgeschw."
+L["opt_wheelspeed_desc"] = "Legt die Anzahl der Scrollschritte f\195\188r das Mausrad fest."
+L["Scroll Icon"] = "Bildlaufsymbol"
+L["Scroll mouse button"] = "Scroll-Maustaste"
+-- minimap button
+L["Skada Summary"] = "Skada Zusammenfassung"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00Linksklick\124r zum umschalten des Skada-Fensters."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+Linksklick\124r zum Ein-/Ausblenden des Skada-Fensters."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+Linksklick\124r zum Zur\195\188cksetzen."
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00Rechtsklick\124r zum \195\150ffnen des Men\195\188s."
+-- skada menu
+L["Skada Menu"] = "Skada-Men\195\188"
+L["Select Segment"] = "Segment ausw\195\164hlen"
+L["Delete Segment"] = "Segment l\195\182schen"
+L["Keep Segment"] = "Segment behalten"
+L["Toggle Windows"] = "Fenster umschalten"
+L["Show/Hide Windows"] = "Fenster anzeigen/ausblenden"
+L["New Segment"] = "Neues Segment"
+L["Starts a new segment."] = "Beginnt ein neues Segment."
+L["New Phase"] = "Neue Phase"
+L["Starts a new phase."] = "Beginnt eine neue Phase."
+L["Select All"] = "W\195\164hlen Sie Alle"
+L["Deselect All"] = "Alle abw\195\164hlen"
+-- window buttons
+L["Configure"] = "Konfigurieren"
+L["Open Config"] = "Konfiguration \195\182ffnen"
+L["btn_config_desc"] = "\195\150ffnet das Konfigurationsfenster."
+L["btn_reset_desc"] = [[Setzt alle Kampfdaten zurück mit Ausnahme der markierten, sie werden beibehalten.
+|cff00ff00Shift Linksklick|r: Segment löschen.]]
+L["Segment"] = "Segment"
+L["btn_segment_desc"] = [[Wechseln zu einem bestimmten Segment.
+|cff00ff00Shift Linksklick|r für |cffffbb00Nächstes|r Segment.
+|cff00ff00Shift Rechtsklick|r für |cffffbb00Vorheriges|r Segment.
+|cff00ff00Mittelklick|r für |cffffbb00Aktuelles|r Segment.]]
+L["Mode"] = "Modus"
+L["Jump to a specific mode."] = "In einen bestimmten Modus springen."
+L["Report"] = "Bericht"
+L["btn_report_desc"] = [[Öffnet ein Dialogfeld, damit Sie Ihre Daten an andere auf verschiedene Weise mitteilen können.
+|cff00ff00Shift-Klick|r für Schnellbericht.]]
+L["Stop"] = "Stopp"
+L["btn_stop_desc"] = "Stoppt oder setzt das aktuelle Segment fort. N\195\188tzlich zur Diskontierung von Daten nach einem Wipe. Kann auch so eingestellt werden, dass in den Einstellungen automatisch gestoppt wird."
+L["Segment Stopped."] = "Segment angehalten."
+L["Segment Paused."] = "Segment pausiert."
+L["Segment Resumed."] = "Segment fortgesetzt."
+L["Quick Access"] = "Schneller Zugang"
+-- default segments
+L["Total"] = "Gesamt"
+L["Current"] = "Momentaner Kampf"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %s f\195\188r %s:"
+L["Self"] = "Lokal"
+L["Whisper Target"] = "Fl\195\188sterziel"
+L["Copy & Paste"] = "Kopieren & Einf\195\188gen"
+L["[General]"] = "Allgemein"
+L["[LocalDefense]"] = "LokaleVerteidigung"
+L["[LookingForGroup]"] = "SucheNachGruppe"
+L["[Trade]"] = "Handel"
+L["Line"] = "Zeile"
+L["Lines"] = "Zeilen"
+L["There is nothing to report."] = "Es gibt nichts zu berichten."
+L["No mode or segment selected for report."] = "Kein Modus oder Segment zum Berichten ausgew\195\164hlt."
+-- Bar Display Module --
+L["Bar Display"] = "Leistenanzeige"
+L["mod_bar_desc"] = "Leistenanzeige ist das normale Leistenfenster, diese Anzeigeart wird von den meisten Schadensmetern verwendet. Sie kann optisch stark ver\195\164ndert werden."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "Leistenanzeige (alt)"
+L["Max Bars"] = "Max. Leisten"
+L["The maximum number of bars shown."] = "Die maximale Anzahl an angezeigten Leisten."
+L["Show Menu Button"] = "Zeige Men\195\188knopf"
+L["Shows a button for opening the menu in the window title bar."] = "Zeigt einen Knopf in der Titelleiste f\195\188r das Men\195\188."
+L["Class Color Bars"] = "Klassen farbige Leisten"
+L["Class Color Text"] = "Klassen farbiger Text"
+-- Threat Module --
+L["Threat"] = "Bedrohung"
+L["Threat Warning"] = "Threat Warning"
+L["Flash Screen"] = "Aufblitzen"
+L["This will cause the screen to flash as a threat warning."] = "L\195\164sst den Bildschirm aufblitzen als Aggrowarnung."
+L["Shake Screen"] = "Beben"
+L["This will cause the screen to shake as a threat warning."] = "L\195\164sst den Bildschirm beben als Aggrowarnung."
+L["Warning Message"] = "Warnmeldungen"
+L["Print a message to screen when you accumulate too much threat."] = "Zeigt eine Meldung auf dem Bildschirm wenn Ihr zu viel Bedrohung erzeugt."
+L["Play sound"] = "Sound"
+L["This will play a sound as a threat warning."] = "Spielt einen Sound als Aggrowarnung."
+L["Message Output"] = "Ausgabe"
+L["Choose where warning messages should be displayed."] = "W\195\164hlen Sie aus, wo Warnmeldungen angezeigt werden sollen."
+L["Chat Frame"] = "Im Chat"
+L["Blizzard Error Frame"] = "Blizzard's Fehler Fenster"
+L["Threat sound"] = "Bedrohungssound"
+L["opt_threat_soundfile_desc"] = "Der Sound, der gespielt wird, wenn die Bedrohung einen gewissen Wert erreicht."
+L["Warning Frequency"] = "Warnh\195\164ufigkeit"
+L["Threat Threshold"] = "Bedrohungsgrenzwert"
+L["opt_threat_threshold_desc"] = "Wenn die eigene Bedrohung gegen\195\188ber dem Tank diesen Wert erreicht, werden Warnungen angezeigt."
+L["Show raw threat"] = "Nettobedrohung"
+L["opt_threat_rawvalue_desc"] = "Zeigt Bedrohungsanteil im Vergleich zum Tank und nicht nach Entfernung."
+L["Use focus target"] = "Fokusziel benutzen"
+L["opt_threat_focustarget_desc"] = "L\195\164sst Skada zus\195\164tzlich den Fokus und das Fokusziel vor dem Ziel, und dem Ziel des Ziels f\195\188r die Bedrohungsanzeige \195\188berpr\195\188fen"
+L["Disable while tanking"] = "Beim Tanken deaktivieren"
+L["opt_threat_notankwarnings_desc"] = "Gibt keine Warnmeldungen aus wenn Verteidigungshaltung, B\195\164rengestalt, Zorn der Gerechtigkeit oder Frost Pr\195\164senz aktiv sind."
+L["Ignore Pets"] = "Haustiere ignorieren"
+L["opt_threat_ignorepets_desc"] = [=[Veranlasst Skada gegnerische Spielerbegleiter ausser acht zu lassen wenn bestimmt wird auf welche Einheit Bedrohung angezeigt werden soll.
+
+Spielerbegleiter haben nur eine Bedrohungsliste wenn sie sich im |cffffff78Aggressiven|r oder |cffffff78Defensiven|r Modus befinden und sich somit wie normale Mobs verhalten, also das Ziel mit der größten Bedrohung angreiffen. Wird der Beleiter dazu veranlasst, eine bestimntes Ziel anzugreiffen, behält der Begleiter eine Bedrohungstabelle, aber bleibt bei dem festgelegten Ziel, welches per Definition 100% Bedrohung hat. Spielerbegleiter können abgespottet werden um sie zu zwingen Sie anzugreiffen.
+
+Spielerbegleiter im |cffffff78Passiven|r Modus haben auf jeden Fall keine Bedrohungstabelle und Spott funktioniert bei ihnen nicht. Sie greiffen das ausgewählte Ziel nur auf Befehl an und das ohne Bedrohungstabelle.
+
+Wenn ein Spielerbegleiter dazu aufgefordert wird, zu |cffffff78Folgen|r, wird die Bedrohungstabelle gelöscht und es hört auf anzugreiffen, dennoch kann es sofort wieder ein neues Ziel aufnehmen, wenn wieder in den Aggressiven/Defensiven Modus gewechselt wird.]=]
+L["> Pull Aggro <"] = "> Aggro ziehen <"
+L["Show Pull Aggro Bar"] = "\"Aggro ziehen\" Leiste anzeigen"
+L["opt_threat_showaggrobar_desc"] = "Zeigt eine Leiste mit dem Wert an Bedrohung der ben\195\182tigt wird um Aggro zu ziehen."
+L["Test Warnings"] = "Testwarnung"
+L["TPS"] = "TPS"
+L["Threat: Personal Threat"] = "Bedrohung: Pers\195\182nliche Bedrohung"
+-- Absorbs & Healing Module --
+L["Healing"] = "Heilung"
+L["Healing Done"] = "Gewirkte Heilung"
+L["Healing Taken"] = "Erhaltene Heilung"
+L["HPS"] = "HPS"
+L["sHPS"] = "HPS (unteransicht)"
+L["Healing: Personal HPS"] = "Heilung: Pers\195\182nliche HPS"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "Heilung: Raid-HPS"
+L["Total Healing"] = "Gesamte Heilung"
+L["Overheal"] = "Überheilen"
+L["Overhealing"] = "Überheilung"
+L["Absorbs"] = "Absorptionen"
+L["Target List"] = "Zielliste"
+L["Spell List"] = "Zauberliste"
+L["APS"] = "APS"
+L["sAPS"] = "APS (unteransicht)"
+L["Absorbs and Healing"] = "Absorptionen und Heilungen"
+L["Healing Done By Spell"] = "Heilung durch Zauber"
+L["Source List"] = "Quellenliste"
+-- Auras Module --
+L["Uptime"] = "Uptime"
+L["Buffs and Debuffs"] = "Buffs and Debuffs"
+L["Buffs"] = "Buffs"
+L["Debuffs"] = "Debuffs"
+L["%s's <%s> targets"] = "%s <%s> Ziele"
+L["%s's <%s> sources"] = "%s <%s> Quellen"
+L["Enemy Buffs"] = "Feindliche Buffs"
+L["Enemy Debuffs"] = "Feindliche Debuffs"
+-- CC Tracker Module --
+L["Crowd Control"] = "Massenkontrolle"
+L["CC Done"] = "Verursachte Massenkontrolle"
+L["CC Taken"] = "Erhaltene Massenkontrolle"
+L["CC Breaks"] = "Entfernte Massenkontrolle"
+L["Ignore Main Tanks"] = "Haupttanks ignorieren"
+L["%s on %s removed by %s"] = "%s auf %s entfernt von %s"
+L["%s on %s removed by %s's %s"] = "%s auf %s entfernt durch %s's %s"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "Umgebung"
+-- damage done module
+L["Damage"] = "Schaden"
+L["Spell Details"] = "Zauberdetails"
+L["Damage Done"] = "Schaden verursacht"
+L["Useful Damage"] = "N\195\188tzlicher Schaden"
+L["Useful damage on %s"] = "N\195\188tzlicher Schaden an %s"
+L["Damage Done By Spell"] = "Durch Zauber verursachter Schaden"
+L["%s's sources"] = "%s Quellen"
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (unteransicht)"
+L["Damage: Personal DPS"] = "Schaden: Pers\195\182nliche DPS"
+L["RDPS"] = "RDPS"
+L["Damage: Raid DPS"] = "Schaden: Raid-DPS"
+L["Absorbed Damage"] = "Absorbierter Schaden"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "Aktivieren Sie diese Option, wenn der verursachte Schaden den absorbierten Schaden einschlie\195\159en soll."
+L["Damage Done By School"] = "Schaden durch die Schule"
+-- killing blows module
+L["Only PvP Kills"] = "Nur PvP-Kills"
+L["When enabled, only kills against enemy players count."] = "Wenn aktiviert, z\195\164hlen nur Kills gegen feindliche Spieler."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "K\195\188ndigen Sie t\195\182dliche Schl\195\164ge nach Kampfende an. Funktioniert nur f\195\188r Bossk\195\164mpfe."
+-- damage taken module
+L["Damage Taken"] = "Schaden erhalten"
+L["Damage Taken By Spell"] = "Schaden erhalten durch Zauber"
+L["%s's targets"] = "%s Ziele"
+L["DTPS"] = "DTPS"
+L["sDTPS"] = "DTPS (unteransicht)"
+-- enemy damage done module
+L["Enemies"] = "Gegner"
+L["Enemy Damage Done"] = "Gegnerischer Schaden"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "Gegnerischer Schaden erhalten"
+L["%s below %s%%"] = "%s unter %s%%"
+L["%s - %s%% to %s%%"] = "%s - %s%% bis %s%%"
+L["Phase %s"] = "Phase %s"
+L["%s - Phase %s"] = "%s - Phase %s"
+L["%s - Phase 1"] = "%s - Phase 1"
+L["%s - Phase 2"] = "%s - Phase 2"
+L["%s - Phase 3"] = "%s - Phase 3"
+L["%s (Main Boss)"] = "%s (Hauptboss)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r gestartet."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r gestoppt."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r fortgesetzt."
+-- enemy healing done module
+L["Enemy Healing Done"] = "Gegnerische Gewirkte Heilung"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "Vermeidung & Minderung"
+L["More Details"] = "Mehr Details"
+L["%s's details"] = "Details von %s"
+-- friendly fire module
+L["Friendly Fire"] = "Friendly Fire"
+-- useful damage targets
+L["Important targets"] = "Wichtige Feinde"
+L["Oozes"] = "Schlamm"
+L["Princes overkilling"] = "Prinzen overkilling"
+-- L["Adds"] = ""
+L["Halion and Inferno"] = "Halion und Inferno"
+L["Valkyrs overkilling"] = "Walk\195\188ren overkilling"
+-- Deaths Module --
+L["%s's deaths"] = "%s : Tode"
+L["Death log"] = "Todesaufzeichnung"
+L["%s's death log"] = "%s Todesprotokoll"
+L["Player's deaths"] = "Tod des Spielers"
+L["%s dies"] = "%s stirbt"
+L["buff"] = "buff"
+L["debuff"] = "debuff"
+L["Spell details"] = "Zauberdetails"
+L["Spell"] = "Zauber"
+L["Amount"] = "Betrag"
+L["Source"] = "Quelle"
+L["Change"] = "\195\132nderung"
+L["Time"] = "Zeit"
+L["Survivability"] = "\195\156berleben"
+L["Events Amount"] = "Ereignisbetrag"
+L["Set the amount of events the death log should record."] = "Stellen Sie die Menge der Ereignisse sollte der Tod Protokoll aufzeichnen."
+L["Minimum Healing"] = "Minimale Heilung"
+L["Ignore heal events that are below this threshold."] = "Ignorieren Ereignisse heilen, die unterhalb dieser Schwelle sind."
+L["Announce Deaths"] = "Todesf\195\164lle bekannt geben"
+L["Announces information about the last hit the player took before they died."] = "Gibt den letzten Treffer der Person an, bevor sie starb."
+L["Alternative Display"] = "Alternative Darstellung"
+L["If a player dies multiple times, each death will be displayed as an independent bar."] = "Wenn ein Spieler mehrmals stirbt, wird jeder Tod als separater Balken angezeigt."
+-- activity module
+L["Activity"] = "Aktivit\195\164t"
+L["Activity per Target"] = "Aktivit\195\164t pro Ziel"
+L["%s's activity"] = "Aktivit\195\164t von %s"
+-- dispels module lines --
+L["Dispel Spells"] = "Zauberliste Zerstreuen"
+L["%s's dispelled spells"] = "%s zerstreute Zauber"
+-- interrupts module lines --
+L["Interrupt Spells"] = "Zauber unterbrechen"
+L["%s's interrupted spells"] = "%s unterbrochene Zauber"
+L["%s interrupted!"] = "%s unterbrochen!"
+-- Power gained module --
+L["Resources"] = "Ressourcen"
+L["Mana Restored"] = "Wiederhergestelltes Mana"
+L["Rage Generated"] = "Erzeugte Wut"
+L["Energy Generated"] = "Erzeugte Energie"
+L["Runic Power Generated"] = "Erzeugte Runenmacht"
+-- Parry module lines --
+L["Parry-Haste"] = "Parieren"
+L["%s parried %s (%s)"] = "%s parierte %s (%s)"
+-- Potions module lines --
+L["Potions"] = "Tr\195\164nke"
+L["%s's potions"] = "%s Zaubertr\195\164nke"
+L["Pre-potion"] = "Pre-potion"
+L["pre-potion: %s"] = "pre-potion: %s"
+L["Prints pre-potion after the end of the combat."] = "Druckt Pre-Trank nach dem Ende des Kampfes."
+-- healthstone --
+L["Healthstones"] = "Gesundheitsstein"
+-- resurrect module lines --
+L["Resurrects"] = "Resurrects"
+-- nickname module lines --
+L["Nickname"] = "Spitzname"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "Spitznamen werden an Gildenmitglieder gesendet und von Skada anstelle deines Charakternamens angezeigt."
+L["Set a nickname for you."] = "Lege deinen Spitznamen fest."
+L["Nickname isn't a valid string."] = "Spitzname ist keine g\195\188ltige Zeichenfolge. "
+L["Your nickname is too long, max of 12 characters is allowed."] = "Dein Spitzname ist zu lang, maximal 12 Zeichen sind erlaubt."
+L["Only letters and two spaces are allowed."] = "Es sind nur Buchstaben und zwei Leerzeichen zul\195\164ssig."
+L["Your nickname contains a forbidden word."] = "Ihr Spitzname enth\195\164lt ein verbotenes Wort."
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "Sie k\195\182nnen denselben Buchstaben nicht dreimal hintereinander, zwei Leerzeichen hintereinander oder mehr als zwei Leerzeichen verwenden."
+L["Ignore Nicknames"] = "Spitznamen ignorieren"
+L["When enabled, nicknames set by Skada users are ignored."] = "Wenn diese Option aktiviert ist, werden von Skada-Benutzern festgelegte Spitznamen ignoriert."
+L["Name display"] = "Namensanzeige"
+L["Choose how names are shown on your bars."] = "W\195\164hlen Sie aus, wie Namen in Ihren Balken angezeigt werden."
+L["Clear Cache"] = "Cache leeren"
+L["Are you sure you want clear cached nicknames?"] = "M\195\182chten Sie zwischengespeicherte Spitznamen wirklich l\195\182schen?"
+-- overkill module lines --
+L["Overkill"] = "Overkill"
+-- tweaks module lines --
+L["Improvement"] = "Verbesserung"
+L["Tweaks"] = "Tweaks"
+L["First hit"] = "Erster Treffer"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00Erster Treffer\124r: %s von %s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00Erster Treffer\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00Boss erstes Ziel\124r: %s"
+L["opt_tweaks_firsthit_desc"] = "Druckt eine Nachricht von dem ersten Treffer vor dem Kampf. \nNur f\195\188r Bossk\195\164mpfe funktioniert."
+L["Filter DPS meters Spam"] = "DPS-Meter Spam filtern"
+L["opt_tweaks_spamage_desc"] = "Unterdr\195\188ckt Chat-Nachrichten von Schadensmessern und stellt Statistiken zu einzelnen Chat-Link-Sch\195\164den in einem Popup bereit."
+L["Reported by: %s"] = "Von: %s"
+L["Smart Stop"] = "Smart Stop"
+L["opt_tweaks_smarthalt_desc"] = "Stoppt automatisch das aktuelle Segment, nachdem der Boss gestorben ist.\nN\195\188tzlich, um die Datenerfassung im Falle eines Kampffehlers zu vermeiden."
+L["Duration"] = "Dauer"
+L["opt_tweaks_smartwait_desc"] = "Wie lange Skada warten soll, bevor die Strecke gestoppt wird."
+L["Modes Icons"] = "Modussymbole"
+L["Show modes icons on bars and menus."] = "Modussymbole in Balken und Men\195\188s anzeigen."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "Aktivieren Sie dies, wenn Sie \124cffffbb00%s\124r ignorieren m\195\182chten."
+L["Custom Colors"] = "Farben \195\164ndern"
+L["Arena Teams"] = "Arenateams"
+L["Are you sure you want to reset all colors?"] = "M\195\182chten Sie wirklich alle Farben zur\195\188cksetzen?"
+L["Announce %s"] = "Announce: %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "Gibt an, wie lange es gedauert hat, %d Stapel von %s anzuwenden, und k\195\188ndigt an, wann es abl\195\164uft."
+L["%s dropped from %s!"] = "%s ist am %s abgelaufen!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%s Stapel von %s auf %s in %s sec angewandt!"
+L["My Spells"] = "Meine Zauber"
+-- total data options
+L["Total Segment"] = "Gesamtes Segment" -- needs review
+L["All Segments"] = "Alle Segmente" -- needs review
+L["Raid Bosses"] = "Raid-Bosse" -- needs review
+L["Raid Trash"] = "Schlachtzug-M\195\188ll" -- needs review
+L["Dungeon Bosses"] = "Dungeon-Bosse" -- needs review
+L["Dungeon Trash"] = "Dungeon-M\195\188ll" -- needs review
+L["opt_tweaks_total_all_desc"] = "Alle Segmente werden zu den Daten des Gesamtsegments hinzugef\195\188gt." -- needs review
+L["opt_tweaks_total_fmt_desc"] = "Segmente mit %s werden zu den Daten des Gesamtsegments hinzugef\195\188gt." -- needs review
+L["Detailed total segment"] = "Detailliertes Gesamtsegment"
+-- L["opt_tweaks_total_full_desc"] = "When enabled, Skada will record everything to the total segment, instead of total numbers (record spell details, their targets as their sources)."
+-- arena
+L["mod_pvp_desc"] = "F\195\188gen Sie eine Spezialisierungserkennung f\195\188r Arenen und Schlachtfelder hinzu und zeigen Sie Arenagegner im selben Fenster an."
+L["Gold Team"] = "Goldenes Team"
+L["Green Team"] = "Gr\195\188nes Team"
+L["Color for %s."] = "Farbe f\195\188r %s."
+-- notifications
+L["Notifications"] = "Benachrichtigungen"
+L["opt_toast_desc"] = "Verwendet visuelle Benachrichtigungen anstelle von Chatfenster-Nachrichten, wann immer zutreffend."
+L["Test Notifications"] = "Benachrichtigungen testen"
+-- comparison module
+L["Comparison"] = "Vergleich"
+L["%s vs %s: %s"] = "%s vs. %s: %s"
+L["%s vs %s: Spells"] = "%s vs. %s: Zauber"
+L["%s vs %s: Targets"] = "%s vs. %s: Ziele"
+-- spellcast module
+L["Casts"] = "Wirkungen"
+L["%s's spells"] = "%s Zauber"
+L["%s's spells on %s"] = "%s Zauber auf %s"
+L["Spells on %s"] = "Zauber auf %s"
+-- about
+L["Author"] = "Autor"
+L["Credits"] = "Credits"
+L["Date"] = "Datum"
+L["License"] = "Lizenz"
+L["Version"] = "Version"
+L["Website"] = "Webseite"
+-- some bosses entries
+L["World Boss"] = "Weltboss"
+L["Auriaya"] = "Auriaya"
+L["Blood Prince Council"] = "Rat der Blutprinzen"
+L["Faction Champions"] = "Fraktionschampions"
+L["Hogger"] = "Hogger"
+L["Icecrown Gunship Battle"] = "Luftschiffkampf um die Eiskronenzitadelle"
+L["Kologarn"] = "Kologarn"
+L["Mimiron"] = "Mimiron"
+L["Thaddius"] = "Thaddius"
+L["The Four Horsemen"] = "Die Vier Reiter"
+L["The Iron Council"] = "Versammlung des Eisens"
+L["The Northrend Beasts"] = "Die Bestien von Nordend"
+L["Thorim"] = "Thorim"
+L["Twin Val'kyr"] = "Zwillingsval'kyr"
+L["Valithria Dreamwalker"] = "Valithria Traumwandler"
+L["Yogg-Saron"] = "Yogg-Saron"
diff --git a/Skada/Locales/enUS.lua b/Skada/Locales/enUS.lua
new file mode 100644
index 0000000..efed6cc
--- /dev/null
+++ b/Skada/Locales/enUS.lua
@@ -0,0 +1,834 @@
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "enUS", true)
+if not L then return end
+
+L["A damage meter."] = true
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = true
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = true
+L["Skada: Modes"] = true
+L["Skada: Fights"] = true
+L["Data Collection"] = true
+L["Enable"] = _G.ENABLE
+L["ENABLED"] = true
+L["Disable"] = _G.DISABLE
+L["DISABLED"] = true
+L["Enable All"] = true
+L["Disable All"] = true
+L["Stopping for wipe."] = true
+L["Usage:"] = true
+L["Commands:"] = true
+L["Import"] = true
+L["Export"] = true
+L["Import/Export"] = true
+L["Pets"] = _G.PETS or "Pets"
+-- profiles
+L["Profiles"] = true
+L["Profile Import/Export"] = true
+L["Import Profile"] = true
+L["Export Profile"] = true
+L["Paste here a profile in text format."] = true
+L["Press CTRL-V to paste the text from your clipboard."] = true
+L["This is your current profile in text format."] = true
+L["Press CTRL-C to copy the text to your clipboard."] = true
+L["Network Sharing"] = true
+L["Player Name"] = true
+L["Send Profile"] = true
+L["Accept profiles from other players."] = true
+L["opt_profile_received"] = "%s has sent you a profile configuration. Do you want to activate received profile?"
+L["Progress"] = true
+L["Data Size: \124cffffffff%.1f\124rKB"] = true
+L["Transmision Progress: %02.f%%"] = true
+L["Transmission Completed"] = true
+-- common lines
+L["ERROR"] = _G.ERROR_CAPS
+L["Yes"] = _G.YES
+L["No"] = _G.NO
+L["None"] = _G.NONE
+L["All"] = _G.ALL
+L["Options"] = true
+L["Options for %s."] = true
+L["General"] = true
+L["General options for %s."] = true
+L["Text"] = true
+L["Text options for %s."] = true
+L["Format"] = true
+L["Format options for %s."] = true
+L["Appearance"] = true
+L["Appearance options for %s."] = true
+L["Advanced"] = true
+L["Advanced options for %s."] = true
+L["Position"] = true
+L["Position settings for %s."] = true
+L["Width"] = true
+L["The width of %s."] = true
+L["Height"] = true
+L["The height of %s."] = true
+L["Active Time"] = true
+L["Segment Time"] = true
+L["Click for \124cff00ff00%s\124r"] = true
+L["Shift-Click for \124cff00ff00%s\124r"] = true
+L["Control-Click for \124cff00ff00%s\124r"] = true
+L["Alt-Click for \124cff00ff00%s\124r"] = true
+L["Toggle Class Filter"] = true
+L["Average"] = true
+L["Minimum"] = _G.MINIMUM
+L["Maximum"] = _G.MAXIMUM
+L["Count"] = true
+L["Refresh"] = true
+L["Percent"] = true
+L["sPercent"] = "Percent (subviews)"
+L["General Options"] = true
+L["HoT"] = true
+L["DoT"] = true
+L["Hits"] = true
+L["Normal Hits"] = true
+L["Crit"] = _G.CRIT_ABBR
+L["Critical"] = true
+L["Critical Hits"] = true
+L["Crushing"] = true
+L["Glancing"] = true
+L["ABSORB"] = "Absorbed"
+L["BLOCK"] = "Blocked"
+L["DEFLECT"] = "Deflect"
+L["DODGE"] = "Dodge"
+L["EVADE"] = "Evade"
+L["IMMUNE"] = "Immune"
+L["MISS"] = "Miss"
+L["PARRY"] = "Parry"
+L["REFLECT"] = "Reflect"
+L["RESIST"] = "Resisted"
+L["Only for bosses."] = true
+L["Enable this only against bosses."] = true
+L["Melee"] = _G.MELEE
+L["Unknown"] = _G.UNKNOWN
+L["Other"] = _G.OTHER
+L["Category"] = _G.CATEGORY
+L["Categories"] = _G.CATEGORIES
+-- segment info
+L["Type"] = _G.TYPE
+L["Arena"] = _G.ARENA
+L["Battleground"] = _G.BATTLEGROUND
+L["Group"] = _G.GROUP
+L["Dungeon"] = _G.LFG_TYPE_DUNGEON
+L["Raid"] = _G.LFG_TYPE_RAID
+L["Zone"] = _G.ZONE
+L["Start"] = true
+L["End"] = true
+-- windows section:
+L["Window"] = true
+L["Windows"] = true
+L["Create Window"] = true
+L["Window Name"] = true
+L["Accept"] = _G.ACCEPT
+L["Cancel"] = _G.CANCEL
+L["Close"] = _G.CLOSE
+L["Create"] = _G.CALENDAR_CREATE
+L["Enter the name for the new window."] = true
+L["Delete Window"] = true
+L["Choose the window to be deleted."] = true
+L["Are you sure you want to delete this window?"] = true
+L["Delete All Windows"] = true
+L["Are you sure you want to delete all windows?"] = true
+L["Rename Window"] = true
+L["Enter the name for the window."] = true
+L["Test Mode"] = true
+L["Creates fake data to help you configure your windows."] = true
+L["Child Window"] = true
+L["A child window will replicate the parent window actions."] = true
+L["Child Window Mode"] = true
+L["Lock Window"] = true
+L["Locks the bar window in place."] = true
+L["Hide Window"] = true
+L["Hides the window."] = true
+L["Sticky Window"] = true
+L["Allows the window to stick to other Skada windows."] = true
+L["Snap to best fit"] = true
+L["Snaps the window size to best fit when resizing."] = true
+L["Disable Resize Buttons"] = true
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = true
+L["Disable stretch button"] = true
+L["Stretch button won't show up when you hover over the window."] = true
+L["Reverse window stretch"] = true
+L["opt_botstretch_desc"] = "Places the stretch button at the bottom of the window and makes the latter stretch downwards."
+L["Display System"] = true
+L["Choose the system to be used for displaying data in this window."] = true
+L["Copy Settings"] = true
+L["Choose the window from which you want to copy the settings."] = true
+-- bars
+L["Bars"] = true
+L["Left Text"] = true
+L["Right Text"] = true
+L["Font"] = true
+L["The font used by %s."] = true
+L["Font Size"] = true
+L["The font size of %s."] = true
+L["Font Outline"] = true
+L["Sets the font outline."] = true
+L["Thick"] = true
+L["Thick outline"] = true
+L["Monochrome"] = true
+L["Outlined monochrome"] = true
+L["Bar Texture"] = true
+L["The texture used by all bars."] = true
+L["Spacing"] = true
+L["Distance between %s."] = true
+L["Displacement"] = true
+L["The distance between the edge of the window and the first bar."] = true
+L["Bar Orientation"] = true
+L["The direction the bars are drawn in."] = true
+L["Left to right"] = true
+L["Right to left"] = true
+L["Reverse bar growth"] = true
+L["Bars will grow up instead of down."] = true
+L["Disable bar highlight"] = true
+L["Hovering a bar won't make it brighter."] = true
+L["Bar Color"] = true
+L["Choose the default color of the bars."] = true
+L["Background Color"] = true
+L["The color of the background."] = true
+L["Custom Color"] = true
+L["Use a different color for my bar."] = true
+L["My Color"] = true
+L["Spell school colors"] = true
+L["Use spell school colors where applicable."] = true
+L["When possible, bars will be colored according to player class."] = true
+L["When possible, bar text will be colored according to player class."] = true
+L["Class Icons"] = true
+L["Use class icons where applicable."] = true
+L["Spec Icons"] = true
+L["Use specialization icons where applicable."] = true
+L["Role Icons"] = true
+L["Use role icons where applicable."] = true
+L["Show Spark Effect"] = true
+L["Click Through"] = true
+L["Disables mouse clicks on bars."] = true
+L["Smooth Bars"] = true
+L["Animate bar changes smoothly rather than immediately."] = true
+-- title bar
+L["Title Bar"] = true
+L["Enables the title bar."] = true
+L["Include set"] = true
+L["Include set name in title bar"] = true
+L["Encounter Timer"] = true
+L["When enabled, a stopwatch is shown on the left side of the text."] = true
+L["Mode Icon"] = true
+L["Shows mode's icon in the title bar."] = true
+L["The texture used as the background of the title."] = true
+L["Border texture"] = true
+L["The texture used for the borders."] = true
+L["Border Color"] = true
+L["The color used for the border."] = true
+L["Buttons"] = true
+L["Auto Hide Buttons"] = true
+L["Show window buttons only if the cursor is over the title bar."] = true
+L["Buttons Style"] = true
+-- general window
+L["Background"] = _G.BACKGROUND
+L["Background Texture"] = true
+L["The texture used as the background."] = true
+L["Tile"] = true
+L["Tile the background texture."] = true
+L["Tile Size"] = true
+L["The size of the texture pattern."] = true
+L["Border"] = true
+L["Border Thickness"] = true
+L["The thickness of the borders."] = true
+L["Border Insets"] = true
+L["The distance between the window and its border."] = true
+L["Scale"] = true
+L["Sets the scale of the window."] = true
+L["Strata"] = true
+L["This determines what other frames will be in front of the frame."] = true
+L["Clamped To Screen"] = true
+L["Toggle whether to permit movement out of screen."] = true
+L["X Offset"] = true
+L["Y Offset"] = true
+-- switching
+L["Mode Switching"] = true
+L["Combat Mode"] = true
+L["opt_combatmode_desc"] = "Automatically switch to set \124cffffbb00Current\124r and this mode when entering combat."
+L["Wipe Mode"] = true
+L["opt_wipemode_desc"] = "Automatically switch to set \124cffffbb00Current\124r and this mode after a wipe."
+L["Return after combat"] = true
+L["Return to the previous set and mode after combat ends."] = true
+L["Auto switch to current"] = true
+L["opt_autocurrent_desc"] = "Whenever a combat starts, this window automatically switches to \124cffffbb00Current\124r segment."
+L["Auto Hide"] = true
+L["While in combat"] = true
+L["While out of combat"] = true
+L["While not in a group"] = true
+L["While inside an instance"] = true
+L["While not inside an instance"] = true
+L["In Battlegrounds"] = true
+L["Inline Bar Display"] = true
+L["mod_inline_desc"] = "Inline display is a horizontal window style."
+L["Font Color"] = true
+L["Font Color.\nClick \"Class Colors\" to begin."] = true
+L["opt_barwidth_desc"] = 'Width of bars. This only applies if the "Fixed bar width" option is used.'
+L["Fixed bar width"] = true
+L["opt_fixedbarwidth_desc"] = "If checked, bar width is fixed. Otherwise, bar width depends on the text width."
+L["Class Colors"] = _G.CLASS_COLORS or "Class Colors"
+L["Use class colors for %s."] = true
+L["opt_isusingclasscolors_desc"] = "With: %s - 5.71M (21.7K)\nWithout: %s - 5.71M (21.7K)"
+L["Put values on new line."] = true
+L["opt_isonnewline_desc"] = "New line:\n%1$s\n5.71M (21.7K)\n\nDivider:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = true
+L["opt_isusingelvuiskin_desc"] = "Check this to use ElvUI skin instead.\nDefault: checked"
+L["Use solid background."] = true
+L["Un-check this for an opaque background."] = true
+L["Data Text"] = true
+L["mod_broker_desc"] = "Data text acts as an LDB data feed. It can be integrated in any LDB display such as Titan Panel or ChocolateBar. It also has an optional internal frame."
+L["Use frame"] = true
+L["opt_useframe_desc"] = "Shows a standalone frame. Not needed if you are using an LDB display provider such as Titan Panel or ChocolateBar."
+L["Text Color"] = true
+L["The text color of %s."] = true
+L["Choose the default color."] = true
+L["Hint: Left-Click to set active mode."] = true
+L["Right-Click to set active set."] = true
+L["Shift+Left-Click to open menu."] = true
+-- data resets
+L["Data Resets"] = true
+L["Reset"] = _G.RESET
+L["Reset on entering instance"] = true
+L["Controls if data is reset when you enter an instance."] = true
+L["Reset on joining a group"] = true
+L["Controls if data is reset when you join a group."] = true
+L["Reset on leaving a group"] = true
+L["Controls if data is reset when you leave a group."] = true
+L["Ask"] = true
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = true
+L["All data has been reset."] = true
+L["There is no data to reset."] = true
+L["Skip reset dialog"] = true
+L["opt_skippopup_desc"] = "Enable this if you want Skada to reset without the confirmation dialog."
+L["Are you sure you want to reinstall Skada?"] = true
+-- general options
+L["Show minimap button"] = true
+L["Toggles showing the minimap button."] = true
+L["Transliterate"] = true
+L["Converts Cyrillic letters into Latin letters."] = true
+L["Remove realm name"] = true
+L["opt_realmless_desc"] = "When enabled, the character realm name isn't displayed."
+L["Merge pets"] = true
+L["Merges pets with their owners. Changing this only affects new data."] = true
+L["Show totals"] = true
+L["Shows a extra row with a summary in certain modes."] = true
+L["Only keep boss fighs"] = true
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = true
+L["Always save boss fights"] = true
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = true
+L["Hide when solo"] = true
+L["Hides Skada's window when not in a party or raid."] = true
+L["Hide in PvP"] = true
+L["Hides Skada's window when in Battlegrounds/Arenas."] = true
+L["Hide in combat"] = true
+L["Hides Skada's window when in combat."] = true
+L["Show in combat"] = true
+L["Shows Skada's window when in combat."] = true
+L["Disable while hidden"] = true
+L["Skada will not collect any data when automatically hidden."] = true
+L["Sort modes by usage"] = true
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = true
+L["Show rank numbers"] = true
+L["Shows numbers for relative ranks for modes where it is applicable."] = true
+L["Aggressive combat detection"] = true
+L["opt_tentativecombatstart_desc"] = [[Skada usually uses a very conservative (simple) combat detection scheme that works best in raids.
+With this option Skada attempts to emulate other damage meters.
+Useful for running dungeons, meaningless on boss encounters.]]
+L["Autostop"] = true
+L["opt_autostop_desc"] = "Automatically stops the current segment after half of all raid members have died."
+L["Always show self"] = true
+L["opt_showself_desc"] = "Keeps the player shown last even if there is not enough space."
+L["Number format"] = true
+L["Controls the way large numbers are displayed."] = true
+L["Condensed"] = true
+L["Detailed"] = true
+L["Combined"] = true
+L["Comma"] = true
+L["Numeral system"] = true
+L["Select which numeral system to use."] = true
+L["Auto"] = true
+L["Western"] = true
+L["East Asia"] = true
+L["Brackets"] = true
+L["Choose which type of brackets to use."] = true
+L["Separator"] = true
+L["Choose which character is used to separator values between brackets."] = true
+L["Number of decimals"] = true
+L["Controls the way percentages are displayed."] = true
+L["Data Feed"] = true
+L["opt_feed_desc"] = "Choose which data feed to show in the DataBroker view. This requires an LDB display addon, such as Titan Panel."
+L["Time Measure"] = true
+L["Activity Time"] = true
+L["Effective Time"] = true
+L["opt_timemesure_desc"] = [=[|cffffff00Activity|r: the timer of each raid member is put on hold if their activity is ceased and back again to count when resumed, common way of measuring DPS and HPS.
+|cffffff00Effective|r: used on rankings, this method uses the elapsed combat time to measure the DPS and HPS of all raid members.]=]
+L["Number set duplicates"] = true
+L["Append a count to set names with duplicate mob names."] = true
+L["Set Format"] = true
+L["Controls the way set names are displayed."] = true
+L["Links in reports"] = true
+L["When possible, use links in the report messages."] = true
+L["Segments to keep"] = true
+L["The number of fight segments to keep. Persistent segments are not included in this."] = true
+L["Persistent segments"] = true
+L["The number of persistent fight segments to keep."] = true
+L["Memory Check"] = true
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = true
+L["Disable Comms"] = true
+L["Minimum segment length"] = true
+L["The minimum length required in seconds for a segment to be saved."] = true
+L["Update frequency"] = true
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = true
+-- columns
+L["Columns"] = true
+-- tooltips
+L["Tooltips"] = true
+L["Show Tooltips"] = true
+L["Shows tooltips with extra information in some modes."] = true
+L["Informative Tooltips"] = true
+L["Shows subview summaries in the tooltips."] = true
+L["Subview Rows"] = true
+L["The number of rows from each subview to show when using informative tooltips."] = true
+L["Tooltip Position"] = true
+L["Position of the tooltips."] = true
+L["Default"] = _G.DEFAULT
+L["Top Right"] = true
+L["Top Left"] = true
+L["Bottom Right"] = true
+L["Bottom Left"] = true
+L["Smart"] = true
+L["Follow Cursor"] = true
+L["Top"] = true
+L["Bottom"] = true
+L["Right"] = true
+L["Left"] = true
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = true
+L["Modules"] = true
+L["Disabled Modules"] = true
+L["Modules Options"] = true
+L["Tick the modules you want to disable."] = true
+L["This change requires a UI reload. Are you sure?"] = true
+-- themes options
+L["Theme"] = true
+L["Themes"] = true
+L["Manage Themes"] = true
+L["All Windows"] = true
+L["Apply Theme"] = true
+L["Apply"] = _G.APPLY
+L["Theme applied!"] = true
+L["Name of your new theme."] = true
+L["Save Theme"] = true
+L["Save"] = _G.SAVE
+L["Delete Theme"] = true
+L["Delete"] = _G.DELETE
+L["Are you sure you want to delete this theme?"] = true
+L["Paste here a theme in text format."] = true
+L["This is your current theme in text format."] = true
+-- scroll options
+L["Scroll"] = true
+L["Mouse"] = _G.MOUSE_LABEL
+L["Wheel Speed"] = true
+L["opt_wheelspeed_desc"] = "Changes how fast the scroll goes when rolling the mouse wheel over the window."
+L["Scroll Icon"] = true
+L["Scroll mouse button"] = true
+L["Scroll Up"] = _G.COMBAT_TEXT_SCROLL_UP
+L["Scroll Down"] = _G.COMBAT_TEXT_SCROLL_DOWN
+L["Keybinding"] = _G.KEY_BINDINGS
+L["Middle Button"] = _G.KEY_BUTTON3
+L["Mouse Button 4"] = _G.KEY_BUTTON4
+L["Mouse Button 5"] = _G.KEY_BUTTON5
+-- minimap button
+L["Skada Summary"] = true
+L["\124cff00ff00Left-Click\124r to toggle windows."] = true
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = true
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = true
+L["\124cff00ff00Right-Click\124r to open menu."] = true
+-- skada menu
+L["Skada Menu"] = true
+L["Select Segment"] = true
+L["Delete Segment"] = true
+L["Keep Segment"] = true
+L["Toggle Windows"] = true
+L["Show/Hide Windows"] = true
+L["New Segment"] = true
+L["Starts a new segment."] = true
+L["New Phase"] = true
+L["Starts a new phase."] = true
+L["Select All"] = true
+L["Deselect All"] = true
+L["Next"] = _G.NEXT
+L["Previous"] = _G.PREVIOUS
+-- window buttons
+L["Configure"] = true
+L["Open Config"] = true
+L["btn_config_desc"] = "Opens the configuration window."
+L["btn_reset_desc"] = [[Resets all fight data except those marked as kept.
+|cff00ff00Shift-LMB|r: Delete segment.]]
+L["Segment"] = true
+L["btn_segment_desc"] = [[Jump to a specific segment.
+|cff00ff00Shift-LMB|r for |cffffbb00next|r segment.
+|cff00ff00Shift-RMB|r for |cffffbb00previous|r segment.
+|cff00ff00Middle-Click|r for |cffffbb00current|r segment.]]
+L["Mode"] = true
+L["Jump to a specific mode."] = true
+L["Report"] = true
+L["btn_report_desc"] = [[Opens a dialog that lets you report your data to others in various ways.
+|cff00ff00Shift-Click|r to Quick Report.]]
+L["Stop"] = "Stop/Resume"
+L["btn_stop_desc"] = "Stops or resumes the current segment. Useful for discounting data after a wipe. Can also be set to automatically stop in the settings."
+L["Segment Stopped."] = true
+L["Segment Paused."] = true
+L["Segment Resumed."] = true
+L["Quick Access"] = true
+-- default segments
+L["Total"] = true
+L["Current"] = "Current fight"
+-- report module and window
+L["Skada: %s for %s:"] = true
+L["Channel"] = _G.CHANNEL
+L["Self"] = true
+L["Whisper"] = _G.WHISPER
+L["Whisper Target"] = true
+L["Say"] = _G.CHAT_MSG_SAY
+L["Yell"] = _G.CHAT_MSG_YELL
+L["Instance"] = _G.INSTANCE
+L["Party"] = _G.CHAT_MSG_PARTY
+L["Raid"] = _G.CHAT_MSG_RAID
+L["Guild"] = _G.CHAT_MSG_GUILD
+L["Officer"] = _G.CHAT_MSG_OFFICER
+L["Raid Warning"] = _G.CHAT_MSG_RAID_WARNING
+L["Copy & Paste"] = true
+L["[General]"] = "General"
+L["[LocalDefense]"] = "LocalDefense"
+L["[LookingForGroup]"] = "LookingForGroup"
+L["[Trade]"] = "Trade"
+L["Line"] = true
+L["Lines"] = true
+L["There is nothing to report."] = true
+L["No mode or segment selected for report."] = true
+-- Bar Display Module --
+L["Bar Display"] = true
+L["mod_bar_desc"] = "Bar display is the normal bar window used by most damage meters. It can be extensively styled."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = true
+L["Max Bars"] = true
+L["The maximum number of bars shown."] = true
+L["Show Menu Button"] = true
+L["Shows a button for opening the menu in the window title bar."] = true
+L["Class Color Bars"] = true
+L["Class Color Text"] = true
+-- Threat Module --
+L["Threat"] = true
+L["Threat Warning"] = true
+L["Flash Screen"] = true
+L["This will cause the screen to flash as a threat warning."] = true
+L["Shake Screen"] = true
+L["This will cause the screen to shake as a threat warning."] = true
+L["Warning Message"] = true
+L["Print a message to screen when you accumulate too much threat."] = true
+L["Play sound"] = true
+L["This will play a sound as a threat warning."] = true
+L["Message Output"] = true
+L["Choose where warning messages should be displayed."] = true
+L["Chat Frame"] = true
+L["Blizzard Error Frame"] = true
+L["opt_threat_soundfile_desc"] = "The sound that will be played when your threat percentage reaches a certain point."
+L["Warning Frequency"] = true
+L["Threat Threshold"] = true
+L["opt_threat_threshold_desc"] = "When your threat reaches this level, relative to tank, warnings are shown."
+L["Show raw threat"] = true
+L["opt_threat_rawvalue_desc"] = "Shows raw threat percentage relative to tank instead of modified for range."
+L["Use focus target"] = true
+L["opt_threat_focustarget_desc"] = 'Tells Skada to additionally check your "focus" and "focustarget" before your "target" and "targettarget" in that order for threat display.'
+L["Disable while tanking"] = true
+L["opt_threat_notankwarnings_desc"] = "Do not give out any warnings if Defensive Stance, Bear Form, Righteous Fury or Frost Presence is active."
+L["Ignore Pets"] = true
+L["opt_threat_ignorepets_desc"] = [[Tells Skada to skip enemy player pets when determining which unit to display threat data on.
+
+Player pets maintain a threat table when in |cffffff78Aggressive|r or |cffffff78Defensive|r mode and behave just like normal mobs, attacking the target with the highest threat. If the pet is instructed to attack a specific target, the pet still maintains the threat table, but sticks on the assigned target which by definition has 100% threat. Player pets can be taunted to force them to attack you.
+
+However, player pets on |cffffff78Passive|r mode do not have a threat table, and taunt does not work on them. They only attack their assigned target when instructed and do so without any threat table.
+
+When a player pet is instructed to |cffffff78Follow|r, the pet's threat table is wiped immediately and stops attacking, although it may immediately reacquire a target based on its Aggressive/Defensive mode.]]
+L["> Pull Aggro <"] = true
+L["Show Pull Aggro Bar"] = true
+L["opt_threat_showaggrobar_desc"] = "Show a bar for the amount of threat you will need to reach in order to pull aggro."
+L["Test Warnings"] = true
+L["TPS"] = true
+L["Threat: Personal Threat"] = true
+L["Threat sound"] = true
+L["%d%% Threat"] = _G.THREAT_TOOLTIP
+L["High Threat"] = _G.COMBAT_THREAT_INCREASE_1
+-- Absorbs & Healing Module --
+L["Healing"] = true
+L["Healing Done"] = true
+L["Healing Taken"] = true
+L["HPS"] = true
+L["sHPS"] = "HPS (subviews)"
+L["Healing: Personal HPS"] = true
+L["RHPS"] = true
+L["Healing: Raid HPS"] = true
+L["Total Healing"] = true
+L["Overheal"] = true
+L["Overhealing"] = true
+L["Absorbs"] = true
+L["Target List"] = true
+L["Spell List"] = true
+L["APS"] = true
+L["sAPS"] = "APS (subviews)"
+L["Absorbs and Healing"] = true
+L["Healing Done By Spell"] = true
+L["Source List"] = true
+-- Auras Module --
+L["Uptime"] = true
+L["Buffs and Debuffs"] = true
+L["Buffs"] = true
+L["Debuffs"] = true
+L["%s's <%s> targets"] = true
+L["%s's <%s> sources"] = true
+L["Enemy Buffs"] = true
+L["Enemy Debuffs"] = true
+-- CC Tracker Module --
+L["Crowd Control"] = true
+L["CC Done"] = true
+L["CC Taken"] = true
+L["CC Breaks"] = true
+L["Ignore Main Tanks"] = true
+L["%s on %s removed by %s"] = true
+L["%s on %s removed by %s's %s"] = true
+-- Damage Module --
+-- environmental damage
+L["Environment"] = true
+L["Falling"] = _G.ACTION_ENVIRONMENTAL_DAMAGE_FALLING
+L["Drowning"] = _G.ACTION_ENVIRONMENTAL_DAMAGE_DROWNING
+L["Fatigue"] = _G.ACTION_ENVIRONMENTAL_DAMAGE_FATIGUE
+L["Fire"] = _G.ACTION_ENVIRONMENTAL_DAMAGE_FIRE
+L["Lava"] = _G.ACTION_ENVIRONMENTAL_DAMAGE_LAVA
+L["Slime"] = _G.ACTION_ENVIRONMENTAL_DAMAGE_SLIME
+-- damage done module
+L["Damage"] = true
+L["Spell Details"] = true
+L["Damage Done"] = true
+L["Pet Damage"] = _G.SHOW_PET_MELEE_DAMAGE or "Pet Damage"
+L["Useful Damage"] = true
+L["Useful damage on %s"] = true
+L["Damage Done By Spell"] = true
+L["%s's sources"] = true
+L["DPS"] = true
+L["sDPS"] = "DPS (subviews)"
+L["Damage: Personal DPS"] = true
+L["RDPS"] = true
+L["Damage: Raid DPS"] = true
+L["Absorbed Damage"] = true
+L["Enable this if you want the damage absorbed to be included in the damage done."] = true
+L["Damage Done By School"] = true
+-- killing blows module
+L["Killing Blows"] = _G.KILLING_BLOWS or "Killing Blows"
+L["Only PvP Kills"] = true
+L["When enabled, only kills against enemy players count."] = true
+L["Announce killing blows after combat ends. Only works for boss fights."] = true
+-- damage taken module
+L["Damage Taken"] = true
+L["Damage Taken By Spell"] = true
+L["%s's targets"] = true
+L["DTPS"] = true
+L["sDTPS"] = "DTPS (subviews)"
+-- enemy damage done module
+L["Enemies"] = true
+L["Enemy Damage Done"] = true
+-- enemy damage taken module
+L["Enemy Damage Taken"] = true
+L["%s below %s%%"] = true
+L["%s - %s%% to %s%%"] = true
+L["Phase %s"] = true
+L["%s - Phase %s"] = true
+L["%s - Phase 1"] = true
+L["%s - Phase 2"] = true
+L["%s - Phase 3"] = true
+L["%s (Main Boss)"] = true
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = true
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = true
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = true
+-- enemy healing done module
+L["Enemy Healing Done"] = true
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = true
+L["More Details"] = true
+L["%s's details"] = true
+-- friendly fire module
+L["Friendly Fire"] = true
+-- useful damage targets
+L["Important targets"] = true
+L["Oozes"] = true
+L["Princes overkilling"] = true
+L["Adds"] = true
+L["Halion and Inferno"] = true
+L["Valkyrs overkilling"] = true
+-- Deaths Module --
+L["Deaths"] = _G.DEATHS
+L["%s's deaths"] = true
+L["Death log"] = true
+L["%s's death log"] = true
+L["Player's deaths"] = true
+L["%s dies"] = true
+L["buff"] = true
+L["debuff"] = true
+L["Spell details"] = true
+L["Spell"] = true
+L["Amount"] = true
+L["Source"] = true
+L["Health"] = _G.HEALTH
+L["Change"] = true
+L["Time"] = true
+L["Survivability"] = true
+L["Events Amount"] = true
+L["Set the amount of events the death log should record."] = true
+L["Minimum Healing"] = true
+L["Ignore heal events that are below this threshold."] = true
+L["Announce Deaths"] = true
+L["Announces information about the last hit the player took before they died."] = true
+L["Alternative Display"] = true
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = true
+-- activity module
+L["Activity"] = true
+L["Activity per Target"] = true
+L["%s's activity"] = true
+-- dispels module lines --
+L["Dispels"] = _G.DISPELS
+L["Dispel Spells"] = true
+L["%s's dispelled spells"] = true
+-- interrupts module lines --
+L["Interrupts"] = _G.INTERRUPTS
+L["Interrupt Spells"] = true
+L["%s's interrupted spells"] = true
+L["%s interrupted!"] = true
+-- Power gained module --
+L["Resources"] = true
+L["Mana Restored"] = true
+L["Rage Generated"] = true
+L["Energy Generated"] = true
+L["Runic Power Generated"] = true
+-- Parry module lines --
+L["Parry-Haste"] = true
+L["%s parried %s (%s)"] = true
+-- Potions module lines --
+L["Potions"] = true
+L["%s's potions"] = true
+L["Pre-potion"] = true
+L["pre-potion: %s"] = true
+L["Prints pre-potion after the end of the combat."] = true
+-- healthstone --
+L["Healthstones"] = true
+-- resurrect module lines --
+L["Resurrects"] = true
+-- nickname module lines --
+L["Nickname"] = true
+L["Name"] = _G.NAME
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = true
+L["Set a nickname for you."] = true
+L["Nickname isn't a valid string."] = true
+L["Your nickname is too long, max of 12 characters is allowed."] = true
+L["Only letters and two spaces are allowed."] = true
+L["Your nickname contains a forbidden word."] = true
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = true
+L["Ignore Nicknames"] = true
+L["When enabled, nicknames set by Skada users are ignored."] = true
+L["Name display"] = true
+L["Choose how names are shown on your bars."] = true
+L["Clear Cache"] = true
+L["Are you sure you want clear cached nicknames?"] = true
+-- overkill module lines --
+L["Overkill"] = true
+-- tweaks module lines --
+L["Improvement"] = true
+L["Tweaks"] = true
+L["First hit"] = true
+L["\124cffffff00First Hit\124r: %s from %s"] = true
+L["\124cffffbb00First Hit\124r: *?*"] = true
+L["\124cffffbb00Boss First Target\124r: %s"] = true
+L["opt_tweaks_firsthit_desc"] = "Prints a message of the first hit before combat.\nOnly works for boss encounters."
+L["Filter DPS meters Spam"] = true
+L["opt_tweaks_spamage_desc"] = "Suppresses chat messages from damage meters and provides single chat-link damage statistics in a popup."
+L["Reported by: %s"] = true
+L["Smart Stop"] = true
+L["opt_tweaks_smarthalt_desc"] = "Automatically stops the current segment after the boss has died.\nUseful to avoid collecting data in case of a combat bug."
+L["Duration"] = true
+L["opt_tweaks_smartwait_desc"] = "For how long Skada should wait before stopping the segment."
+L["Modes Icons"] = true
+L["Show modes icons on bars and menus."] = true
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = true
+L["Colors"] = _G.COLORS
+L["Custom Colors"] = true
+L["Arena Teams"] = true
+L["Are you sure you want to reset all colors?"] = true
+L["Announce %s"] = true
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = true
+L["%s dropped from %s!"] = true
+L["%s stacks of %s applied on %s in %s sec!"] = true
+L["My Spells"] = true
+-- total data options
+L["Total Segment"] = true
+L["All Segments"] = true
+L["Raid Bosses"] = true
+L["Raid Trash"] = true
+L["Dungeon Bosses"] = true
+L["Dungeon Trash"] = true
+L["opt_tweaks_total_all_desc"] = "All segments are added to total segment data."
+L["opt_tweaks_total_fmt_desc"] = "Segments with %s are added to total segment data."
+L["Detailed total segment"] = true
+L["opt_tweaks_total_full_desc"] = "When enabled, Skada will record everything to the total segment, instead of total numbers (record spell details, their targets and their sources)."
+-- arena
+L["Player vs. Player"] = _G.PLAYER_V_PLAYER
+L["mod_pvp_desc"] = "Adds specialization detection for arenas and battlegrounds, and shows arena opponents on the same window."
+L["Gold Team"] = true
+L["Green Team"] = true
+L["Color"] = _G.COLOR
+L["Color for %s."] = true
+-- notifications
+L["Opacity"] = _G.OPACITY
+L["Notifications"] = true
+L["opt_toast_desc"] = "Uses visual notifications instead of chat window messages whenever applicable."
+L["Test Notifications"] = true
+-- comparison module
+L["Comparison"] = true
+L["%s vs %s: %s"] = true
+L["%s vs %s: Spells"] = true
+L["%s vs %s: Targets"] = true
+-- spellcast module
+L["Casts"] = true
+L["%s's spells"] = true
+L["%s's spells on %s"] = true
+L["Spells on %s"] = true
+-- about
+L["Author"] = true
+L["Credits"] = true
+L["Date"] = true
+L["License"] = true
+L["Version"] = true
+L["Website"] = true
+-- custom class names using globals
+L["BOSS"] = _G.BOSS
+L["ENEMY"] = _G.ENEMY
+L["MONSTER"] = _G.EXAMPLE_TARGET_MONSTER
+L["NEUTRAL"] = _G.FACTION_STANDING_LABEL4
+L["PET"] = _G.PET
+L["PLAYER"] = _G.PLAYER
+L["UNKNOWN"] = _G.UNKNOWN
+-- some bosses entries
+L["World Boss"] = true
+L["Auriaya"] = true
+L["Blood Prince Council"] = true
+L["Faction Champions"] = true
+L["Hogger"] = true
+L["Icecrown Gunship Battle"] = true
+L["Kologarn"] = true
+L["Mimiron"] = true
+L["Thaddius"] = true
+L["The Four Horsemen"] = true
+L["The Iron Council"] = true
+L["The Northrend Beasts"] = true
+L["Thorim"] = true
+L["Twin Val'kyr"] = true
+L["Valithria Dreamwalker"] = true
+L["Yogg-Saron"] = true
diff --git a/Skada/Locales/esMX.lua b/Skada/Locales/esMX.lua
new file mode 100644
index 0000000..7914e49
--- /dev/null
+++ b/Skada/Locales/esMX.lua
@@ -0,0 +1,759 @@
+--[[ Translators: Ícar#8167 / Septimun#8954 / 𝔸𝕓𝕖𝕝#9150 ]] --
+local folder = ...
+local AceLocale = LibStub("AceLocale-3.0")
+local L = AceLocale:NewLocale(folder, "esES") or AceLocale:NewLocale(folder, "esMX")
+if not L then return end
+
+L["A damage meter."] = "Un medidor de da\195\177o."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "El uso de memoria es alto. Es posible que desee restablecer Skada y habilitar una de las opciones de restablecimiento autom\195\161tico."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada est\195\161 desactualizado. Puedes descargar la versi\195\179n m\195\161s nueva de \124cffffbb00%s\124r"
+L["Skada: Modes"] = "Skada: Modos"
+L["Skada: Fights"] = "Skada: Luchas"
+L["Data Collection"] = "Recopilaci\195\179n de datos"
+L["ENABLED"] = "HABILITADO"
+L["DISABLED"] = "DESHABILITDO"
+L["Enable All"] = "Habilitar todo"
+L["Disable All"] = "Deshabilitar todo"
+L["Stopping for wipe."] = "Detenido por muerte de la banda."
+L["Usage:"] = "Utilizar:"
+L["Commands:"] = "Comandos:"
+L["Import"] = "Importar"
+L["Export"] = "Exportar"
+L["Import/Export"] = "Importar/Exportar"
+-- profiles
+L["Profiles"] = "Perfiles"
+L["Profile Import/Export"] = "Importaci\195\179n/Exportaci\195\179n de perfiles"
+L["Import Profile"] = "Importar perfil"
+L["Export Profile"] = "Exportar perfil"
+L["Paste here a profile in text format."] = "Pegue aqui un perfil en formato de texto."
+L["Press CTRL-V to paste the text from your clipboard."] = "Pulse CTRL+V para pegar el texto de su portapapeles."
+L["This is your current profile in text format."] = "Este es su actual perfil en formato the texto."
+L["Press CTRL-C to copy the text to your clipboard."] = "Pulse CTRL-C para copiar el texto al Portapapeles."
+L["Network Sharing"] = "Compartici\195\179n de red"
+L["Player Name"] = "Nombre del jugador"
+L["Send Profile"] = "Enviar perfil"
+L["Accept profiles from other players."] = "Aceptar perfiles de otros jugadores."
+L["opt_profile_received"] = "%s te ha enviado una configuraci\195\179n para el Skada. Quieres activar el perfil recibido?"
+L["Progress"] = "Progreso"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "Tama\195\177o de los datos: \124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "Progreso de la transmisi\195\179n: %d%%"
+L["Transmission Completed"] = "Transmisi\195\179n finalizada"
+-- common lines
+L["Options"] = "Opciones"
+L["Options for %s."] = "Opciones de %s."
+L["General"] = "General"
+L["General options for %s."] = "Opciones generales de %s."
+L["Text"] = "Texto"
+L["Text options for %s."] = "Opciones de texto de %s."
+L["Format"] = "Formato"
+L["Format options for %s."] = "Opciones de formato de %s."
+L["Appearance"] = "Apariencia"
+L["Appearance options for %s."] = "Opciones de apariencia de %s."
+L["Advanced"] = "Avanzado"
+L["Advanced options for %s."] = "Opciones avanzadas de %s."
+L["Position"] = "Posici\195\179n"
+L["Position settings for %s."] = "Configuraci\195\179n de posici\195\179n de %s."
+L["Width"] = "Anchura"
+L["The width of %s."] = "El anchura de %s."
+L["Height"] = "Altura"
+L["The height of %s."] = "El altura de %s."
+L["Active Time"] = "Tiempo activo"
+L["Segment Time"] = "Segmento de tiempo"
+L["Click for \124cff00ff00%s\124r"] = "Click para \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift+click para \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Control+click para \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt+click para \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "Filtrar por clase"
+L["Average"] = "Promedio"
+L["Count"] = "Contar"
+L["Refresh"] = "Actualizaci\195\179n"
+L["Percent"] = "Porcentaje"
+L["sPercent"] = "Porcentaje (subvistas)"
+L["General Options"] = "Opciones generales"
+-- L["HoT"] = "HoT"
+-- L["DoT"] = "DoT"
+L["Hits"] = "Golpes"
+L["Normal Hits"] = "Golpes normales"
+L["Critical"] = "Cr\195\173tico"
+L["Critical Hits"] = "Golpes cr\195\173ticos"
+L["Crushing"] = "Aplastante"
+L["Glancing"] = "Glancing"
+L["ABSORB"] = "Absorbida"
+L["BLOCK"] = "Bloqueado"
+L["DEFLECT"] = "Desviado"
+L["DODGE"] = "Esquivado"
+L["EVADE"] = "Evadido"
+L["IMMUNE"] = "Inmune"
+L["MISS"] = "Fallado"
+L["PARRY"] = "Parado"
+L["REFLECT"] = "Reflejado"
+L["RESIST"] = "Resistido"
+L["Only for bosses."] = "Solo para jefes."
+L["Enable this only against bosses."] = "Habilita esto solo contra jefes."
+-- segment info
+L["Start"] = "Iniciar"
+L["End"] = "Terminar"
+-- windows section:
+L["Window"] = "Ventana"
+L["Windows"] = "Ventanas"
+L["Create Window"] = "Crear ventana"
+L["Window Name"] = "Nombre de la ventana"
+L["Enter the name for the new window."] = "Introducir el nombre para la nueva ventana"
+L["Delete Window"] = "Borrar ventana"
+L["Choose the window to be deleted."] = "Escoger la ventana para ser borrada"
+L["Are you sure you want to delete this window?"] = "¿Est\195\161 seguro de que desea eliminar esta ventana?"
+L["Delete All Windows"] = "Eliminar todas las ventanas"
+L["Are you sure you want to delete all windows?"] = "¿Est\195\161 seguro de que desea eliminar todas las ventanas?"
+L["Rename Window"] = "Renombrar ventana"
+L["Enter the name for the window."] = "Introducir el nombre para la ventana"
+L["Test Mode"] = "Modo de prueba"
+L["Creates fake data to help you configure your windows."] = "Crea datos falsos para ayudarlo a configurar sus ventanas."
+L["Child Window"] = "Ventana secundaria"
+L["A child window will replicate the parent window actions."] = "Una ventana secundaria copiar\195\161 las acciones de la ventana principal."
+L["Child Window Mode"] = "Modo de ventana secundaria"
+L["Lock Window"] = "Bloquear ventana"
+L["Locks the bar window in place."] = "Bloquear la barra de la ventana en su lugar"
+L["Hide Window"] = "Ocultar ventana"
+L["Hides the window."] = "Esconde la ventana"
+L["Sticky Window"] = "Ventana pegajosa"
+L["Allows the window to stick to other Skada windows."] = "Permite que la ventana se ajuste a otras ventanas de Skada."
+L["Snap to best fit"] = "Ajustar para un mejor encaje"
+L["Snaps the window size to best fit when resizing."] = "Ajustar el tama\195\177o de la ventana para un mejor encaje cuando se redimensiona"
+L["Disable Resize Buttons"] = "Desac. los botones de redimensionamiento"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "Los botones de redimensionar y bloquear/desbloquear no aparecen al pasar el rat\195\179n por encima de la ventana."
+L["Disable stretch button"] = "Desac. el bot\195\179n de estiramiento"
+L["Stretch button won't show up when you hover over the window."] = "El bot\195\179n estiramiento no aparecer\195\161 cuando pase el mouse sobre la ventana."
+L["Reverse window stretch"] = "Estiramiento de ventana inversa"
+L["opt_botstretch_desc"] = "Coloca el bot\195\179n de estiramiento en la parte inferior de la ventana y hace que este \195\186ltimo se estire hacia abajo."
+L["Display System"] = "Sistema de visualizaci\195\179n"
+L["Choose the system to be used for displaying data in this window."] = "Escoger el sistema para ser usado como visualizaci\195\179n de los datos en esta ventana"
+L["Copy Settings"] = "Copiar configuraci\195\179n"
+L["Choose the window from which you want to copy the settings."] = "Elija la ventana desde la que desea copiar la configuraci\195\179n."
+-- bars
+L["Bars"] = "Barras"
+L["Left Text"] = "Texto Izquierdo"
+L["Right Text"] = "Texto derecho"
+L["Font"] = "Fuente"
+L["The font used by %s."] = "La fuente utilizada por %s."
+L["Font Size"] = "Tama\195\177o de fuente"
+L["The font size of %s."] = "El tama\195\177o de fuente de %s."
+L["Font Outline"] = "Contorno de la fuente"
+L["Sets the font outline."] = "Establece el contorno de la fuente."
+L["Outline"] = "Contorno"
+L["Thick"] = "Grueso"
+L["Thick outline"] = "Contorno grueso"
+L["Monochrome"] = "Monocromo"
+L["Outlined monochrome"] = "Contorno monocromo"
+L["Bar Texture"] = "Textura de la barra"
+L["The texture used by all bars."] = "La textura usada por todas las barras"
+L["Spacing"] = "Espaciado"
+L["Distance between %s."] = "Distancia entre %s."
+L["Displacement"] = "Desplazamiento"
+L["The distance between the edge of the window and the first bar."] = "La distancia entre el borde de la ventana y la primera barra."
+L["Bar Orientation"] = "Orientaci\195\179n de la barra"
+L["The direction the bars are drawn in."] = "La direcci\195\179n en que las barras se retraen"
+L["Left to right"] = "Izquierda a derecha"
+L["Right to left"] = "Derecha a izquierda"
+L["Reverse bar growth"] = "Invertir crecimiento de la barra"
+L["Bars will grow up instead of down."] = "Las barras crecen hacia arriba en lugar de hacia abajo"
+L["Disable bar highlight"] = "Deshabilitar el resaltado de la barra"
+L["Hovering a bar won't make it brighter."] = "Pasar el cursor sobre una barra no la har\195\161 m\195\161s brillante."
+L["Bar Color"] = "Color de la barra"
+L["Choose the default color of the bars."] = "Escoger el color por defecto de las barras"
+L["Background Color"] = "Color del fondo"
+L["The color of the background."] = "El color del fondo"
+L["Custom Color"] = "Color personalizado"
+L["Use a different color for my bar."] = "Utilizar un color diferente para mi barra."
+L["My Color"] = "Mi color"
+L["Spell school colors"] = "Colores de la escuela de hechizos"
+L["Use spell school colors where applicable."] = "Utilizar colores de la escuela de hechizos cuando corresponda."
+L["When possible, bars will be colored according to player class."] = "Cuando sea posible, las barras ser\195\161 coloreado acorde con la clase del jugador."
+L["When possible, bar text will be colored according to player class."] = "Cuando sea posible, el texto ser\195\161 coloreado acorde con la clase del jugador."
+L["Class Icons"] = "Iconos de clase"
+L["Use class icons where applicable."] = "Utilizar iconos de clase cuando corresponda."
+L["Spec Icons"] = "Iconos de especificaciones"
+L["Use specialization icons where applicable."] = "Utilizar iconos de especializaci\195\179n cuando corresponda."
+L["Role Icons"] = "Iconos de rol"
+L["Use role icons where applicable."] = "Utilizar iconos de rol cuando corresponda."
+L["Show Spark Effect"] = "Mostrar efecto de chispa"
+L["Click Through"] = "Click a trav\195\169s"
+L["Disables mouse clicks on bars."] = "Deshabilitar los clicks del rat\195\179n en las barras"
+L["Smooth Bars"] = "Barras animadas"
+L["Animate bar changes smoothly rather than immediately."] = "Animar barras suavemente en lugar de inmediatamente."
+-- title bar
+L["Title Bar"] = "Barra de t\195\173tulo"
+L["Enables the title bar."] = "Habilita la barra de t\195\173tulo"
+L["Include set"] = "Incluir segmento"
+L["Include set name in title bar"] = "Incluir el nombre del segmento en la barra de t\195\173tulo"
+L["Encounter Timer"] = "Temporizador de encuentro"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "Cuando est\195\161 habilitado, se muestra un cron\195\179metro en el lado izquierdo del texto."
+L["Mode Icon"] = "Icono de modo"
+L["Shows mode's icon in the title bar."] = "Muestra el icono del modo en la barra de t\195\173tulo."
+L["The texture used as the background of the title."] = "La textura usada como fondo del t\195\173tulo."
+L["Border texture"] = "Textura del borde"
+L["The texture used for the borders."] = "La textura usada para los bordes."
+L["Border Color"] = "Color del borde"
+L["The color used for the border."] = "El color utilizado para el borde."
+L["Buttons"] = "Botones"
+L["Auto Hide Buttons"] = "Ocultar botones autom\195\161ticamente"
+L["Show window buttons only if the cursor is over the title bar."] = "Mostrar botones de ventana solo si el cursor est\195\161 sobre la barra de t\195\173tulo."
+L["Buttons Style"] = "Estilo de botones"
+-- general window
+L["Background Texture"] = "Textura del fondo"
+L["The texture used as the background."] = "La textura usada como fondo"
+L["Tile"] = "Loseta"
+L["Tile the background texture."] = "Loseta de la textura de fondo."
+L["Tile Size"] = "Tama\195\177o de la loseta"
+L["The size of the texture pattern."] = "El tama\195\177o del patr\195\179n de textura."
+L["Border"] = "Borde"
+L["Border Thickness"] = "Grosor del borde"
+L["The thickness of the borders."] = "El grosor de los bordes"
+L["Border Insets"] = "Distancia del borde"
+L["The distance between the window and its border."] = "La distancia entre la ventana y su borde."
+L["Scale"] = "Escala"
+L["Sets the scale of the window."] = "Ajustar la escala de la ventana"
+L["Strata"] = "Estrato"
+L["This determines what other frames will be in front of the frame."] = "Esto determina qu\195\169 otros macros estar\195\161n delante del macro."
+L["Clamped To Screen"] = "Dentro de la pantalla"
+L["Toggle whether to permit movement out of screen."] = "Impide mover la ventana fuera de la pantalla."
+L["X Offset"] = "X Posicion"
+L["Y Offset"] = "Y Posicion"
+-- switching
+L["Mode Switching"] = "Modo de intercambio"
+L["Combat Mode"] = "Modo de combate"
+L["opt_combatmode_desc"] = "Autom\195\161ticamente cambiar entre al segmento \124cffffbb00Actual\124r y este modo cuando se entra en combate"
+L["Wipe Mode"] = "Modo de wipe"
+L["opt_wipemode_desc"] = "Autom\195\161ticamente cambiar entre al segmento \124cffffbb00Actual\124r y este modo despu\195\169s de un wipe."
+L["Return after combat"] = "Regresar tras combate"
+L["Return to the previous set and mode after combat ends."] = "Regresar al ajuste y modo previo despu\195\169s del fin del combate."
+L["Auto switch to current"] = "Auto-cambiar al actual"
+L["opt_autocurrent_desc"] = "Cambiar automaticamente al segmento \124cffffbb00Actual\124r al entrar en combate si ninguna otra ventana ya lo muestra."
+L["Auto Hide"] = "Auto-escondite"
+L["While in combat"] = "En combate"
+L["While out of combat"] = "Fuera de combate"
+L["While not in a group"] = "No en un grupo"
+L["While inside an instance"] = "Dentro de una instancia"
+L["While not inside an instance"] = "No dentro de una instancia"
+L["In Battlegrounds"] = "En campos de batalla"
+L["Inline Bar Display"] = "Barras en l\195\173nea"
+L["mod_inline_desc"] = "La visualizaci\195\179n en l\195\173nea es un estilo de ventana horizontal."
+L["Font Color"] = "Color de fuente"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "Color de fuente.\nHaga clic en \"Colores de clase\" para comenzar."
+L["opt_barwidth_desc"] = "Ancho de barras. Esto solo se aplica si se utiliza la opci\195\179n \"Ancho de barra fijo\"."
+L["Fixed bar width"] = "Ancho de barra fijo"
+L["opt_fixedbarwidth_desc"] = "Si est\195\161 activado, el ancho de la barra ser\195\161 fijo. Si no, el ancho depender\195\161 de lo que ocupe el texto."
+L["Use class colors for %s."] = "Usar colores de clase para %s."
+L["opt_isusingclasscolors_desc"] = "Con: %s - 5.71M (21.7K)\nSin: %s - 5.71M (21.7K)"
+L["Put values on new line."] = "Ponga valores en una nueva l\195\173nea."
+L["opt_isonnewline_desc"] = "Nueva l\195\173nea:\n%1$s\n5.71M (21.7K)\n\nDivisor:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = "Utilice piel ElvUI si est\195\161 disponible."
+L["opt_isusingelvuiskin_desc"] = "Marque esto para usar la piel ElvUI.\nPredeterminado: marcado"
+L["Use solid background."] = "Utilice un fondo s\195\179lido."
+L["Un-check this for an opaque background."] = "Desmarque esto para usar un fondo opaco."
+L["Data Text"] = "Los datos de texto"
+L["mod_broker_desc"] = "Los datos de texto act\195\186an como una fuente de datos LDB. Se puede integrar en cualquier pantalla LDB como Titan Panel o ChocolateBar. Tambi\195\169n tiene un marco interno opcional"
+L["Use frame"] = "Utilizar la ventana"
+L["opt_useframe_desc"] = "Muestra una ventana independiente. No es necesario si est\195\161 utilizando una pantalla LDB como Titan Panel o ChocolateBar."
+L["Text Color"] = "Color del texto"
+L["The text color of %s."] = "El color del texto de %s."
+L["Choose the default color."] = "Selecciona el color por defecto"
+L["Hint: Left-Click to set active mode."] = "Sugerencia: haz clic con el bot\195\179n izquierdo para establecer el modo activo."
+L["Right-Click to set active set."] = "Clic derecho para establecer el conjunto activo."
+L["Shift+Left-Click to open menu."] = "Shift+Left-Click para abrir el menu."
+-- data resets
+L["Data Resets"] = "Restablecimiento de datos"
+L["Reset on entering instance"] = "Restablecer al entrar en una estancia"
+L["Controls if data is reset when you enter an instance."] = "Controla si los datos son restablecidos cuando entra en una estancia"
+L["Reset on joining a group"] = "Restablecer al unirse a un grupo"
+L["Controls if data is reset when you join a group."] = "Controla si los datos son restablecidos cuando se une a un grupo"
+L["Reset on leaving a group"] = "Restablecer al abandonar un grupo"
+L["Controls if data is reset when you leave a group."] = "Controla si los datos son restablecidos cuando abandona un grupo"
+L["Ask"] = "Preguntar"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "¿Quiere restablecer Skada?\nMantenga pulsado SHIFT para restablecer todo."
+L["All data has been reset."] = "Todos los datos han sido reestablecidos."
+L["There is no data to reset."] = "No hay datos para restablecer."
+L["Skip reset dialog"] = "Omitir di\195\161logo de reinicio"
+L["opt_skippopup_desc"] = "Habilite esto si desea que Skada se reinicie sin mostrar el di\195\161logo de confirmaci\195\179n."
+L["Are you sure you want to reinstall Skada?"] = "¿Est\195\161s seguro de que quieres reinstalar Skada?"
+-- general options
+L["Show minimap button"] = "Mostrar bot\195\179n minimapa"
+L["Toggles showing the minimap button."] = "Mostrar/No mostrar el bot\195\179n del minimapa"
+L["Transliterate"] = "Transliterar"
+L["Converts Cyrillic letters into Latin letters."] = "Convierte letras cir\195\173licas en letras latinas."
+L["Remove realm name"] = "Eliminar nombre de reino"
+L["opt_realmless_desc"] = "Eliminar los nombres de reinos de los nombres de personajes."
+L["Merge pets"] = "Unir mascotas"
+L["Merges pets with their owners. Changing this only affects new data."] = "Unir mascotas a sus due\195\177os, cambiar esto solo afecta a los nuevos datos"
+L["Show totals"] = "Mostrar totales"
+L["Shows a extra row with a summary in certain modes."] = "Mostrar una fila extra con un resumen en ciertos modos"
+L["Only keep boss fighs"] = "Solo guardar las luchas contra jefes"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "Las luchas de los jefes permanecer\195\161n con esto activo, y las luchas que no sean de jefes son descartadas"
+L["Always save boss fights"] = "Mantener siempre las peleas contra jefes"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "Las peleas contra jefes se mantendr\195\161n con esta opci\195\179n y no ser\195\161n afectadas al reiniciar Skada."
+L["Hide when solo"] = "Ocultar cuando est\195\161 solo"
+L["Hides Skada's window when not in a party or raid."] = "Ocultar ventana de Skada cuando no est\195\161 en grupo o banda"
+L["Hide in PvP"] = "Ocultar en JcJ"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "Ocultar la ventana de Skada cuando se est\195\161 en Campos de Batalla/Arenas."
+L["Hide in combat"] = "Ocultar en combate"
+L["Hides Skada's window when in combat."] = "Ocultar la ventana de Skada en combate"
+L["Show in combat"] = "Mostrar en combate"
+L["Shows Skada's window when in combat."] = "Muestra ventanas de Skada cuando est\195\161 en combate."
+L["Disable while hidden"] = "Deshabilitar mientras est\195\161 oculto"
+L["Skada will not collect any data when automatically hidden."] = "Skada no recolectar\195\161 ning\195\186n dato cuando est\195\169 oculto autom\195\161ticamente"
+L["Sort modes by usage"] = "Ordenar modos por uso"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "La lista de modos se ordenar\195\161 para reflejar el uso en lugar de alfab\195\169ticamente."
+L["Show rank numbers"] = "Mostrar n\195\186meros de rango"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "Mostrar n\195\186meros para rangos relativos para los modos donde esto es aplicable"
+L["Aggressive combat detection"] = "Detecci\195\179n de combate agresiva"
+L["opt_tentativecombatstart_desc"] = [[Skada usualmente utiliza un muy conservador (simple) esquema de detección del combate que funciona mejor en bandas.
+Con esta opción Skada intenta emular otros medidores de daño.
+Útil cuando se hacen mazmorras, insignificante en encuentros de jefes.]]
+L["Autostop"] = "Autoestop"
+L["opt_autostop_desc"] = "Detiene autom\195\161ticamente el segmento actual despu\195\169s de que la mitad de los miembros hayan muerto."
+L["Always show self"] = "Mu\195\169strate siempre"
+L["opt_showself_desc"] = "Mantiene al jugador mostrado en \195\186ltimo lugar incluso si no hay suficiente espacio."
+L["Number format"] = "Formato de n\195\186meros"
+L["Controls the way large numbers are displayed."] = "Controlo el modo en que los n\195\186meros largos son mostrados"
+L["Condensed"] = "Condensado"
+L["Detailed"] = "Detallado"
+L["Combined"] = "Combinado"
+L["Comma"] = "Coma"
+L["Numeral system"] = "Sistema de numeraci\195\179n"
+L["Select which numeral system to use."] = "Selecciona qu\195\169 sistema de numeraci\195\179n usar."
+L["Auto"] = "Autom\195\161tico"
+L["Western"] = "Occidental"
+L["East Asia"] = "Este de Asia"
+L["Brackets"] = "Par\195\169ntesis"
+L["Choose which type of brackets to use."] = "Elija qu\195\169 tipo de par\195\169ntesis usar."
+L["Separator"] = "Separador"
+L["Choose which character is used to separator values between brackets."] = "Elija qu\195\169 car\195\161cter se utiliza para separar los valores entre par\195\169ntesis."
+L["Number of decimals"] = "N\195\186mero de decimales"
+L["Controls the way percentages are displayed."] = "Controlo el modo en que los porcentajes son mostrados."
+L["Data Feed"] = "Recolecta de datos"
+L["opt_feed_desc"] = "Escoger que datos recogidos son mostrados en la vista del DataBroker. Esto requiere un addon de mostrar LDB como Titan Panel."
+L["Time Measure"] = "Medida de tiempo"
+L["Activity Time"] = "Tiempo activo"
+L["Effective Time"] = "Tiempo efectivo"
+L["opt_timemesure_desc"] = [=[|cffffff00Actividad|r: el temporizador de cada miembro de la banda se pone en espera si se detiene su actividad y vuelve a contar cuando se reanuda, forma común de medir DPS y SPS.
+|cffffff00Efectivo|r: utilizado en las clasificaciones, este método utiliza el tiempo de combate transcurrido para medir el DPS y el SPS de todos los miembros de la banda.]=]
+L["Number set duplicates"] = "N\195\186mero de duplicados"
+L["Append a count to set names with duplicate mob names."] = "Agregue un recuento para establecer nombres con nombres de segmento duplicados."
+L["Set Format"] = "Formato del conjunto"
+L["Controls the way set names are displayed."] = "Controla la forma en que se muestran los nombres de los conjuntos."
+L["Links in reports"] = "Los enlaces en los informes"
+L["When possible, use links in the report messages."] = "Cuando sea posible, utilizar enlaces en los mensajes de informes."
+L["Segments to keep"] = "Segmentos para guardar"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "El n\195\186mero de segmentos de combate para guardar. Los segmentos permanentes no est\195\161n inclu\195\173dos en esto."
+L["Persistent segments"] = "Segmentos persistentes"
+L["The number of persistent fight segments to keep."] = "El n\195\186mero de segmentos persistentes que se van a conservar."
+L["Memory Check"] = "Verif. de la memoria"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "Comprueba el uso de la memoria y le advierte si es mayor o igual a %dMB."
+L["Disable Comms"] = "Desac. las comunicaciones"
+L["Minimum segment length"] = "Longitud m\195\173nima del segmento"
+L["The minimum length required in seconds for a segment to be saved."] = "La longitud m\195\173nima requerida en segundos para que se guarde un segmento."
+L["Update frequency"] = "Frecuencia de actualizaci\195\179n"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "Con qu\195\169 frecuencia se actualizan las ventanas. M\195\161s corto para actualizaciones m\195\161s r\195\161pidas. Aumenta el uso de la CPU."
+-- columns
+L["Columns"] = "Columnas"
+-- tooltips
+L["Tooltips"] = "Tooltips"
+L["Show Tooltips"] = "Mostrar tooltips"
+L["Shows tooltips with extra information in some modes."] = "Mostrar tooltips con informaci\195\179n extra en algunos modos."
+L["Informative Tooltips"] = "Tooltips informativos"
+L["Shows subview summaries in the tooltips."] = "Mostrar subvistas de resumen en los tooltips"
+L["Subview Rows"] = "Filas de subvistas"
+L["The number of rows from each subview to show when using informative tooltips."] = "El n\195\186mero de filas desde cada subvista para mostrar cuando se usan los tooltips informativos."
+L["Tooltip Position"] = "Posici\195\179n del tooltip"
+L["Position of the tooltips."] = "Posici\195\179n de los tooltips"
+L["Top Right"] = "Arriba a la derecha"
+L["Top Left"] = "Arriba a la izquierda"
+L["Bottom Right"] = "Abajo a la derecha"
+L["Bottom Left"] = "Abajo a la izquierda"
+L["Smart"] = "Inteligente"
+L["Follow Cursor"] = "Seguir el cursor"
+L["Top"] = "Cima"
+L["Bottom"] = "Fondo"
+L["Right"] = "Derecha"
+L["Left"] = "Izquierda"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00Requiere\124r: %s"
+L["Modules"] = "M\195\179dulos"
+L["Disabled Modules"] = "M\195\179dulos deshabilitados"
+L["Modules Options"] = "Opciones de m\195\179dulos"
+L["Tick the modules you want to disable."] = "Marque los m\195\179dulos que desea deshabilitar."
+L["This change requires a UI reload. Are you sure?"] = "Este cambio requiere una recarga de la UI. ¿Est\195\161s seguro?"
+-- themes options
+L["Theme"] = "Tema"
+L["Themes"] = "Temas"
+L["Manage Themes"] = "Gestionar temas"
+L["All Windows"] = "Todas las ventanas"
+L["Apply Theme"] = "Aplicar tema"
+L["Theme applied!"] = "¡Tema aplicado!"
+L["Name of your new theme."] = "Nombra tu nuevo tema."
+L["Save Theme"] = "Guardar tema"
+L["Delete Theme"] = "Eliminar tema"
+L["Are you sure you want to delete this theme?"] = "¿Seguro que quieres eliminar este tema?"
+L["Paste here a theme in text format."] = "Pegue aqui un tema en formato de texto."
+L["This is your current theme in text format."] = "Este es su actual tema en formato the texto."
+-- scroll options
+L["Scroll"] = "Desplazarse"
+L["Wheel Speed"] = "Velocidad de desplazamiento"
+L["opt_wheelspeed_desc"] = "Cambia la velocidad de desplazamiento al pasar la rueda del rat\195\179n por la ventana."
+L["Scroll Icon"] = "Icono de desplazamiento"
+L["Scroll mouse button"] = "Bot\195\179n de desplazamiento del mouse"
+-- minimap button
+L["Skada Summary"] = "Resumen de Skada"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00Click izquierdo\124r para alternar ventanas."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+Click izquierdo\124r para mostrar/ocultar ventanas."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+Click izquierdo\124r para restablecer."
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00Click derecho\124r para abrir men\195\186."
+-- skada menu
+L["Skada Menu"] = "Men\195\186 de Skada"
+L["Select Segment"] = "Seleccionar segmento"
+L["Delete Segment"] = "Borrar segmento"
+L["Keep Segment"] = "Guardar segmento"
+L["Toggle Windows"] = "Alternar ventanas"
+L["Show/Hide Windows"] = "Mostrar/Ocultar ventanas"
+L["New Segment"] = "Nuevo segmento"
+L["Starts a new segment."] = "Comenzar nuevo segmento."
+L["New Phase"] = "Nueva fase"
+L["Starts a new phase."] = "Comenzar nueva fase."
+L["Select All"] = "Seleccionar todo"
+L["Deselect All"] = "Deselecciona todo"
+-- window buttons
+L["Configure"] = "Configurar"
+L["Open Config"] = "Abrir configuraci\195\179n"
+L["btn_config_desc"] = "Abre la ventana de configuraci\195\179n."
+L["btn_reset_desc"] = [[Restablece todos los datos excepto los marcados como guardados.
+|cff00ff00Shift clic|r: Borrar segmento.]]
+L["Segment"] = "Segmento"
+L["btn_segment_desc"] = [[Salte a un segmento específico.
+|cff00ff00Shift clic|r: segmento |cffffbb00siguiente|r.
+|cff00ff00Shift Clic derecho|r: segmento |cffffbb00anterior|r.
+|cff00ff00Clic central|r: segmento |cffffbb00actual|r.]]
+L["Mode"] = "Modo"
+L["Jump to a specific mode."] = "Salta a un modo espec\195\173fico."
+L["Report"] = "Informar"
+L["btn_report_desc"] = [[Abre el diálogo que te permite informar de tus datos a otros de varias maneras.
+|cff00ff00Shift-click|r para Informe rápido.]]
+L["Stop"] = "Parar"
+L["btn_stop_desc"] = "Para o resume el segmento actual. \195\154til para descontar los datos despu\195\169s de una muerte del grupo. Puede ser establecido para que se pare autom\195\161ticamente en las opciones."
+L["Segment Stopped."] = "Segmento detenido."
+L["Segment Paused."] = "Segmento en pausa."
+L["Segment Resumed."] = "Segmento reanudado."
+L["Quick Access"] = "Acceso rapido"
+-- default segments
+L["Total"] = "Total"
+L["Current"] = "Actual"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %s por %s:"
+L["Self"] = "Propio"
+L["Whisper Target"] = "Susurrar objetivo"
+L["Copy & Paste"] = "Copiar y empastar"
+L["[General]"] = "General"
+L["[LocalDefense]"] = "DefensaLocal"
+L["[LookingForGroup]"] = "BuscandoGrupo"
+L["[Trade]"] = "Comercio"
+L["Line"] = "Linea"
+L["Lines"] = "Lineas"
+L["There is nothing to report."] = "No hay nada que informar."
+L["No mode or segment selected for report."] = "No hay modo o segmento seleccionado para informe."
+-- Bar Display Module --
+L["Bar Display"] = "Visualizaci\195\179n de la barra"
+L["mod_bar_desc"] = "Lo que muestra la barra es la normal usada por la mayor\195\173a de extensiones Medidores de Da\195\177o. Puede ser profusamente customizada."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "Visualizaci\195\179n de barra (antiguo)"
+L["Max Bars"] = "Barras M\195\161ximas"
+L["The maximum number of bars shown."] = "El n\195\186mero m\195\161ximo de barras para mostrar."
+L["Show Menu Button"] = "Mostrar bot\195\179n\195\173de men\195\186"
+L["Shows a button for opening the menu in the window title bar."] = "Muestra un bot\195\179n para abrir el men\195\186 en la barra de t\195\173tulo de la ventana."
+L["Class Color Bars"] = "Barras coloreadas por clase"
+L["Class Color Text"] = "Texto coloreado por clase"
+-- Threat Module --
+L["Threat"] = "Amenaza"
+L["Threat Warning"] = "Advertencia de amenaza"
+L["Flash Screen"] = "Destello de la pantalla"
+L["This will cause the screen to flash as a threat warning."] = "Esto causar\195\161 un destello en la pantalla como advertencia de amenaza."
+L["Shake Screen"] = "Agitar la pantalla"
+L["This will cause the screen to shake as a threat warning."] = "Esto causar\195\161 que se agite la pantalla como advertencia de amenaza."
+L["Warning Message"] = "Mensaje de advertencia"
+L["Print a message to screen when you accumulate too much threat."] = "Mostrar una mensaje en pantalla cu\195\161ndo acumulas demasiada amenaza."
+L["Play sound"] = "Reproducir un sonido"
+L["This will play a sound as a threat warning."] = "Esto reproducir\195\161 un sonido como advertencia de amenaza."
+L["Message Output"] = "Salida de mensaje"
+L["Choose where warning messages should be displayed."] = "Elija d\195\179nde deben aparecer los mensajes de advertencia."
+L["Chat Frame"] = "Cuadro de chat"
+L["Blizzard Error Frame"] = "Cuadro de error"
+L["Threat sound"] = "Sonido de amenaza"
+L["opt_threat_soundfile_desc"] = "El sonido que ser\195\161 reproducido cuando tu porcentaje de amenaza alcance un porcentaje concreto."
+L["Warning Frequency"] = "Frecuencia de advertencia"
+L["Threat Threshold"] = "Umbral de amenaza"
+L["opt_threat_threshold_desc"] = "Cuando tu amenaza alcance este nivel, relativo al tanque, las advertencias son mostrados."
+L["Show raw threat"] = "Mostrar amenaza cruda"
+L["opt_threat_rawvalue_desc"] = "Mostrar porcentaje de amenaza cruda relativa al tanque en lugar de modificada por rango."
+L["Use focus target"] = "Utilizar el objetivo del foco"
+L["opt_threat_focustarget_desc"] = "Indica a Skada que adicionalmente revise tu 'foco' y 'objetivo de foco' antes que tu 'objetivo' y 'objetivo de objetivo' en ese orden en la ventana de amenaza."
+L["Disable while tanking"] = "Desac. cu\195\161ndo eres el tanque"
+L["opt_threat_notankwarnings_desc"] = "No dar ninguna alerta si Actitud defensiva, Forma de oso, Furia recta o Presencia de Escarcha est\195\161 activado."
+L["Ignore Pets"] = "Ignorar las mascotas"
+L["opt_threat_ignorepets_desc"] = [=[Indica a Skada que ignore las mascotas de los jugadores enemigos al determinar qué unidades debe mostrar en los datos de amenaza.
+
+Las mascotas de los jugadores mantienen una tabla de amenaza cuando se encuentran en modo |cffffff78Agresivo|r o |cffffff78Defensivo|r y se comportan de manera normal atacando al objetivo con la amenaza más alta. Si se le indica a la mascota que ataque a un objetivo específico, ésta mantiene su tabla de amenaza, pero permanece con el objetivo asignado el cual por definición tiene 100% de amenaza. Las mascotas de los jugadores pueden ser provocadas para forzarlas a que te ataquen.
+
+Las mascotas de los jugadores en modo |cffffff78Pasivo|r no tienen tabla de amenaza y la habilidad provocar no funciona en ellas, sólo atacarán a su objetivo asignado cuando se les indique hacerlo y lo harán sin ninguna tabla de amenaza.
+
+Cuando a una mascota se le indica |cffffff78Seguir|r al jugador, su tabla de amenaza es eliminada inmediatamente y deja de atacar su objetivo, aunque podría volver a adquirir un nuevo objetivo si se encuentra en modo agresivo/defensivo.]=]
+L["> Pull Aggro <"] = "> Amenaza para Aggro <"
+L["Show Pull Aggro Bar"] = "Mostrar Barra de Amenaza para Aggro"
+L["opt_threat_showaggrobar_desc"] = "Mostrar una barra que indica la amenaza que necesitas para conseguir el aggro y te ataquen (Amenaza para Aggro)."
+L["Test Warnings"] = "Avisos de Prueba"
+L["TPS"] = "APS"
+L["Threat: Personal Threat"] = "Amenaza: Amenaza Personal"
+-- Absorbs & Healing Module --
+L["Healing"] = "Sanaci\195\179n"
+L["Healing Done"] = "Sanaci\195\179n realizada"
+L["Healing Taken"] = "Sanaci\195\179n recibida"
+L["HPS"] = "SPS"
+L["sHPS"] = "SPS (subvistas)"
+L["Healing: Personal HPS"] = "Sanaci\195\179n: HPS Personal"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "Sanaci\195\179n: HPS de Banda"
+L["Total Healing"] = "Curaci\195\179n total"
+L["Overheal"] = "Curaci\195\179n excesiva"
+L["Overhealing"] = "Curaci\195\179n excesiva"
+L["Absorbs"] = "Absorci\195\179n"
+L["Target List"] = "Lista de objetivos"
+L["Spell List"] = "Lista de hechizos"
+L["APS"] = "AbPS"
+L["sAPS"] = "AbPS (subvistas)"
+L["Absorbs and Healing"] = "Absorci\195\179n y sanaci\195\179n"
+L["Healing Done By Spell"] = "Sanaci\195\179n hecha por hechizo"
+L["Source List"] = "Lista de fuentes"
+-- Auras Module --
+L["Uptime"] = "Disponibilidad"
+L["Buffs and Debuffs"] = "Bufos y Debufos"
+L["Buffs"] = "Bufos"
+L["Debuffs"] = "Debufos"
+L["%s's <%s> targets"] = "Objetivos de <%2$s> de %1$s"
+L["%s's <%s> sources"] = "Fuentes de <%2$s> de %1$s"
+L["Enemy Buffs"] = "Bufos de enemigo"
+L["Enemy Debuffs"] = "Debufos de enemigo"
+-- CC Tracker Module --
+L["Crowd Control"] = "Controles de masas"
+L["CC Done"] = "Controles hechos"
+L["CC Taken"] = "Controles recibidos"
+L["CC Breaks"] = "Controles interrumpidos"
+L["Ignore Main Tanks"] = "Ignorar los tanques principales"
+L["%s on %s removed by %s"] = "%s sobre %s eliminado por %s"
+L["%s on %s removed by %s's %s"] = "%1$s sobre %2$s eliminado por %4$s de %3$s"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "Entorno"
+-- damage done module
+L["Damage"] = "Da\195\177o"
+L["Spell Details"] = "Detalles del hechizo"
+L["Damage Done"] = "Da\195\177o hecho"
+L["Useful Damage"] = "Da\195\177o \195\186til"
+L["Useful damage on %s"] = "Da\195\177o \195\186til en %s"
+L["Damage Done By Spell"] = "Da\195\177o causado por hechizo"
+L["%s's sources"] = "Fuentes de %s"
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (subvistas)"
+L["Damage: Personal DPS"] = "Da\195\177o: DPS Personal"
+L["RDPS"] = "DPS de Banda"
+L["Damage: Raid DPS"] = "Da\195\177o: DPS de Banda"
+L["Absorbed Damage"] = "Da\195\177o absorbido"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "Active esta opci\195\179n si desea que el da\195\177o hecho de incluir el da\195\177o absorbido."
+L["Damage Done By School"] = "Da\195\177o hecho por la escuela"
+-- killing blows module
+L["Only PvP Kills"] = "Solo muertes en JcJ"
+L["When enabled, only kills against enemy players count."] = "Cuando est\195\161 activado, s\195\179lo cuentan las muertes contra jugadores enemigos."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "Anuncia golpes de gracia una vez finalizado el combate. Solo funciona contra jefes."
+-- damage taken module
+L["Damage Taken"] = "Da\195\177o recibido"
+L["Damage Taken By Spell"] = "Da\195\177o recibido por hechizos"
+L["%s's targets"] = "Objetivos de %s"
+L["DTPS"] = "DRPS"
+L["sDTPS"] = "DRPS (subvistas)"
+-- enemy damage done module
+L["Enemies"] = "Enemigos"
+L["Enemy Damage Done"] = "Da\195\177o de enemigo hecho"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "Da\195\177o de enemigo recibido"
+L["%s below %s%%"] = "%s bajo %s%%"
+L["%s - %s%% to %s%%"] = "%s - %s%% a %s%%"
+L["Phase %s"] = "Fase %s"
+L["%s - Phase %s"] = "%s - Fase %s"
+L["%s - Phase 1"] = "%s - Fase 1"
+L["%s - Phase 2"] = "%s - Fase 2"
+L["%s - Phase 3"] = "%s - Fase 3"
+L["%s (Main Boss)"] = "%s (Jefe principal)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r comenz\195\179."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r detenida."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r continu\195\179."
+-- enemy healing done module
+L["Enemy Healing Done"] = "Sanaci\195\179n de Enemigos"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "Evitaci\195\179n y mitigaci\195\179n"
+L["More Details"] = "M\195\161s detalles"
+L["%s's details"] = "Detalles de %s"
+-- friendly fire module
+L["Friendly Fire"] = "Fuego amigo"
+-- useful damage targets
+L["Important targets"] = "Objetivos importantes"
+L["Oozes"] = "Oozes"
+L["Princes overkilling"] = "Da\195\177o excesivo en los pr\195\173ncipes"
+L["Adds"] = "Adds"
+L["Halion and Inferno"] = "Halion y Inferno"
+L["Valkyrs overkilling"] = "Da\195\177o excesivo en Valkyrs"
+-- Deaths Module --
+L["%s's deaths"] = "Muertes de %s"
+L["Death log"] = "Log de muertes"
+L["%s's death log"] = "Log de muertes de %s"
+L["Player's deaths"] = "Muertes de jugadores"
+L["%s dies"] = "%s muere"
+L["buff"] = "bufo"
+L["debuff"] = "debufo"
+L["Spell details"] = "Detalle de hechizos"
+L["Spell"] = "Hechizo"
+L["Amount"] = "Cantidad"
+L["Source"] = "Fuente"
+L["Change"] = "Cambio"
+L["Time"] = "Hora"
+L["Survivability"] = "Supervivencia"
+L["Events Amount"] = "Cantidad de eventos"
+L["Set the amount of events the death log should record."] = "Establecer la cantidad de eventos del registro de muerte debe registrar."
+L["Minimum Healing"] = "Curaci\195\179n m\195\173nima"
+L["Ignore heal events that are below this threshold."] = "Ignore los eventos de sanaci\195\179n que est\195\169n por debajo de este umbral."
+L["Announce Deaths"] = "Anunciar muertes"
+L["Announces information about the last hit the player took before they died."] = "Anuncia el \195\186ltimo golpe que recibi\195\179 el jugador antes de morir."
+L["Alternative Display"] = "Visualizaci\195\179n alternativa"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "Si un jugador mueren varias veces, cada muerte ser\195\161 visualizada como una barra separada."
+-- activity module
+L["Activity"] = "Actividad"
+L["Activity per Target"] = "Actividad por objetivo"
+L["%s's activity"] = "Actividad de %s"
+-- dispels module lines --
+L["Dispel Spells"] = "Hechizos de disipar"
+L["%s's dispelled spells"] = "Hechizos disipados de %s"
+-- interrupts module lines --
+L["Interrupts"] = "Interrupciones"
+L["Interrupt Spells"] = "Hechizos de interrupci\195\179n"
+L["%s's interrupted spells"] = "Hechizos interrumpidos de %s"
+L["%s interrupted!"] = "¡%s interrumpida!"
+-- Power gained module --
+L["Resources"] = "Recursos"
+L["Mana Restored"] = "Mana restaurada"
+L["Rage Generated"] = "Ira generada"
+L["Energy Generated"] = "Energ\195\173a generada"
+L["Runic Power Generated"] = "Poder runico generado"
+-- Parry module lines --
+L["Parry-Haste"] = "Parar-celeridad"
+L["%s parried %s (%s)"] = "%s par\195\179 a %s (%s)"
+-- Potions module lines --
+L["Potions"] = "Pociones"
+L["%s's potions"] = "Pociones de %s"
+L["Pre-potion"] = "Pre-poci\195\179n"
+L["pre-potion: %s"] = "pre-poci\195\179n: %s"
+L["Prints pre-potion after the end of the combat."] = "Imprime la lista de jugadores que usaron pre-poci\195\179n despu\195\169s de salir de combate."
+-- healthstone --
+L["Healthstones"] = "Piedras de salud"
+-- resurrect module lines --
+L["Resurrects"] = "Resurrecciones"
+-- nickname module lines --
+L["Nickname"] = "Apodo"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "El apodo se env\195\173a a los miembres de la hermandad, y se muestra en Skada en vez del nombre de su personaje."
+L["Set a nickname for you."] = "Reemplazar el nombre de su personaje."
+L["Nickname isn't a valid string."] = "El apodo no es una cadena v\195\161lida."
+L["Your nickname is too long, max of 12 characters is allowed."] = "Su apodo es demasiado largo, se permite un m\195\161ximo de 12 caracteres."
+L["Only letters and two spaces are allowed."] = "Solo se permiten letras y dos espacios."
+L["Your nickname contains a forbidden word."] = "Tu apodo contiene una palabra prohibida."
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "No puede usar la misma letra tres veces consecutivas, dos espacios consecutivos o m\195\161s de dos espacios."
+L["Ignore Nicknames"] = "Ignorar apodos"
+L["When enabled, nicknames set by Skada users are ignored."] = "Cuando est\195\161 habilitado, los apodos establecidos por los usuarios de Skada se ignoran."
+L["Name display"] = "Formato de nombres"
+L["Choose how names are shown on your bars."] = "Elija c\195\179mo se muestran los nombres en sus barras."
+L["Clear Cache"] = "Limpiar Cach\195\169"
+L["Are you sure you want clear cached nicknames?"] = "¿Est\195\161s seguro de que quieres borrar los apodos almacenados en cach\195\169?"
+-- overkill module lines --
+L["Overkill"] = "Exceso de da\195\177o"
+-- tweaks module lines --
+L["Improvement"] = "Mejora"
+L["Tweaks"] = "Ajustes"
+L["First hit"] = "Primer golpe"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00Primer golpe\124r: %s de %s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00Primer golpe\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00Jefe primer objetivo\124r: %s"
+L["opt_tweaks_firsthit_desc"] = "Imprime un mensaje con el primer golpe antes de entrar en combate.\nSolo funciona para encuentos con jefes."
+L["Filter DPS meters Spam"] = "Filtrar el spamn de medidores de DPS"
+L["opt_tweaks_spamage_desc"] = "Suprime los mensajes en el chat de medidores de da\195\177o y brinda un \195\186nico link en el chat con estadisticas en una ventana emergente."
+L["Reported by: %s"] = "Reportado por: %s"
+L["Smart Stop"] = "Parada inteligente"
+L["opt_tweaks_smarthalt_desc"] = "Detiene autom\195\161ticamente el segmento actual despu\195\169s de que el jefe ha muerto.\n\195\154til para evitar la recopilaci\195\179n de datos en caso de un error de combate."
+L["Duration"] = "Duraci\195\179n"
+L["opt_tweaks_smartwait_desc"] = "¿Por cu\195\161nto tiempo debe esperar antes de Skada detener el segmento?"
+L["Modes Icons"] = "Iconos de modos"
+L["Show modes icons on bars and menus."] = "Muestra los iconos de los modos en las barras y los men\195\186s."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "Active esta opci\195\179n si quiere ignorar \124cffffbb00%s\124r."
+L["Custom Colors"] = "Colores personalizados"
+L["Arena Teams"] = "Equipos de arena"
+L["Are you sure you want to reset all colors?"] = "¿Est\195\161s seguro de que quieres restablecer todos los colores?"
+L["Announce %s"] = "Anunciar: %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "Anuncia el tiempo que tom\195\179 en aplicar %d cargas de %s y anuncia cuando expiren."
+L["%s dropped from %s!"] = "%s expir\195\179 en %s!"
+L["%s stacks of %s applied on %s in %s sec!"] = "¡%s pilas de %s aplicadas a %s en %s seg!"
+L["My Spells"] = "Mis habilidades"
+-- total data options
+L["Total Segment"] = "Segmento total" -- needs review
+L["All Segments"] = "Todos los segmentos" -- needs review
+L["Raid Bosses"] = "Jefes de raid" -- needs review
+L["Raid Trash"] = "Trash de raid" -- needs review
+L["Dungeon Bosses"] = "Jefes de mazmorra" -- needs review
+L["Dungeon Trash"] = "Trash de mazmorra" -- needs review
+L["opt_tweaks_total_all_desc"] = "Todos los segmentos se a\195\177aden a los datos del segmento total." -- needs review
+L["opt_tweaks_total_fmt_desc"] = "Los segmentos con %s se a\195\177aden a los datos del segmento total." -- needs review
+L["Detailed total segment"] = "Segmento total detallado"
+L["opt_tweaks_total_full_desc"] = "Cuando est\195\161 habilitado, Registrar\195\161 todo en el segmento total en lugar de solo los totales (registre los detalles del hechizo en el segmento \124cffffbb00total\124r)."
+-- arena
+L["mod_pvp_desc"] = "A\195\177adir detecci\195\179n de especializaci\195\179n para arenas y campos de batalla, y mostrar a los oponentes de la arena en la misma ventana."
+L["Gold Team"] = "Equipo dorado"
+L["Green Team"] = "Equipo verde"
+L["Color for %s."] = "Color para %s."
+-- notifications
+L["Notifications"] = "Notificaciones"
+L["opt_toast_desc"] = "Utiliza notificaciones visuales en lugar de mensajes de la ventana de chat cuando corresponde."
+L["Test Notifications"] = "Notificaciones de prueba"
+-- comparison module
+L["Comparison"] = "Comparaci\195\179n"
+L["%s vs %s: %s"] = "%s vs %s: %s"
+L["%s vs %s: Spells"] = "%s vs %s: Hechizos"
+L["%s vs %s: Targets"] = "%s vs %s: Objetivos"
+-- spellcast module
+L["Casts"] = "Lanzar"
+L["%s's spells"] = "Hechizos de %s"
+L["%s's spells on %s"] = "Hechizos de %s en %s"
+L["Spells on %s"] = "Hechizos en %s"
+-- about
+L["Author"] = "Autor"
+L["Credits"] = "Cr\195\169ditos"
+L["Date"] = "Fecha"
+L["License"] = "Licencia"
+L["Version"] = "Versi\195\179n"
+L["Website"] = "Sitio web"
+-- some bosses entries
+L["World Boss"] = "Jefe de mundo"
+L["Auriaya"] = "Auriaya"
+L["Blood Prince Council"] = "Consejo de Pr\195\173ncipes de Sangre"
+L["Faction Champions"] = "Campeones de Facci\195\179n"
+L["Hogger"] = "Hogger"
+L["Icecrown Gunship Battle"] = "Batalla de las Aeronaves de Corona de Hielo"
+L["Kologarn"] = "Kologarn"
+L["Mimiron"] = "Mimiron"
+L["Thaddius"] = "Thaddius"
+L["The Four Horsemen"] = "Los Cuatro Jinetes"
+L["The Iron Council"] = "Asamblea de Hierro"
+L["The Northrend Beasts"] = "Las bestias de Rasganorte"
+L["Thorim"] = "Thorim"
+L["Twin Val'kyr"] = "Gemelas Val'kyr"
+L["Valithria Dreamwalker"] = "Valithria Caminasue\195\177os"
+L["Yogg-Saron"] = "Yogg-Saron"
diff --git a/Skada/Locales/frFR.lua b/Skada/Locales/frFR.lua
new file mode 100644
index 0000000..6f731e4
--- /dev/null
+++ b/Skada/Locales/frFR.lua
@@ -0,0 +1,760 @@
+--[[ Translator: Kader B ]] --
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "frFR")
+if not L then return end
+
+L["A damage meter."] = "Un \"damage meter\"."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "L'utilisation de la m\195\169moire est \195\169lev\195\169e. Vous devriez r\195\169initialiser Skada et activer une des options de r\195\169initialisation automatique."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada n'est pas \195\160 jour. Vous pouvez t\195\169l\195\169charger la nouvelle version sur \124cffffbb00%s\124r"
+L["Skada: Modes"] = "Skada: Modes"
+L["Skada: Fights"] = "Skada : Combats"
+L["Data Collection"] = "Collecte de donn\195\169es"
+L["ENABLED"] = "ACTIV\195\137"
+L["DISABLED"] = "D\195\137SACTIV\195\137"
+L["Enable All"] = "Activer tout"
+L["Disable All"] = "D\195\169sactiver tout"
+L["Stopping for wipe."] = "Arr\195\170t pour cause de wipe."
+L["Usage:"] = "Usage:"
+L["Commands:"] = "Commandes:"
+L["Import"] = "Importer"
+L["Export"] = "Exporter"
+L["Import/Export"] = "Importer/Exporter"
+-- profiles
+L["Profiles"] = "Profils"
+L["Profile Import/Export"] = "Importation/Exportation de profils"
+L["Import Profile"] = "Importer un profil"
+L["Export Profile"] = "Exporter le profil"
+L["Paste here a profile in text format."] = "Collez ici un profil au format texte."
+L["Press CTRL-V to paste the text from your clipboard."] = "Ctrl-V pour coller le texte depuis votre presse-papiers."
+L["This is your current profile in text format."] = "Voici votre profil actuel au format texte."
+L["Press CTRL-C to copy the text to your clipboard."] = "Ctrl-C pour copier le texte dans votre presse-papier."
+L["Network Sharing"] = "Partage sur le r\195\169seau"
+L["Player Name"] = "Nom du joueur"
+L["Send Profile"] = "Envoyer le profil"
+L["Accept profiles from other players."] = "Accepter les profils des autres joueurs."
+L["opt_profile_received"] = "%s vous a envoy\195\169 un profil de configuration. Voulez-vous activer le profil re\195\167u?"
+L["Progress"] = "Progression"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "Taille des donn\195\169es : \124cffffffff%.1f\124rKo"
+L["Transmision Progress: %02.f%%"] = "Progression de la transmission : %d%%"
+L["Transmission Completed"] = "Transmission termin\195\169e"
+-- common lines
+L["Options"] = "Param\195\168tres"
+L["Options for %s."] = "Param\195\168tres \1242 %s."
+L["General"] = "G\195\169n\195\169ral"
+L["General options for %s."] = "Param\195\168tres g\195\169n\195\169raux \1242 %s."
+L["Text"] = "Texte"
+L["Text options for %s."] = "Param\195\168tres de texte \1242 %s."
+L["Format"] = "Format"
+L["Format options for %s."] = "Options de format \1242 %s."
+L["Appearance"] = "Apparence"
+L["Appearance options for %s."] = "Options d'apparence \1242 %s."
+L["Advanced"] = "Avanc\195\169"
+L["Advanced options for %s."] = "Param\195\168tres avanc\195\169s \1242 %s."
+L["Position"] = "Position"
+L["Position settings for %s."] = "Param\195\168tres de position \1242 %s."
+L["Width"] = "Largeur"
+L["The width of %s."] = "La largeur \1242 %s."
+L["Height"] = "Hauteur"
+L["The height of %s."] = "La hauteur \1242 %s."
+L["Active Time"] = "Temps d'activit\195\169"
+L["Segment Time"] = "Temps du segment"
+L["Click for \124cff00ff00%s\124r"] = "Cliquer pour \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift clic pour \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Ctrl clic pour \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt clic pour \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "Filtrer par classe"
+L["Average"] = "Moyenne"
+L["Count"] = "Nombre"
+L["Refresh"] = "R\195\169actualisation"
+L["Percent"] = "Pourcentage"
+L["sPercent"] = "Pourcentage (sous-vues)"
+L["General Options"] = "Param\195\168tres g\195\169n\195\169raux"
+-- L["HoT"] = "HoT"
+-- L["DoT"] = "DoT"
+L["Hits"] = "Coups"
+L["Normal Hits"] = "Coups normaux"
+L["Critical"] = "Critique"
+L["Critical Hits"] = "Coups critiques"
+L["Crushing"] = "\195\137crasement"
+L["Glancing"] = "\195\137rafle"
+L["ABSORB"] = "Absorb\195\169"
+L["BLOCK"] = "Bloqu\195\169"
+L["DEFLECT"] = "D\195\169vie"
+L["DODGE"] = "Esquive"
+L["EVADE"] = "\195\137vite"
+L["IMMUNE"] = "Insensible"
+L["MISS"] = "Rat\195\169"
+L["PARRY"] = "Pare"
+L["REFLECT"] = "Renvoy\195\169"
+L["RESIST"] = "R\195\169sist\195\169"
+L["Only for bosses."] = "Uniquement contre les boss"
+L["Enable this only against bosses."] = "Activer uniquement contre les boss."
+-- segment info
+L["Start"] = "D\195\169but"
+L["End"] = "Fin"
+-- windows section:
+L["Window"] = "Fen\195\170tre"
+L["Windows"] = "Fen\195\170tres"
+L["Create Window"] = "Cr\195\169er une fen\195\170tre"
+L["Window Name"] = "Nom de la fen\195\170tre"
+L["Enter the name for the new window."] = "Entrez le nom de la nouvelle fen\195\170tre"
+L["Delete Window"] = "Supprimer la fen\195\170tre"
+L["Choose the window to be deleted."] = "Choisissez la fen\195\170tre \195\160 supprimer"
+L["Are you sure you want to delete this window?"] = "\195\138tes-vous s\195\187r de vouloir supprimer cette fen\195\170tre?"
+L["Delete All Windows"] = "Supprimer toutes les fen\195\170tres"
+L["Are you sure you want to delete all windows?"] = "\195\138tes-vous s\195\187r de vouloir supprimer toutes les fen\195\170tres?"
+L["Rename Window"] = "Renommer la fen\195\170tre"
+L["Enter the name for the window."] = "Entrez le nom de la fen\195\170tre"
+L["Test Mode"] = "Mode de test"
+L["Creates fake data to help you configure your windows."] = "Cr\195\169e de fausses donn\195\169es pour vous aider \195\160 configurer vos fen\195\170tres."
+L["Child Window"] = "Fen\195\170tre enfant"
+L["A child window will replicate the parent window actions."] = "Une fen\195\170tre enfant copiera les actions de la fen\195\170tre parente."
+L["Child Window Mode"] = "Mode Parent-Enfant"
+L["Lock Window"] = "Verrouiller la fen\195\170tre"
+L["Locks the bar window in place."] = "Verrouille la fen\195\170tre des barres \195\160 sa position actuelle."
+L["Hide Window"] = "Cacher la fen\195\170tre"
+L["Hides the window."] = "Cache la fen\195\170tre"
+L["Sticky Window"] = "Fen\195\170tre collante"
+L["Allows the window to stick to other Skada windows."] = "Permet \195\160 la fen\195\170tre de s'aligner sur d'autres fen\195\170tres Skada."
+L["Snap to best fit"] = "Corriger pour adapter"
+L["Snaps the window size to best fit when resizing."] = "Corrige la taille de la fen\195\170tre afin qu'elle s'adapte mieux \195\160 son contenu lors des redimensionnements."
+L["Disable Resize Buttons"] = "D\195\169s. les boutons de redimensionnements"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "Les boutons de redimensionnement et de verrouillage/d\195\169verrouillage ne s'afficheront pas lorsque vous survolez la fen\195\170tre."
+L["Disable stretch button"] = "D\195\169s. le bouton d'\195\169tirement"
+L["Stretch button won't show up when you hover over the window."] = "Le bouton d'\195\169tirement ne s'affiche pas lorsque vous survolez la fen\195\170tre."
+L["Reverse window stretch"] = "\195\137tirement vers le bas"
+L["opt_botstretch_desc"] = "Place le bouton d'\195\169tirement en bas de la fenê\195\170tre et fait en sorte que cette derni\195\168re s'\195\169tire vers le bas."
+L["Display System"] = "Syst\195\168me d'affichage"
+L["Choose the system to be used for displaying data in this window."] = "Choisissez le syst\195\168me \195\160 utiliser pour l'affichage des donn\195\169es dans cette fen\195\170tre."
+L["Copy Settings"] = "Copier les param\195\168tres"
+L["Choose the window from which you want to copy the settings."] = "Choisissez la fen\195\170tre \195\160 partir de laquelle vous souhaitez copier les param\195\168tres."
+-- bars
+L["Bars"] = "Barres"
+L["Left Text"] = "Texte de gauche"
+L["Right Text"] = "Texte de droite"
+L["Font"] = "Police"
+L["The font used by %s."] = "La police utilis\195\169e par %s."
+L["Font Size"] = "Taille de police"
+L["The font size of %s."] = "La taille de police \1242 %s."
+L["Font Outline"] = "Contour de la police"
+L["Sets the font outline."] = "D\195\169finit le type de contour de la police."
+L["Outline"] = "Contour"
+L["Thick"] = "\195\137pais"
+L["Thick outline"] = "Contour \195\169pais"
+L["Monochrome"] = "Monochrome"
+L["Outlined monochrome"] = "Contour monochrome"
+L["Bar Texture"] = "Texture des barres"
+L["The texture used by all bars."] = "La texture utilis\195\169e par toutes les barres."
+L["Spacing"] = "Espacement"
+L["Distance between %s."] = "La distance entre %s."
+L["Displacement"] = "D\195\169calage"
+L["The distance between the edge of the window and the first bar."] = "La distance entre le bord de la fen\195\170tre et la premi\195\168re barre."
+L["Bar Orientation"] = "Orientation des barres"
+L["The direction the bars are drawn in."] = "La direction vers laquelle les barres sont dessin\195\169es"
+L["Left to right"] = "Gauche vers la droite"
+L["Right to left"] = "Droite vers la gauche"
+L["Reverse bar growth"] = "Croissance invers\195\169e des barres"
+L["Bars will grow up instead of down."] = "Les barres s'ajouteront vers le haut au lieu de vers le bas."
+L["Disable bar highlight"] = "D\195\169s. la mise en \195\169vidence de la barre"
+L["Hovering a bar won't make it brighter."] = "Le survol d'une barre ne la rendra pas plus lumineuse."
+L["Bar Color"] = "Couleur des barres"
+L["Choose the default color of the bars."] = "Choisissez la couleur par d\195\169faut des barres."
+L["Background Color"] = "Couleur du fond"
+L["The color of the background."] = "La couleur du fond."
+L["Custom Color"] = "Couleur perso."
+L["Use a different color for my bar."] = "Utiliser une couleur diff\195\169rente pour ma barre."
+L["My Color"] = "Ma couleur"
+L["Spell school colors"] = "Couleurs de sorts"
+L["Use spell school colors where applicable."] = "Utiliser les couleurs des \195\169coles de magie quand cela est possible."
+L["When possible, bars will be colored according to player class."] = "Quand cela est possible les barres seront colori\195\169es selon la classe des joueurs repr\195\169sent\195\169s."
+L["When possible, bar text will be colored according to player class."] = "Quand cela est possible, le texte des barres sera colori\195\169 selon la classe du joueur repr\195\169sent\195\169."
+L["Class Icons"] = "Ic\195\180nes de classe"
+L["Use class icons where applicable."] = "Utiliser les ic\195\180nes de classe quand cela est possible."
+L["Spec Icons"] = "Ic\195\180nes de sp\195\169cialisation"
+L["Use specialization icons where applicable."] = "Utiliser les ic\195\180nes de sp\195\169cialisation quand cela est possible."
+L["Role Icons"] = "Ic\195\180nes de r\195\180le"
+L["Use role icons where applicable."] = "Utiliser les ic\195\180nes de r\195\180le quand cela est possible."
+L["Show Spark Effect"] = "Effet de lueur"
+L["Click Through"] = "Clic \195\160 travers"
+L["Disables mouse clicks on bars."] = "D\195\169s. les clics de souris sur les barres."
+L["Smooth Bars"] = "Barres fluides"
+L["Animate bar changes smoothly rather than immediately."] = "Animation fluide des barres."
+-- title bar
+L["Title Bar"] = "Barre de titre"
+L["Enables the title bar."] = "Active la barre-titre."
+L["Include set"] = "Inclure l'ensemble"
+L["Include set name in title bar"] = "Inclure le nom d'ensemble dans la barre de titre"
+L["Encounter Timer"] = "Temps de combat"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "Si activ\195\169, un chronom\195\168tre sera affich\195\169 \195\160 gauche du texte du titre."
+L["Mode Icon"] = "Ic\195\180ne de module"
+L["Shows mode's icon in the title bar."] = "Afficher l'ic\195\180ne du mode dans la barre de titre."
+L["The texture used as the background of the title."] = "La texture utilis\195\169e comme fond de la barre de titre."
+L["Border texture"] = "Texture de la bordure"
+L["The texture used for the borders."] = "La texture utilis\195\169e pour les bordures."
+L["Border Color"] = "Couleur de la bordure"
+L["The color used for the border."] = "La couleur \195\160 utiliser pour la bordure."
+L["Buttons"] = "Boutons"
+L["Auto Hide Buttons"] = "Afficher au survol de la souris"
+L["Show window buttons only if the cursor is over the title bar."] = "Afficher les boutons de la fen\195\170tre uniquement si le curseur se trouve au-dessus de la barre de titre."
+L["Buttons Style"] = "Style des boutons"
+L["Are you sure you want to reinstall Skada?"] = "\195\138tes-vous s\195\187r de vouloir r\195\169installer Skada?"
+-- general window
+L["Background Texture"] = "Texture du fond"
+L["The texture used as the background."] = "La texture utilis\195\169e comme fond."
+L["Tile"] = "Tuile"
+L["Tile the background texture."] = "Tuile la texture du fond"
+L["Tile Size"] = "Taille des tuiles"
+L["The size of the texture pattern."] = "La taille du motif de la texture."
+L["Background Color"] = "Couleur de fond"
+L["Border"] = "Bordure"
+L["Border Thickness"] = "\195\137paisseur de la bordure"
+L["The thickness of the borders."] = "L'\195\169paisseur des bordures."
+L["Border Insets"] = "Distance de la bordure"
+L["The distance between the window and its border."] = "La distance entre la fen\195\170tre et sa bordure."
+L["Scale"] = "\195\137chelle"
+L["Sets the scale of the window."] = "D\195\169finit l'\195\169chelle de la fen\195\170tre."
+L["Strata"] = "Couche"
+L["This determines what other frames will be in front of the frame."] = "Ceci d\195\169termine quels autres cadres sont plac\195\169s devant le cadre."
+L["Clamped To Screen"] = "Restreindre \195\160 l'\195\169cran"
+L["Toggle whether to permit movement out of screen."] = "Permet ou non le d\195\169placement de la fen\195\170tre hors de l'\195\169cran."
+L["X Offset"] = "D\195\169calage X"
+L["Y Offset"] = "D\195\169calage Y"
+-- switching
+L["Mode Switching"] = "Changement de vue"
+L["Combat Mode"] = "Mode en combat"
+L["opt_combatmode_desc"] = "Passe automatiquement au segment \124cffffbb00Actuel\124r et au mode choisi ci-dessous quand vous entrez en combat."
+L["Wipe Mode"] = "Mode wipe"
+L["opt_wipemode_desc"] = "Passe automatiquement au segment \124cffffbb00Actuel\124r et \195\160 ce mode apr\195\168s un wipe."
+L["Return after combat"] = "Retour apr\195\168s combat"
+L["Return to the previous set and mode after combat ends."] = "Retourne au mode et \195\160 la vue pr\195\169c\195\169dente une fois le combat termin\195\169."
+L["Auto switch to current"] = "Retour au seg. actuel"
+L["opt_autocurrent_desc"] = "Une fois en combat, cette fen\195\170tre retourne automatiquement au segment \124cffffbb00Actuel\124r."
+L["Auto Hide"] = "Masquage automatique"
+L["While in combat"] = "En combat"
+L["While out of combat"] = "Hors combat"
+L["While not in a group"] = "Pas en groupe"
+L["While inside an instance"] = "Dans une instance"
+L["While not inside an instance"] = "Pas dans une instance"
+L["In Battlegrounds"] = "Dans les champs de battaile"
+L["Inline Bar Display"] = "Barres en ligne"
+L["mod_inline_desc"] = "L'affichage en ligne est un style de fen\195\170tre horizontale."
+L["Font Color"] = "Couleur de police"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "Couleur de la police.\nCochez \"Couleurs de classes\" pour commencer."
+L["opt_barwidth_desc"] = "Largeur des barres. Ceci n'est applicable que si \"Largeur de barre fixe\" est coch\195\169e."
+L["Fixed bar width"] = "Largeur de barre fixe"
+L["opt_fixedbarwidth_desc"] = "Si coch\195\169, la largeur de barre sera fixe. Autrement, la largeur de barre d\195\169pend de la largeur du texte."
+L["Use class colors for %s."] = "Utiliser les couleurs des classes pour %s."
+L["opt_isusingclasscolors_desc"] = "Avec: %s - 5.71M (21.7K)\nSans: %s - 5.71M (21.7K)"
+L["Put values on new line."] = "Valeurs sur une nouvelle ligne."
+L["opt_isonnewline_desc"] = "Nouvelle ligne:\n%1$s\n5.71M (21.7K)\n\nS\195\169parateur:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = "Utiliser le skin ElvUI si disponible."
+L["opt_isusingelvuiskin_desc"] = "Cochez pour utiliser un skin ElvUI.\nPar d\195\169faut: coch\195\169e"
+L["Use solid background."] = "Utiliser un fond opaque."
+L["Un-check this for an opaque background."] = "D\195\169cochez pour un fond opaque."
+L["Data Text"] = "Texte de donn\195\169es"
+L["mod_broker_desc"] = "Les textes de donn\195\169es agissent comme une source LDB. Ils peuvent \195\170tre int\195\169gr\195\169s dans n'importe quel affichage LDB comme Titan Panel ou ChocolateBar. Ils ont \195\169galement un fen\195\170tre interne optionnelle."
+L["Use frame"] = "Utiliser la fen\195\170tre"
+L["opt_useframe_desc"] = "Affiche une fen\195\170tre autonome. Pas n\195\169cessaire si vous utilisez un affichage LDB tel que Titan Panel ou ChocolateBar."
+L["Text Color"] = "Couleur du texte"
+L["The text color of %s."] = "La couleur du texte \1242 %s."
+L["Choose the default color."] = "Choisissez la couleur par d\195\169faut."
+L["Hint: Left-Click to set active mode."] = "Astuce : clic-gauche pour activer."
+L["Right-Click to set active set."] = "Clic-droit pour d\195\169finir l'ensemble actif."
+L["Shift+Left-Click to open menu."] = "Shift+clic-gauche pour ouvrir le menu."
+-- data resets
+L["Data Resets"] = "R\195\169initialisation"
+L["Reset on entering instance"] = "En entrant en instance"
+L["Controls if data is reset when you enter an instance."] = "D\195\169termine si les donn\195\169es doivent \195\170tre r\195\169initialis\195\169es quand vous entrez dans une instance."
+L["Reset on joining a group"] = "En rejoignant un groupe"
+L["Controls if data is reset when you join a group."] = "D\195\169termine si les donn\195\169es doivent \195\170tre r\195\169initialis\195\169es quand vous rejoignez un groupe."
+L["Reset on leaving a group"] = "En quittant un groupe"
+L["Controls if data is reset when you leave a group."] = "D\195\169termine si les donn\195\169es doivent \195\170tre r\195\169initialis\195\169es quand vous quittez un groupe."
+L["Ask"] = "Demander"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "Voulez-vous r\195\169initialiser Skada?\nMaintenez SHIFT pour tout r\195\169initialiser."
+L["All data has been reset."] = "Toutes les donn\195\169es ont \195\169t\195\169 r\195\169initialis\195\169es."
+L["There is no data to reset."] = "Pas de donn\195\169es \195\160 r\195\169initialiser."
+L["Skip reset dialog"] = "R\195\169init. sans confirmation"
+L["opt_skippopup_desc"] = "Si activ\195\169, Skada sera r\195\169initialis\195\169 sans afficher la bo\195\174te de confirmation."
+-- general options
+L["Show minimap button"] = "Bouton de la minicarte"
+L["Toggles showing the minimap button."] = "Affiche ou non l'ic\195\180ne de la minicarte."
+L["Transliterate"] = "Translit\195\169rer"
+L["Converts Cyrillic letters into Latin letters."] = "Convertit les lettres cyrilliques en lettres latines."
+L["Remove realm name"] = "Retirer le nom du royaume"
+L["opt_realmless_desc"] = "Si activ\195\169, le nom du royaume du personnage ne sera pas affich\195\169."
+L["Merge pets"] = "Fusionner familiers"
+L["Merges pets with their owners. Changing this only affects new data."] = "Fusionne les familiers avec leurs ma\195\174tres respectifs. Cela n'affectera que les nouvelles donn\195\169es."
+L["Show totals"] = "Afficher les totaux"
+L["Shows a extra row with a summary in certain modes."] = "Affiche une rang\195\169e suppl\195\169mentaire dans certain modes contenant un r\195\169sum\195\169."
+L["Only keep boss fighs"] = "Garder uniquement les boss"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "Les combats contre les boss seront conserv\195\169s avec ceci activ\195\169, le reste sera ignor\195\169."
+L["Always save boss fights"] = "Toujours garder les boss"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "Les combats contre les boss sont gard\195\169s et ne seront pas affect\195\169s par une r\195\169initialisation de Skada."
+L["Always keep boss fighs"] = "Toujours garder les boss"
+L["Boss fights will be kept with this on and are not affected by Skada reset."] = "Les combats contre les bosses sont conserv\195\169s et ne seront pas affect\195\169s par la r\195\169initialisation."
+L["Hide when solo"] = "Cacher quand seul"
+L["Hides Skada's window when not in a party or raid."] = "Cache la fen\195\170tre de Skada quand vous n'\195\170tes pas dans un groupe ou un raid."
+L["Hide in PvP"] = "Cacher en JcJ"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "Cache la fen\195\170tre de Skada quand vous \195\170tes dans un champ de bataille ou une ar\195\168ne."
+L["Hide in combat"] = "Cacher en combat"
+L["Hides Skada's window when in combat."] = "Cache la fen\195\170tre de Skada quand vous \195\170tes en combat."
+L["Show in combat"] = "Afficher en combat"
+L["Shows Skada's window when in combat."] = "Affiche la fen\195\170tre de Skada quand vous \195\170tes en combat."
+L["Disable while hidden"] = "D\195\169sac. quand cach\195\169"
+L["Skada will not collect any data when automatically hidden."] = "Skada ne r\195\169coltera aucune donn\195\169e quand il est automatiquement cach\195\169."
+L["Sort modes by usage"] = "Modes tri\195\169s par utilisation"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "La liste des modes sera tri\195\169e selon votre utilisation au lieu de l'\195\170tre alphab\195\169tiquement."
+L["Show rank numbers"] = "Afficher n° des rangs"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "Affiche les num\195\169ros des rangs relatifs pour les modes o\195\185 cela est applicable."
+L["Aggressive combat detection"] = "D\195\169tection agressive des combats"
+L["opt_tentativecombatstart_desc"] = [[Skada utilise un mode conservateur (simple) de détection de combat qui fonctionne mieux en raids.
+Avec cette option, Skada, tente de simuler les autres "damage meters".
+Pratique en solo ou bien en donjons, inutile contre les bosses.]]
+L["Autostop"] = "Arr\195\170t automatique"
+L["opt_autostop_desc"] = "Arr\195\170te automatiquement le segment apr\195\168s que la moiti\195\169 du groupe soient morts."
+L["Always show self"] = "Toujours afficher ma barre"
+L["opt_showself_desc"] = "Garde le joueur affich\195\169 en dernier m\195\170me s'il n'y a pas assez de place."
+L["Number format"] = "Format des nombres"
+L["Controls the way large numbers are displayed."] = "D\195\169termine la fa\195\167on dont les nombres sont affich\195\169s."
+L["Condensed"] = "Condens\195\169"
+L["Detailed"] = "D\195\169taill\195\169"
+L["Combined"] = "Combin\195\169"
+L["Comma"] = "Virgule"
+L["Numeral system"] = "Syst\195\168me num\195\169rique"
+L["Select which numeral system to use."] = "S\195\169lectionnez le syst\195\168me num\195\169rique \195\160 utiliser."
+L["Auto"] = "Auto"
+L["Western"] = "Occidental"
+L["East Asia"] = "Asie de l'Est"
+L["Brackets"] = "Parenth\195\168ses"
+L["Choose which type of brackets to use."] = "Choisissez le type de parenth\195\168se \195\160 utiliser."
+L["Separator"] = "S\195\169parateur"
+L["Choose which character is used to separator values between brackets."] = "Choisissez le caract\195\168re utilis\195\169 pour s\195\169parer les valeurs entre parenth\195\168ses."
+L["Number of decimals"] = "Nombre de d\195\169cimales"
+L["Controls the way percentages are displayed."] = "Contr\195\180le la fa\195\167on dont les pourcentages sont affich\195\169s."
+L["Data Feed"] = "Flux de donn\195\169es"
+L["opt_feed_desc"] = "Choisissez le flux de donn\195\169es \195\160 afficher sur le greffon DataBlocker. Ceci n\195\169cessite un addon d'affichage LDB, tel que Titan Panel."
+L["Time Measure"] = "Mesure du temps"
+L["Activity Time"] = "Temps d'activit\195\169"
+L["Effective Time"] = "Temps effectif"
+L["opt_timemesure_desc"] = [=[|cffffff00Activité|r : le chronomètre de chaque membre du raid est mis en pause si son activité est interrompue et reprend le compte quand l'activité reprend, méthode commune de mesure des DPS et HPS.
+
+|cffffff00Effective|r : utilisée pour les classements, cette méthode utilise le temps de combat écoulé pour mesurer le DPS et le HPS de tous les membres du raid.]=]
+L["Number set duplicates"] = "Nombre de doublons"
+L["Append a count to set names with duplicate mob names."] = "Ajoute un compteur aux noms d'ensemble ayant des noms de monstres dupliqu\195\169s."
+L["Set Format"] = "Format des ensembles"
+L["Controls the way set names are displayed."] = "Contr\195\180le la fa\195\167on dont les noms d'ensemble sont affich\195\169s."
+L["Links in reports"] = "Liens dans les rapports"
+L["When possible, use links in the report messages."] = "Utiliser des liens dans les messages de rapport quand cela est possible."
+L["Segments to keep"] = "Segments \195\160 garder"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "Le nombre de segments de combat \195\160 garder. Les segments persistants ne sont pas compt\195\169s avec."
+L["Persistent segments"] = "Segments persistants"
+L["The number of persistent fight segments to keep."] = "Le nombre de segments persistants \195\160 conserver."
+L["Memory Check"] = "V\195\169rif. de la m\195\169moire"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "V\195\169rifie l'utilisation de la m\195\169moire et vous avertit si elle est sup\195\169rieure ou \195\169gale \195\160 %d Mo."
+L["Disable Comms"] = "D\195\169sac. les communications"
+L["Minimum segment length"] = "Dur\195\169e minimale des segments"
+L["The minimum length required in seconds for a segment to be saved."] = "La dur\195\169e minimale requise en secondes pour qu'un segment soit enregistr\195\169."
+L["Update frequency"] = "Fr\195\169quence de mise \195\160 jour"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "La fr\195\169quence de rafraichissement des fen\195\170tres. Plus court pour des mises \195\160 jour plus fr\195\169quentes. Augmente l'utilisation du CPU."
+-- columns
+L["Columns"] = "Colonnes"
+-- tooltips
+L["Tooltips"] = "Bulles d'aide"
+L["Show Tooltips"] = "Afficher les bulles"
+L["Shows tooltips with extra information in some modes."] = "Affiche les bulles d'aide contenant des informations suppl\195\169mentaires dans certains modes."
+L["Informative Tooltips"] = "Bulles d'aide d\195\169tail\195\169es"
+L["Shows subview summaries in the tooltips."] = "Affiche le r\195\169sum\195\169 des sous-vues dans les bulles d'aide."
+L["Subview Rows"] = "Lignes de sous-vue"
+L["The number of rows from each subview to show when using informative tooltips."] = "Le nombre de rang\195\169es de chaque sous-vue afficher lors de l'utilisation des bulles d'aide informatives."
+L["Tooltip Position"] = "Position de la bulle d'aide"
+L["Position of the tooltips."] = "La position des bulles d'aide."
+L["Top Right"] = "En haut \195\160 droite"
+L["Top Left"] = "En haut \195\160 gauche"
+L["Bottom Right"] = "En bas \195\160 droite"
+L["Bottom Left"] = "En bas \195\160 gauche"
+L["Smart"] = "Intelligent"
+L["Follow Cursor"] = "Suivre le curseur"
+L["Top"] = "Haut"
+L["Bottom"] = "Bas"
+L["Right"] = "Droite"
+L["Left"] = "Gauche"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00Requiert\124r: %s"
+L["Modules"] = "Modules"
+L["Disabled Modules"] = "Modules D\195\169sactive\195\169s"
+L["Modules Options"] = "Options des modules"
+L["Tick the modules you want to disable."] = "Cocher les modules que vous souhaitez d\195\169sactiver."
+L["This change requires a UI reload. Are you sure?"] = "Ce changement n\195\169cessite un rechargement de l'IU. \195\138tes-vous s\195\187r?"
+-- themes options
+L["Theme"] = "Th\195\168me"
+L["Themes"] = "Th\195\168mes"
+L["Manage Themes"] = "G\195\169rer les th\195\168mes"
+L["All Windows"] = "Toutes les fen\195\170tres"
+L["Apply Theme"] = "Appliquer le th\195\168me"
+L["Theme applied!"] = "Th\195\168me appliqu\195\169!"
+L["Name of your new theme."] = "Le nom de votre nouveau th\195\168me."
+L["Save Theme"] = "Sauvegarde le th\195\168me"
+L["Delete Theme"] = "Supprimer le th\195\168me"
+L["Are you sure you want to delete this theme?"] = "\195\138tes-vous s\195\187r de vouloir supprimer ce th\195\168me?"
+L["Paste here a theme in text format."] = "Collez ici un th\195\168me au format texte."
+L["This is your current theme in text format."] = "Voici votre th\195\168me actuel au format texte."
+-- scroll options
+L["Scroll"] = "D\195\169filement"
+L["Wheel Speed"] = "Vitesse de d\195\169filement"
+L["opt_wheelspeed_desc"] = "Change la vitesse de d\195\169filement lorsque vous utilisez la roulette de la souris sur la fen\195\170tre."
+L["Scroll Icon"] = "Ic\195\180ne de d\195\169filement"
+L["Scroll mouse button"] = "Bouton de d\195\169filement de la souris"
+-- minimap button
+L["Skada Summary"] = "R\195\169sum\195\169 Skada"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00Clic-gauche\124r pour basculer l'affichage des fen\195\170tres."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+clic-gauche\124r pour afficher/cacher les fen\195\170tres."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+clic-gauche\124r pour r\195\169initialiser."
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00Clic-droit\124r pour ouvrir le menu."
+-- skada menu
+L["Skada Menu"] = "Menu Skada"
+L["Select Segment"] = "Choix de segment"
+L["Delete Segment"] = "Suppr. un segment"
+L["Keep Segment"] = "Garder un segment"
+L["Toggle Windows"] = "Basculer l'affichage"
+L["Show/Hide Windows"] = "Afficher/Cacher les fen\195\170tres"
+L["New Segment"] = "Nouveau segment"
+L["Starts a new segment."] = "D\195\169marre un nouveau segment."
+L["New Phase"] = "Nouvelle phase"
+L["Starts a new phase."] = "D\195\169marre une nouvelle phase."
+L["Select All"] = "Tout s\195\169lectionner"
+L["Deselect All"] = "Tout d\195\169selectionner"
+-- window buttons
+L["Configure"] = "Configurer"
+L["Open Config"] = "Ouvrir la configuration"
+L["btn_config_desc"] = "Ouvre la fen\195\170tre de configuration."
+L["btn_reset_desc"] = [[Réinitialise les données de tous les combats sauf ceux que vous avez choisi de garder.
+|cff00ff00Shift clic|r: Supprimer le segment.]]
+L["Segment"] = "Segment"
+L["btn_segment_desc"] = [[Vous permet de sélectionner un segment spécific.
+|cff00ff00Shift clic|r: segment |cffffbb00suivant|r.
+|cff00ff00Shift clic-droit|r: segment |cffffbb00précédent|r.
+|cff00ff00Clic du milieu|r: segment |cffffbb00actuel|r.]]
+L["Mode"] = "Mode"
+L["Jump to a specific mode."] = "Vous permet de s\195\169lectionner un mode sp\195\169cific."
+L["Report"] = "Rapport"
+L["btn_report_desc"] = [[Ouvre la fenêtre qui vous permet de rapporter les données aux autres de différentes manières.
+|cff00ff00Shift clic|r pour un rapport rapide.]]
+L["Stop"] = "Arr\195\170ter/Reprendre"
+L["btn_stop_desc"] = "Arr\195\170te ou reprend le segment en cours. Utile pour arr\195\170ter la collecte des donn\195\169es apr\195\168s un wipe. L'arr\195\170t automatique peut \195\170tre activ\195\169 dans les param\195\168tres."
+L["Segment Stopped."] = "Segment arr\195\170t\195\169."
+L["Segment Paused."] = "Segment suspendu."
+L["Segment Resumed."] = "Segment repris."
+L["Quick Access"] = "Acc\195\168s rapide"
+-- default segments
+L["Total"] = "Total"
+L["Current"] = "Actuel"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %s pour %s:"
+L["Self"] = "Soi-m\195\170me"
+L["Whisper Target"] = "Chuchoter \195\160 la cible"
+L["Copy & Paste"] = "Copier & coller"
+L["[General]"] = "G\195\169n\195\169ral"
+L["[LocalDefense]"] = "D\195\169fenseLocale"
+L["[LookingForGroup]"] = "RechercheDeGroupe"
+L["[Trade]"] = "Commerce"
+L["Line"] = "Ligne"
+L["Lines"] = "Lignes"
+L["There is nothing to report."] = "Il n'y a rien \195\160 rapporter."
+L["No mode or segment selected for report."] = "Aucun mode ou segment n'a \195\169t\195\169 s\195\169lectionn\195\169 pour le rapport."
+-- Bar Display Module --
+L["Bar Display"] = "Affichage \195\160 barres"
+L["mod_bar_desc"] = "L'affichage \195\160 barres est la fen\195\170tre de barres habituellement utilis\195\169e par la plupart des damage meters. Il peut \195\170tre personnalis\195\169 de fa\195\167on approfondie."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "Affichage \195\160 barres (ancien)"
+L["Max Bars"] = "Nbre max. de barres"
+L["The maximum number of bars shown."] = "Le nombre maximal de barres \195\160 afficher."
+L["Show Menu Button"] = "Aff. bouton Menu"
+L["Shows a button for opening the menu in the window title bar."] = "Affiche un bouton permettant d'ouvrir le menu sur la barre du titre de la fen\195\170tre."
+L["Class Color Bars"] = "Barres: couleur de classe"
+L["Class Color Text"] = "Texte: couleur de classe"
+-- Threat Module --
+L["Threat"] = "Menace"
+L["Threat Warning"] = "Avertissement de la menace"
+L["Flash Screen"] = "Flasher l'\195\169cran"
+L["This will cause the screen to flash as a threat warning."] = "Ceci fera clignoter l'\195\169cran pour en faire un avertissement sur la menace."
+L["Shake Screen"] = "Secouer l'\195\169cran"
+L["This will cause the screen to shake as a threat warning."] = "Ceci fera secouer l'\195\169cran pour en faire un avertissement sur la menace."
+L["Warning Message"] = "Message d'avertissement"
+L["Print a message to screen when you accumulate too much threat."] = "Affiche un message \195\160 l'\195\169cran quand vous avez accumul\195\169 trop de menace."
+L["Play sound"] = "Jouer un son"
+L["This will play a sound as a threat warning."] = "Ceci jouera un son pour en faire un avertissement sur la menace"
+L["Message Output"] = "Sortie des avertissements"
+L["Choose where warning messages should be displayed."] = "Choisissez o\195\185 les messages d'avertissement doivent \195\170tre affich\195\169s."
+L["Chat Frame"] = "Fen\195\170tre de discussion"
+L["Blizzard Error Frame"] = "Cadre des erreurs"
+L["Threat sound"] = "Son de menace"
+L["opt_threat_soundfile_desc"] = "Le son qui sera jou\195\169 chaque fois que votre pourcentage de menace atteint un certain point."
+L["Warning Frequency"] = "Fr\195\169quence des alertes"
+L["Threat Threshold"] = "Seuil de menace"
+L["opt_threat_threshold_desc"] = "Quand votre menace atteint ce niveau par rapport au tank, les avertissements sont affich\195\169s."
+L["Show raw threat"] = "Menace brute"
+L["opt_threat_rawvalue_desc"] = "Affiche le pourcentage brut de menace par rapport au tank au lieu de celui modifi\195\169 selon la port\195\169e."
+L["Use focus target"] = "Cible de la focalisation"
+L["opt_threat_focustarget_desc"] = "Demande \195\160 Skada de v\195\169rifier \195\169galement votre focalisation et la cible de votre focalisation (dans cet ordre) pour l'affichage de la menace."
+L["Disable while tanking"] = "D\195\169sactiver en tankant"
+L["opt_threat_notankwarnings_desc"] = "Ne donne aucun avertissement si vous \195\170tes en posture d\195\169fensive, en forme d'ours, sous fureur vertueuse ou en pr\195\169sence de givre."
+L["Ignore Pets"] = "Ignorer les familiers"
+L["opt_threat_ignorepets_desc"] = [=[Demande à Skada de ne pas s'occuper des familiers des autres joueurs lors de la détermination de l'unité à afficher.
+
+Ces familiers gardent une table des menaces lorsqu'ils sont en mode |cffffff78aggressif|r ou |cffffff78défensif|r et se comportent alors comme les monstres normaux, attaquant la cible avec laquelle ils ont la plus haute menace. Si on leur donne l'ordre d'attaquer une cible spécifique, ils gardent toujours la table des menaces, mais se focalisent sur la cible assignée qui a alors par définition 100% de menace. Ils peuvent être provoqués pour les forcer à vous attaquer.
+
+Les fam. des joueurs en mode |cffffff78passif|r n'ont pas de table des menaces, et la provocation ne fonctionne pas sur eux. Ils attaquent uniquement leur cible assignée et le font sans aucune table des menaces.
+
+Quand un fam. de joueur reçoit l'ordre de |cffffff78suivre|r, la table des menaces du familier est détruite immédiatement et il arrête d'attaquer. Cependant, il risque de reprendre immédiatement une cible s'il se trouve en mode aggressif/défensif.]=]
+L["> Pull Aggro <"] = "> Reprise d'aggro <"
+L["Show Pull Aggro Bar"] = "Barre reprise d'aggro"
+L["opt_threat_showaggrobar_desc"] = "Affiche une barre indiquant la quantit\195\169 de menace que vous avez besoin de faire pour reprendre l'aggro."
+L["Test Warnings"] = "Test d'avertissement"
+L["TPS"] = "MPS"
+L["Threat: Personal Threat"] = "Menace : Menace perso."
+-- Absorbs & Healing Module --
+L["Healing"] = "Soins prodigu\195\169s"
+L["Healing Done"] = "Soins prodigu\195\169s"
+L["Healing Taken"] = "Soins re\195\167us"
+L["HPS"] = "SPS"
+L["sHPS"] = "SPS (sous-vues)"
+L["Healing: Personal HPS"] = "Soins prodigu\195\169s: SPS perso."
+L["RHPS"] = "RSPS"
+L["Healing: Raid HPS"] = "Soins prodigu\195\169s: SPS du raid"
+L["Total Healing"] = "Total des soins"
+L["Overheal"] = "Soins excessifs"
+L["Overhealing"] = "Soins excessifs"
+L["Absorbs"] = "Absorptions"
+L["Target List"] = "Liste des cibles"
+L["Spell List"] = "Liste des sorts"
+L["APS"] = "APS"
+L["sAPS"] = "APS (sous-vues)"
+L["Absorbs and Healing"] = "Absorptions et soins"
+L["Healing Done By Spell"] = "Soins prodigu\195\169s par sort"
+L["Source List"] = "Liste des sources"
+-- Auras Module --
+L["Uptime"] = "Disponibilit\195\169"
+L["Buffs and Debuffs"] = "Buffs et Debuffs"
+L["Buffs"] = "Buffs"
+L["Debuffs"] = "Debuffs"
+L["%s's <%s> targets"] = "Cibles \1242 <%2$s> \1242 %1$s"
+L["%s's <%s> sources"] = "Sources \1242 <%2$s> \1242 %1$s"
+L["Enemy Buffs"] = "Buffs (Ennemi)"
+L["Enemy Debuffs"] = "Debuffs (Ennemi)"
+-- CC Tracker Module --
+L["Crowd Control"] = "Contr\195\180le de foule"
+L["CC Done"] = "Contr\195\180les effectu\195\169s"
+L["CC Taken"] = "Contr\195\180les subis"
+L["CC Breaks"] = "Contr\195\180le bris\195\169s"
+L["Ignore Main Tanks"] = "Ignorer tanks principaux"
+L["%s on %s removed by %s"] = "%s sur %s enlev\195\169(e) par %s"
+L["%s on %s removed by %s's %s"] = "%s sur %s enlev\195\169(e) par %s avec %s"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "Environnement"
+-- damage done module
+L["Damage"] = "D\195\169g\195\162ts inflig\195\169s"
+L["Spell Details"] = "D\195\169tails du sort"
+L["Damage Done"] = "D\195\169g\195\162ts inflig\195\169s"
+L["Useful Damage"] = "D\195\169g\195\162ts utiles"
+L["Useful damage on %s"] = "D\195\169g\195\162ts utiles sur %s"
+L["Damage Done By Spell"] = "D\195\169g\195\162ts inflig\195\169s par sort"
+L["%s's sources"] = "Sources \1242 %s"
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (sous-vues)"
+L["Damage: Personal DPS"] = "D\195\169g\195\162ts : DPS personnel"
+L["RDPS"] = "RDPS"
+L["Damage: Raid DPS"] = "D\195\169g\195\162ts : DPS du raid"
+L["Absorbed Damage"] = "D\195\169g\195\162ts absorb\195\169s"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "Si activ\195\169, les d\195\169g\195\162ts absorb\195\169s seront inclus dans les d\195\169g\195\162ts inflig\195\169s."
+L["Damage Done By School"] = "D\195\169g\195\162ts inflig\195\169s par \195\169cole"
+-- killing blows module
+L["Only PvP Kills"] = "Seulement en PvP"
+L["When enabled, only kills against enemy players count."] = "Si activ\195\169, seuls les coups fatals contre des joueurs ennemies comptent."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "Annoncer les coups fatals une fois le combat termin\195\169. Fonctionne seulement contre les boss."
+-- damage taken module
+L["Damage Taken"] = "D\195\169g\195\162ts subis"
+L["Damage Taken By Spell"] = "D\195\169g\195\162ts subis par sort"
+L["%s's targets"] = "Cibles \1242 %s"
+L["DTPS"] = "DSPS"
+L["sDTPS"] = "DSPS (sous-vues)"
+-- enemy damage done module
+L["Enemies"] = "Ennemis"
+L["Enemy Damage Done"] = "D\195\169g\195\162ts inflig\195\169s (Ennemi)"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "D\195\169g\195\162ts subis (Ennemi)"
+L["%s below %s%%"] = "%s \195\160 partir \1242 %s%%"
+L["%s - %s%% to %s%%"] = "%s - %s%% \195\160 %s%%"
+L["Phase %s"] = "Phase %s"
+L["%s - Phase %s"] = "%s - Phase %s"
+L["%s - Phase 1"] = "%s - Phase 1"
+L["%s - Phase 2"] = "%s - Phase 2"
+L["%s - Phase 3"] = "%s - Phase 3"
+L["%s (Main Boss)"] = "%s (Boss principal)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r d\195\169marr\195\169."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r arr\195\170t\195\169."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r repris."
+-- enemy healing done module
+L["Enemy Healing Done"] = "Soins prodigu\195\169s (Ennemi)"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "\195\137vitement et mitigation"
+L["More Details"] = "Plus de d\195\169tails"
+L["%s's details"] = "D\195\169tails \1242 %s"
+-- friendly fire module
+L["Friendly Fire"] = "D\195\169g\195\162ts aux alli\195\169s"
+-- useful damage targets
+L["Important targets"] = "Cibles importantes"
+L["Oozes"] = "Limons"
+L["Princes overkilling"] = "D\195\169g\195\162t exag\195\169r\195\169 sur les Princes"
+-- L["Adds"] = ""
+L["Halion and Inferno"] = "Halion et Inferno"
+L["Valkyrs overkilling"] = "D\195\169g\195\162t exag\195\169r\195\169 sur les Valkyrs"
+-- Deaths Module --
+L["%s's deaths"] = "Morts \1242 %s"
+L["Death log"] = "Journal de mort"
+L["%s's death log"] = "Journal de mort \1242 %s"
+L["Player's deaths"] = "Morts du joueur"
+L["%s dies"] = "%s meurt"
+L["buff"] = "buff"
+L["debuff"] = "debuff"
+L["Spell details"] = "D\195\169tails du sort"
+L["Spell"] = "Sort"
+L["Amount"] = "Montant"
+L["Source"] = "Source"
+L["Change"] = "Changement"
+L["Time"] = "Temps"
+L["Survivability"] = "Survie"
+L["Events Amount"] = "Nombre d'\195\169v\195\169nments"
+L["Set the amount of events the death log should record."] = "Choisissez le nombre d'\195\169v\195\169nments que le journal de mort doit enregistrer."
+L["Minimum Healing"] = "Minimum des soins"
+L["Ignore heal events that are below this threshold."] = "Ignorer tous les soins prodigu\195\169s inf\195\169rieurs \195\160 ce seuil."
+L["Announce Deaths"] = "Annoncer les morts"
+L["Announces information about the last hit the player took before they died."] = "Annonce le dernier coup que la personne a re\195\167u avant de mourir."
+L["Alternative Display"] = "Affichage alternatif"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "Si un joueur meurt plusieurs fois, chaque mort aura sa propre barre."
+-- activity module
+L["Activity"] = "Activit\195\169"
+L["Activity per Target"] = "Activit\195\169 par cible"
+L["%s's activity"] = "Activit\195\169 \1242 %s"
+-- dispels module lines --
+L["Dispel Spells"] = "Sorts de dissipation"
+L["%s's dispelled spells"] = "Sorts dissip\195\169s par %s"
+-- interrupts module lines --
+L["Interrupt Spells"] = "Sorts d'interruption"
+L["%s's interrupted spells"] = "Sorts interrompus par %s"
+L["%s interrupted!"] = "%s interrompu!"
+-- Power gained module --
+L["Resources"] = "Ressources"
+L["Mana Restored"] = "Mana restaur\195\169e"
+L["Rage Generated"] = "Rage g\195\169n\195\169r\195\169e"
+L["Energy Generated"] = "\195\137nergie g\195\169n\195\169r\195\169e"
+L["Runic Power Generated"] = "P. Runique g\195\169n\195\169r\195\169e"
+-- Parry module lines --
+L["Parry-Haste"] = "Parade-h\195\162te"
+L["%s parried %s (%s)"] = "%s a par\195\169 %s (%s)"
+-- Potions module lines --
+L["Potions"] = "Potions"
+L["%s's potions"] = "Potions \1242 %s"
+L["Pre-potion"] = "Pre-potion"
+L["pre-potion: %s"] = "pr\195\169-potion: %s"
+L["Prints pre-potion after the end of the combat."] = "Affiche, en fin du combat, la liste des joueurs ayant utilis\195\169 des potions avant le d\195\169but du combat."
+-- healthstone --
+L["Healthstones"] = "Pierres de soins"
+-- resurrect module lines --
+L["Resurrects"] = "R\195\169surrections"
+-- nickname module lines --
+L["Nickname"] = "Surnom"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "Les surnoms sont envoy\195\169s aux membres de votre groupe et Skada pourra l'utilise \195\160 la place du nom de votre personnage."
+L["Set a nickname for you."] = "D\195\169finissez un surnom pour vous."
+L["Nickname isn't a valid string."] = "Le surnom contient des caract\195\168res invalides."
+L["Your nickname is too long, max of 12 characters is allowed."] = "Votre surnom est trop long, un maximum de 12 caract\195\168res est autoris\195\169."
+L["Only letters and two spaces are allowed."] = "Seules les lettres et deux espaces sont autoris\195\169s."
+L["Your nickname contains a forbidden word."] = "Votre surnom contient un mot interdit."
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "Vous ne pouvez pas utiliser la m\195\170me lettre trois fois de suite, deux espaces cons\195\169cutifs ou plus de deux espaces."
+L["Ignore Nicknames"] = "Ignorer les surnoms"
+L["When enabled, nicknames set by Skada users are ignored."] = "Si activ\195\169, les surnoms d\195\169finis par les autres utilisateur Skada sont ignor\195\169s."
+L["Name display"] = "Format des noms"
+L["Choose how names are shown on your bars."] = "Choisissez comment les noms seront affich\195\169s sur les barres."
+L["Clear Cache"] = "Vider le cache"
+L["Are you sure you want clear cached nicknames?"] = "\195\138tes-vous s\195\187r vouloir vider le cache des surnoms?"
+-- overkill module lines --
+L["Overkill"] = "D\195\169g\195\162ts excessifs"
+-- tweaks module lines --
+L["Improvement"] = "Am\195\169lioration"
+L["Tweaks"] = "Ajustements"
+L["First hit"] = "Premi\195\168re attaque"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00Premi\195\168re attaque\124r: %s \1242 %s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00Premi\195\168re attaque\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00Premi\195\168re cible de boss\124r: %s"
+L["opt_tweaks_firsthit_desc"] = "Affiche la premi\195\168re attaque causant le d\195\169but de combat.\nFonctionne uniquement contre les boss."
+L["Filter DPS meters Spam"] = "Filtrer les messages DPS"
+L["opt_tweaks_spamage_desc"] = "Supprime les messages provenant des damage meters et les remplace par un lien unique affichant les statistics dans une popup."
+L["Reported by: %s"] = "Rapport\195\169 par: %s"
+L["Smart Stop"] = "Arr\195\170t intelligent"
+L["opt_tweaks_smarthalt_desc"] = "Arr\195\170te automatiquement le segment en cours apr\195\168s la mort du boss.\nUtile pour \195\169viter de collecter des donn\195\169es en cas de bug de combat."
+L["Duration"] = "Dur\195\169e"
+L["opt_tweaks_smartwait_desc"] = "Combien de temps Skada doit attendre avant d'arr\195\170ter le segment?"
+L["Modes Icons"] = "Ic\195\180nes des modes"
+L["Show modes icons on bars and menus."] = "Afficher les ic\195\180nes des modes sur les barres et les menus."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "Si activ\195\169, \124cffffbb00%s\124r sera compl\195\168tement ignor\195\169(e)."
+L["Custom Colors"] = "Couleurs personnalisées"
+L["Arena Teams"] = "\195\137quipes d'ar\195\168ne"
+L["Are you sure you want to reset all colors?"] = "\195\138tes-vous s\195\187r de vouloir r\195\169initialiser toutes les couleurs?"
+L["Announce %s"] = "Annoncer %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "Annonce combien de temps il a fallu pour appliquer %d piles \1242 %s et annonce quand il expire."
+L["%s dropped from %s!"] = "%s sur %s a expir\195\169!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%s piles \1242 %s appliqu\195\169es sur %s en %s sec!"
+L["My Spells"] = "Mes sorts"
+-- total data options
+L["Total Segment"] = "Segment total"
+L["All Segments"] = "Tous les segments"
+L["Raid Bosses"] = "Boss de raid"
+L["Raid Trash"] = "Trash de raid"
+L["Dungeon Bosses"] = "Boss de donjon"
+L["Dungeon Trash"] = "Trash de donjon"
+L["opt_tweaks_total_all_desc"] = "Tous les segments sont ajout\195\169s aux donn\195\169es du segment total."
+L["opt_tweaks_total_fmt_desc"] = "Les segments avec %s sont ajout\195\169s aux donn\195\169es du segment total."
+L["Detailed total segment"] = "Segment total d\195\169taill\195\169"
+L["opt_tweaks_total_full_desc"] = "Si activ\195\169e, Skada enregistrera tout dans le segment \124cffffbb00Total\124r, au lieu que des totaux."
+-- arena
+L["mod_pvp_desc"] = "Ajoute la d\195\169tection des sp\195\169cialisations pour les ar\195\168nes et les champs de bataille, et affiche les adversaires de l'ar\195\168ne dans la m\195\170me fen\195\170tre."
+L["Gold Team"] = "\195\137quipe dor\195\169e"
+L["Green Team"] = "\195\137quipe verte"
+L["Color for %s."] = "Couleur \1242 %s."
+-- notifications
+L["Notifications"] = "Notifications"
+L["opt_toast_desc"] = "Utiliser des notifications visuelles au lieu des messages de chat quand cela est possible."
+L["Test Notifications"] = "Tester les notifications"
+-- comparison module
+L["Comparison"] = "Comparaison"
+L["%s vs %s: %s"] = "%s vs %s: %s"
+L["%s vs %s: Spells"] = "%s vs %s: Sorts"
+L["%s vs %s: Targets"] = "%s vs %s: Cibles"
+-- spellcast module
+L["Casts"] = "Incantations"
+L["%s's spells"] = "Sorts \1242 %s"
+L["%s's spells on %s"] = "Sorts \1242 %s sur %s"
+L["Spells on %s"] = "Sorts sur %s"
+-- about
+L["Author"] = "Auteur"
+L["Credits"] = "Cr\195\169dits"
+L["Date"] = "Date"
+L["License"] = "Licence"
+L["Version"] = "Version"
+L["Website"] = "Site web"
+-- some bosses entries
+L["World Boss"] = "Boss hors instance"
+L["Auriaya"] = "Auriaya"
+L["Blood Prince Council"] = "Conseil des princes de sang"
+L["Faction Champions"] = "Champions de faction"
+L["Hogger"] = "Lardeur"
+L["Icecrown Gunship Battle"] = "Bataille des canonni\195\168res"
+L["Kologarn"] = "Kologarn"
+L["Mimiron"] = "Mimiron"
+L["Thaddius"] = "Thaddius"
+L["The Four Horsemen"] = "Les quatre cavaliers"
+L["The Iron Council"] = "Assembl\195\169e du fer"
+L["The Northrend Beasts"] = "Les b\195\170tes du Norfendre"
+L["Thorim"] = "Thorim"
+L["Twin Val'kyr"] = "Jumelles val'kyrs"
+L["Valithria Dreamwalker"] = "Valithria Marcher\195\170ve"
+L["Yogg-Saron"] = "Yogg-Saron"
diff --git a/Skada/Locales/itIT.lua b/Skada/Locales/itIT.lua
new file mode 100644
index 0000000..638fa09
--- /dev/null
+++ b/Skada/Locales/itIT.lua
@@ -0,0 +1,757 @@
+--[[ Translators: Chat GPT ]] --
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "itIT")
+if not L then return end
+
+L["A damage meter."] = "Un misuratore di danni."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "L'uso della memoria è elevato. Potresti voler resettare Skada e abilitare una delle opzioni di reset automatico."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada è obsoleto. Puoi scaricare l'ultima versione da \124cffffbb00%s\124r"
+L["Skada: Modes"] = "Skada: Modalità"
+L["Skada: Fights"] = "Skada: Combattimenti"
+L["Data Collection"] = "Raccolta Dati"
+L["ENABLED"] = "ABILITATO"
+L["DISABLED"] = "DISABILITATO"
+L["Enable All"] = "Abilita Tutti"
+L["Disable All"] = "Disabilita Tutti"
+L["Stopping for wipe."] = "Fermarsi per il wipe."
+L["Usage:"] = "Utilizzo:"
+L["Commands:"] = "Comandi:"
+L["Import"] = "Importa"
+L["Export"] = "Esporta"
+L["Import/Export"] = "Importa/Esporta"
+-- profiles
+L["Profiles"] = "Profili"
+L["Profile Import/Export"] = "Importa/Esporta Profilo"
+L["Import Profile"] = "Importa Profilo"
+L["Export Profile"] = "Esporta Profilo"
+L["Paste here a profile in text format."] = "Incolla qui un profilo in formato testo."
+L["Press CTRL-V to paste the text from your clipboard."] = "Premi CTRL-V per incollare il testo dagli appunti."
+L["This is your current profile in text format."] = "Questo è il tuo profilo attuale in formato testo."
+L["Press CTRL-C to copy the text to your clipboard."] = "Premi CTRL-C per copiare il testo negli appunti."
+L["Network Sharing"] = "Condivisione Rete"
+L["Player Name"] = "Nome Personaggio"
+L["Send Profile"] = "Invia Profilo"
+L["Accept profiles from other players."] = "Accetta profili dagli altri personaggio."
+L["opt_profile_received"] = "%s ti ha inviato una configurazione del profilo. Vuoi attivare il profilo ricevuto?"
+L["Progress"] = "Progresso"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "Dimensione Dati: \124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "Progresso Trasmissione: %02.f%%"
+L["Transmission Completed"] = "Trasmissione Completata"
+-- common lines
+L["Options"] = "Opzioni"
+L["Options for %s."] = "Opzioni per %s."
+L["General"] = "Generale"
+L["General options for %s."] = "Opzioni generali per %s."
+L["Text"] = "Testo"
+L["Text options for %s."] = "Opzioni di testo per %s."
+L["Format"] = "Formato"
+L["Format options for %s."] = "Opzioni di formato per %s."
+L["Appearance"] = "Aspetto"
+L["Appearance options for %s."] = "Opzioni di aspetto per %s."
+L["Advanced"] = "Avanzate"
+L["Advanced options for %s."] = "Opzioni avanzate per %s."
+L["Position"] = "Posizione"
+L["Position settings for %s."] = "Impostazioni della posizione per %s."
+L["Width"] = "Larghezza"
+L["The width of %s."] = "La larghezza di %s."
+L["Height"] = "Altezza"
+L["The height of %s."] = "L'altezza di %s."
+L["Active Time"] = "Tempo Attivo"
+L["Segment Time"] = "Tempo Segmento"
+L["Click for \124cff00ff00%s\124r"] = "Clicca per \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift-Clicca per \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Ctrl-Clicca per \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt-Clicca per \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "Attiva Filtro Classe"
+L["Average"] = "Media"
+L["Count"] = "Conteggio"
+L["Refresh"] = "Aggiorna"
+L["Percent"] = "Percentuale"
+L["sPercent"] = "Percentuale (sotto-viste)"
+L["General Options"] = "Opzioni Generali"
+L["HoT"] = "HoT"
+L["DoT"] = "DoT"
+L["Hits"] = "Colpi"
+L["Normal Hits"] = "Colpi Normali"
+L["Critical"] = "Critico"
+L["Critical Hits"] = "Colpi Critici"
+L["Crushing"] = "Devastante"
+L["Glancing"] = "Impreciso"
+L["ABSORB"] = "Assorbito"
+L["BLOCK"] = "Bloccato"
+L["DEFLECT"] = "Deviato"
+L["DODGE"] = "Schivato"
+L["EVADE"] = "Elusione"
+L["IMMUNE"] = "Immune"
+L["MISS"] = "Mancato"
+L["PARRY"] = "Parato"
+L["REFLECT"] = "Riflessione"
+L["RESIST"] = "Resistito"
+L["Only for bosses."] = "Solo per i boss."
+L["Enable this only against bosses."] = "Attiva solo contro i boss."
+-- segment info
+L["Start"] = "Inizio"
+L["End"] = "Fine"
+-- windows section:
+L["Window"] = "Finestra"
+L["Windows"] = "Finestre"
+L["Create Window"] = "Crea Finestra"
+L["Window Name"] = "Nome Finestra"
+L["Enter the name for the new window."] = "Inserisci il nome per la nuova finestra."
+L["Delete Window"] = "Elimina Finestra"
+L["Choose the window to be deleted."] = "Scegli la finestra da eliminare."
+L["Are you sure you want to delete this window?"] = "Sei sicuro di voler eliminare questa finestra?"
+L["Delete All Windows"] = "Elimina Tutte le Finestre"
+L["Are you sure you want to delete all windows?"] = "Sei sicuro di voler eliminare tutte le finestre?"
+L["Rename Window"] = "Rinomina Finestra"
+L["Enter the name for the window."] = "Inserisci il nome per la finestra."
+L["Test Mode"] = "Modalità di Test"
+L["Creates fake data to help you configure your windows."] = "Crea dati falsi per aiutarti a configurare le finestre."
+L["Child Window"] = "Finestra Figlia"
+L["A child window will replicate the parent window actions."] = "Una finestra figlia replicherà le azioni della finestra principale."
+L["Child Window Mode"] = "Modalità Finestra Figlia"
+L["Lock Window"] = "Blocca Finestra"
+L["Locks the bar window in place."] = "Blocca la finestra della barra nella posizione corrente."
+L["Hide Window"] = "Nascondi Finestra"
+L["Hides the window."] = "Nasconde la finestra."
+L["Sticky Window"] = "Finestra Attaccata"
+L["Allows the window to stick to other Skada windows."] = "Permette alla finestra di attaccarsi ad altre finestre di Skada."
+L["Snap to best fit"] = "Adatta automaticamente"
+L["Snaps the window size to best fit when resizing."] = "Adatta automaticamente la dimensione della finestra durante il ridimensionamento."
+L["Disable Resize Buttons"] = "Disabilita Pulsanti Ridimensiona"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "I pulsanti di ridimensionamento e blocco/sblocco non appariranno quando passi sopra la finestra."
+L["Disable stretch button"] = "Disabilita pulsante allungamento"
+L["Stretch button won't show up when you hover over the window."] = "Il pulsante di allungamento non apparirà quando passi sopra la finestra."
+L["Reverse window stretch"] = "Allungamento inverso"
+L["opt_botstretch_desc"] = "Posiziona il pulsante di allungamento nella parte inferiore della finestra e la fa allungare verso il basso."
+L["Display System"] = "Sistema di Visualizzazione"
+L["Choose the system to be used for displaying data in this window."] = "Scegli il sistema da utilizzare per visualizzare i dati in questa finestra."
+L["Copy Settings"] = "Copia Impostazioni"
+L["Choose the window from which you want to copy the settings."] = "Scegli la finestra dalla quale vuoi copiare le impostazioni."
+-- bars
+L["Bars"] = "Barre"
+L["Left Text"] = "Testo Sinistra"
+L["Right Text"] = "Testo Destra"
+L["Font"] = "Carattere"
+L["The font used by %s."] = "Il carattere utilizzato da %s."
+L["Font Size"] = "Dimensione Carattere"
+L["The font size of %s."] = "La dimensione del carattere di %s."
+L["Font Outline"] = "Bordo Carattere"
+L["Sets the font outline."] = "Imposta il bordo del carattere."
+L["Outline"] = "Bordo"
+L["Thick"] = "Spesso"
+L["Thick outline"] = "Bordo spesso"
+L["Monochrome"] = "Monocromatico"
+L["Outlined monochrome"] = "Monocromatico con bordo"
+L["Bar Texture"] = "Texture Barre"
+L["The texture used by all bars."] = "La texture utilizzata per tutte le barre."
+L["Spacing"] = "Spaziatura"
+L["Distance between %s."] = "Distanza tra %s."
+L["Displacement"] = "Dislocazione"
+L["The distance between the edge of the window and the first bar."] = "La distanza tra il bordo della finestra e la prima barra."
+L["Bar Orientation"] = "Orientamento Barre"
+L["The direction the bars are drawn in."] = "La direzione in cui le barre sono disegnate."
+L["Left to right"] = "Da sinistra a destra"
+L["Right to left"] = "Da destra a sinistra"
+L["Reverse bar growth"] = "Crescita inversa delle barre"
+L["Bars will grow up instead of down."] = "Le barre cresceranno verso l'alto invece che verso il basso."
+L["Disable bar highlight"] = "Disabilita l'evidenziazione delle barre"
+L["Hovering a bar won't make it brighter."] = "Passando sopra una barra non la renderà più luminosa."
+L["Bar Color"] = "Colore Barre"
+L["Choose the default color of the bars."] = "Scegli il colore predefinito delle barre."
+L["Background Color"] = "Colore Sfondo"
+L["The color of the background."] = "Il colore dello sfondo."
+L["Custom Color"] = "Colore Personalizzato"
+L["Use a different color for my bar."] = "Utilizza un colore diverso per la mia barra."
+L["My Color"] = "Mio Colore"
+L["Spell school colors"] = "Colori delle scuole di magia"
+L["Use spell school colors where applicable."] = "Utilizza i colori delle scuole di magia dove applicabile."
+L["When possible, bars will be colored according to player class."] = "Quando possibile, le barre verranno colorate in base alla classe del giocatore."
+L["When possible, bar text will be colored according to player class."] = "Quando possibile, il testo delle barre verrà colorato in base alla classe del giocatore."
+L["Class Icons"] = "Icone Classe"
+L["Use class icons where applicable."] = "Utilizza le icone delle classi dove applicabile."
+L["Spec Icons"] = "Icone Specializzazione"
+L["Use specialization icons where applicable."] = "Utilizza le icone delle specializzazioni dove applicabile."
+L["Role Icons"] = "Icone Ruolo"
+L["Use role icons where applicable."] = "Utilizza le icone dei ruoli dove applicabile."
+L["Show Spark Effect"] = "Mostra Effetto Scintilla"
+L["Click Through"] = "Clicca Attraverso"
+L["Disables mouse clicks on bars."] = "Disabilita i clic del mouse sulle barre."
+L["Smooth Bars"] = "Barre Fluide"
+L["Animate bar changes smoothly rather than immediately."] = "Anima le modifiche alle barre in modo fluido anziché immediato."
+-- title bar
+L["Title Bar"] = "Barra Titolo"
+L["Enables the title bar."] = "Abilita la barra del titolo."
+L["Include set"] = "Includi Set"
+L["Include set name in title bar"] = "Includi il nome del set nella barra del titolo"
+L["Encounter Timer"] = "Timer Incontri"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "Quando abilitato, un cronometro viene mostrato sul lato sinistro del testo."
+L["Mode Icon"] = "Icona Modalità"
+L["Shows mode's icon in the title bar."] = "Mostra l'icona della modalità nella barra del titolo."
+L["The texture used as the background of the title."] = "La texture utilizzata come sfondo del titolo."
+L["Border texture"] = "Texture Bordo"
+L["The texture used for the borders."] = "La texture utilizzata per i bordi."
+L["Border Color"] = "Colore Bordo"
+L["The color used for the border."] = "Il colore utilizzato per il bordo."
+L["Buttons"] = "Pulsanti"
+L["Auto Hide Buttons"] = "Nascondi automaticamente i pulsanti"
+L["Show window buttons only if the cursor is over the title bar."] = "Mostra i pulsanti della finestra solo se il cursore è sopra la barra del titolo."
+L["Buttons Style"] = "Stile Pulsanti"
+-- general window
+L["Background Texture"] = "Texture Sfondo"
+L["The texture used as the background."] = "La texture utilizzata come sfondo."
+L["Tile"] = "Ripeti"
+L["Tile the background texture."] = "Ripeti la texture dello sfondo."
+L["Tile Size"] = "Dimensione Ripetizione"
+L["The size of the texture pattern."] = "La dimensione del motivo della texture."
+L["Border"] = "Bordo"
+L["Border Thickness"] = "Spessore Bordo"
+L["The thickness of the borders."] = "Lo spessore dei bordi."
+L["Border Insets"] = "Margine Bordo"
+L["The distance between the window and its border."] = "La distanza tra la finestra e il suo bordo."
+L["Scale"] = "Scala"
+L["Sets the scale of the window."] = "Imposta la scala della finestra."
+L["Strata"] = "Strato"
+L["This determines what other frames will be in front of the frame."] = "Questo determina quali altri riquadri saranno davanti al riquadro."
+L["Clamped To Screen"] = "Vincolato allo Schermo"
+L["Toggle whether to permit movement out of screen."] = "Attiva o disattiva lo spostamento fuori dallo schermo."
+L["X Offset"] = "Spostamento X"
+L["Y Offset"] = "Spostamento Y"
+-- switching
+L["Mode Switching"] = "Cambio Modalità"
+L["Combat Mode"] = "Modalità Combattimento"
+L["opt_combatmode_desc"] = "Cambia automaticamente al set \124cffffbb00Corrente\124r e a questa modalità quando si entra in combattimento."
+L["Wipe Mode"] = "Modalità Wipe"
+L["opt_wipemode_desc"] = "Cambia automaticamente al set \124cffffbb00Corrente\124r e a questa modalità dopo un wipe."
+L["Return after combat"] = "Ritorna dopo il combattimento"
+L["Return to the previous set and mode after combat ends."] = "Ritorna al set e alla modalità precedenti dopo la fine del combattimento."
+L["Auto switch to current"] = "Cambio automatico a corrente"
+L["opt_autocurrent_desc"] = "Ogni volta che inizia un combattimento, questa finestra passa automaticamente al segmento \124cffffbb00Corrente\124r."
+L["Auto Hide"] = "Nascondi automaticamente"
+L["While in combat"] = "Mentre in combattimento"
+L["While out of combat"] = "Mentre fuori combattimento"
+L["While not in a group"] = "Mentre non in gruppo"
+L["While inside an instance"] = "Mentre dentro un'istanza"
+L["While not inside an instance"] = "Mentre fuori da un'istanza"
+L["In Battlegrounds"] = "Nei Campi di Battaglia"
+L["Inline Bar Display"] = "Visualizzazione Barre Inline"
+L["mod_inline_desc"] = "La visualizzazione inline è uno stile orizzontale della finestra."
+L["Font Color"] = "Colore Carattere"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "Colore carattere.\nClicca su \"Colori Classe\" per iniziare."
+L["opt_barwidth_desc"] = 'Larghezza delle barre. Si applica solo se è abilitata l\'opzione "Larghezza barre fissa".'
+L["Fixed bar width"] = "Larghezza barre fissa"
+L["opt_fixedbarwidth_desc"] = "Se selezionato, la larghezza delle barre è fissa. Altrimenti, la larghezza delle barre dipende dalla larghezza del testo."
+L["Use class colors for %s."] = "Utilizza i colori della classe per %s."
+L["opt_isusingclasscolors_desc"] = "Con: %s - 5.71M (21.7K)\nSenza: %s - 5.71M (21.7K)"
+L["Put values on new line."] = "Inserisci i valori su una nuova linea."
+L["opt_isonnewline_desc"] = "Nuova linea:\n%1$s\n5.71M (21.7K)\n\nDivisore:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if available."] = "Utilizza la skin di ElvUI se disponibile."
+L["opt_isusingelvuiskin_desc"] = "Seleziona questa opzione per utilizzare la skin di ElvUI. Predefinita: selezionata"
+L["Use solid background."] = "Utilizza uno sfondo opaco."
+L["Un-check this for an opaque background."] = "Deseleziona per uno sfondo trasparente."
+L["Data Text"] = "Testo Dati"
+L["mod_broker_desc"] = "Il testo dei dati funge da feed dati LDB. Può essere integrato in qualsiasi visualizzatore LDB come Titan Panel o ChocolateBar. Ha anche un telaio interno opzionale."
+L["Use frame"] = "Utilizza telaio"
+L["opt_useframe_desc"] = "Mostra un telaio autonomo. Non è necessario se si sta utilizzando un visualizzatore di dati LDB come Titan Panel o ChocolateBar."
+L["Text Color"] = "Colore Testo"
+L["The text color of %s."] = "Il colore del testo di %s."
+L["Choose the default color."] = "Scegli il colore predefinito."
+L["Hint: Left-Click to set active mode."] = "Suggerimento: clicca sinistro per impostare la modalità attiva."
+L["Right-Click to set active set."] = "Clicca destro per impostare il set attivo."
+L["Shift+Left-Click to open menu."] = "Shift+Clic sinistro per aprire il menu."
+-- data resets
+L["Data Resets"] = "Reset Dati"
+L["Reset on entering instance"] = "Resetta all'ingresso dell'istanza"
+L["Controls if data is reset when you enter an instance."] = "Controlla se i dati vengono resettati quando si entra in un'istanza."
+L["Reset on joining a group"] = "Resetta all'entrata in gruppo"
+L["Controls if data is reset when you join a group."] = "Controlla se i dati vengono resettati quando si entra in un gruppo."
+L["Reset on leaving a group"] = "Resetta all'uscita dal gruppo"
+L["Controls if data is reset when you leave a group."] = "Controlla se i dati vengono resettati quando si esce dal gruppo."
+L["Ask"] = "Chiedi"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "Vuoi resettare Skada?\nTieni premuto SHIFT per resettare tutti i dati."
+L["All data has been reset."] = "Tutti i dati sono stati resettati."
+L["There is no data to reset."] = "Non ci sono dati da resettare."
+L["Skip reset dialog"] = "Salta la finestra di reset"
+L["opt_skippopup_desc"] = "Attiva questa opzione se vuoi che Skada venga resettato senza la finestra di conferma."
+L["Are you sure you want to reinstall Skada?"] = "Sei sicuro di voler reinstallare Skada?"
+-- general options
+L["Show minimap button"] = "Mostra pulsante minimappa"
+L["Toggles showing the minimap button."] = "Attiva o disattiva la visualizzazione del pulsante sulla minimappa."
+L["Transliterate"] = "Traslitterazione"
+L["Converts Cyrillic letters into Latin letters."] = "Converte le lettere cirilliche in lettere latine."
+L["Remove realm name"] = "Rimuovi nome reame"
+L["opt_realmless_desc"] = "Quando attivato, il nome del reame del personaggio non viene visualizzato."
+L["Merge pets"] = "Unisci famigli"
+L["Merges pets with their owners. Changing this only affects new data."] = "Unisce i famigli ai loro proprietari. Cambiare questa opzione avrà effetto solo sui nuovi dati."
+L["Show totals"] = "Mostra totali"
+L["Shows an extra row with a summary in certain modes."] = "Mostra una riga aggiuntiva con un riepilogo in certe modalità."
+L["Only keep boss fights"] = "Mantieni solo i combattimenti contro i boss"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "I combattimenti contro i boss verranno mantenuti con questa opzione attiva, mentre i combattimenti contro non-boss verranno scartati."
+L["Always save boss fights"] = "Salva sempre i combattimenti contro i boss"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "I combattimenti contro i boss verranno mantenuti con questa opzione attiva e non saranno influenzati dal reset di Skada."
+L["Hide when solo"] = "Nascondi in solitaria"
+L["Hides Skada's window when not in a party or raid."] = "Nasconde la finestra di Skada quando non sei in un gruppo o in un'incursione."
+L["Hide in PvP"] = "Nascondi in PvP"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "Nasconde la finestra di Skada quando sei in Battleground/Arena."
+L["Hide in combat"] = "Nascondi in combattimento"
+L["Hides Skada's window when in combat."] = "Nasconde la finestra di Skada quando sei in combattimento."
+L["Show in combat"] = "Mostra in combattimento"
+L["Shows Skada's window when in combat."] = "Mostra la finestra di Skada quando sei in combattimento."
+L["Disable while hidden"] = "Disabilita quando nascosto"
+L["Skada will not collect any data when automatically hidden."] = "Skada non raccoglierà dati quando è nascosto automaticamente."
+L["Sort modes by usage"] = "Ordina le modalità per utilizzo"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "La lista delle modalità sarà ordinata in base all'utilizzo invece che in ordine alfabetico."
+L["Show rank numbers"] = "Mostra numeri di rango"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "Mostra i numeri per i ranghi relativi nelle modalità in cui è applicabile."
+L["Aggressive combat detection"] = "Rilevamento di combattimento aggressivo"
+L["opt_tentativecombatstart_desc"] = [[Skada di solito utilizza un metodo di rilevamento di combattimento molto conservativo (semplice) che funziona meglio nelle incursioni.
+Con questa opzione, Skada cerca di emulare altri misuratori di danni.
+Utile per le spedizioni, inutile negli scontri con i boss.]]
+L["Autostop"] = "Arresto automatico"
+L["opt_autostop_desc"] = "Arresta automaticamente il segmento corrente dopo che la metà dei membri del raid è morta."
+L["Always show self"] = "Mostra sempre te stesso"
+L["opt_showself_desc"] = "Mantiene sempre il giocatore mostrato per ultimo anche se non c'è abbastanza spazio."
+L["Number format"] = "Formato numeri"
+L["Controls the way large numbers are displayed."] = "Controlla il modo in cui vengono visualizzati i numeri grandi."
+L["Condensed"] = "Condensato"
+L["Detailed"] = "Dettagliato"
+L["Combined"] = "Combinato"
+L["Comma"] = "Virgola"
+L["Numeral system"] = "Sistema numerico"
+L["Select which numeral system to use."] = "Seleziona quale sistema numerico utilizzare."
+L["Auto"] = "Automatico"
+L["Western"] = "Occidentale"
+L["East Asia"] = "Asia orientale"
+L["Brackets"] = "Parentesi"
+L["Choose which type of brackets to use."] = "Scegli che tipo di parentesi utilizzare."
+L["Separator"] = "Separatore"
+L["Choose which character is used to separate values between brackets."] = "Scegli quale carattere utilizzare per separare i valori tra parentesi."
+L["Number of decimals"] = "Numero di decimali"
+L["Controls the way percentages are displayed."] = "Controlla il modo in cui vengono visualizzati i numeri decimali."
+L["Data Feed"] = "Feed Dati"
+L["opt_feed_desc"] = "Scegli quale feed dati mostrare nella vista DataBroker. Questo richiede un addon di visualizzazione LDB, come Titan Panel."
+L["Time Measure"] = "Misura del tempo"
+L["Activity Time"] = "Tempo di attività"
+L["Effective Time"] = "Tempo effettivo"
+L["opt_timemesure_desc"] = [=[|cffffff00Attività|r: il timer di ogni membro del raid viene messo in pausa se la loro attività cessa e torna a contare quando riprende, modo comune di misurare DPS e HPS.
+|cffffff00Effettivo|r: utilizzato nelle classifiche, questo metodo utilizza il tempo di combattimento trascorso per misurare DPS e HPS di tutti i membri del raid.]=]
+L["Number set duplicates"] = "Numero di duplicati nei set"
+L["Append a count to set names with duplicate mob names."] = "Aggiungi un conteggio ai nomi dei set con nomi di mob duplicati."
+L["Set Format"] = "Formato Set"
+L["Controls the way set names are displayed."] = "Controlla il modo in cui vengono visualizzati i nomi dei set."
+L["Links in reports"] = "Link nei rapporti"
+L["When possible, use links in the report messages."] = "Quando possibile, utilizza i link nei messaggi di report."
+L["Segments to keep"] = "Segmenti da mantenere"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "Il numero di segmenti di combattimento da mantenere. I segmenti persistenti non sono inclusi in questo conteggio."
+L["Persistent segments"] = "Segmenti persistenti"
+L["The number of persistent fight segments to keep."] = "Il numero di segmenti di combattimento persistenti da mantenere."
+L["Memory Check"] = "Controllo Memoria"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "Controlla l'utilizzo della memoria e avvisa se è maggiore o uguale a %dmb."
+L["Disable Comms"] = "Disabilita Comms"
+L["Minimum segment length"] = "Lunghezza minima del segmento"
+L["The minimum length required in seconds for a segment to be saved."] = "La lunghezza minima richiesta in secondi per salvare un segmento."
+L["Update frequency"] = "Frequenza di aggiornamento"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "Con quale frequenza vengono aggiornate le finestre. Più breve per aggiornamenti più veloci. Aumenta l'utilizzo della CPU."
+-- columns
+L["Columns"] = "Colonne"
+-- tooltips
+L["Tooltips"] = "Descrizioni"
+L["Show Tooltips"] = "Mostra descrizioni"
+L["Shows tooltips with extra information in some modes."] = "Mostra descrizioni con informazioni aggiuntive in alcune modalità."
+L["Informative Tooltips"] = "Descrizioni informative"
+L["Shows subview summaries in the tooltips."] = "Mostra riassunti delle sotto-viste nelle descrizioni."
+L["Subview Rows"] = "Righe sotto-vista"
+L["The number of rows from each subview to show when using informative tooltips."] = "Il numero di righe da ogni sotto-vista da mostrare quando si utilizzano descrizioni informative."
+L["Tooltip Position"] = "Posizione descrizioni"
+L["Position of the tooltips."] = "Posizione delle descrizioni."
+L["Top Right"] = "In alto a destra"
+L["Top Left"] = "In alto a sinistra"
+L["Bottom Right"] = "In basso a destra"
+L["Bottom Left"] = "In basso a sinistra"
+L["Smart"] = "Intelligente"
+L["Follow Cursor"] = "Segue cursore"
+L["Top"] = "In alto"
+L["Bottom"] = "In basso"
+L["Right"] = "A destra"
+L["Left"] = "A sinistra"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00Richiede\124r: %s"
+L["Modules"] = "Moduli"
+L["Disabled Modules"] = "Moduli disabilitati"
+L["Modules Options"] = "Opzioni moduli"
+L["Tick the modules you want to disable."] = "Spunta i moduli che desideri disabilitare."
+L["This change requires a UI reload. Are you sure?"] = "Questa modifica richiede un riavvio dell'interfaccia. Sei sicuro?"
+-- themes options
+L["Theme"] = "Tema"
+L["Themes"] = "Temi"
+L["Manage Themes"] = "Gestisci temi"
+L["All Windows"] = "Tutte le finestre"
+L["Apply Theme"] = "Applica tema"
+L["Theme applied!"] = "Tema applicato!"
+L["Name of your new theme."] = "Nome del tuo nuovo tema."
+L["Save Theme"] = "Salva tema"
+L["Delete Theme"] = "Elimina tema"
+L["Are you sure you want to delete this theme?"] = "Sei sicuro di voler eliminare questo tema?"
+L["Paste here a theme in text format."] = "Incolla qui un tema in formato testo."
+L["This is your current theme in text format."] = "Questo è il tuo tema attuale in formato testo."
+-- scroll options
+L["Scroll"] = "Scorrimento"
+L["Wheel Speed"] = "Velocità rotella"
+L["opt_wheelspeed_desc"] = "Cambia quanto velocemente avviene lo scorrimento quando si ruota la rotella del mouse sulla finestra."
+L["Scroll Icon"] = "Icona di scorrimento"
+L["Scroll mouse button"] = "Pulsante di scorrimento del mouse"
+-- minimap button
+L["Skada Summary"] = "Sommario di Skada"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00Clic sinistro\124r per mostrare/nascondere le finestre."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+Clic sinistro\124r per mostrare/nascondere le finestre."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+Clic sinistro\124r per resettare."
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00Clic destro\124r per aprire il menu."
+-- skada menu
+L["Skada Menu"] = "Menu di Skada"
+L["Select Segment"] = "Seleziona segmento"
+L["Delete Segment"] = "Elimina segmento"
+L["Keep Segment"] = "Mantieni segmento"
+L["Toggle Windows"] = "Mostra/Nascondi finestre"
+L["Show/Hide Windows"] = "Mostra/Nascondi finestre"
+L["New Segment"] = "Nuovo segmento"
+L["Starts a new segment."] = "Inizia un nuovo segmento."
+L["New Phase"] = "Nuova fase"
+L["Starts a new phase."] = "Inizia una nuova fase."
+L["Select All"] = "Seleziona tutto"
+L["Deselect All"] = "Deseleziona tutto"
+-- window buttons
+L["Configure"] = "Configura"
+L["Open Config"] = "Apri configurazione"
+L["btn_config_desc"] = "Apre la finestra di configurazione."
+L["btn_reset_desc"] = [[Resetta tutti i dati di combattimento tranne quelli contrassegnati come mantenuti.
+|cff00ff00Shift-Clic sinistro|r: Elimina segmento.]]
+L["Segment"] = "Segmento"
+L["btn_segment_desc"] = [[Vai a un segmento specifico.
+|cff00ff00Shift-Clic sinistro|r per il segmento |cffffbb00successivo|r.
+|cff00ff00Shift-Clic destro|r per il segmento |cffffbb00precedente|r.
+|cff00ff00Clic centrale|r per il segmento |cffffbb00corrente|r.]]
+L["Mode"] = "Modalità"
+L["Jump to a specific mode."] = "Vai a una modalità specifica."
+L["Report"] = "Rapporto"
+L["btn_report_desc"] = [[Apre un dialogo che consente di riportare i dati agli altri in vari modi.
+|cff00ff00Shift-Clic|r per un Rapporto Rapido.]]
+L["Stop"] = "Arresta/Riprendi"
+L["btn_stop_desc"] = "Arresta o riprende il segmento corrente. Utile per escludere i dati dopo un wipe. Può anche essere impostato per fermarsi automaticamente nelle impostazioni."
+L["Segment Stopped."] = "Segmento fermato."
+L["Segment Paused."] = "Segmento in pausa."
+L["Segment Resumed."] = "Segmento ripreso."
+L["Quick Access"] = "Accesso rapido"
+-- default segments
+L["Total"] = "Totale"
+L["Current"] = "Attuale"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %s per %s:"
+L["Self"] = "Personale"
+L["Whisper Target"] = "Sussurra al bersaglio"
+L["Copy & Paste"] = "Copia e incolla"
+L["[General]"] = "[Generale]"
+L["[LocalDefense]"] = "[Difesa Locale]"
+L["[LookingForGroup]"] = "[CercaGruppo]"
+L["[Trade]"] = "[Commercio]"
+L["Line"] = "Linea"
+L["Lines"] = "Linee"
+L["There is nothing to report."] = "Non c'è nulla da segnalare."
+L["No mode or segment selected for report."] = "Nessuna modalità o segmento selezionato per il report."
+-- Bar Display Module --
+L["Bar Display"] = "Visualizzazione a barre"
+L["mod_bar_desc"] = "La visualizzazione a barre è la finestra normale utilizzata dalla maggior parte dei misuratori di danni. Può essere estesamente personalizzata."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "Visualizzazione a barre (legacy)"
+L["Max Bars"] = "Barre massime"
+L["The maximum number of bars shown."] = "Il numero massimo di barre mostrate."
+L["Show Menu Button"] = "Mostra pulsante del menu"
+L["Shows a button for opening the menu in the window title bar."] = "Mostra un pulsante per aprire il menu nella barra del titolo della finestra."
+L["Class Color Bars"] = "Barre a colori di classe"
+L["Class Color Text"] = "Testo a colori di classe"
+-- Threat Module --
+L["Threat"] = "Minaccia"
+L["Threat Warning"] = "Avviso di minaccia"
+L["Flash Screen"] = "Flash dello schermo"
+L["This will cause the screen to flash as a threat warning."] = "Questo farà lampeggiare lo schermo come avviso di minaccia."
+L["Shake Screen"] = "Scuoti schermo"
+L["This will cause the screen to shake as a threat warning."] = "Questo farà scuotere lo schermo come avviso di minaccia."
+L["Warning Message"] = "Messaggio di avviso"
+L["Print a message to the screen when you accumulate too much threat."] = "Stampa un messaggio allo schermo quando accumuli troppa minaccia."
+L["Play sound"] = "Riproduci suono"
+L["This will play a sound as a threat warning."] = "Questo riprodurrà un suono come avviso di minaccia."
+L["Message Output"] = "Output del messaggio"
+L["Choose where warning messages should be displayed."] = "Scegli dove dovrebbero essere mostrati i messaggi di avviso."
+L["Chat Frame"] = "Finestra di chat"
+L["Blizzard Error Frame"] = "Finestra di errore di Blizzard"
+L["opt_threat_soundfile_desc"] = "Il suono che verrà riprodotto quando la tua percentuale di minaccia raggiunge un certo punto."
+L["Warning Frequency"] = "Frequenza di avviso"
+L["Threat Threshold"] = "Soglia di minaccia"
+L["opt_threat_threshold_desc"] = "Quando la tua minaccia raggiunge questo livello, rispetto al tank, vengono mostrati gli avvisi."
+L["Show raw threat"] = "Mostra minaccia grezza"
+L["opt_threat_rawvalue_desc"] = "Mostra la percentuale di minaccia grezza rispetto al tank anziché modificata per la distanza."
+L["Use focus target"] = "Usa il target focus"
+L["opt_threat_focustarget_desc"] = 'Dice a Skada di controllare anche il tuo "focus" e "focustarget" prima di "target" e "targettarget" in quest\'ordine per la visualizzazione della minaccia.'
+L["Disable while tanking"] = "Disabilita durante il tanking"
+L["opt_threat_notankwarnings_desc"] = "Non inviare nessun avviso se Difensiva, Forma d'Orso, Furore Righteous o Presenza Ghiacciata è attiva."
+L["Ignore Pets"] = "Ignora i famigli"
+L["opt_threat_ignorepets_desc"] = [[Dice a Skada di saltare i famigli dei personaggio nemici quando determina su quale unità mostrare i dati di minaccia.
+
+I famigli dei personaggio mantengono una tabella di minaccia quando sono in modalità |cffffff78Aggressiva|r o |cffffff78Difensiva|r e si comportano proprio come i mob normali, attaccando il bersaglio con la minaccia più alta. Se il famiglio riceve l'istruzione di attaccare un bersaglio specifico, il famiglio mantiene comunque la tabella di minaccia, ma si attacca al bersaglio assegnato che per definizione ha il 100% di minaccia. I famigli dei personaggio possono essere provocati per forzarli ad attaccarti.
+
+Tuttavia, i famigli dei personaggio in modalità |cffffff78Passiva|r non hanno una tabella di minaccia, e la provocazione non funziona su di loro. Attaccano solo il bersaglio assegnato quando istruiti a farlo e lo fanno senza alcuna tabella di minaccia.
+
+Quando un famiglio di un giocatore riceve l'istruzione di |cffffff78Seguire|r, la tabella di minaccia del famiglio viene immediatamente cancellata e smette di attaccare, anche se potrebbe immediatamente riacquisire un bersaglio basandosi sulla sua modalità Aggressiva/Difensiva.]]
+L["> Pull Aggro <"] = "> Tira la minaccia <"
+L["Show Pull Aggro Bar"] = "Mostra la barra di tiro della minaccia"
+L["opt_threat_showaggrobar_desc"] = "Mostra una barra per la quantità di minaccia che avrai bisogno di raggiungere per tirare la minaccia."
+L["Test Warnings"] = "Test di avvisi"
+L["TPS"] = "TPS"
+L["Threat: Personal Threat"] = "Minaccia: Minaccia personale"
+L["Threat sound"] = "Suono di minaccia"
+-- Absorbs & Healing Module --
+L["Healing"] = "Cura"
+L["Healing Done"] = "Cure effettuate"
+L["Healing Taken"] = "Cure ricevute"
+L["HPS"] = "HPS"
+L["sHPS"] = "HPS (sotto-viste)"
+L["Healing: Personal HPS"] = "Cura: HPS personale"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "Cura: RHPS di raid"
+L["Total Healing"] = "Cure totali"
+L["Overheal"] = "Eccesso di cure"
+L["Overhealing"] = "Eccesso di cure"
+L["Absorbs"] = "Assorbimenti"
+L["Target List"] = "Lista bersagli"
+L["Spell List"] = "Lista incantesimi"
+L["APS"] = "APS"
+L["sAPS"] = "APS (sotto-viste)"
+L["Absorbs and Healing"] = "Assorbimenti e cure"
+L["Healing Done By Spell"] = "Cure effettuate per incantesimo"
+L["Source List"] = "Lista fonti"
+-- Auras Module --
+L["Uptime"] = "Durata"
+L["Buffs and Debuffs"] = "Benefici e penalità"
+L["Buffs"] = "Benefici"
+L["Debuffs"] = "Penalità"
+L["%s's <%s> targets"] = "Bersagli di %s <%s>"
+L["%s's <%s> sources"] = "Fonti di %s <%s>"
+L["Enemy Buffs"] = "Benefici nemici"
+L["Enemy Debuffs"] = "Penalità nemiche"
+-- CC Tracker Module --
+L["Crowd Control"] = "Controllo della folla"
+L["CC Done"] = "CC inflitti"
+L["CC Taken"] = "CC subiti"
+L["CC Breaks"] = "Rotture CC"
+L["Ignore Main Tanks"] = "Ignora i Tank principali"
+L["%s on %s removed by %s"] = "%s su %s rimosso da %s"
+L["%s on %s removed by %s's %s"] = "%s su %s rimosso da %s %s di %s"
+-- Damage Module --
+-- damage done module
+L["Damage"] = "Danno"
+L["Spell Details"] = "Dettagli incantesimi"
+L["Damage Done"] = "Danno inflitto"
+L["Pet Damage"] = _G.SHOW_PET_MELEE_DAMAGE or "Danno del Famiglio"
+L["Useful Damage"] = "Danno utile"
+L["Useful damage on %s"] = "Danno utile su %s"
+L["Damage Done By Spell"] = "Danno inflitto per incantesimo"
+L["%s's sources"] = "Fonti di %s"
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (sotto-viste)"
+L["Damage: Personal DPS"] = "Danno: DPS personale"
+L["RDPS"] = "RDPS"
+L["Damage: Raid DPS"] = "Danno: RDPS di raid"
+L["Absorbed Damage"] = "Danno assorbito"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "Abilita se vuoi che il danno assorbito sia incluso nel danno inflitto."
+L["Damage Done By School"] = "Danno inflitto per scuola"
+-- killing blows module
+L["Killing Blows"] = _G.KILLING_BLOWS or "Colpi di Grazia"
+L["Only PvP Kills"] = "Solo uccisioni PvP"
+L["When enabled, only kills against enemy players count."] = "Quando abilitato, solo le uccisioni contro personaggio nemici contano."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "Annuncia i colpi mortali dopo la fine del combattimento. Funziona solo per i combattimenti contro i boss."
+-- damage taken module
+L["Damage Taken"] = "Danno subito"
+L["Damage Taken By Spell"] = "Danno subito per incantesimo"
+L["%s's targets"] = "Bersagli di %s"
+L["DTPS"] = "DTPS"
+L["sDTPS"] = "DTPS (sotto-viste)"
+-- enemy damage done module
+L["Enemies"] = "Nemici"
+L["Enemy Damage Done"] = "Danno inflitto dai nemici"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "Danno subito dai nemici"
+L["%s below %s%%"] = "%s sotto il %s%%"
+L["%s - %s%% to %s%%"] = "%s - %s%% al %s%%"
+L["Phase %s"] = "Fase %s"
+L["%s - Phase %s"] = "%s - Fase %s"
+L["%s - Phase 1"] = "%s - Fase 1"
+L["%s - Phase 2"] = "%s - Fase 2"
+L["%s - Phase 3"] = "%s - Fase 3"
+L["%s (Main Boss)"] = "%s (Boss principale)"
+L["\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r iniziata."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r iniziata."
+L["\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r terminata."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r terminata."
+L["\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r ripresa."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r ripresa."
+-- enemy healing done module
+L["Enemy Healing Done"] = "Cure inflitte dai nemici"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "Evitamento e mitigazione"
+L["More Details"] = "Altri dettagli"
+L["%s's details"] = "Dettagli di %s"
+-- friendly fire module
+L["Friendly Fire"] = "Fuoco amico"
+-- useful damage targets
+L["Important targets"] = "Bersagli importanti"
+L["Oozes"] = "Melme"
+L["Princes overkilling"] = "Principi overkilling"
+L["Adds"] = "Aggiunte"
+L["Halion and Inferno"] = "Halion e Inferno"
+L["Valkyrs overkilling"] = "Valkyrie overkilling"
+-- Deaths Module --
+L["%s's deaths"] = "Morti di %s"
+L["Death log"] = "Registro delle morti"
+L["%s's death log"] = "Registro delle morti di %s"
+L["Player's deaths"] = "Morti del giocatore"
+L["%s dies"] = "%s muore"
+L["buff"] = "beneficio"
+L["debuff"] = "penalità"
+L["Spell details"] = "Dettagli incantesimo"
+L["Spell"] = "Incantesimo"
+L["Amount"] = "Quantità"
+L["Source"] = "Fonte"
+L["Change"] = "Variazione"
+L["Time"] = "Tempo"
+L["Survivability"] = "Sopravvivenza"
+L["Events Amount"] = "Quantità di eventi"
+L["Set the amount of events the death log should record."] = "Imposta la quantità di eventi che il registro delle morti dovrebbe registrare."
+L["Minimum Healing"] = "Cure minime"
+L["Ignore heal events that are below this threshold."] = "Ignora eventi di cura che sono al di sotto di questa soglia."
+L["Announce Deaths"] = "Annuncia le morti"
+L["Announces information about the last hit the player took before they died."] = "Annuncia informazioni sull'ultimo colpo che il giocatore ha subito prima di morire."
+L["Alternative Display"] = "Visualizzazione alternativa"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "Se un giocatore muore più volte, ogni morte verrà visualizzata come una barra separata."
+-- activity module
+L["Activity"] = "Attività"
+L["Activity per Target"] = "Attività per bersaglio"
+L["%s's activity"] = "Attività di %s"
+-- dispels module lines --
+L["Dispel Spells"] = "Incantesimi dissolti"
+L["%s's dispelled spells"] = "Incantesimi dissolti di %s"
+-- interrupts module lines --
+L["Interrupt Spells"] = "Incantesimi interrotti"
+L["%s's interrupted spells"] = "Incantesimi interrotti di %s"
+L["%s interrupted!"] = "%s interrotto!"
+-- Power gained module --
+L["Resources"] = "Risorse"
+L["Mana Restored"] = "Mana ripristinato"
+L["Rage Generated"] = "Rabbia generata"
+L["Energy Generated"] = "Energia generata"
+L["Runic Power Generated"] = "Potenza runica generata"
+-- Parry module lines --
+L["Parry-Haste"] = "Parata-Istantanea"
+L["%s parried %s (%s)"] = "%s ha parato %s (%s)"
+-- Potions module lines --
+L["Potions"] = "Pozioni"
+L["%s's potions"] = "Pozioni di %s"
+L["Pre-potion"] = "Pre-pozione"
+L["pre-potion: %s"] = "pre-pozione: %s"
+L["Prints pre-potion after the end of the combat."] = "Stampa pre-pozione alla fine del combattimento."
+-- healthstone --
+L["Healthstones"] = "Pietre della salute"
+-- resurrect module lines --
+L["Resurrects"] = "Resurrezioni"
+-- nickname module lines --
+L["Nickname"] = "Soprannome"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "I soprannomi vengono inviati ai membri del gruppo e Skada può utilizzarli al posto del tuo nome del personaggio."
+L["Set a nickname for you."] = "Imposta un soprannome per te."
+L["Nickname isn't a valid string."] = "Il soprannome non è una stringa valida."
+L["Your nickname is too long, max of 12 characters is allowed."] = "Il tuo soprannome è troppo lungo, è consentito un massimo di 12 caratteri."
+L["Only letters and two spaces are allowed."] = "Sono ammesse solo lettere e due spazi."
+L["Your nickname contains a forbidden word."] = "Il tuo soprannome contiene una parola vietata."
+L["You can't use the same letter three times consecutively, two spaces consecutively or more than two spaces."] = "Non puoi utilizzare la stessa lettera tre volte consecutivamente, due spazi consecutivamente o più di due spazi."
+L["Ignore Nicknames"] = "Ignora soprannomi"
+L["When enabled, nicknames set by Skada users are ignored."] = "Quando abilitato, i soprannomi impostati dagli utenti di Skada vengono ignorati."
+L["Name display"] = "Visualizzazione nome"
+L["Choose how names are shown on your bars."] = "Scegli come visualizzare i nomi sulle tue barre."
+L["Clear Cache"] = "Cancella cache"
+L["Are you sure you want clear cached nicknames?"] = "Sei sicuro di voler cancellare i soprannomi memorizzati nella cache?"
+-- overkill module lines --
+L["Overkill"] = "Eccesso di danno"
+-- tweaks module lines --
+L["Improvement"] = "Miglioramento"
+L["Tweaks"] = "Modifiche"
+L["First hit"] = "Primo colpo"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00Primo Colpo\124r: %s da %s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00Primo Colpo\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00Primo Bersaglio Boss\124r: %s"
+L["opt_tweaks_firsthit_desc"] = "Stampa un messaggio sul primo colpo prima del combattimento.\nFunziona solo per gli incontri con i boss."
+L["Filter DPS meters Spam"] = "Filtra lo spam dei misuratori DPS"
+L["opt_tweaks_spamage_desc"] = "Sopprime i messaggi di chat dai misuratori di danno e fornisce statistiche di danno in una finestra popup."
+L["Reported by: %s"] = "Riportato da: %s"
+L["Smart Stop"] = "Stop intelligente"
+L["opt_tweaks_smarthalt_desc"] = "Interrompe automaticamente il segmento corrente dopo la morte del boss.\nUtile per evitare la raccolta di dati in caso di bug di combattimento."
+L["Duration"] = "Durata"
+L["opt_tweaks_smartwait_desc"] = "Per quanto tempo Skada dovrebbe attendere prima di fermare il segmento."
+L["Modes Icons"] = "Icone delle modalità"
+L["Show modes icons on bars and menus."] = "Mostra le icone delle modalità su barre e menu."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "Abilita se vuoi ignorare \124cffffbb00%s\124r."
+L["Custom Colors"] = "Colori personalizzati"
+L["Arena Teams"] = "Squadre Arena"
+L["Are you sure you want to reset all colors?"] = "Sei sicuro di voler ripristinare tutti i colori?"
+L["Announce %s"] = "Annuncia %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "Annuncia quanto tempo è stato necessario per applicare %d stack di %s e annuncia quando scade."
+L["%s dropped from %s!"] = "%s è scaduto da %s!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%d stack di %s applicati su %s in %s sec!"
+L["My Spells"] = "Le mie magie"
+-- total data options
+L["Total Segment"] = "Segmento totale"
+L["All Segments"] = "Tutti i segmenti"
+L["Raid Bosses"] = "Boss dell'incursione"
+L["Raid Trash"] = "Moblin dell'incursione"
+L["Dungeon Bosses"] = "Boss della spedizione"
+L["Dungeon Trash"] = "Moblin della spedizione"
+L["opt_tweaks_total_all_desc"] = "Tutti i segmenti vengono aggiunti ai dati del segmento totale."
+L["opt_tweaks_total_fmt_desc"] = "I segmenti con %s vengono aggiunti ai dati del segmento totale."
+L["Detailed total segment"] = "Segmento totale dettagliato"
+L["opt_tweaks_total_full_desc"] = "Quando abilitato, Skada registrerà tutto nel segmento totale, invece dei numeri totali (registra i dettagli degli incantesimi, i loro bersagli e le loro fonti)."
+-- arena
+L["mod_pvp_desc"] = "Aggiunge la rilevazione della specializzazione per arene e campi di battaglia, e mostra gli avversari dell'arena sulla stessa finestra."
+L["Gold Team"] = "Squadra Oro"
+L["Green Team"] = "Squadra Verde"
+L["Color for %s."] = "Colore per %s."
+-- notifications
+L["Notifications"] = "Notifiche"
+L["opt_toast_desc"] = "Utilizza notifiche visive invece di messaggi nella finestra di chat quando applicabile."
+L["Test Notifications"] = "Prova notifiche"
+-- comparison module
+L["Comparison"] = "Confronto"
+L["%s vs %s: %s"] = "%s vs %s: %s"
+L["%s vs %s: Spells"] = "%s vs %s: Incantesimi"
+L["%s vs %s: Targets"] = "%s vs %s: Bersagli"
+-- spellcast module
+L["Casts"] = "Lanci"
+L["%s's spells"] = "Incantesimi di %s"
+L["%s's spells on %s"] = "Incantesimi di %s su %s"
+L["Spells on %s"] = "Incantesimi su %s"
+-- about
+L["Author"] = "Autore"
+L["Credits"] = "Crediti"
+L["Date"] = "Data"
+L["License"] = "Licenza"
+L["Version"] = "Versione"
+L["Website"] = "Sito web"
+-- custom class names using globals
+-- some bosses entries
+L["World Boss"] = "Boss Mondiale"
+-- L["Auriaya"] = ""
+L["Blood Prince Council"] = "Concilio del Sangue"
+-- L["Faction Champions"] = ""
+-- L["Hogger"] = ""
+-- L["Icecrown Gunship Battle"] = ""
+-- L["Kologarn"] = ""
+-- L["Mimiron"] = ""
+-- L["Thaddius"] = ""
+L["The Four Horsemen"] = "I Quattro Cavalieri"
+L["The Iron Council"] = "Il Concilio di Ferro"
+L["The Northrend Beasts"] = "Le Bestie del Nordania"
+-- L["Thorim"] = ""
+L["Twin Val'kyr"] = "Gemelle Val'kyr"
+L["Valithria Dreamwalker"] = "Valithria Vagasogni"
+-- L["Yogg-Saron"] = ""
diff --git a/Skada/Locales/koKR.lua b/Skada/Locales/koKR.lua
new file mode 100644
index 0000000..766d831
--- /dev/null
+++ b/Skada/Locales/koKR.lua
@@ -0,0 +1,757 @@
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "koKR")
+if not L then return end
+
+L["A damage meter."] = "데미지 미터기입니다."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "메모리 사용량이 높습니다. Skada 초기화가 필요할 수 있으며, 자동 초기화 옵션 중 하나를 활성화하세요."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada가 오래된 버전입니다. \124cffffbb00%s\124r 에서 새 버전을 다운로드 받으세요."
+L["Skada: Modes"] = "Skada: 모드"
+L["Skada: Fights"] = "Skada: 전투"
+L["Data Collection"] = "데이터 수집"
+L["ENABLED"] = "활성화됨"
+L["DISABLED"] = "비활성화됨"
+L["Enable All"] = "모두 활성화"
+L["Disable All"] = "모두 비활성화"
+L["Stopping for wipe."] = "때문에 닦아의 중지."
+L["Usage:"] = "사용:"
+L["Commands:"] = "명령:"
+L["Import"] = "가져오기"
+L["Export"] = "내보내기"
+L["Import/Export"] = "가져오기/내보내기"
+-- profiles
+L["Profiles"] = "프로필"
+L["Profile Import/Export"] = "프로필 가져오기/내보내기"
+L["Import Profile"] = "프로필 가져오기"
+L["Export Profile"] = "프로필 내보내기"
+L["Paste here a profile in text format."] = "여기에 문자 형식으로 프로필 붙여넣기."
+L["Press CTRL-V to paste the text from your clipboard."] = "CTRL-V를 눌러 클립보드의 텍스트를 붙여넣습니다."
+L["This is your current profile in text format."] = "이것은 문자 형식의 현재 프로필입니다."
+L["Press CTRL-C to copy the text to your clipboard."] = "CTRL-C를 눌러 텍스트를 클립보드에 복사합니다."
+L["Network Sharing"] = "네트워크 공유"
+L["Player Name"] = "플레이어 이름"
+L["Send Profile"] = "프로필 보내기"
+L["Accept profiles from other players."] = "다른 플레이어의 프로필 수락."
+L["opt_profile_received"] = "%s님이 프로필을 보내드렸습니다. 받은 프로필을 활성화 하시겠습니까?"
+L["Progress"] = "진행"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "데이터 크기: \124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "진행 상황: %d%%"
+L["Transmission Completed"] = "전송 완료"
+-- common lines
+L["Options"] = "옵션"
+L["Options for %s."] = "%s\1241을;를; 위한 옵션을 설정합니다."
+L["General"] = "일반"
+L["General options for %s."] = "%s의 일반 옵션."
+L["Text"] = "정본"
+L["Text options for %s."] = "%s의 텍스트 옵션."
+L["Format"] = "체재"
+L["Format options for %s."] = "%s의 형식 옵션."
+L["Appearance"] = "겉 모습"
+L["Appearance options for %s."] = "%s의 모양 옵션."
+L["Advanced"] = "상세"
+L["Advanced options for %s."] = "%s의 고급 옵션."
+L["Position"] = "위치"
+L["Position settings for %s."] = "%s의 위치 옵션."
+L["Width"] = "너비"
+L["The width of %s."] = "%s의 너비."
+L["Height"] = "높이"
+L["The height of %s."] = "%s의 높이입니다."
+L["Active Time"] = "활동 시간"
+L["Segment Time"] = "세분화 시간"
+L["Click for \124cff00ff00%s\124r"] = "클릭 -> \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift-클릭 -> \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Control-클릭 -> \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt-클릭 -> \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "수업 필터"
+L["Average"] = "평균"
+L["Count"] = "카운트"
+L["Refresh"] = "새로 고침 "
+L["Percent"] = "백분율"
+L["sPercent"] = "백분율 (하위 보기)"
+L["General Options"] = "일반 옵션"
+L["HoT"] = "지속 치유"
+L["DoT"] = "지속 피해"
+L["Hits"] = "횟수"
+L["Normal Hits"] = "일반 적중"
+L["Critical"] = "치명상"
+L["Critical Hits"] = "치명타 및 극대화 적중"
+L["Crushing"] = "강타"
+L["Glancing"] = "비껴맞음"
+L["ABSORB"] = "흡수함"
+L["BLOCK"] = "방패 막기"
+L["DEFLECT"] = "튕김"
+L["DODGE"] = "피함"
+L["EVADE"] = "벗어남"
+L["IMMUNE"] = "면역"
+L["MISS"] = "빗나감"
+L["PARRY"] = "막음"
+L["REFLECT"] = "반사함"
+L["RESIST"] = "저항함"
+L["Only for bosses."] = "상사에게만."
+L["Enable this only against bosses."] = "보스에 대해서만 활성화하십시오."
+-- segment info
+L["Start"] = "시작"
+L["End"] = "종료"
+-- windows section:
+L["Window"] = "창"
+L["Windows"] = "창"
+L["Create Window"] = "창 생성"
+L["Window Name"] = "창 이름"
+L["Enter the name for the new window."] = "새 창의 이름을 입력합니다."
+L["Delete Window"] = "창 삭제"
+L["Choose the window to be deleted."] = "삭제할 창을 선택합니다."
+L["Are you sure you want to delete this window?"] = "이 창을 삭제 하시겠습니까?"
+L["Delete All Windows"] = "모든 창 삭제"
+L["Are you sure you want to delete all windows?"] = "모든 창을 삭제하시겠습니까?"
+L["Rename Window"] = "창 이름 변경"
+L["Enter the name for the window."] = "창의 이름을 입력합니다."
+L["Test Mode"] = "시험 모드"
+L["Creates fake data to help you configure your windows."] = "창 구성에 도움이 되도록 가짜 데이터를 생성합니다."
+-- L["Child Window"] = ""
+-- L["A child window will replicate the parent window actions."] = ""
+-- L["Child Window Mode"] = ""
+L["Lock Window"] = "창 고정"
+L["Locks the bar window in place."] = "바 창을 고정합니다."
+L["Hide Window"] = "창 숨기기"
+L["Hides the window."] = "창을 숨 깁니다."
+L["Sticky Window"] = "끈적한 창"
+L["Allows the window to stick to other Skada windows."] = "창을 다른 Skada 창에 스냅 할 수 있습니다."
+L["Snap to best fit"] = "최적의 크기로 자동 조절"
+L["Snaps the window size to best fit when resizing."] = "창 크기를 조절할 때 최적의 크기로 맞춥니다."
+L["Disable Resize Buttons"] = "크기 조절 버튼 비활성"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "창 위로 마우스를 가져갈 때 크기 조정 및 잠금/잠금 해제 버튼을 억제합니다."
+L["Disable stretch button"] = "늘리기 버튼 비활성"
+L["Stretch button won't show up when you hover over the window."] = "창 위로 마우스를 가져가면 늘이기 버튼이 표시되지 않습니다."
+L["Reverse window stretch"] = "창을 아래로 늘이기"
+L["opt_botstretch_desc"] = "늘이기 버튼을 창의 맨 아래에 놓고 창을 아래쪽으로 늘립니다."
+L["Display System"] = "표시 시스템"
+L["Choose the system to be used for displaying data in this window."] = "이 창에 자료를 표시하는 데 사용할 시스템을 선택합니다."
+L["Copy Settings"] = "설정 복사"
+L["Choose the window from which you want to copy the settings."] = "설정을 복사 할 창을 선택하십시오."
+-- bars
+L["Bars"] = "바"
+L["Left Text"] = "왼쪽 텍스트"
+L["Right Text"] = "오른쪽 텍스트"
+L["Font"] = "폰트"
+L["The font used by %s."] = "%s에서 사용하는 글꼴입니다."
+L["Font Size"] = "글꼴 크기"
+L["The font size of %s."] = "%s의 글꼴 크기입니다."
+L["Font Outline"] = "글꼴 그림자"
+L["Sets the font outline."] = "글꼴 윤곽을 설정합니다."
+L["Outline"] = "외곽선"
+L["Thick"] = "두꺼운"
+L["Thick outline"] = "두꺼운 외곽선"
+L["Monochrome"] = "모노크롬"
+L["Outlined monochrome"] = "모노크롬 외곽선"
+L["Bar Texture"] = "바 텍스쳐"
+L["The texture used by all bars."] = "모든 바에 사용할 바 텍스쳐입니다."
+L["Spacing"] = "간격"
+L["Distance between %s."] = "%s 사이의 거리입니다."
+L["Displacement"] = "배수량"
+L["The distance between the edge of the window and the first bar."] = "창 가장자리와 첫 번째 막대 사이의 거리."
+L["Bar Orientation"] = "바 방향"
+L["The direction the bars are drawn in."] = "바의 그려지는 방향입니다."
+L["Left to right"] = "왼쪽에서 오른쪽"
+L["Right to left"] = "오른쪽에서 왼쪽"
+L["Reverse bar growth"] = "바 성장 방향 반대로"
+L["Bars will grow up instead of down."] = "바를 위로 성장시킵니다."
+L["Disable bar highlight"] = "바 강조 비활성"
+L["Hovering a bar won't make it brighter."] = "이 옵션을 사용하면 바에 마우스를 올렸을 때 바를 강조하지 않습니다."
+L["Bar Color"] = "바 색상"
+L["Choose the default color of the bars."] = "바의 기본 색상을 선택합니다."
+L["Background Color"] = "배경 색상"
+L["The color of the background."] = "배경의 색상을 설정합니다."
+L["Custom Color"] = "커스텀 컬러"
+L["Use a different color for my bar."] = "내 바에 다른 색상을 사용하십시오."
+L["My Color"] = "나의 색깔"
+L["Spell school colors"] = "주문 속성 색상"
+L["Use spell school colors where applicable."] = "적용 가능한 곳에 주문 속성 색상을 사용합니다."
+L["When possible, bars will be colored according to player class."] = "가능할 때 바에 플레이어 직업에 따라 색상을 입힙니다."
+L["When possible, bar text will be colored according to player class."] = "가능할 때 바 문자에 플레이어 직업에 따라 색상을 입힙니다."
+L["Class Icons"] = "직업 아이콘"
+L["Use class icons where applicable."] = "적용 가능한 곳에 직업 아이콘을 사용합니다."
+L["Spec Icons"] = "사양 아이콘"
+L["Use specialization icons where applicable."] = "해당되는 경우 전문화 아이콘을 사용하십시오."
+L["Role Icons"] = "역할 아이콘"
+L["Use role icons where applicable."] = "적용 가능한 곳에 역할 아이콘을 사용합니다."
+L["Show Spark Effect"] = "섬광 효과 표시"
+L["Click Through"] = "클릭 무시"
+L["Disables mouse clicks on bars."] = "바를 클릭할 수 없도록 합니다."
+L["Smooth Bars"] = "부드러운 바"
+L["Animate bar changes smoothly rather than immediately."] = "바를 즉시 변경하지 않고 부드럽게 변경시킵니다."
+-- title bar
+L["Title Bar"] = "제목 바"
+L["Enables the title bar."] = "제목 표시줄을 활성화합니다."
+L["Include set"] = "세트 포함"
+L["Include set name in title bar"] = "제목 바에 세트 이름 포함"
+L["Encounter Timer"] = "우두머리 전투 타이머"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "활성화하면 문자 왼쪽에 초시계가 표시됩니다."
+L["Mode Icon"] = "모드 아이콘"
+L["Shows mode's icon in the title bar."] = "제목 표시줄에 모드 아이콘을 표시합니다."
+L["The texture used as the background of the title."] = "제목의 배경에 사용할 텍스쳐를 설정합니다."
+L["Border texture"] = "테두리 텍스쳐"
+L["The texture used for the borders."] = "테두리에 사용할 텍스쳐를 설정합니다."
+L["Border Color"] = "테두리 색상"
+L["The color used for the border."] = "테두리 색상으로 사용합니다."
+L["Buttons"] = "버튼"
+L["Auto Hide Buttons"] = "버튼 자동 숨기기"
+L["Show window buttons only if the cursor is over the title bar."] = "커서가 제목 표시줄 위에 있을 때만 창 버튼을 표시합니다."
+L["Buttons Style"] = "버튼 스타일"
+-- general window
+L["Background"] = "배경"
+L["Background Texture"] = "배경 텍스쳐"
+L["The texture used as the background."] = "배경으로 사용할 텍스쳐를 설정합니다."
+L["Tile"] = "바둑판 배열"
+L["Tile the background texture."] = "배경 텍스쳐를 바둑판 배열합니다."
+L["Tile Size"] = "바둑판 큭기"
+L["The size of the texture pattern."] = "텍스쳐 패턴의 크기입니다."
+L["Border"] = "테두리"
+L["Border Thickness"] = "테두리 두께"
+L["The thickness of the borders."] = "테두리의 두께를 설정합니다."
+L["Border Insets"] = "보더 인셋"
+L["The distance between the window and its border."] = "창과 테두리 사이의 거리입니다."
+L["Scale"] = "크기 비율"
+L["Sets the scale of the window."] = "창의 크기 비율을 설정합니다."
+L["Strata"] = "우선순위"
+L["This determines what other frames will be in front of the frame."] = "프레임 앞에 어떤 다른 프레임을 표시할 지 선택합니다."
+L["Clamped To Screen"] = "화면에 고정"
+L["Toggle whether to permit movement out of screen."] = "화면 밖으로 창이 나가지 않도록 사용합니다."
+L["X Offset"] = "X 좌표"
+L["Y Offset"] = "Y 좌표"
+-- switching
+L["Mode Switching"] = "모드 전환"
+L["Combat Mode"] = "전투 모드"
+L["opt_combatmode_desc"] = "전투 시작시 자동으로 \124cffffbb00현재\124r 세분화의 이 모드로 전환합니다."
+L["Wipe Mode"] = "전멸 모드"
+L["opt_wipemode_desc"] = "전멸 후 자동으로 \124cffffbb00현재\124r 세분화의 이 모드로 전환합니다."
+L["Return after combat"] = "전투 후 돌아가기"
+L["Return to the previous set and mode after combat ends."] = "전투 종료 후 이전 세트와 모드로 돌아갑니다."
+L["Auto switch to current"] = "현재 전투로 자동 변경"
+L["opt_autocurrent_desc"] = "전투가 시작되면 자동으로 \124cffffbb00현재\124r 전투 세분화로 변경합니다."
+L["Auto Hide"] = "자동 숨기기"
+L["While in combat"] = "전투 중일 때"
+L["While out of combat"] = "전투 중이 아닐 때"
+L["While not in a group"] = "파티가 아닐 때"
+L["While inside an instance"] = "인스턴스 안에 있을 때"
+L["While not inside an instance"] = "인스턴스 밖에 있을 때"
+L["In Battlegrounds"] = "전장에서"
+L["Inline Bar Display"] = "인라인 바 표시"
+L["mod_inline_desc"] = "인라인 표시는 수평 창 스타일입니다."
+L["Font Color"] = "글자 색"
+-- L["Font Color.\nClick \"Class Colors\" to begin."] = ""
+-- L["opt_barwidth_desc"] = ""
+L["Fixed bar width"] = "바 너비 고정"
+L["opt_fixedbarwidth_desc"] = "선택하면 바 너비가 고정됩니다. 선택하지 않으면 바 너비는 문자 길이에 따라 달라집니다."
+L["Use class colors for %s."] = "%s 에 클래스 색상을 사용합니다."
+L["opt_isusingclasscolors_desc"] = "와 함께: %s - 5.71M (21.7K)\n없이: %s - 5.71M (21.7K)"
+L["Put values on new line."] = "새 줄에 값을 넣습니다. "
+-- L["opt_isonnewline_desc"] = ""
+L["Use ElvUI skin if avaliable."] = "가능한 경우 사용 ElvUI 피부."
+-- L["opt_isusingelvuiskin_desc"] = ""
+L["Use solid background."] = "단색 배경을 사용하십시오."
+-- L["Un-check this for an opaque background."] = ""
+L["Data Text"] = "자료 문자"
+L["mod_broker_desc"] = "자료 문자는 LDB 자료 제공으로 작동합니다. Titan Panel이나 ChocolateBar같은 모든 LDB 표시 애드온과 작동할 수 있습니다. 선택적 내장 프레임도 있습니다."
+L["Use frame"] = "창을 사용"
+L["opt_useframe_desc"] = "독립 실행형 창을 표시합니다. Titan Panel 또는 ChocolateBar와 같은 LDB 디스플레이 공급자를 사용하는 경우에는 필요하지 않습니다."
+L["Text Color"] = "문자 색상"
+L["Choose the default color."] = "기본 색상을 선택하십시오."
+L["Hint: Left-Click to set active mode."] = "힌트: 활성화 모드를 설정하려면 왼쪽-클릭"
+L["Right-Click to set active set."] = "활성화 세트를 설정하려면 오른쪽-클릭하세요."
+L["Shift+Left-Click to open menu."] = "Shift+왼쪽-클릭으로 메뉴를 엽니다."
+-- data resets
+L["Data Resets"] = "자료 초기화"
+L["Reset on entering instance"] = "인스턴스 입장 시 초기화"
+L["Controls if data is reset when you enter an instance."] = "인스턴스 입장 시 자료를 초기화할 지 설정합니다."
+L["Reset on joining a group"] = "파티/공격대 참여 시 초기화"
+L["Controls if data is reset when you join a group."] = "파티/공격대 참여 시 자료를 초기화할 지 설정합니다."
+L["Reset on leaving a group"] = "파티/공격대 탈퇴 시 초기화"
+L["Controls if data is reset when you leave a group."] = "파티/공격대를 떠났을 때 자료를 초기화할 지 설정합니다."
+L["Ask"] = "묻기"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "Skada를 초기화하시겠습니까?\n리셋 모든 것에 보류 SHIFT."
+L["All data has been reset."] = "모든 자료가 초기화되었습니다."
+L["There is no data to reset."] = "재설정할 데이터가 없습니다."
+L["Skip reset dialog"] = "재설정 대화 상자 건너 뛰기"
+L["opt_skippopup_desc"] = "확인 대화 상자없이 Skada를 재설정하려면이 옵션을 활성화하십시오."
+L["Are you sure you want to reinstall Skada?"] = "Skada를 다시 설치하시겠습니까?"
+-- general options
+L["Show minimap button"] = "미니맵 버튼 표시"
+L["Toggles showing the minimap button."] = "미니맵 버튼 표시를 전환합니다."
+L["Transliterate"] = "음역하다"
+L["Converts Cyrillic letters into Latin letters."] = "키릴 문자를 라틴 문자로 변환합니다."
+L["Remove realm name"] = "서버 이름 제거"
+L["opt_realmless_desc"] = "활성화하면 캐릭터의 서버 이름을 표시하지 않습니다."
+L["Merge pets"] = "소환수 합산"
+L["Merges pets with their owners. Changing this only affects new data."] = "소환수를 소유자와 합산합니다. 새로운 자료부터 적용됩니다."
+L["Show totals"] = "총량 표시"
+L["Shows a extra row with a summary in certain modes."] = "특정 모드에서 요약을 나타내는 추가 칸을 표시합니다."
+L["Only keep boss fighs"] = "우두머리 전투만 유지"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "우두머리 전투는 이 상태로 유지되며, 비-우두머리 전투는 차단됩니다."
+L["Always save boss fights"] = "항상 보스 싸움을 저장"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "보스전은 유지되며 Skada 초기화의 영향을 받지 않습니다."
+L["Hide when solo"] = "솔로잉 시 숨기기"
+L["Hides Skada's window when not in a party or raid."] = "파티 또는 공격대가 아닐 때 Skada 창을 숨깁니다."
+L["Hide in PvP"] = "PvP 시 숨기기"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "전장/투기장에서 Skada 창을 숨깁니다."
+L["Hide in combat"] = "전투 중 숨기기"
+L["Hides Skada's window when in combat."] = "전투 시 Skada 창을 숨깁니다."
+L["Show in combat"] = "전투에 표시"
+L["Shows Skada's window when in combat."] = "전투 중일 때 Skada 창을 표시합니다."
+L["Disable while hidden"] = "숨겨진 동안 비활성화"
+L["Skada will not collect any data when automatically hidden."] = "자동으로 숨겨져 있을 때 Skada는 어떠한 자료도 수집하지 않습니다."
+L["Sort modes by usage"] = "용도 별 모드 정렬"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "모드 목록을 가나다 순 대신 용도에 따라 정렬합니다."
+L["Show rank numbers"] = "순위 표시"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "사용 가능한 모드에서 순위를 표시합니다."
+L["Aggressive combat detection"] = "적극적인 전투 감지"
+L["opt_tentativecombatstart_desc"] = [[Skada는 공격대 중 가장 잘 작동하는 매우 전통적인 전투 감지 방법을 사용합니다.
+이 옵션을 사용하면 Skada는 다른 데미지 미터기를 모방합니다.
+던전을 진행할 때 유용합니다, 우두머리 전투에선 의미가 없습니다.]]
+L["Autostop"] = "전멸 시 일찍 멈추기"
+L["opt_autostop_desc"] = "전체 공격대원의 절반 이상이 죽으면 현재 세분화를 자동으로 멈춥니다."
+L["Always show self"] = "항상 자신 표시"
+L["opt_showself_desc"] = "충분한 공간이 없어도 플레이어를 마지막에 표시하도록 합니다."
+L["Number format"] = "숫자 형식"
+L["Controls the way large numbers are displayed."] = "큰 숫자의 표시 방식을 설정합니다."
+L["Condensed"] = "요약"
+L["Detailed"] = "상세"
+L["Combined"] = "결함"
+L["Comma"] = "반점"
+L["Numeral system"] = "명수법"
+L["Select which numeral system to use."] = "사용할 명수법을 선택하세요."
+L["Auto"] = "자동"
+L["Western"] = "서양"
+L["East Asia"] = "동아시아"
+L["Brackets"] = "괄호"
+L["Choose which type of brackets to use."] = "사용할 괄호 유형을 선택하십시오."
+L["Separator"] = "구분자"
+L["Choose which character is used to separator values between brackets."] = "괄호 사이의 값을 구분하는 데 사용할 문자를 선택합니다."
+L["Number of decimals"] = "소수 자릿수"
+L["Controls the way percentages are displayed."] = "백분율이 표시되는 방식을 제어합니다."
+L["Data Feed"] = "자료 제공"
+L["Time Measure"] = "시간 측정"
+L["Activity Time"] = "활동 시간"
+L["Effective Time"] = "실질 시간"
+L["opt_timemesure_desc"] = [=[|cffffff00활동 시간|r: 각 공격대원의 타이머가 해당 공대원의 활동이 중단되면 초읽기를 중지했다가 활동 재개시 다시 초읽기에 들어갑니다. Dps와 Hps 산출의 일반적인 방법입니다.
+
+|cffffff00실질 시간|r: 순위를 매길때 쓰입니다, 이 방법은 모든 공격대원의 Dps와 Hps를 산출하기 위해 측정된 전투 시간을 사용합니다.]=]
+L["opt_feed_desc"] = "DataBroker 보기에 어떤 자료를 표시할 지 선택하세요. Titan Panel같은 LDB 표시 애드온이 필요합니다."
+L["Number set duplicates"] = "중복 횟수"
+L["Append a count to set names with duplicate mob names."] = "몹 이름을 복제하여 세트 이름에 수를 추가합니다."
+L["Set Format"] = "세트 형식"
+L["Controls the way set names are displayed."] = "세트 이름 표시 방식을 설정합니다."
+L["Links in reports"] = "보고서의 링크"
+L["When possible, use links in the report messages."] = "가능하면 보고서 메시지에 링크를 사용하십시오."
+L["Segments to keep"] = "보관할 세그먼트"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "유지할 전투 세분화의 수입니다. 지속 세분화는 여기 포함되지 않습니다."
+L["Persistent segments"] = "영구 세그먼트"
+L["The number of persistent fight segments to keep."] = "유지할 영구 세그먼트의 수입니다."
+L["Memory Check"] = "메모리 확인"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "메모리 사용량을 확인하고 %dMB보다 크거나 같은 경우 경고합니다."
+L["Disable Comms"] = "통신 비활성화"
+L["Minimum segment length"] = "최소 세그먼트 길이"
+L["The minimum length required in seconds for a segment to be saved."] = "저장될 세그먼트에 필요한 최소 길이(초)입니다."
+L["Update frequency"] = "갱신 주기"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "윈도우 업데이트됩니다 얼마나 자주. 빠른 업데이트에 대한 짧은. CPU 사용량이 증가합니다."
+-- columns
+L["Columns"] = "세로 (칸)"
+-- tooltips
+L["Tooltips"] = "툴팁"
+L["Show Tooltips"] = "툴팁 표시"
+L["Shows tooltips with extra information in some modes."] = "일부 모드에서 툴팁에 추가 정보를 표시합니다."
+L["Informative Tooltips"] = "유용한 정보 툴팁"
+L["Shows subview summaries in the tooltips."] = "툴팁에 요약 정보 부가 표시를 표시합니다."
+L["Subview Rows"] = "부가 표시 열"
+L["The number of rows from each subview to show when using informative tooltips."] = "유용한 정보 툴팁을 사용할 때 각 부가 표시의 열의 번호를 표시합니다."
+L["Tooltip Position"] = "툴팁 위치"
+L["Position of the tooltips."] = "툴팁의 위치입니다."
+L["Top Right"] = "오른쪽 상단"
+L["Top Left"] = "왼쪽 상단"
+L["Bottom Right"] = "오른쪽 하단"
+L["Bottom Left"] = "왼쪽 하단"
+L["Smart"] = "스마트"
+L["Follow Cursor"] = "커서 따라 가기"
+L["Top"] = "상단"
+L["Bottom"] = "하단"
+L["Right"] = "오른쪽"
+L["Left"] = "왼쪽"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00필요사항\124r: %s"
+L["Modules"] = "모듈"
+L["Disabled Modules"] = "비활성화된 모듈"
+L["Modules Options"] = "모듈 설정"
+L["Tick the modules you want to disable."] = "비활성화할 모듈을 찍으세요."
+L["This change requires a UI reload. Are you sure?"] = "변경하려면 UI 재시작이 필요합니다. 다시 불러올까요?"
+-- themes options
+L["Theme"] = "테마"
+L["Themes"] = "테마"
+L["Manage Themes"] = "테마 관리"
+L["All Windows"] = "모든 창문"
+L["Apply Theme"] = "테마 적용"
+L["Theme applied!"] = "테마 적용!"
+L["Name of your new theme."] = "당신의 새로운 테마의 이름입니다."
+L["Save Theme"] = "테마 저장"
+L["Delete Theme"] = "테마 삭제"
+L["Are you sure you want to delete this theme?"] = "이 테마를 삭제하시겠습니까?"
+L["Paste here a theme in text format."] = "여기에 문자 형식으로 테마 붙여넣기."
+L["This is your current theme in text format."] = "이것은 문자 형식의 현재 테마입니다."
+-- scroll options
+L["Scroll"] = "스크롤"
+L["Wheel Speed"] = "휠 속도"
+L["opt_wheelspeed_desc"] = "창에서 마우스 휠을 사용할 때 스크롤 속도를 변경합니다."
+L["Scroll Icon"] = "스크롤 아이콘"
+L["Scroll mouse button"] = "스크롤 마우스 버튼"
+-- minimap button
+L["Skada Summary"] = "Skada 요약"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "창을 전환하려면 왼쪽 버튼을 클릭하십시오."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "Ctrl+왼쪽-창 표시/숨기기."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "Shift+왼쪽-클릭으로 초기화합니다."
+L["\124cff00ff00Right-Click\124r to open menu."] = "메뉴를 열려면 오른쪽 클릭."
+-- skada menu
+L["Skada Menu"] = "Skada 메뉴"
+L["Select Segment"] = "선택 세그먼트"
+L["Delete Segment"] = "세분화 삭제"
+L["Keep Segment"] = "세분화 유지"
+L["Toggle Windows"] = "창 전환"
+L["Show/Hide Windows"] = "창 표시/숨기기"
+L["New Segment"] = "새 세그먼트"
+L["Starts a new segment."] = "새 세그먼트를 시작합니다."
+L["New Phase"] = "새로운 단계"
+L["Starts a new phase."] = "새 단계를 시작합니다."
+L["Select All"] = "모두 선택"
+L["Deselect All"] = "모두 선택 해제"
+-- window buttons
+L["Configure"] = "설정"
+L["Open Config"] = "구성 열기"
+L["btn_config_desc"] = "설정 창 열기"
+L["btn_reset_desc"] = [[유지하도록 설정한 것을 제외하고 모든 전투 자료를 초기화합니다.
+|cff00ff00Shift 클릭|r -> 세분화 삭제.]]
+L["Segment"] = "세분화"
+L["btn_segment_desc"] = [[특정 세분화로 변경합니다.
+|cff00ff00Shift 클릭|r -> |cffffbb00다음|r 전투.
+|cff00ff00Shift 오른쪽 클릭|r -> |cffffbb00이전|r 전투.
+|cff00ff00가운데 클릭|r -> |cffffbb00현재|r 전투.]]
+L["Mode"] = "모드"
+L["Jump to a specific mode."] = "특정 모드로 변경합니다."
+L["Report"] = "보고서"
+L["btn_report_desc"] = [[다양한 방법으로 다른 사람에게 당신의 자료를 보고할 수 있는 대화창을 엽니다.
+|cff00ff00Shift-클릭|r -> 퀵 리포트.]]
+L["Stop"] = "중지"
+L["btn_stop_desc"] = "현재 세분화를 중지하거나 재개합니다. 전멸 후 자료를 제외하는 데 유용합니다. 설정에서 자동으로 중지하도록 설정할 수 있습니다."
+L["Segment Stopped."] = "세그먼트 중지됨."
+L["Segment Paused."] = "세그먼트 일시 중지됨."
+L["Segment Resumed."] = "세그먼트 재개됨."
+L["Quick Access"] = "빠른 접근"
+-- default segments
+L["Total"] = "전체"
+L["Current"] = "현재"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %2$s의 %1$s:"
+L["Self"] = "자신"
+L["Whisper Target"] = "대상에게 귓속말"
+L["Copy & Paste"] = "복사 & 붙여넣기"
+L["[General]"] = "공개"
+L["[LocalDefense]"] = "수비"
+L["[LookingForGroup]"] = "파티찾기"
+L["[Trade]"] = "거래"
+L["Line"] = "줄"
+L["Lines"] = "줄"
+L["There is nothing to report."] = "보고할 자료가 없습니다."
+L["No mode or segment selected for report."] = "보고서를 위한 모드나 세분화가 선택되지 않았습니다."
+-- Bar Display Module --
+L["Bar Display"] = "바 표시"
+L["mod_bar_desc"] = "바 표시는 대부분의 데미지 미터기가 사용하는 일반적인 바 형식의 창입니다. 폭 넓게 스타일링할 수 있습니다."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "바 표시(구)"
+L["Max Bars"] = "최대 바"
+L["The maximum number of bars shown."] = "표시할 바의 최대 수치입니다."
+L["Show Menu Button"] = "메뉴 버튼 표시"
+L["Shows a button for opening the menu in the window title bar."] = "창 제목 바에 메뉴를 여는 버튼을 표시합니다."
+L["Class Color Bars"] = "직업 색상 바"
+L["Class Color Text"] = "직업 색상 문자"
+-- Threat Module --
+L["Threat"] = "위협 수준"
+L["Threat Warning"] = "위협 수준 경고"
+L["Flash Screen"] = "화면 깜빡임"
+L["This will cause the screen to flash as a threat warning."] = "위협 수준 경고로 화면을 깜빡입니다."
+L["Shake Screen"] = "화면 진동"
+L["This will cause the screen to shake as a threat warning."] = "위협 수준 경고로 화면을 흔듭니다."
+L["Warning Message"] = "경고 메시지"
+L["Print a message to screen when you accumulate too much threat."] = "너무 많은 위협 수준이 쌓일때 화면에 메시지를 보여줍니다."
+L["Play sound"] = "소리 재생"
+L["This will play a sound as a threat warning."] = "위협 수준 경고로 소리를 재생합니다."
+L["Message Output"] = "출력"
+L["Choose where warning messages should be displayed."] = "경고 메시지를 표시할 위치를 선택합니다."
+L["Chat Frame"] = "대화창"
+L["Blizzard Error Frame"] = "블리자드 오류 창"
+L["Threat sound"] = "위협 수준 소리"
+L["opt_threat_soundfile_desc"] = "당신의 위협 수준 백분율이 특정 수준에 도달했을 때 재생할 소리입니다."
+L["Warning Frequency"] = "경고 빈도"
+L["Threat Threshold"] = "위협 수준 임계치"
+L["opt_threat_threshold_desc"] = "당신의 위협 수준이 방어 전담과 비교하여 이 수준에 도달했을 때 경고가 표시됩니다."
+L["Show raw threat"] = "기본 위협 표시"
+L["opt_threat_rawvalue_desc"] = "원거리에서 변경된 위협 수준 백분율 대신 방어 전담과 비교하여 기본 위협 수준 백분율을 표시합니다."
+L["Use focus target"] = "주시 대상 사용"
+L["opt_threat_focustarget_desc"] = "Skada에 당신의 '대상'과 '대상의 대상'에 대한 위협을 표시하기 위해 추가로 당신의 '주시'와 '주시 대상'을 검사합니다."
+L["Disable while tanking"] = "방어전담시 사용 안함"
+L["opt_threat_notankwarnings_desc"] = "방어 태세, 곰 변신, 정의의 격노나 냉기의 형상일때 모든 경고를 보이지 않습니다."
+L["Ignore Pets"] = "펫 무시"
+L["opt_threat_ignorepets_desc"] = [=[위협 수준 데이터를 표시할 유닛을 정할 때 Skada이 적대적 플레이어의 소환수는 걸러내도록 지시합니다.
+
+플레이어의 소환수가 |cffffff78적극적|r 또는 |cffffff78방어적|r 모드일 때는 위협 수준 테이블을 유지하고 가장 높은 위협 수준으로 대상을 공격하는 일반적인 몹처럼 작동합니다. 만약 소환수가 특정 대상을 공격하도록 지시하면, 소환수는 여전히 위협 수준 테이블을 유지하지만 지정한 대상에게 100%의 위협 수준을 가진것으로 고정됩니다. 플레이어의 소환수는 당신을 공격하도록 강제로 도발할 수 있습니다.
+
+하지만, |cffffff78수동적|r 모드의 플레이어 소환수는 위협 수준 테이블을 가지지 않으며, 그들을 도발할 수 없습니다. 소환수는 어떠한 위협 수준 테이블을 가지지 않은 채로 오직 공격하도록 지시된 대상을 공격합니다.
+
+플레이어 소환수를 |cffffff78따르기|r로 지시했을 때, 소환수의 위협 수준 테이블은 즉시 삭제되며 공격을 멈춥니다, 하지만 적극적/방어적 모드에 따라서 즉시 새로운 대상을 다시 얻습니다.]=]
+L["> Pull Aggro <"] = "> 어그로 획득 <"
+L["Show Pull Aggro Bar"] = "어그로 획득 바 표시"
+L["opt_threat_showaggrobar_desc"] = "어그로를 획득하기 위해 당신이 넘어야 할 위협 바를 표시합니다."
+L["Test Warnings"] = "테스트 경고"
+L["TPS"] = "TPS"
+L["Threat: Personal Threat"] = "위협 수준: 개인 위협 수준"
+-- Absorbs & Healing Module --
+L["Healing"] = "치유"
+L["Healing Done"] = "치유량"
+L["Healing Taken"] = "받은 치유"
+L["HPS"] = "HPS"
+L["sHPS"] = "HPS (하위 보기)"
+L["Healing: Personal HPS"] = "치유: 개인 HPS"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "치유: 공격대 HPS"
+L["Total Healing"] = "총 치유"
+L["Overheal"] = "초과 치유"
+L["Overhealing"] = "초과 치유"
+L["Absorbs"] = "흡수"
+L["Target List"] = "대상 목록"
+L["Spell List"] = "스펠 리스트"
+L["APS"] = "APS"
+L["sAPS"] = "APS (하위 보기)"
+L["Absorbs and Healing"] = "흡수와 치유"
+L["Healing Done By Spell"] = "주문에서 치유"
+L["Source List"] = "소스 목록"
+-- Auras Module --
+L["Uptime"] = "가동 시간"
+L["Buffs and Debuffs"] = "버프 및 디버프"
+L["Buffs"] = "버프"
+L["Debuffs"] = "디버프"
+L["%s's <%s> targets"] = "%s - %s의 대상"
+-- L["%s's <%s> sources"] = ""
+-- L["Enemy Buffs"] = ""
+-- L["Enemy Debuffs"] = ""
+-- CC Tracker Module --
+L["Crowd Control"] = "군중 제어"
+L["CC Done"] = "시전한 군중 제어"
+L["CC Taken"] = "받은 군중 제어"
+L["CC Breaks"] = "군중 제어 제거됨"
+L["Ignore Main Tanks"] = "방어 전담 무시"
+L["%s on %s removed by %s"] = "%2$s에게 걸린 %1$s\1241이;가; %3$s\1241으로;로; 제거되었습니다"
+L["%s on %s removed by %s's %s"] = "%2$s에게 걸린 %1$s\1241이;가; %3$s의 %4$s\1241으로;로; 제거되었습니다"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "환경"
+-- damage done module
+L["Damage"] = "피해"
+L["Spell Details"] = "주문세부"
+L["Damage Done"] = "피해량"
+L["Useful Damage"] = "유용한 손상"
+L["Useful damage on %s"] = "%s에 유용한 피해"
+L["Damage Done By Spell"] = "주문으로 인한 피해"
+-- L["%s's sources"] = ""
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (하위 보기)"
+L["Damage: Personal DPS"] = "피해: 개인 DPS"
+L["RDPS"] = "RDPS"
+L["Damage: Raid DPS"] = "피해: 공격대 DPS"
+L["Absorbed Damage"] = "흡수된 손상"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "가한 피해에 흡수된 피해가 포함되도록 하려면 이 옵션을 활성화합니다."
+L["Damage Done By School"] = "학교가 가한 피해"
+-- killing blows module
+L["Only PvP Kills"] = "PvP 킬만 계산됩니다."
+L["When enabled, only kills against enemy players count."] = "활성화되면 적 플레이어에 대한 킬만 계산됩니다."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "전투가 끝난 후 결정타를 선언합니다. 보스에게만 작동합니다."
+-- damage taken module
+L["Damage Taken"] = "받은 피해"
+L["Damage Taken By Spell"] = "주문 별 받은 피해"
+L["%s's targets"] = "%s의 표적"
+L["DTPS"] = "DTPS"
+L["sDTPS"] = "DTPS (하위 보기)"
+-- enemy damage done module
+L["Enemies"] = "적"
+L["Enemy Damage Done"] = "적 피해량"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "적이 받은 피해"
+L["%s below %s%%"] = "%s %s%% 미만"
+L["%s - %s%% to %s%%"] = "%s - %s%% 에서 %s%%"
+L["Phase %s"] = "위상 %s"
+L["%s - Phase %s"] = "%s - 위상 %s"
+L["%s - Phase 1"] = "%s - 위상 1"
+L["%s - Phase 2"] = "%s - 위상 2"
+L["%s - Phase 3"] = "%s - 위상 3"
+L["%s (Main Boss)"] = "%s (주보스)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00위상 %s\124r 시작됨."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00위상 %s\124r 중지됨."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00위상 %s\124r 재개됨."
+-- enemy healing done module
+L["Enemy Healing Done"] = "적의 치유량"
+-- avoidance and mitigation module
+-- L["Avoidance & Mitigation"] = ""
+L["More Details"] = "자세한 내용은"
+L["%s's details"] = "%s의 세부정보"
+-- friendly fire module
+L["Friendly Fire"] = "아군에게 준 피해"
+-- useful damage targets
+L["Important targets"] = "중요한 적들"
+-- L["Oozes"] = ""
+-- L["Princes overkilling"] = ""
+-- L["Adds"] = ""
+-- L["Halion and Inferno"] = ""
+-- L["Valkyrs overkilling"] = ""
+-- Deaths Module --
+L["Deaths"] = "죽음"
+-- L["%s's deaths"] = ""
+L["Death log"] = "죽음 기록"
+-- L["%s's death log"] = ""
+-- L["Player's deaths"] = ""
+L["%s dies"] = "%s 죽음"
+L["buff"] = "버프"
+L["debuff"] = "디버프"
+L["Spell details"] = "주문 세부"
+-- L["Spell"] = ""
+-- L["Amount"] = ""
+-- L["Source"] = ""
+L["Change"] = "변경"
+L["Time"] = "시각"
+L["Survivability"] = "활착"
+L["Events Amount"] = "이벤트 금액"
+L["Set the amount of events the death log should record."] = "사망 기록에 기록해야하는 이벤트의 양을 설정합니다."
+L["Minimum Healing"] = "최소 치유"
+L["Ignore heal events that are below this threshold."] = "이 임계 값보다 낮은 치유 이벤트는 무시하십시오."
+L["Announce Deaths"] = "사망 발표"
+L["Announces information about the last hit the player took before they died."] = "플레이어가 죽기 전에 마지막으로 한 명중을 알려줍니다."
+L["Alternative Display"] = "대체 디스플레이"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "플레이어가 여러 번 사망하면 각 사망은 별도의 막대로 표시됩니다."
+-- activity module
+L["Activity"] = "활동"
+L["Activity per Target"] = "대상당 활동"
+L["%s's activity"] = "%s의 활동"
+-- dispels module lines --
+-- L["Dispel Spells"] = ""
+-- L["%s's dispelled spells"] = ""
+-- interrupts module lines --
+-- L["Interrupt Spells"] = ""
+-- L["%s's interrupted spells"] = ""
+L["%s interrupted!"] = "%s 차단!"
+-- Power gained module --
+L["Resources"] = "자원"
+L["Mana Restored"] = "마나 회복"
+L["Rage Generated"] = "분노 생성"
+L["Energy Generated"] = "기력 생성"
+L["Runic Power Generated"] = "룬 마력 생성"
+-- Parry module lines --
+L["Parry-Haste"] = "패리-가속"
+L["%s parried %s (%s)"] = "%s 패리 %s (%s)"
+-- Potions module lines --
+-- L["Potions"] = ""
+-- L["%s's potions"] = ""
+-- L["Pre-potion"] = "Pre-potion"
+-- L["pre-potion: %s"] = "pre-potion: %s"
+-- L["Prints pre-potion after the end of the combat."] = ""
+-- healthstone --
+L["Healthstones"] = "생명석"
+-- resurrect module lines --
+-- L["Resurrects"] = ""
+-- nickname module lines --
+L["Nickname"] = "별명"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "별명은 길드원들에게 보내지며 Skada에서 캐릭터 이름대신 사용합니다."
+L["Set a nickname for you."] = "당신의 별명을 정합니다."
+-- L["Nickname isn't a valid string."] = ""
+-- L["Your nickname is too long, max of 12 characters is allowed."] = ""
+-- L["Only letters and two spaces are allowed."] = ""
+-- L["Your nickname contains a forbidden word."] = ""
+-- L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = ""
+L["Ignore Nicknames"] = "별명 무시"
+L["When enabled, nicknames set by Skada users are ignored."] = "활성화되면 다른 Skada 사용자가 설정 한 별명은 무시됩니다."
+-- L["Name display"] = ""
+-- L["Choose how names are shown on your bars."] = ""
+L["Clear Cache"] = "캐시 지우기"
+L["Are you sure you want clear cached nicknames?"] = "캐시 된 별명을 지우시겠습니까?"
+-- overkill module lines --
+L["Overkill"] = "과도한 손상"
+-- tweaks module lines --
+L["Improvement"] = "개선"
+L["Tweaks"] = "개선"
+L["First hit"] = "첫 번째 히트"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00첫 번째 히트\124r: %2$s의 %1$s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffff00첫 번째 히트\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00보스의 첫 번째 타겟\124r: %s"
+-- L["opt_tweaks_firsthit_desc"] = ""
+-- L["Filter DPS meters Spam"] = ""
+-- L["opt_tweaks_spamage_desc"] = ""
+L["Reported by: %s"] = "%s의 보고"
+-- L["Smart Stop"] = ""
+-- L["opt_tweaks_smarthalt_desc"] = ""
+-- L["Duration"] = ""
+-- L["opt_tweaks_smartwait_desc"] = ""
+L["Modes Icons"] = "모드 아이콘"
+L["Show modes icons on bars and menus."] = "바와 메뉴에 모드 아이콘을 표시합니다."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "\124cffffbb00%s\124r.를 무시하려면 이 옵션을 활성화하십시오."
+L["Custom Colors"] = "맞춤 색상"
+L["Arena Teams"] = "투기장 팀"
+L["Are you sure you want to reset all colors?"] = "모든 색상을 재설정하시겠습니까?"
+L["Announce %s"] = "발표: %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "%d 스택(%s)을 적용하는 데 걸린 시간을 알리고 언제 드롭되는지 알립니다."
+L["%s dropped from %s!"] = "%s 는 %s 에 만료!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%4$s초 만에 %3$s에 %2$s %1$s중첩 적용!"
+L["My Spells"] = "내 주문"
+-- total data options
+L["Total Segment"] = "총 세그먼트" -- needs review
+L["All Segments"] = "모든 세그먼트" -- needs review
+L["Raid Bosses"] = "레이드 보스" -- needs review
+L["Raid Trash"] = "레이드 휴지통" -- needs review
+L["Dungeon Bosses"] = "던전 보스" -- needs review
+L["Dungeon Trash"] = "던전 휴지통" -- needs review
+L["opt_tweaks_total_all_desc"] = "모든 세그먼트는 전체 세그먼트의 데이터에 추가됩니다." -- needs review
+L["opt_tweaks_total_fmt_desc"] = "전체 세그먼트의 데이터에 %s가 있는 세그먼트가 추가됩니다." -- needs review
+L["Detailed total segment"] = "상세 합계"
+-- L["opt_tweaks_total_full_desc"] = "When enabled, Skada will record everything to the total segment, instead of total numbers (record spell details, their targets as their sources)."
+-- arena
+L["mod_pvp_desc"] = "투기장 및 전장에 대한 전문화 감지를 추가하고 같은 창에 투기장 상대를 표시합니다."
+L["Gold Team"] = "금색팀"
+L["Green Team"] = "녹색팀"
+L["Color for %s."] = "%s의 색상입니다."
+-- notifications
+L["Notifications"] = "알림"
+L["opt_toast_desc"] = "해당되는 경우 채팅 창 메시지 대신 시각적 알림을 사용합니다."
+L["Test Notifications"] = "테스트 알림"
+-- comparison module
+L["Comparison"] = "비교"
+L["%s vs %s: %s"] = "%s 대 %s: %s"
+L["%s vs %s: Spells"] = "%s 대 %s: 스펠스"
+L["%s vs %s: Targets"] = "%s 대 %s: 대상"
+-- spellcast module
+L["Casts"] = "시전"
+L["%s's spells"] = "%s 스펠스"
+L["%s's spells on %s"] = "%s의 %s 주문"
+L["Spells on %s"] = "%s의 주문"
+-- about
+L["Author"] = "저작자"
+L["Credits"] = "크레딧"
+L["Date"] = "날짜"
+L["License"] = "라이센스"
+L["Version"] = "버전"
+L["Website"] = "웹 사이트"
+-- some bosses entries
+L["World Boss"] = "야외 우두머리"
+L["Auriaya"] = "아우리아야"
+L["Blood Prince Council"] = "피의 공작 의회"
+L["Faction Champions"] = "진영 대표 용사"
+L["Hogger"] = "들창코"
+L["Icecrown Gunship Battle"] = "얼음왕관 비행포격선 전투"
+L["Kologarn"] = "콜로간"
+L["Mimiron"] = "미미론"
+L["Sapphiron"] = "사피론"
+L["The Four Horsemen"] = "4인의 기병대"
+L["The Iron Council"] = "무쇠 평의회"
+L["The Northrend Beasts"] = "노스렌드 야수"
+L["Thorim"] = "토림"
+L["Twin Val'kyr"] = "발키르 쌍둥이"
+L["Valithria Dreamwalker"] = "발리스리아 드림워커"
+L["Yogg-Saron"] = "요그사론"
diff --git a/Skada/Locales/ptBR.lua b/Skada/Locales/ptBR.lua
new file mode 100644
index 0000000..0d8f39c
--- /dev/null
+++ b/Skada/Locales/ptBR.lua
@@ -0,0 +1,739 @@
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "ptBR")
+if not L then return end
+
+L["A damage meter."] = "Um medidor de dano."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "O uso de memória está alto. Você pode querer redefinir o Skada e habilitar uma das opções de redefinição automática."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "O Skada está desatualizado. Você pode baixar a versão mais recente em \124cffffbb00%s\124r"
+L["Skada: Modes"] = "Skada: Modos"
+L["Skada: Fights"] = "Skada: Combates"
+L["Data Collection"] = "Coleta de Dados"
+L["ENABLED"] = "Habilitado"
+L["DISABLED"] = "Desabilitado"
+L["Enable All"] = "Habilitar Todos"
+L["Disable All"] = "Desabilitar Todos"
+L["Stopping for wipe."] = "Parando para limpar."
+L["Usage:"] = "Uso:"
+L["Commands:"] = "Comandos:"
+L["Import"] = "Importar"
+L["Export"] = "Exportar"
+L["Import/Export"] = "Importar/Exportar"
+L["Pets"] = "Bichos de Estimação"
+-- profiles
+L["Profiles"] = "Perfis"
+L["Profile Import/Export"] = "Importar/Exportar Perfil"
+L["Import Profile"] = "Importar Perfil"
+L["Export Profile"] = "Exportar Perfil"
+L["Paste here a profile in text format."] = "Cole aqui um perfil em formato de texto."
+L["Press CTRL-V to paste the text from your clipboard."] = "Pressione CTRL-V para colar o texto da sua área de transferência."
+L["This is your current profile in text format."] = "Este é o seu perfil atual em formato de texto."
+L["Press CTRL-C to copy the text to your clipboard."] = "Pressione CTRL-C para copiar o texto para sua área de transferência."
+L["Network Sharing"] = "Compartilhamento de Rede"
+L["Player Name"] = "Nome do Jogador"
+L["Send Profile"] = "Enviar Perfil"
+L["Accept profiles from other players."] = "Aceitar perfis de outros jogadores."
+L["opt_profile_received"] = "%s enviou a você uma configuração de perfil. Você deseja ativar o perfil recebido?"
+L["Progress"] = "Progresso"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "Tamanho dos Dados: \124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "Progresso de Transmissão: %02.f%%"
+L["Transmission Completed"] = "Transmissão Concluída"
+-- common lines
+L["Options"] = "Opções"
+L["Options for %s."] = "Opções para %s."
+L["General"] = "Geral"
+L["General options for %s."] = "Opções gerais para %s."
+L["Text"] = "Texto"
+L["Text options for %s."] = "Opções de texto para %s."
+L["Format"] = "Formato"
+L["Format options for %s."] = "Opções de formato para %s."
+L["Appearance"] = "Aparência"
+L["Appearance options for %s."] = "Opções de aparência para %s."
+L["Advanced"] = "Avançado"
+L["Advanced options for %s."] = "Opções avançadas para %s."
+L["Position"] = "Posição"
+L["Position settings for %s."] = "Configurações de posição para %s."
+L["Width"] = "Largura"
+L["The width of %s."] = "A largura de %s."
+L["Height"] = "Altura"
+L["The height of %s."] = "A altura de %s."
+L["Active Time"] = "Tempo Ativo"
+L["Segment Time"] = "Tempo do Segmento"
+L["Click for \124cff00ff00%s\124r"] = "Clique para \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift-Clique para \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Ctrl-Clique para \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt-Clique para \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "Alternar Filtro de Classe"
+L["Average"] = "Média"
+L["Count"] = "Contagem"
+L["Refresh"] = "Atualizar"
+L["Percent"] = "Porcentagem"
+L["sPercent"] = "Porcentagem (subvisões)"
+L["General Options"] = "Opções Gerais"
+L["Hits"] = "Acertos"
+L["Normal Hits"] = "Acertos Normais"
+L["Critical"] = "Crítico"
+L["Critical Hits"] = "Acertos Críticos"
+L["Crushing"] = "Esmagamento"
+L["Glancing"] = "Relance"
+L["ABSORB"] = "Absorver"
+L["BLOCK"] = "Bloquear"
+L["DEFLECT"] = "Desviar"
+L["DODGE"] = "Esquivar"
+L["EVADE"] = "Evasão"
+L["IMMUNE"] = "Imune"
+L["MISS"] = "Perda"
+L["PARRY"] = "Aparar"
+L["REFLECT"] = "Refletir"
+L["RESIST"] = "Resistir"
+L["Only for bosses."] = "Apenas para chefes."
+L["Enable this only against bosses."] = "Ative isso apenas contra chefes."
+-- segment info
+L["Start"] = "Início"
+L["End"] = "Fim"
+-- windows section:
+L["Window"] = "Janela"
+L["Windows"] = "Janelas"
+L["Create Window"] = "Criar Janela"
+L["Window Name"] = "Nome da Janela"
+L["Enter the name for the new window."] = "Digite o nome para a nova janela."
+L["Delete Window"] = "Excluir Janela"
+L["Choose the window to be deleted."] = "Escolha a janela a ser excluída."
+L["Are you sure you want to delete this window?"] = "Tem certeza de que deseja excluir esta janela?"
+L["Delete All Windows"] = "Excluir Todas as Janelas"
+L["Are you sure you want to delete all windows?"] = "Tem certeza de que deseja excluir todas as janelas?"
+L["Rename Window"] = "Renomear Janela"
+L["Enter the name for the window."] = "Digite o nome para a janela."
+L["Test Mode"] = "Modo de Teste"
+L["Creates fake data to help you configure your windows."] = "Cria dados falsos para ajudar você a configurar suas janelas."
+L["Child Window"] = "Janela Filha"
+L["A child window will replicate the parent window actions."] = "Uma janela filha replicará as ações da janela pai."
+L["Child Window Mode"] = "Modo de Janela Filha"
+L["Lock Window"] = "Travar Janela"
+L["Locks the bar window in place."] = "Trava a janela de barras no lugar."
+L["Hide Window"] = "Ocultar Janela"
+L["Hides the window."] = "Oculta a janela."
+L["Sticky Window"] = "Janela Adesiva"
+L["Allows the window to stick to other Skada windows."] = "Permite que a janela se prenda a outras janelas do Skada."
+L["Snap to best fit"] = "Ajustar ao Melhor Encaixe"
+L["Snaps the window size to best fit when resizing."] = "Ajusta o tamanho da janela para o melhor encaixe ao redimensionar."
+L["Disable Resize Buttons"] = "Desativar Botões de Redimensionamento"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "Os botões de redimensionamento e travamento/destravamento não aparecerão quando você passar o mouse sobre a janela."
+L["Disable stretch button"] = "Desativar botão de esticar"
+L["Stretch button won't show up when you hover over the window."] = "O botão de esticar não aparecerá quando você passar o mouse sobre a janela."
+L["Reverse window stretch"] = "Esticamento reverso da janela"
+L["opt_botstretch_desc"] = "Coloca o botão de esticamento na parte inferior da janela e faz a janela esticar para baixo."
+L["Display System"] = "Sistema de Exibição"
+L["Choose the system to be used for displaying data in this window."] = "Escolha o sistema a ser usado para exibir dados nesta janela."
+L["Copy Settings"] = "Copiar Configurações"
+L["Choose the window from which you want to copy the settings."] = "Escolha a janela da qual deseja copiar as configurações."
+-- bars
+L["Bars"] = "Barras"
+L["Left Text"] = "Texto à Esquerda"
+L["Right Text"] = "Texto à Direita"
+L["Font"] = "Fonte"
+L["The font used by %s."] = "A fonte usada por %s."
+L["Font Size"] = "Tamanho da Fonte"
+L["The font size of %s."] = "O tamanho da fonte de %s."
+L["Font Outline"] = "Contorno da Fonte"
+L["Sets the font outline."] = "Define o contorno da fonte."
+L["Thick"] = "Grosso"
+L["Thick outline"] = "Contorno grosso"
+L["Monochrome"] = "Monocromático"
+L["Outlined monochrome"] = "Monocromático contornado"
+L["Bar Texture"] = "Textura da Barra"
+L["The texture used by all bars."] = "A textura usada por todas as barras."
+L["Spacing"] = "Espaçamento"
+L["Distance between %s."] = "Distância entre %s."
+L["Displacement"] = "Deslocamento"
+L["The distance between the edge of the window and the first bar."] = "A distância entre a borda da janela e a primeira barra."
+L["Bar Orientation"] = "Orientação da Barra"
+L["The direction the bars are drawn in."] = "A direção em que as barras são desenhadas."
+L["Left to right"] = "Da esquerda para a direita"
+L["Right to left"] = "Da direita para a esquerda"
+L["Reverse bar growth"] = "Crescimento reverso da barra"
+L["Bars will grow up instead of down."] = "As barras crescerão para cima em vez de para baixo."
+L["Disable bar highlight"] = "Desativar destaque da barra"
+L["Hovering a bar won't make it brighter."] = "Passar o mouse sobre uma barra não a deixará mais clara."
+L["Bar Color"] = "Cor da Barra"
+L["Choose the default color of the bars."] = "Escolha a cor padrão das barras."
+L["Background Color"] = "Cor de Fundo"
+L["The color of the background."] = "A cor do fundo."
+L["Custom Color"] = "Cor Personalizada"
+L["Use a different color for my bar."] = "Usar uma cor diferente para minha barra."
+L["My Color"] = "Minha Cor"
+L["Spell school colors"] = "Cores das Escolas de Magia"
+L["Use spell school colors where applicable."] = "Usar cores das escolas de magia onde aplicável."
+L["When possible, bars will be colored according to player class."] = "Quando possível, as barras serão coloridas de acordo com a classe do jogador."
+L["When possible, bar text will be colored according to player class."] = "Quando possível, o texto da barra será colorido de acordo com a classe do jogador."
+L["Class Icons"] = "Ícones de Classe"
+L["Use class icons where applicable."] = "Usar ícones de classe onde aplicável."
+L["Spec Icons"] = "Ícones de Especialização"
+L["Use specialization icons where applicable."] = "Usar ícones de especialização onde aplicável."
+L["Role Icons"] = "Ícones de Função"
+L["Use role icons where applicable."] = "Usar ícones de função onde aplicável."
+L["Show Spark Effect"] = "Mostrar Efeito de Centelha"
+L["Click Through"] = "Clique Através"
+L["Disables mouse clicks on bars."] = "Desabilita cliques do mouse nas barras."
+L["Smooth Bars"] = "Barras Suaves"
+L["Animate bar changes smoothly rather than immediately."] = "Anima mudanças nas barras suavemente em vez de imediatamente."
+-- title bar
+L["Title Bar"] = "Barra de Título"
+L["Enables the title bar."] = "Ativa a barra de título."
+L["Include set"] = "Incluir conjunto"
+L["Include set name in title bar"] = "Incluir nome do conjunto na barra de título"
+L["Encounter Timer"] = "Temporizador de Encontro"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "Quando ativado, um cronômetro é exibido no lado esquerdo do texto."
+L["Mode Icon"] = "Ícone de Modo"
+L["Shows mode's icon in the title bar."] = "Mostra o ícone do modo na barra de título."
+L["The texture used as the background of the title."] = "A textura usada como plano de fundo do título."
+L["Border texture"] = "Textura da Borda"
+L["The texture used for the borders."] = "A textura usada para as bordas."
+L["Border Color"] = "Cor da Borda"
+L["The color used for the border."] = "A cor usada para a borda."
+L["Buttons"] = "Botões"
+L["Auto Hide Buttons"] = "Ocultar Botões Automaticamente"
+L["Show window buttons only if the cursor is over the title bar."] = "Mostrar botões de janela apenas se o cursor estiver sobre a barra de título."
+L["Buttons Style"] = "Estilo dos Botões"
+-- general window
+L["Background Texture"] = "Textura de Fundo"
+L["The texture used as the background."] = "A textura usada como fundo."
+L["Tile"] = "Repetir"
+L["Tile the background texture."] = "Repetir a textura de fundo."
+L["Tile Size"] = "Tamanho do Mosaico"
+L["The size of the texture pattern."] = "O tamanho do padrão de textura."
+L["Border"] = "Borda"
+L["Border Thickness"] = "Espessura da Borda"
+L["The thickness of the borders."] = "A espessura das bordas."
+L["Border Insets"] = "Margens da Borda"
+L["The distance between the window and its border."] = "A distância entre a janela e sua borda."
+L["Scale"] = "Escala"
+L["Sets the scale of the window."] = "Define a escala da janela."
+L["Strata"] = "Camada"
+L["This determines what other frames will be in front of the frame."] = "Isso determina quais outros quadros estarão na frente do quadro."
+L["Clamped To Screen"] = "Preso à Tela"
+L["Toggle whether to permit movement out of screen."] = "Alterna se permite ou não movimento fora da tela."
+L["X Offset"] = "Deslocamento X"
+L["Y Offset"] = "Deslocamento Y"
+-- switching
+L["Mode Switching"] = "Troca de Modo"
+L["Combat Mode"] = "Modo de Combate"
+L["opt_combatmode_desc"] = "Muda automaticamente para o conjunto \124cffffbb00Atual\124r e este modo ao entrar em combate."
+L["Wipe Mode"] = "Modo de Limpeza"
+L["opt_wipemode_desc"] = "Muda automaticamente para o conjunto \124cffffbb00Atual\124r e este modo após uma limpeza."
+L["Return after combat"] = "Retornar após combate"
+L["Return to the previous set and mode after combat ends."] = "Retornar para o conjunto e modo anterior após o término do combate."
+L["Auto switch to current"] = "Troca automática para o atual"
+L["opt_autocurrent_desc"] = "Sempre que um combate começar, esta janela muda automaticamente para o segmento \124cffffbb00Atual\124r."
+L["Auto Hide"] = "Ocultar Automaticamente"
+L["While in combat"] = "Enquanto em combate"
+L["While out of combat"] = "Enquanto fora de combate"
+L["While not in a group"] = "Enquanto não estiver em um grupo"
+L["While inside an instance"] = "Enquanto dentro de uma instância"
+L["While not inside an instance"] = "Enquanto não estiver dentro de uma instância"
+L["In Battlegrounds"] = "Em Campos de Batalha"
+L["Inline Bar Display"] = "Exibição de Barra em Linha"
+L["mod_inline_desc"] = "A exibição em linha é um estilo de janela horizontal."
+L["Font Color"] = "Cor da Fonte"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "Cor da fonte.\nClique em \"Cores de Classe\" para começar."
+L["opt_barwidth_desc"] = 'Largura das barras. Isso só se aplica se a opção "Largura de barra fixa" for usada.'
+L["Fixed bar width"] = "Largura de barra fixa"
+L["opt_fixedbarwidth_desc"] = "Se marcado, a largura da barra é fixa. Caso contrário, a largura da barra depende da largura do texto."
+L["Use class colors for %s."] = "Usar cores de classe para %s."
+L["opt_isusingclasscolors_desc"] = "Com: %s - 5.71M (21.7K)\nSem: %s - 5.71M (21.7K)"
+L["Put values on new line."] = "Colocar valores em nova linha."
+L["opt_isonnewline_desc"] = "Nova linha:\n%1$s\n5.71M (21.7K)\n\nDivisor:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = "Usar a skin do ElvUI, se disponível."
+L["opt_isusingelvuiskin_desc"] = "Marque isso para usar a skin do ElvUI. \nPadrão: marcado"
+L["Use solid background."] = "Usar fundo sólido."
+L["Un-check this for an opaque background."] = "Desmarque isso para um fundo opaco."
+L["Data Text"] = "Texto de Dados"
+L["mod_broker_desc"] = "O texto de dados atua como uma fonte de dados LDB. Pode ser integrado em qualquer exibição LDB, como o Titan Panel ou o ChocolateBar. Também possui uma estrutura interna opcional."
+L["Use frame"] = "Usar Moldura"
+L["opt_useframe_desc"] = "Mostra uma estrutura independente. Não necessário se estiver usando um provedor de exibição LDB, como o Titan Panel ou o ChocolateBar."
+L["Text Color"] = "Cor do Texto"
+L["The text color of %s."] = "A cor do texto de %s."
+L["Choose the default color."] = "Escolha a cor padrão."
+L["Hint: Left-Click to set active mode."] = "Dica: clique com o botão esquerdo para definir o modo ativo."
+L["Right-Click to set active set."] = "Clique com o botão direito para definir o conjunto ativo."
+L["Shift+Left-Click to open menu."] = "Shift+clique com o botão esquerdo para abrir o menu."
+-- data resets
+L["Data Resets"] = "Reinicializações de Dados"
+L["Reset on entering instance"] = "Reiniciar ao entrar na instância"
+L["Controls if data is reset when you enter an instance."] = "Controla se os dados são reiniciados ao entrar em uma instância."
+L["Reset on joining a group"] = "Reiniciar ao entrar em um grupo"
+L["Controls if data is reset when you join a group."] = "Controla se os dados são reiniciados ao entrar em um grupo."
+L["Reset on leaving a group"] = "Reiniciar ao sair de um grupo"
+L["Controls if data is reset when you leave a group."] = "Controla se os dados são reiniciados ao sair de um grupo."
+L["Ask"] = "Perguntar"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "Você deseja reiniciar o Skada?\nPressione SHIFT para reiniciar todos os dados."
+L["All data has been reset."] = "Todos os dados foram reinicializados."
+L["There is no data to reset."] = "Não há dados para reiniciar."
+L["Skip reset dialog"] = "Pular diálogo de reinicialização"
+L["opt_skippopup_desc"] = "Ative isso se quiser que o Skada seja reiniciado sem o diálogo de confirmação."
+L["Are you sure you want to reinstall Skada?"] = "Tem certeza de que deseja reinstalar o Skada?"
+-- general options
+L["Show minimap button"] = "Mostrar botão no minimapa"
+L["Toggles showing the minimap button."] = "Ativa ou desativa a exibição do botão no minimapa."
+L["Transliterate"] = "Transliterar"
+L["Converts Cyrillic letters into Latin letters."] = "Converte letras cirílicas em letras latinas."
+L["Remove realm name"] = "Remover nome do reino"
+L["opt_realmless_desc"] = "Quando habilitado, o nome do reino do personagem não é exibido."
+L["Merge pets"] = "Mesclar Mascotes"
+L["Merges pets with their owners. Changing this only affects new data."] = "Mescla mascotes com seus proprietários. Mudar isso afeta apenas novos dados."
+L["Show totals"] = "Mostrar Totais"
+L["Shows a extra row with a summary in certain modes."] = "Mostra uma linha extra com um resumo em certos modos."
+L["Only keep boss fighs"] = "Manter apenas lutas contra chefes"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "As lutas contra chefes serão mantidas com esta opção ativada, e as lutas não contra chefes serão descartadas."
+L["Always save boss fights"] = "Sempre salvar lutas contra chefes"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "As lutas contra chefes serão mantidas com isso ativado e não serão afetadas pela reinicialização do Skada."
+L["Hide when solo"] = "Ocultar quando sozinho"
+L["Hides Skada's window when not in a party or raid."] = "Oculta a janela do Skada quando não estiver em grupo ou raide."
+L["Hide in PvP"] = "Ocultar no PvP"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "Oculta a janela do Skada quando em Campos de Batalha/Arenas."
+L["Hide in combat"] = "Ocultar em combate"
+L["Hides Skada's window when in combat."] = "Oculta a janela do Skada durante o combate."
+L["Show in combat"] = "Mostrar em combate"
+L["Shows Skada's window when in combat."] = "Mostra a janela do Skada durante o combate."
+L["Disable while hidden"] = "Desabilitar enquanto oculto"
+L["Skada will not collect any data when automatically hidden."] = "O Skada não coletará nenhum dado quando estiver automaticamente oculto."
+L["Sort modes by usage"] = "Ordenar modos por uso"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "A lista de modos será ordenada para refletir o uso em vez de alfabeticamente."
+L["Show rank numbers"] = "Mostrar números de classificação"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "Mostra números de classificação relativa para modos onde é aplicável."
+L["Aggressive combat detection"] = "Detecção de combate agressiva"
+L["opt_tentativecombatstart_desc"] = [[O Skada geralmente usa um esquema de detecção de combate muito conservador (simples) que funciona melhor em raides.
+Com esta opção, o Skada tenta emular outros medidores de dano.
+Útil para executar masmorras, sem significado em encontros de chefe.]]
+L["Autostop"] = "Parada automática"
+L["opt_autostop_desc"] = "Interrompe automaticamente o segmento atual depois que metade de todos os membros da raide morrerem."
+L["Always show self"] = "Sempre mostrar a si mesmo"
+L["opt_showself_desc"] = "Mantém o jogador mostrado por último mesmo se não houver espaço suficiente."
+L["Number format"] = "Formato de número"
+L["Controls the way large numbers are displayed."] = "Controla a forma como os números grandes são exibidos."
+L["Condensed"] = "Condensado"
+L["Detailed"] = "Detalhado"
+L["Combined"] = "Combinado"
+L["Comma"] = "Vírgula"
+L["Numeral system"] = "Sistema Numérico"
+L["Select which numeral system to use."] = "Selecione qual sistema numérico usar."
+L["Auto"] = "Automático"
+L["Western"] = "Ocidental"
+L["East Asia"] = "Ásia Oriental"
+L["Brackets"] = "Parênteses"
+L["Choose which type of brackets to use."] = "Escolha qual tipo de parênteses usar."
+L["Separator"] = "Separador"
+L["Choose which character is used to separate values between brackets."] = "Escolha qual caractere é usado para separar os valores entre parênteses."
+L["Number of decimals"] = "Número de casas decimais"
+L["Controls the way percentages are displayed."] = "Controla a forma como as porcentagens são exibidas."
+L["Data Feed"] = "Feed de Dados"
+L["opt_feed_desc"] = "Escolha qual feed de dados mostrar na visualização DataBroker. Isso requer um complemento de exibição LDB, como o Titan Panel."
+L["Time Measure"] = "Medida de Tempo"
+L["Activity Time"] = "Tempo de Atividade"
+L["Effective Time"] = "Tempo Efetivo"
+L["opt_timemesure_desc"] = [=[|cffffff00Atividade|r: o temporizador de cada membro da raide é colocado em pausa se sua atividade cessar e volta a contar quando retomada, forma comum de medir DPS e HPS.
+|cffffff00Efetivo|r: usado em classificações, este método usa o tempo de combate decorrido para medir o DPS e HPS de todos os membros da raide.]=]
+L["Number set duplicates"] = "Números de conjuntos duplicados"
+L["Append a count to set names with duplicate mob names."] = "Anexar uma contagem aos nomes dos conjuntos com nomes de monstros duplicados."
+L["Set Format"] = "Formato do Conjunto"
+L["Controls the way set names are displayed."] = "Controla a forma como os nomes dos conjuntos são exibidos."
+L["Links in reports"] = "Links nos relatórios"
+L["When possible, use links in the report messages."] = "Quando possível, use links nos mensagens do relatório."
+L["Segments to keep"] = "Segmentos para manter"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "O número de segmentos de combate para manter. Segmentos persistentes não estão incluídos nisso."
+L["Persistent segments"] = "Segmentos persistentes"
+L["The number of persistent fight segments to keep."] = "O número de segmentos de combate persistentes para manter."
+L["Memory Check"] = "Verificação de Memória"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "Verifica o uso de memória e avisa se for maior ou igual a %dmb."
+L["Disable Comms"] = "Desativar Comunicações"
+L["Minimum segment length"] = "Comprimento mínimo do segmento"
+L["The minimum length required in seconds for a segment to be saved."] = "O comprimento mínimo necessário em segundos para um segmento ser salvo."
+L["Update frequency"] = "Frequência de atualização"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "Com que frequência as janelas são atualizadas. Menor para atualizações mais rápidas. Aumenta o uso da CPU."
+-- columns
+L["Columns"] = "Colunas"
+-- tooltips
+L["Tooltips"] = "Dicas de Ferramentas"
+L["Show Tooltips"] = "Mostrar Dicas de Ferramentas"
+L["Shows tooltips with extra information in some modes."] = "Mostra dicas de ferramentas com informações extras em alguns modos."
+L["Informative Tooltips"] = "Dicas de Ferramentas Informativas"
+L["Shows subview summaries in the tooltips."] = "Mostra resumos da subvisão nas dicas de ferramentas."
+L["Subview Rows"] = "Linhas da Subvisão"
+L["The number of rows from each subview to show when using informative tooltips."] = "O número de linhas de cada subvisão a serem mostradas ao usar dicas de ferramentas informativas."
+L["Tooltip Position"] = "Posição da Dica de Ferramenta"
+L["Position of the tooltips."] = "Posição das dicas de ferramentas."
+L["Top Right"] = "Canto Superior Direito"
+L["Top Left"] = "Canto Superior Esquerdo"
+L["Bottom Right"] = "Canto Inferior Direito"
+L["Bottom Left"] = "Canto Inferior Esquerdo"
+L["Smart"] = "Inteligente"
+L["Follow Cursor"] = "Seguir Cursor"
+L["Top"] = "Topo"
+L["Bottom"] = "Fundo"
+L["Right"] = "Direita"
+L["Left"] = "Esquerda"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00Requer\124r: %s"
+L["Modules"] = "Módulos"
+L["Disabled Modules"] = "Módulos Desativados"
+L["Modules Options"] = "Opções de Módulos"
+L["Tick the modules you want to disable."] = "Marque os módulos que deseja desativar."
+L["This change requires a UI reload. Are you sure?"] = "Essa alteração requer uma recarga da interface. Tem certeza?"
+-- themes options
+L["Theme"] = "Tema"
+L["Themes"] = "Temas"
+L["Manage Themes"] = "Gerenciar Temas"
+L["All Windows"] = "Todas as Janelas"
+L["Apply Theme"] = "Aplicar Tema"
+L["Theme applied!"] = "Tema aplicado!"
+L["Name of your new theme."] = "Nome do seu novo tema."
+L["Save Theme"] = "Salvar Tema"
+L["Delete Theme"] = "Excluir Tema"
+L["Are you sure you want to delete this theme?"] = "Tem certeza de que deseja excluir este tema?"
+L["Paste here a theme in text format."] = "Cole aqui um tema em formato de texto."
+L["This is your current theme in text format."] = "Este é o seu tema atual em formato de texto."
+-- scroll options
+L["Scroll"] = "Rolagem"
+L["Wheel Speed"] = "Velocidade da Roda"
+L["opt_wheelspeed_desc"] = "Altera a velocidade da rolagem ao rolar a roda do mouse sobre a janela."
+L["Scroll Icon"] = "Ícone de Rolagem"
+L["Scroll mouse button"] = "Botão de rolagem do mouse"
+-- minimap button
+L["Skada Summary"] = "Resumo do Skada"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00Clique Esquerdo\124r para alternar janelas."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+Clique Esquerdo\124r para mostrar/ocultar janelas."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+Clique Esquerdo\124r para redefinir."
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00Clique Direito\124r para abrir o menu."
+-- skada menu
+L["Skada Menu"] = "Menu do Skada"
+L["Select Segment"] = "Selecionar Segmento"
+L["Delete Segment"] = "Excluir Segmento"
+L["Keep Segment"] = "Manter Segmento"
+L["Toggle Windows"] = "Alternar Janelas"
+L["Show/Hide Windows"] = "Mostrar/Ocultar Janelas"
+L["New Segment"] = "Novo Segmento"
+L["Starts a new segment."] = "Inicia um novo segmento."
+L["New Phase"] = "Nova Fase"
+L["Starts a new phase."] = "Inicia uma nova fase."
+L["Select All"] = "Selecionar Todos"
+L["Deselect All"] = "Desselecionar Todos"
+-- window buttons
+L["Configure"] = "Configurar"
+L["Open Config"] = "Abrir Configuração"
+L["btn_config_desc"] = "Abre a janela de configuração."
+L["btn_reset_desc"] = [=[Redefine todos os dados de combate, exceto os marcados como mantidos.
+|cff00ff00Shift-LMB|r: Excluir segmento.]=]
+L["Segment"] = "Segmento"
+L["btn_segment_desc"] = [=[Ir para um segmento específico.
+|cff00ff00Shift-LMB|r para o |cffffbb00próximo|r segmento.
+|cff00ff00Shift-RMB|r para o |cffffbb00segmento anterior|r.
+|cff00ff00Clique do Meio|r para o |cffffbb00segmento atual|r.]=]
+L["Mode"] = "Modo"
+L["Jump to a specific mode."] = "Ir para um modo específico."
+L["Report"] = "Relatório"
+L["btn_report_desc"] = [=[Abre um diálogo que permite relatar seus dados para outras pessoas de várias maneiras.
+|cff00ff00Shift-Clique|r para Relatório Rápido.]=]
+L["Stop"] = "Parar/Retomar"
+L["btn_stop_desc"] = [=[Para ou retoma o segmento atual. Útil para descartar dados após um wipe. Também pode ser definido para parar automaticamente nas configurações.]=]
+L["Segment Stopped."] = "Segmento Parado."
+L["Segment Paused."] = "Segmento Pausado."
+L["Segment Resumed."] = "Segmento Retomado."
+L["Quick Access"] = "Acesso Rápido"
+-- default segments
+L["Total"] = "Total"
+L["Current"] = "Luta atual"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %s para %s:"
+L["Self"] = "Próprio"
+L["Whisper Target"] = "Sussurrar Alvo"
+L["Copy & Paste"] = "Copiar e Colar"
+L["[General]"] = "[Geral]"
+L["[LocalDefense]"] = "[DefesaLocal]"
+L["[LookingForGroup]"] = "[ProcurandoGrupo]"
+L["[Trade]"] = "[Comércio]"
+L["Line"] = "Linha"
+L["Lines"] = "Linhas"
+L["There is nothing to report."] = "Não há nada para relatar."
+L["No mode or segment selected for report."] = "Nenhum modo ou segmento selecionado para relatório."
+-- Bar Display Module --
+L["Bar Display"] = "Exibição de Barra"
+L["mod_bar_desc"] = "A exibição de barra é a janela de barra normal usada pela maioria dos medidores de dano. Pode ser estilizada extensivamente."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "Exibição de Barra Legado"
+L["Max Bars"] = "Máximo de Barras"
+L["The maximum number of bars shown."] = "O número máximo de barras mostradas."
+L["Show Menu Button"] = "Mostrar Botão de Menu"
+L["Shows a button for opening the menu in the window title bar."] = "Mostra um botão para abrir o menu na barra de título da janela."
+L["Class Color Bars"] = "Barras de Cor de Classe"
+L["Class Color Text"] = "Texto de Cor de Classe"
+-- Threat Module --
+L["Threat"] = "Ameaça"
+L["Threat Warning"] = "Aviso de Ameaça"
+L["Flash Screen"] = "Tela Piscante"
+L["This will cause the screen to flash as a threat warning."] = "Isso fará com que a tela pisque como um aviso de ameaça."
+L["Shake Screen"] = "Tela Tremendo"
+L["This will cause the screen to shake as a threat warning."] = "Isso fará com que a tela trema como um aviso de ameaça."
+L["Warning Message"] = "Mensagem de Aviso"
+L["Print a message to screen when you accumulate too much threat."] = "Imprimir uma mensagem na tela quando você acumula muita ameaça."
+L["Play sound"] = "Reproduzir som"
+L["This will play a sound as a threat warning."] = "Isso reproduzirá um som como um aviso de ameaça."
+L["Message Output"] = "Saída de Mensagem"
+L["Choose where warning messages should be displayed."] = "Escolha onde as mensagens de aviso devem ser exibidas."
+L["Chat Frame"] = "Quadro de Bate-papo"
+L["Blizzard Error Frame"] = "Quadro de Erro do Blizzard"
+L["Warning Frequency"] = "Frequência de Aviso"
+L["Threat Threshold"] = "Limiar de Ameaça"
+L["Show raw threat"] = "Mostrar ameaça bruta"
+L["Use focus target"] = "Usar alvo de foco"
+L["Disable while tanking"] = "Desativar enquanto tanque"
+L["Ignore Pets"] = "Ignorar Mascotes"
+L["> Pull Aggro <"] = "> Puxar Aggro <"
+L["Show Pull Aggro Bar"] = "Mostrar Barra de Puxar Aggro"
+L["Test Warnings"] = "Testar Avisos"
+L["TPS"] = "TPS"
+L["Threat: Personal Threat"] = "Ameaça: Ameaça Pessoal"
+L["Threat sound"] = "Som de Ameaça"
+-- Absorbs & Healing Module --
+L["Healing"] = "Cura"
+L["Healing Done"] = "Cura Feita"
+L["Healing Taken"] = "Cura Recebida"
+L["HPS"] = "HPS"
+L["sHPS"] = "HPS (subvisões)"
+L["Healing: Personal HPS"] = "Cura: HPS Pessoal"
+L["RHPS"] = "HPSR"
+L["Healing: Raid HPS"] = "Cura: HPS de Raide"
+L["Total Healing"] = "Cura Total"
+L["Overheal"] = "Supercura"
+L["Overhealing"] = "Supercura"
+L["Absorbs"] = "Absorções"
+L["Target List"] = "Lista de Alvos"
+L["Spell List"] = "Lista de Feitiços"
+L["APS"] = "APS"
+L["sAPS"] = "APS (subvisões)"
+L["Absorbs and Healing"] = "Absorções e Cura"
+L["Healing Done By Spell"] = "Cura Feita por Feitiço"
+L["Source List"] = "Lista de Fontes"
+-- Auras Module --
+L["Uptime"] = "Tempo de Atividade"
+L["Buffs and Debuffs"] = "Bônus e Penalidades"
+L["Buffs"] = "Bônus"
+L["Debuffs"] = "Penalidades"
+L["%s's <%s> targets"] = "Alvos de <%s> de %s"
+L["%s's <%s> sources"] = "Fontes de <%s> de %s"
+L["Enemy Buffs"] = "Bônus do Inimigo"
+L["Enemy Debuffs"] = "Penalidades do Inimigo"
+-- CC Tracker Module --
+L["Crowd Control"] = "Controle de Massa"
+L["CC Done"] = "CM Feito"
+L["CC Taken"] = "CM Sofrido"
+L["CC Breaks"] = "CM Quebrado"
+L["Ignore Main Tanks"] = "Ignorar Tanques Principais"
+L["%s on %s removed by %s"] = "%s em %s removido por %s"
+L["%s on %s removed by %s's %s"] = "%s em %s removido por %s's %s"
+-- damage done module
+L["Damage"] = "Dano"
+L["Spell Details"] = "Detalhes do Feitiço"
+L["Damage Done"] = "Dano Causado"
+L["Useful Damage"] = "Dano Útil"
+L["Useful damage on %s"] = "Dano útil em %s"
+L["Damage Done By Spell"] = "Dano Causado por Feitiço"
+L["%s's sources"] = "Fontes de %s"
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (subvisões)"
+L["Damage: Personal DPS"] = "Dano: DPS Pessoal"
+L["RDPS"] = "RDPS"
+L["Damage: Raid DPS"] = "Dano: DPS de Raide"
+L["Absorbed Damage"] = "Dano Absorvido"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "Habilitar isso se você quiser que o dano absorvido seja incluído no dano causado."
+L["Damage Done By School"] = "Dano Causado por Tipo"
+-- killing blows module
+L["Only PvP Kills"] = "Apenas Mortes em PvP"
+L["When enabled, only kills against enemy players count."] = "Quando habilitado, apenas as mortes contra jogadores inimigos são contadas."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "Anunciar golpes fatais após o fim do combate. Funciona apenas em lutas contra chefes."
+-- damage taken module
+L["Damage Taken"] = "Dano Recebido"
+L["Damage Taken By Spell"] = "Dano Recebido por Feitiço"
+L["%s's targets"] = "Alvos de %s"
+L["DTPS"] = "DTPS"
+L["sDTPS"] = "DTPS (subvisões)"
+-- enemy damage done module
+L["Enemies"] = "Inimigos"
+L["Enemy Damage Done"] = "Dano Causado por Inimigo"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "Dano Recebido de Inimigo"
+L["%s below %s%%"] = "%s abaixo de %s%%"
+L["%s - %s%% to %s%%"] = "%s - de %s%% a %s%%"
+L["Phase %s"] = "Fase %s"
+L["%s - Phase %s"] = "%s - Fase %s"
+L["%s - Phase 1"] = "%s - Fase 1"
+L["%s - Phase 2"] = "%s - Fase 2"
+L["%s - Phase 3"] = "%s - Fase 3"
+L["%s (Main Boss)"] = "%s (Chefe Principal)"
+L["\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r iniciada."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r iniciada."
+L["\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r encerrada."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r encerrada."
+L["\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r retomada."] = "\124cffffbb00%s\124r - \124cff00ff00Fase %s\124r retomada."
+-- enemy healing done module
+L["Enemy Healing Done"] = "Cura Causada por Inimigo"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "Evitação e Mitigação"
+L["More Details"] = "Mais Detalhes"
+L["%s's details"] = "Detalhes de %s"
+-- friendly fire module
+L["Friendly Fire"] = "Fogo Amigo"
+-- useful damage targets
+L["Important targets"] = "Alvos Importantes"
+L["Oozes"] = "Gosmas"
+L["Princes overkilling"] = "Príncipes causando excesso de dano"
+L["Adds"] = "Adds"
+L["Halion and Inferno"] = "Halion e Inferno"
+L["Valkyrs overkilling"] = "Valkyrs causando excesso de dano"
+-- Deaths Module --
+L["%s's deaths"] = "Mortes de %s"
+L["Death log"] = "Registro de Mortes"
+L["%s's death log"] = "Registro de Mortes de %s"
+L["Player's deaths"] = "Mortes do Jogador"
+L["%s dies"] = "%s morre"
+L["buff"] = "bônus"
+L["debuff"] = "penalidade"
+L["Spell details"] = "Detalhes do Feitiço"
+L["Spell"] = "Feitiço"
+L["Amount"] = "Quantidade"
+L["Source"] = "Fonte"
+L["Change"] = "Alteração"
+L["Time"] = "Tempo"
+L["Survivability"] = "Sobrevivência"
+L["Events Amount"] = "Quantidade de Eventos"
+L["Set the amount of events the death log should record."] = "Defina a quantidade de eventos que o registro de mortes deve registrar."
+L["Minimum Healing"] = "Cura Mínima"
+L["Ignore heal events that are below this threshold."] = "Ignorar eventos de cura abaixo desse limite."
+L["Announce Deaths"] = "Anunciar Mortes"
+L["Announces information about the last hit the player took before they died."] = "Anuncia informações sobre o último golpe que o jogador recebeu antes de morrer."
+L["Alternative Display"] = "Exibição Alternativa"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "Se um jogador morrer várias vezes, cada morte será exibida como uma barra separada."
+-- activity module
+L["Activity"] = "Atividade"
+L["Activity per Target"] = "Atividade por Alvo"
+L["%s's activity"] = "Atividade de %s"
+-- dispels module lines --
+L["Dispel Spells"] = "Feitiços de Dissipação"
+L["%s's dispelled spells"] = "Feitiços dissipados de %s"
+-- interrupts module lines --
+L["Interrupt Spells"] = "Feitiços Interrompidos"
+L["%s's interrupted spells"] = "Feitiços interrompidos de %s"
+L["%s interrupted!"] = "%s interrompido!"
+-- Power gained module --
+L["Resources"] = "Recursos"
+L["Mana Restored"] = "Mana Restaurada"
+L["Rage Generated"] = "Raiva Gerada"
+L["Energy Generated"] = "Energia Gerada"
+L["Runic Power Generated"] = "Poder Rúnico Gerado"
+-- Parry module lines --
+L["Parry-Haste"] = "Aparo-Rapidez"
+L["%s parried %s (%s)"] = "%s aparou %s (%s)"
+-- Potions module lines --
+L["Potions"] = "Poções"
+L["%s's potions"] = "Poções de %s"
+L["Pre-potion"] = "Pré-poção"
+L["pre-potion: %s"] = "pré-poção: %s"
+L["Prints pre-potion after the end of the combat."] = "Imprime pré-poção após o fim do combate."
+-- healthstone --
+L["Healthstones"] = "Pedras de Vida"
+-- resurrect module lines --
+L["Resurrects"] = "Ressurreições"
+-- nickname module lines --
+L["Nickname"] = "Apelido"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "Os apelidos são enviados para membros do grupo e o Skada pode usá-los em vez do nome do seu personagem."
+L["Set a nickname for you."] = "Defina um apelido para você."
+L["Nickname isn't a valid string."] = "O apelido não é uma string válida."
+L["Your nickname is too long, max of 12 characters is allowed."] = "Seu apelido é muito longo, o máximo permitido é de 12 caracteres."
+L["Only letters and two spaces are allowed."] = "Apenas letras e dois espaços são permitidos."
+L["Your nickname contains a forbidden word."] = "Seu apelido contém uma palavra proibida."
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "Você não pode usar a mesma letra três vezes consecutivamente, dois espaços consecutivos ou mais de dois espaços."
+L["Ignore Nicknames"] = "Ignorar Apelidos"
+L["When enabled, nicknames set by Skada users are ignored."] = "Quando habilitado, os apelidos definidos pelos usuários do Skada são ignorados."
+L["Name display"] = "Exibição de Nome"
+L["Choose how names are shown on your bars."] = "Escolha como os nomes são exibidos em suas barras."
+L["Clear Cache"] = "Limpar Cache"
+L["Are you sure you want clear cached nicknames?"] = "Tem certeza de que deseja limpar os apelidos em cache?"
+-- overkill module lines --
+L["Overkill"] = "Sobrepujar"
+-- tweaks module lines --
+L["Improvement"] = "Melhoria"
+L["Tweaks"] = "Ajustes"
+L["First hit"] = "Primeiro golpe"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00Primeiro Golpe\124r: %s de %s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00Primeiro Golpe\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00Primeiro Alvo do Chefe\124r: %s"
+L["opt_tweaks_firsthit_desc"] = "Exibe uma mensagem do primeiro golpe antes do combate.\nFunciona apenas em encontros com chefes."
+L["Filter DPS meters Spam"] = "Filtrar Spam dos Medidores de DPS"
+L["opt_tweaks_spamage_desc"] = "Suprime mensagens de bate-papo dos medidores de dano e fornece estatísticas de dano em uma janela emergente."
+L["Reported by: %s"] = "Relatado por: %s"
+L["Smart Stop"] = "Parada Inteligente"
+L["opt_tweaks_smarthalt_desc"] = "Interrompe automaticamente o segmento atual após o chefe ter morrido.\nÚtil para evitar a coleta de dados em caso de bug de combate."
+L["Duration"] = "Duração"
+L["opt_tweaks_smartwait_desc"] = "Por quanto tempo o Skada deve esperar antes de parar o segmento."
+L["Modes Icons"] = "Ícones de Modos"
+L["Show modes icons on bars and menus."] = "Mostra ícones de modos em barras e menus."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "Habilite isso se você quiser ignorar \124cffffbb00%s\124r."
+L["Custom Colors"] = "Cores Personalizadas"
+L["Arena Teams"] = "Equipes de Arena"
+L["Are you sure you want to reset all colors?"] = "Tem certeza de que deseja redefinir todas as cores?"
+L["Announce %s"] = "Anunciar %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "Anuncia quanto tempo levou para aplicar %d pilhas de %s e anuncia quando cai."
+L["%s dropped from %s!"] = "%s caiu de %s!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%s pilhas de %s aplicadas em %s em %s seg!"
+L["My Spells"] = "Meus Feitiços"
+-- total data options
+L["Total Segment"] = "Segmento Total"
+L["All Segments"] = "Todos os Segmentos"
+L["Raid Bosses"] = "Chefes de Raide"
+L["Raid Trash"] = "Lixo de Raide"
+L["Dungeon Bosses"] = "Chefes de Masmorra"
+L["Dungeon Trash"] = "Lixo de Masmorra"
+L["opt_tweaks_total_all_desc"] = "Todos os segmentos são adicionados aos dados do segmento total."
+L["opt_tweaks_total_fmt_desc"] = "Segmentos com %s são adicionados aos dados do segmento total."
+L["Detailed total segment"] = "Segmento Total Detalhado"
+L["opt_tweaks_total_full_desc"] = "Quando habilitado, o Skada registrará tudo no segmento total, em vez de números totais (registra detalhes do feitiço, seus alvos e suas fontes)."
+-- arena
+L["Player vs. Player"] = "Jogador vs. Jogador"
+L["mod_pvp_desc"] = "Adiciona detecção de especialização para arenas e campos de batalha e mostra oponentes de arena na mesma janela."
+L["Gold Team"] = "Equipe Ouro"
+L["Green Team"] = "Equipe Verde"
+L["Color for %s."] = "Cor para %s."
+-- notifications
+L["Notifications"] = "Notificações"
+L["opt_toast_desc"] = "Usa notificações visuais em vez de mensagens de bate-papo sempre que aplicável."
+L["Test Notifications"] = "Testar Notificações"
+-- comparison module
+L["Comparison"] = "Comparação"
+L["%s vs %s: %s"] = "%s vs %s: %s"
+L["%s vs %s: Spells"] = "%s vs %s: Feitiços"
+L["%s vs %s: Targets"] = "%s vs %s: Alvos"
+-- spellcast module
+L["Casts"] = "Lançamentos"
+L["%s's spells"] = "Feitiços de %s"
+L["%s's spells on %s"] = "Feitiços de %s em %s"
+L["Spells on %s"] = "Feitiços em %s"
+-- about
+L["Author"] = "Autor"
+L["Credits"] = "Créditos"
+L["Date"] = "Data"
+L["License"] = "Licença"
+L["Version"] = "Versão"
+L["Website"] = "Website"
+-- custom class names using globals
+-- some bosses entries
+L["World Boss"] = "Chefe Mundial"
+L["Auriaya"] = "Auriaya"
+L["Blood Prince Council"] = "Conselho dos Príncipes Sangrentos"
+L["Faction Champions"] = "Campeões da Facção"
+L["Hogger"] = "Hogger"
+L["Icecrown Gunship Battle"] = "Batalha do Navio de Guerra de Coroa de Gelo"
+L["Kologarn"] = "Kologarn"
+L["Mimiron"] = "Mimiron"
+L["Thaddius"] = "Thaddius"
+L["The Four Horsemen"] = "Os Quatro Cavaleiros"
+L["The Iron Council"] = "O Conselho de Ferro"
+L["The Northrend Beasts"] = "As Feras da Nortúndria"
+L["Thorim"] = "Thorim"
+L["Twin Val'kyr"] = "Val'kyr Gêmeas"
+L["Valithria Dreamwalker"] = "Valithria Andassonho"
+L["Yogg-Saron"] = "Yogg-Saron"
diff --git a/Skada/Locales/ruRU.lua b/Skada/Locales/ruRU.lua
new file mode 100644
index 0000000..66578b0
--- /dev/null
+++ b/Skada/Locales/ruRU.lua
@@ -0,0 +1,758 @@
+--[[ Translators: NGL#7282 / Barsoom#0484 ]] --
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "ruRU")
+if not L then return end
+
+L["A damage meter."] = "Измеритель урона."
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "Использование памяти слишком велико. Вы можете сбросить данные Skada и включить один из вариантов автоматического сброса."
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada устарел. Вы можете скачать последнюю версию с \124cffffbb00%s\124r"
+L["Skada: Modes"] = "Skada: Режимы"
+L["Skada: Fights"] = "Skada: Бои"
+L["Data Collection"] = "Сбор данных"
+L["ENABLED"] = "ВКЛЮЧЕН"
+L["DISABLED"] = "ВЫКЛЮЧЕН"
+L["Enable All"] = "Включить все"
+L["Disable All"] = "Отключить все"
+L["Stopping for wipe."] = "Остановка из-за протирать."
+L["Usage:"] = "Использовать:"
+L["Commands:"] = "Команды:"
+L["Import"] = "Импорта"
+L["Export"] = "Экспорта"
+L["Import/Export"] = "Импорта/Экспорта"
+-- profiles
+L["Profiles"] = "Профили"
+L["Profile Import/Export"] = "Профиль Импорта/Экспорта"
+L["Import Profile"] = "Импорт профиля"
+L["Export Profile"] = "Экспорт профиля"
+L["Paste here a profile in text format."] = "Вставить сюда профиль в текстовом формате."
+L["Press CTRL-V to paste the text from your clipboard."] = "Нажмите CTRL-V для вставки текста из буфера обмена."
+L["This is your current profile in text format."] = "Это ваш текущий профиль с текстовом формате."
+L["Press CTRL-C to copy the text to your clipboard."] = "Нажмите CTRL-С на вашей клавиатуре для копирования текст."
+L["Network Sharing"] = "Общий доступ к сети"
+L["Player Name"] = "Имя персонажа"
+L["Send Profile"] = "Отправить профиль"
+L["Accept profiles from other players."] = "Принимать профили от других игроков."
+L["opt_profile_received"] = "%s послал вам профиль настроек. Хотите активировать полученный профиль?"
+L["Progress"] = "Прогресс"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "Размер данных: \124cffffffff%.1f\124rКБ"
+L["Transmision Progress: %02.f%%"] = "Прогресс трансфера: %d%%"
+L["Transmission Completed"] = "Передача завершена"
+-- common lines
+L["Options"] = "Опции"
+L["Options for %s."] = "Опции для %s."
+L["General"] = "Общие"
+L["General options for %s."] = "Общие параметры для %s."
+L["Text"] = "Текст"
+L["Text options for %s."] = "Параметры текста для %s."
+L["Format"] = "Формат"
+L["Format options for %s."] = "Варианты формата для %s."
+L["Appearance"] = "Внешность"
+L["Appearance options for %s."] = "Варианты внешнего вида %s."
+L["Advanced"] = "Дополнительные"
+L["Advanced options for %s."] = "Расширенные параметры для %s."
+L["Position"] = "Позиция"
+L["Position settings for %s."] = "Параметры позиции %s."
+L["Width"] = "Ширина"
+L["The width of %s."] = "Ширина %s."
+L["Height"] = "Высота"
+L["The height of %s."] = "Высота %s."
+L["Active Time"] = "Время активности"
+L["Segment Time"] = "Время сегмента"
+L["Click for \124cff00ff00%s\124r"] = "ЛКМ - \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift-ЛКМ - \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Control-ЛКМ - \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt-ЛКМ - \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "фильтр класса"
+L["Average"] = "В среднем"
+L["Count"] = "Количество"
+L["Refresh"] = "Обновление"
+L["Percent"] = "Процент"
+L["sPercent"] = "Процент (подрежимы)"
+L["General Options"] = "Основные настройки"
+L["HoT"] = "ИЗВ"
+L["DoT"] = "УЗВ"
+L["Hits"] = "Попадания"
+L["Normal Hits"] = "Обычные попадания"
+L["Critical"] = "Критический"
+L["Critical Hits"] = "Критические попадания"
+L["Crushing"] = "Сокр. удар"
+L["Glancing"] = "Вскользь"
+L["ABSORB"] = "Поглощено"
+L["BLOCK"] = "Заблокировано"
+L["DEFLECT"] = "Отклонение"
+L["DODGE"] = "Уклонение"
+L["EVADE"] = "Мимо"
+L["IMMUNE"] = "Невосприимчивость"
+L["MISS"] = "Промах"
+L["PARRY"] = "Парирование"
+L["REFLECT"] = "Отражение"
+L["RESIST"] = "Сопротивление"
+L["Only for bosses."] = "Только для боссов."
+L["Enable this only against bosses."] = "Включите это только против боссов."
+-- segment info
+L["Start"] = "Начало"
+L["End"] = "Конец"
+-- windows section:
+L["Window"] = "Окно"
+L["Windows"] = "Окна"
+L["Create Window"] = "Создать окно"
+L["Window Name"] = "Имя окна"
+L["Enter the name for the new window."] = "Введите имя нового окна."
+L["Delete Window"] = "Удалить окно"
+L["Choose the window to be deleted."] = "Выберите окно для удаления."
+L["Are you sure you want to delete this window?"] = "Вы уверены, что хотите удалить это окно?"
+L["Delete All Windows"] = "Удалить все окна"
+L["Are you sure you want to delete all windows?"] = "Вы уверены, что хотите удалить все окна?"
+L["Rename Window"] = "Переименовать окно"
+L["Enter the name for the window."] = "Введите новое имя для окна."
+L["Test Mode"] = "Тестовый режим"
+L["Creates fake data to help you configure your windows."] = "Создает поддельные данные, которые помогут вам настроить окна."
+L["Child Window"] = "Дочернее окно"
+L["A child window will replicate the parent window actions."] = "Дочернее окно скопирует действия родительского окна."
+-- L["Child Window Mode"] = ""
+L["Lock Window"] = "Зафиксировать окно"
+L["Locks the bar window in place."] = "Блокирует окно на месте."
+L["Hide Window"] = "Скрыть окно"
+L["Hides the window."] = "Скрывает окно."
+L["Sticky Window"] = "Клейкие окна"
+L["Allows the window to stick to other Skada windows."] = "Позволяет привязывать окно к другим окнам Skada."
+L["Snap to best fit"] = "Притягивание размера"
+L["Snaps the window size to best fit when resizing."] = "Размер окна автоматически подстраивается для лучшего отображения информации."
+L["Disable Resize Buttons"] = "Отключить кнопки изменения размера"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "Кнопки изменения размера и заблокировать/разблокировать не отображаются, когда вы наводите курсор на окно."
+L["Disable stretch button"] = "Отключить кнопку растяжения"
+L["Stretch button won't show up when you hover over the window."] = "Кнопка растягивания не будет отображаться при наведении курсора на окно."
+L["Reverse window stretch"] = "Растянуть окно вниз"
+L["opt_botstretch_desc"] = "Помещает кнопку растягивания в нижнюю часть окна и заставляет его растягиваться вниз."
+L["Display System"] = "Система отображения"
+L["Choose the system to be used for displaying data in this window."] = "Выберите систему, используемую для отображения данных в окне."
+L["Copy Settings"] = "Копировать настройки"
+L["Choose the window from which you want to copy the settings."] = "Выберите окно, из которого вы хотите скопировать настройки."
+-- bars
+L["Bars"] = "Полосы"
+L["Left Text"] = "Левый текст"
+L["Right Text"] = "Правый текст"
+L["Font"] = "Шрифт"
+L["The font used by %s"] = "Шрифт для %s"
+L["Font Size"] = "Размер шрифта"
+L["The font size of %s"] = "Размер шрифта для %s"
+L["Font Outline"] = "Контур шрифта"
+L["Sets the font outline."] = "Устанавливает контур шрифта."
+L["Outline"] = "Окантовка"
+L["Thick"] = "Толстая"
+L["Thick outline"] = "Толстая окантовка"
+L["Monochrome"] = "Черно-белое"
+L["Outlined monochrome"] = "Черно-белое с окантовкой"
+L["Bar Texture"] = "Текстура полос"
+L["The texture used by all bars."] = "Текстура, используемая всеми полосами."
+L["Spacing"] = "Интервал"
+L["Distance between %s."] = "Расстояние между %s."
+L["Displacement"] = "Водоизмещение"
+L["The distance between the edge of the window and the first bar."] = "Расстояние между краем окна и первой полосой."
+L["Bar Orientation"] = "Ориентация полос"
+L["The direction the bars are drawn in."] = "Направление заполнения полос."
+L["Left to right"] = "Слева направо"
+L["Right to left"] = "Справа налево"
+L["Reverse bar growth"] = "Обратный рост полос"
+L["Bars will grow up instead of down."] = "Полосы будут расти вверх, а не вниз."
+L["Disable bar highlight"] = "Отключение подсветки полосы"
+L["Hovering a bar won't make it brighter."] = "При наведении курсора на полосу, не сделает его ярче."
+L["Bar Color"] = "Цвет полос"
+L["Choose the default color of the bars."] = "Выберите цвет полос по умолчанию."
+L["Background Color"] = "Цвет фона"
+L["The color of the background."] = "Цвет фона."
+L["Custom Color"] = "Пользовательский цвет"
+L["Use a custom color for my bar."] = "Использовать другой цвет для моей полоски."
+L["My Color"] = "Мой цвет"
+L["Spell school colors"] = "Цвет школы заклинания"
+L["Use spell school colors where applicable."] = "Использовать цвет школы заклинания, если возможно."
+L["When possible, bars will be colored according to player class."] = "Когда это возможно, полосы будут окрашены в соответствии с классом игрока."
+L["When possible, bar text will be colored according to player class."] = "Когда это возможно, текст полос будет окрашен в соответствии с классом игрока."
+L["Class Icons"] = "Иконки класса"
+L["Use class icons where applicable."] = "Использовать иконки класса, когда это приемлемо."
+L["Spec Icons"] = "Иконки талантов"
+L["Use specialization icons where applicable."] = "Использовать иконки талантов, когда это приемлемо."
+L["Role Icons"] = "Иконки ролей"
+L["Use role icons where applicable."] = "Использовать иконки ролей (если возможно)."
+L["Show Spark Effect"] = "Показать эффект искры"
+L["Click Through"] = "Клик насквозь"
+L["Disables mouse clicks on bars."] = "Отключить нажатия мышкой по полоскам."
+L["Smooth Bars"] = "Плавные полосы"
+L["Animate bar changes smoothly rather than immediately."] = "Анимация полосы меняется плавно, а не сразу."
+-- title bar
+L["Title Bar"] = "Полоса заголовка"
+L["Enables the title bar."] = "Включить полосу заголовка."
+L["Include set"] = "Текущий сегмент"
+L["Include set name in title bar"] = "Отображать в полосе заголовка текущий сегмент"
+L["Encounter Timer"] = "Таймер сражения"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "Когда включено секундомер отображается в левой части текста."
+L["Mode Icon"] = "Значок режима"
+L["Shows mode's icon in the title bar."] = "Показывает значок режима в строке заголовка."
+L["The texture used as the background of the title."] = "Текстура, используемая для фона заголовка."
+L["Border texture"] = "Текстура рамки"
+L["The texture used for the borders."] = "Текстура, используемая для рамок."
+L["Border Color"] = "Цвет рамки"
+L["The color used for the border."] = "Цвет, используемый для рамок."
+L["Buttons"] = "Кнопки"
+L["Auto Hide Buttons"] = "Авто-скрытие кнопок"
+L["Show window buttons only if the cursor is over the title bar."] = "Отображать кнопки окна, только если курсор находится над строкой заголовка."
+L["Buttons Style"] = "Пуговицы Стиль"
+-- general window
+L["Background Texture"] = "Текстура фона"
+L["The texture used as the background."] = "Текстура, используемая для фона."
+L["Tile"] = "Заполнение"
+L["Tile the background texture."] = "Заполнение фоновой текстуры"
+L["Tile Size"] = "Размер заполнения"
+L["The size of the texture pattern."] = "Размер шаблона текстуры."
+L["Border"] = "Рамка"
+L["Border Thickness"] = "Толщина рамки"
+L["The thickness of the borders."] = "Толщина рамок."
+L["Border Insets"] = "Расстояние до рамки"
+L["The distance between the window and its border."] = "Расстояние между окном и его границей."
+L["Scale"] = "Масштаб"
+L["Sets the scale of the window."] = "Устанавливает масштаб окна."
+L["Strata"] = "Слой"
+L["This determines what other frames will be in front of the frame."] = "Это определяет, что другие окна будут перед этим окном."
+L["Clamped To Screen"] = "В пределах экрана"
+L["Toggle whether to permit movement out of screen."] = "Не позволять перемещать окно за пределы экрана."
+L["X Offset"] = "Смещение по X"
+L["Y Offset"] = "Смещение по Y"
+-- switching
+L["Mode Switching"] = "Смена режима"
+L["Combat Mode"] = "Режим битвы"
+L["opt_combatmode_desc"] = "Автоматически переключаться на этот режим и сегмент \124cffffbb00Текущий\124r при входе в бой."
+L["Wipe Mode"] = "Режим вайпа"
+L["opt_wipemode_desc"] = "Автоматически переключиться на этот режим и сегмент \124cffffbb00Текущий\124r после вайпа."
+L["Return after combat"] = "Возврат после боя"
+L["Return to the previous set and mode after combat ends."] = "Возврат к предыдущему режиму и сегменту после окончания боя."
+L["Auto switch to current"] = "Авто переход к текущему"
+L["opt_autocurrent_desc"] = "Всякий раз, когда начинается бой, это окно автоматически переключается на \124cffffbb00Текущий\124r сегмент."
+L["Auto Hide"] = "Авто-скрытие"
+L["While in combat"] = "В бою"
+L["While out of combat"] = "Не в бою"
+L["While not in a group"] = "Не в группе"
+L["While inside an instance"] = "Внутри подземелья"
+L["While not inside an instance"] = "Не внутри подземелья"
+L["In Battlegrounds"] = "На полях битв"
+L["Inline Bar Display"] = "Полосы в одну линию"
+L["mod_inline_desc"] = "Отображение в одну линию является горизонтальным стилем окна."
+L["Font Color"] = "Цвет шрифта"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "Цвет шрифта.\nЧтобы начать, нажмите \"Цвета класса\"."
+L["opt_barwidth_desc"] = "Ширина штанг. Это применимо, только если используется опция \"Фиксированная ширина полос\"."
+L["Fixed bar width"] = "Фиксированная ширина полос"
+L["opt_fixedbarwidth_desc"] = "Если включено, то ширина полосы зафиксирована. В противном случае, ширина полосы зависит от ширины текста."
+L["Use class colors for %s."] = "Используйте цвета класса для %s."
+L["opt_isusingclasscolors_desc"] = "С: %s - 5.71М (21.7К)\nБез: %s - 5.71М (21.7К)"
+L["Put values on new line."] = "Поместите значения в новую строку."
+L["opt_isonnewline_desc"] = "Новая строка:\n%1$s\n5.71М (21.7К)\n\nРазделитель:\n%1$s - 5.71М (21.7К)"
+L["Use ElvUI skin if avaliable."] = "Если возможно, используйте скин ElvUI."
+L["opt_isusingelvuiskin_desc"] = "Установите этот флажок, чтобы вместо этого использовать скин ElvUI.\nПо умолчанию: установлен"
+L["Use solid background."] = "Используйте сплошной фон."
+L["Un-check this for an opaque background."] = "Снимите флажок для непрозрачного фона."
+L["Data Text"] = "Текстовые данные"
+L["mod_broker_desc"] = "Текст данных актов действует в качестве LDB канала данных. Он может быть интегрирован в любой LDB дисплей, такие как, Titan Panel или Chocolate Bar. Он также имеет дополнительною внутреннюю рамку."
+L["Use frame"] = "Используйте окно"
+L["opt_useframe_desc"] = "Показывает отдельное окно. Не требуется, если вы используете поставщика дисплеев LDB, например Titan Panel или ChocolateBar."
+L["Text Color"] = "Цвет текста"
+L["The text color of %s."] = "Цвет текста %s."
+L["Choose the default color."] = "Выберите цвет по умолчанию."
+L["Hint: Left-Click to set active mode."] = "ЛКМ - Выбор активного режима."
+L["Right-Click to set active set."] = "ПКМ - Установить активный сегмент."
+L["Shift+Left-Click to open menu."] = "Shift+ЛКМ - Открыть меню"
+-- data resets
+L["Data Resets"] = "Сброс данных"
+L["Reset on entering instance"] = "Сбрасывать при входе в подземелье"
+L["Controls if data is reset when you enter an instance."] = "Управление сбросом данных при входе в подземелье."
+L["Reset on joining a group"] = "Сбрасывать при присоединении к группе"
+L["Controls if data is reset when you join a group."] = "Управление сбросом данных при присоединении к группе."
+L["Reset on leaving a group"] = "Сбрасывать при покидании группы"
+L["Controls if data is reset when you leave a group."] = "Управление сбросом данных после выхода из группы."
+L["Ask"] = "Уточнить"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "Вы хотите сбросить Skada?\nУдерживайте SHIFT, чтобы сбросить все."
+L["All data has been reset."] = "Все данные были сброшены."
+L["There is no data to reset."] = "Нет данных для сброса."
+L["Skip reset dialog"] = "Пропустить диалог сброса"
+L["opt_skippopup_desc"] = "Включите это, если хотите, чтобы Skada сбрасывалась без диалогового окна подтверждения."
+L["Are you sure you want to reinstall Skada?"] = "Вы уверены, что хотите переустановить Skada?"
+-- general options
+L["Show minimap button"] = "Показывать кнопку у миникарты"
+L["Toggles showing the minimap button."] = "Отобразить/скрыть кнопку у миникарты."
+L["Transliterate"] = "Транслитерация"
+L["Converts Cyrillic letters into Latin letters."] = "Представление кириллических символов латинскими."
+L["Remove realm name"] = "Убрать название игрового мира"
+L["opt_realmless_desc"] = "Когда включено, название игрового мира персонажа не отображается."
+L["Merge pets"] = "Объединять питомцев"
+L["Merges pets with their owners. Changing this only affects new data."] = "Объединяет урон питомцев с их хозяевами. Изменение опции повлияет только на новые данные."
+L["Show totals"] = "Показывать итог"
+L["Shows a extra row with a summary in certain modes."] = "Показывает дополнительную строку с суммарной информацией в некоторых режимах."
+L["Only keep boss fighs"] = "Записывать только бои с боссами"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "При включении этой опции будут записываться только бои с боссами."
+L["Always save boss fights"] = "Всегда сохранять бои с боссами"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "При включении этой опции бои с боссами будут сохраняться, и не будут затронуты сбросом Skada."
+L["Hide when solo"] = "Скрывать когда один"
+L["Hides Skada's window when not in a party or raid."] = "Скрывает окно Skada, если вы не состоите в группе или рейде."
+L["Hide in PvP"] = "Скрывать в PvP"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "Скрывает окно Skada на аренах/полях сражений."
+L["Hide in combat"] = "Скрывать в бою"
+L["Hides Skada's window when in combat."] = "Скрывает окно Skada в бою."
+L["Show in combat"] = "Показать в бою"
+L["Shows Skada's window when in combat."] = "Показывает Skada окна, когда в бою."
+L["Disable while hidden"] = "Отключить когда скрыт"
+L["Skada will not collect any data when automatically hidden."] = "Skada не будет собирать данные, когда окно автоматически скрывается."
+L["Sort modes by usage"] = "Упорядочить режимы по использованию"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "Сортировка списка режимов по частоте использования, вместо алфавитного."
+L["Show rank numbers"] = "Показать номера полос"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "Показывает номера полос в режимах, где это применимо."
+L["Aggressive combat detection"] = "Агрессивное определение режима боя"
+L["opt_tentativecombatstart_desc"] = [[Обычно Skada использует простую схему определения начала боя, которая работает лучше всего в рейдах.
+С этой опцией Skada будет действовать как другие аддоны для подсчета урона.
+Полезно для подземелий, бессмысленно на рейдовых боссах.]]
+L["Autostop"] = "Останавливать в начале вайпа"
+L["opt_autostop_desc"] = "Автоматически останавливает текущий сегмент после смерти половины участников рейда."
+L["Always show self"] = "Всегда показывать себя"
+L["opt_showself_desc"] = "Отображать полосу игрока, даже если места недостаточно."
+L["Number format"] = "Формат чисел"
+L["Controls the way large numbers are displayed."] = "Выбор вида отображения больших чисел."
+L["Condensed"] = "Кратко"
+L["Detailed"] = "Детально"
+L["Combined"] = "Совместный"
+L["Comma"] = "Запятая"
+L["Numeral system"] = "Система чисел"
+L["Select which numeral system to use."] = "Выбрать, какую систему счисления использовать."
+L["Auto"] = "Автоматический"
+L["Western"] = "Западная"
+L["East Asia"] = "Восточная Азия"
+L["Brackets"] = "Скобка"
+L["Choose which type of brackets to use."] = "Выберите, какой тип скобок использовать."
+L["Separator"] = "Разделитель"
+L["Choose which character is used to separator values between brackets."] = "Выберите, какой символ будет использоваться для разделения значений между скобками."
+L["Number of decimals"] = "Десятичные дроби"
+L["Controls the way percentages are displayed."] = "Управляет способом отображения процентов."
+L["Data Feed"] = "Подача данных" --?
+L["opt_feed_desc"] = "Выберите, какие данные выводить в DataBroker. Для этого требуется, аддон который поддерживает отображение LDB, к примеру Titan Panel."
+L["Time Measure"] = "Мера времени"
+L["Activity Time"] = "По активности"
+L["Effective Time"] = "По эффективности"
+L["opt_timemesure_desc"] = [=[|cffffff00Активный|r: таймер каждого участника рейда ставится на удержание, если их активность прекращается, и снова подсчитывается при возобновлении, общий способ измерения УВС и ИВС.
+
+|cffffff00Эффективный|r: используется в рейтинге, этот метод использует прошедшее боевое время для измерения УВС и ИВС - всех участников рейда.]=]
+L["Number set duplicates"] = "Количество дубликатов"
+L["Append a count to set names with duplicate mob names."] = "Добавлять счетчик для противников с одинаковыми именами."
+L["Set Format"] = "Установить формат"
+L["Links in reports"] = "Ссылки в отчетах"
+L["When possible, use links in the report messages."] = "По возможности используйте ссылки в сообщениях с отчетами."
+L["Controls the way set names are displayed."] = "Настройка форматирования заголовков для боя."
+L["Segments to keep"] = "Сегменты для хранения"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "Число сохраняемых сегментов боев. В это число не входят постоянные сегменты."
+L["Persistent segments"] = "Постоянные сегменты"
+L["The number of persistent fight segments to keep."] = "Количество сохраняемых постоянных сегментов."
+L["Memory Check"] = "Проверка памяти"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "Проверяет использование памяти и предупреждает, если оно больше или равно %d МБ."
+L["Disable Comms"] = "Отключить связь"
+L["Minimum segment length"] = "Минимальная длина сегмента"
+L["The minimum length required in seconds for a segment to be saved."] = "Минимальная длина в секундах, необходимая для сохранения сегмента."
+L["Update frequency"] = "Частота обновления"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "Частота обновления окон. Меньшее значение способствует более быстрому обновлению. Увеличивает нагрузку процессора."
+-- columns
+L["Columns"] = "Колонки"
+-- tooltips
+L["Tooltips"] = "Подсказки"
+L["Show Tooltips"] = "Показывать подсказки"
+L["Shows tooltips with extra information in some modes."] = "Показывает подсказки с дополнительной информацией в некоторых режимах."
+L["Informative Tooltips"] = "Информативная подсказка"
+L["Shows subview summaries in the tooltips."] = "Показывает детальную информацию в подсказках."
+L["Subview Rows"] = "Количество строк в подсказках"
+L["The number of rows from each subview to show when using informative tooltips."] = "Число строк с детальной информацией, когда используются информативные подсказки."
+L["Tooltip Position"] = "Позиция подсказки"
+L["Position of the tooltips."] = "Позиция подсказок."
+L["Top Right"] = "Сверху справа"
+L["Top Left"] = "Сверху слева"
+L["Bottom Right"] = "Снизу справа"
+L["Bottom Left"] = "Снизу слева"
+L["Smart"] = "Умный"
+L["Follow Cursor"] = "Курсор мыши"
+L["Top"] = "Сверху"
+L["Bottom"] = "Снизу"
+L["Right"] = "Справа"
+L["Left"] = "Слева"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00Требуется\124r: %s"
+L["Modules"] = "Модулей"
+L["Disabled Modules"] = "Отключение модулей"
+L["Modules Options"] = "Настроить модули"
+L["Tick the modules you want to disable."] = "Выберите модули, которые хотите отключить."
+L["This change requires a UI reload. Are you sure?"] = "Это изменение требует перезагрузки пользовательского интерфейса. Вы уверены?"
+-- themes options
+L["Theme"] = "Тема"
+L["Themes"] = "Темы"
+L["Manage Themes"] = "Управление темами"
+L["All Windows"] = "Все окна"
+L["Apply Theme"] = "Применить тему"
+L["Theme applied!"] = "Тема применена!"
+L["Name of your new theme."] = "Название вашей новой темы."
+L["Save Theme"] = "Сохранить тему"
+L["Delete Theme"] = "Удалить тему"
+L["Are you sure you want to delete this theme?"] = "Вы уверены, что хотите удалить этот тема?"
+L["Paste here a theme in text format."] = "Вставить сюда тема в текстовом формате."
+L["This is your current theme in text format."] = "Это ваш текущий тема с текстовом формате."
+-- scroll options
+L["Scroll"] = "Прокрутка"
+L["Wheel Speed"] = "Скорость прокрутки"
+L["opt_wheelspeed_desc"] = "Изменяет скорость прокрутки при повороте колеса мыши над окном."
+L["Scroll Icon"] = "Значок прокрутки"
+L["Scroll mouse button"] = "Кнопка прокрутки мыши"
+-- minimap button
+L["Skada Summary"] = "Skada: Сводка"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00ЛКМ\124r - Окно переключения."
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+ЛКМ\124r - Отобразить/Скрыть окна."
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+ЛКМ\124r - Сброс данных."
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00ПКМ\124r - Открыть меню."
+-- skada menu
+L["Skada Menu"] = "Меню Skada"
+L["Select Segment"] = "Выбрать сегмент"
+L["Delete Segment"] = "Удалить сегмент"
+L["Keep Segment"] = "Хранить сегмент"
+L["Toggle Windows"] = "Окно переключения"
+L["Show/Hide Windows"] = "Открыть/закрыть Окна"
+L["New Segment"] = "Новый сегмент"
+L["Starts a new segment."] = "Начать новый сегмент."
+L["New Phase"] = "Новую фазу"
+L["Starts a new phase."] = "Начать новую фазу."
+L["Select All"] = "Выбрать все"
+L["Deselect All"] = "Снять все"
+-- window buttons
+L["Configure"] = "Конфигурация"
+L["Open Config"] = "Открыть конфигурацию"
+L["btn_config_desc"] = "Открывает окно конфигурации."
+L["btn_reset_desc"] = [[Сбрасывает все данные боя, кроме отмеченных как сохраненные.
+|cff00ff00Shift+ЛКМ|r - Удалить сегмент.]]
+L["Segment"] = "Сегмент"
+L["btn_segment_desc"] = [[Перейти к определенному сегменту.
+|cff00ff00Shift+ЛКМ|r - |cffffbb00Следующий|r сегмент.
+|cff00ff00Shift+ПКМ|r - |cffffbb00Предыдущий|r сегмент.
+|cff00ff00Средний щелчок|r - |cffffbb00Текущий|r сегмент.]]
+L["Mode"] = "Режим"
+L["Jump to a specific mode."] = "Перейти к определенному режиму."
+L["Report"] = "Отчет"
+L["btn_report_desc"] = [[Открывает диалоговое окно, в котором можно различными способами сообщать свои данные другим пользователям.
+|cff00ff00Shift-ЛКМ|r - Быстрый отчет.]]
+L["Stop"] = "Остановить"
+L["btn_stop_desc"] = "Останавливает или возобновляет запись текущего сегмента. Полезна для сокращения объема данных при вайпе. Возможна настройка автоматической остановки в настройках."
+L["Segment Stopped."] = "Сегмент остановлен."
+L["Segment Paused."] = "Сегмент приостановлен."
+L["Segment Resumed."] = "Сегмент возобновлен."
+L["Quick Access"] = "Быстрый доступ"
+-- default segments
+L["Total"] = "Всего"
+L["Current"] = "Текущий"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada: %s для %s:"
+L["Self"] = "Себе"
+L["Whisper Target"] = "Шепот цели"
+L["Copy & Paste"] = "Копировать и Вставить"
+L["[General]"] = "Общий"
+L["[LocalDefense]"] = "Оборона"
+L["[LookingForGroup]"] = "Поиск спутников"
+L["[Trade]"] = "Торговля"
+L["Line"] = "Линия"
+L["Lines"] = "Линии"
+L["There is nothing to report."] = "Нет данных для отчета."
+L["No mode or segment selected for report."] = "Для отчета не выбран режим или сегмент."
+-- Bar Display Module --
+L["Bar Display"] = "Отображение полос"
+L["mod_bar_desc"] = "Отображение полос - это обычное окно с полосами, которое использует большинство измерителей урона. Имеет множество возможностей для стилизации."
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "Отображение полос (старая)"
+L["Max Bars"] = "Макс полос"
+L["The maximum number of bars shown."] = "Максимальное количество отображаемых полос."
+L["Show Menu Button"] = "Показывать кнопку меню"
+L["Shows a button for opening the menu in the window title bar."] = "Показывает кнопку для открытия меню в заголовке окна."
+L["Class Color Bars"] = "Полосы по цвету класса"
+L["Class Color Text"] = "Текст по цвету класса"
+-- Threat Module --
+L["Threat"] = "Угроза"
+L["Threat Warning"] = "Предупреждение об угрозе"
+L["Flash Screen"] = "Мигание экрана"
+L["This will cause the screen to flash as a threat warning."] = "Предупреждение об угрозе будет производиться посредством мигания экрана."
+L["Shake Screen"] = "Тряска экрана"
+L["This will cause the screen to shake as a threat warning."] = "Предупреждение об угрозе будет производиться посредством тряски экрана."
+L["Warning Message"] = "Оповещения"
+L["Print a message to screen when you accumulate too much threat."] = "Выводить сообщение на экран, когда вы вырабатываете слишком много угрозы."
+L["Play sound"] = "Проиграть звук"
+L["This will play a sound as a threat warning."] = "Предупреждение об угрозе будет производиться посредством звукового сигнала."
+L["Message Output"] = "Вывод"
+L["Choose where warning messages should be displayed."] = "Выберите место отображения предупреждающих сообщений."
+L["Chat Frame"] = "Чат"
+L["Blizzard Error Frame"] = "Фрейм ошибок Blizzard"
+L["Threat sound"] = "Звук угрозы"
+L["opt_threat_soundfile_desc"] = "Этот звук будет воспроизводиться, когда процент угрозы достигнет определенной точки."
+L["Warning Frequency"] = "Частота предупреждений"
+L["Threat Threshold"] = "Порог угрозы"
+L["opt_threat_threshold_desc"] = "При достижении угрозы до этого уровня, по сравнению с танком, будут показаны предупреждения."
+L["Show raw threat"] = "Показать необработанную угрозу"
+L["opt_threat_rawvalue_desc"] = "Показывает процент необработанной угрозы относительно танка, а не модифицированный для диапазона."
+L["Use focus target"] = "Использовать цель фокуса"
+L["opt_threat_focustarget_desc"] = "Выполнять дополнительную проверку вашего 'focus' перед проверкой 'target' и 'targettarget' на наличие угрозы для ее отображения."
+L["Disable while tanking"] = "Отключать при танковании"
+L["opt_threat_notankwarnings_desc"] = "Не выводить предупреждений, если на вас активна Оборонительная стойка, Облик медведя, Праведное неистовство или Власть льда."
+L["Ignore Pets"] = "Игнорировать питомцев"
+L["opt_threat_ignorepets_desc"] = [=[Игнорировать питомцев вражеских игроков при определении объекта для отображения данных по угрозе.
+
+Питомцы игрока отображаются в таблице угрозы, в |cffffff78Агрессивном|r или |cffffff78Оборонительном|r режиме, и ведут себя, как обычные мобы, атакуя цель с наибольшим уровнем угрозы. Если питомцу указано атаковать конкретные цели, питомец будет поддерживать угрозу в таблице, полоса установленной цели по определению будет указывать 100% угрозы. Питомцы игрока могут быть спровоцированы, чтобы заставить их атаковать вас.
+
+Однако, питомцы в |cffffff78пассивном|r режиме не будут внесены с таблицу угрозы, и провокация на них не подействует. Они будут атаковать только указанные цели, и не будут внесены в таблицу угрозы.
+
+Если питомцу приказано |cffffff78Следовать|r, то значения в таблице угрозы питомца будут аннулированы, а атака прекратится, но, несмотря на это, он может снова приобрести цель в зависимости от того, находится он в режиме Агрессии, или же Обороны.]=]
+L["> Pull Aggro <"] = "> Срыв аггро <"
+L["Show Pull Aggro Bar"] = "Отображать полосу срыва аггро"
+L["opt_threat_showaggrobar_desc"] = "Отображать полосу со значением угрозы, достигнув которого вы сорвёте аггро."
+L["Test Warnings"] = "Тестирование предупреждений"
+L["TPS"] = "УгВС"
+L["Threat: Personal Threat"] = "Угроза: Своя Угроза"
+-- Absorbs & Healing Module --
+L["Healing"] = "Исцеление"
+L["Healing Done"] = "Исцеление"
+L["Healing Taken"] = "Исцеление - Получено"
+L["HPS"] = "ИВС"
+L["sHPS"] = "ИВС (подрежимы)"
+L["Healing: Personal HPS"] = "Исцеление: Собственный ИВС"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "Исцеление: ИВС рейда"
+L["Total Healing"] = "Исцеление - Всего"
+L["Overheal"] = "Избыточное"
+L["Overhealing"] = "Исцеление - Избыточное"
+L["Absorbs"] = "Поглощение"
+L["Target List"] = "Список целей"
+L["Spell List"] = "Список заклинаний"
+L["APS"] = "ПВС"
+L["sAPS"] = "ПВС (подрежимы)"
+L["Absorbs and Healing"] = "Поглощение и Исцеление"
+L["Healing Done By Spell"] = "Исцеление - От заклинаний"
+L["Source List"] = "Исходный список"
+-- Auras Module --
+L["Uptime"] = "Время"
+L["Buffs and Debuffs"] = "Бафы и Дебафы"
+L["Buffs"] = "Бафы"
+L["Debuffs"] = "Дебафы"
+L["%s's <%s> targets"] = "%s - Цели <%s>"
+L["%s's <%s> sources"] = "%s - Источник <%s>"
+L["Enemy Buffs"] = "Вражеские баффы"
+L["Enemy Debuffs"] = "Вражеские дебаффы"
+-- CC Tracker Module --
+L["Crowd Control"] = "Контроль толпы"
+L["CC Done"] = "Контроль - Успешный"
+L["CC Taken"] = "Контроль - Полученный"
+L["CC Breaks"] = "Контроль - Прерывания"
+L["Ignore Main Tanks"] = "Игнорировать танков"
+L["%s on %s removed by %s"] = "%s на %s прервал %s"
+L["%s on %s removed by %s's %s"] = "%s на %s прервал %s (%s)"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "Окружающая среда"
+-- damage done module
+L["Damage"] = "Урон"
+L["Spell Details"] = "детали заклинания"
+L["Damage Done"] = "Нанесено урона"
+L["Useful Damage"] = "Урон - Полезный"
+L["Useful damage on %s"] = "Полезный урон по %s"
+L["Damage Done By Spell"] = "Урон - От заклинаний"
+L["%s's sources"] = "%s - Источники"
+L["DPS"] = "УВС"
+L["sDPS"] = "УВС (подрежимы)"
+L["Damage: Personal DPS"] = "Урон: Собственный УВС"
+L["RDPS"] = "РУВС"
+L["Damage: Raid DPS"] = "Урон: УВС рейда"
+L["Absorbed Damage"] = "Поглощенный урон"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "Включите это, если хотите, чтобы наносимый урон включал поглощенный урон."
+L["Damage Done By School"] = "Ущерб, нанесенный школами"
+-- killing blows module
+L["Only PvP Kills"] = "Только убийства в PvP"
+L["When enabled, only kills against enemy players count."] = "Если этот параметр включен, засчитываются только убийства вражеских игроков."
+L["Announce killing blows after combat ends. Only works for boss fights."] = "Объявляйте смертельные удары после окончания боя. Работает только против боссов."
+-- damage taken module
+L["Damage Taken"] = "Получено урона"
+L["Damage Taken By Spell"] = "Получено урона - От заклинаний"
+L["%s's targets"] = "%s - Цели"
+L["DTPS"] = "ПУВС"
+L["sDTPS"] = "ПУВС (подрежимы)"
+-- enemy damage done module
+L["Enemies"] = "Враги"
+L["Enemy Damage Done"] = "Нанесено урона врагом"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "Получено урона врагом"
+L["%s below %s%%"] = "%s ниже %s%%"
+L["%s - %s%% to %s%%"] = "%s - от %s%% до %s%%"
+L["Phase %s"] = "Фаза %s"
+L["%s - Phase %s"] = "%s - Фаза %s"
+L["%s - Phase 1"] = "%s - Фаза 1"
+L["%s - Phase 2"] = "%s - Фаза 2"
+L["%s - Phase 3"] = "%s - Фаза 3"
+L["%s (Main Boss)"] = "%s (Главный босс)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00Фаза %s\124r началась."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00Фаза %s\124r остановлена."
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00Фаза %s\124r возобновлена."
+-- enemy healing done module
+L["Enemy Healing Done"] = "Произведено исцеления врагом"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "Избегание и уменьшение урона"
+L["More Details"] = "Подробнее"
+L["%s's details"] = "Детали %о %s"
+-- friendly fire module
+L["Friendly Fire"] = "Урон - По союзникам"
+-- useful damage targets
+L["Important targets"] = "Важные враги" -- The Lich King
+L["Oozes"] = "Слизнюки" -- Professor Putricide
+L["Princes overkilling"] = "Принцы - избыточный урон" -- Blood Prince Council
+L["Adds"] = "Прислужники" -- Lady Deathwhisper
+L["Halion and Inferno"] = "Халион и элементали" -- Halion
+L["Valkyrs overkilling"] = "Валькирии - избыточный урон" -- The Lich King
+-- Deaths Module --
+L["%s's deaths"] = "%s - Смерти"
+L["Death log"] = "Журнал смертей"
+L["%s's death log"] = "%s - Журнал смерти"
+L["Player's deaths"] = "Смерти игрока"
+L["%s dies"] = "%s умирает"
+L["buff"] = "баф"
+L["debuff"] = "дебаф"
+L["Spell details"] = "Детали заклинания"
+L["Spell"] = "Заклинание"
+L["Amount"] = "Количество"
+L["Source"] = "Источник"
+L["Change"] = "Изменение"
+L["Time"] = "Время"
+L["Survivability"] = "Выживание"
+L["Events Amount"] = "Количество событий"
+L["Set the amount of events the death log should record."] = "Задает количество событий отображаемое в журнале смерти."
+L["Minimum Healing"] = "Минимальное исцеление"
+L["Ignore heal events that are below this threshold."] = "Игнорировать события исцеления ниже этого порога."
+L["Announce Deaths"] = "Объявить Смерти"
+L["Announces information about the last hit the player took before they died."] = "Объявляет последний удар игрок принял перед смертью."
+L["Alternative Display"] = "Альтернативное отображение"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "Если игрок умирает несколько раз, каждая смерть будет отображаться отдельной полосой."
+-- activity module
+L["Activity"] = "Активность"
+L["Activity per Target"] = "Активность по цели"
+L["%s's activity"] = "%s активность"
+-- dispels module lines --
+L["Dispel Spells"] = "Заклинания рассеивания"
+L["%s's dispelled spells"] = "%s - Рассеянные заклинания"
+-- interrupts module lines --
+L["Interrupt Spells"] = "Заклинания прерывания"
+L["%s's interrupted spells"] = "%s - Прерванные заклинания"
+L["%s interrupted!"] = "%s прервано!"
+-- Power gained module --
+L["Resources"] = "Ресурсы"
+L["Mana Restored"] = "Получено: Мана"
+L["Rage Generated"] = "Получено: Ярость"
+L["Energy Generated"] = "Получено: Энергия"
+L["Runic Power Generated"] = "Получено: Сила рун"
+-- Parry module lines --
+L["Parry-Haste"] = "Пари-хаст"
+L["%s parried %s (%s)"] = "%s парировал %s (%s)"
+-- Potions module lines --
+L["Potions"] = "Зелья"
+L["%s's potions"] = "Зелья %s"
+L["Pre-potion"] = "Пре-поты"
+L["pre-potion: %s"] = "пре-поты: %s"
+L["Prints pre-potion after the end of the combat."] = "После окончания боя отображает в чате использовавших зелья заранее."
+-- healthstone --
+L["Healthstones"] = "Камень здоровья"
+-- resurrect module lines --
+L["Resurrects"] = "Воскрешения"
+-- nickname module lines --
+L["Name"] = "Имя"
+L["Nickname"] = "Псевдоним"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "Псевдонимы отправляются участникам группы и могут использоваться вместо имени вашего персонажа."
+L["Set a nickname for you."] = "Задайте ваш псевдоним."
+L["Nickname isn't a valid string."] = "Неверный формат псевдонима."
+L["Your nickname is too long, max of 12 characters is allowed."] = "Ваш псевдоним слишком длинный, допускается не более 12 символов."
+L["Only letters and two spaces are allowed."] = "Допускаются только буквы и два пробела."
+L["Your nickname contains a forbidden word."] = "Ваш псевдоним содержит запрещенное слово."
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "Вы не можете использовать одну и ту же букву три раза подряд, два пробела подряд или более двух пробелов."
+L["Ignore Nicknames"] = "Игнорировать Псевдонимы"
+L["When enabled, nicknames set by Skada users are ignored."] = "Когда эта опция включена, Псевдонимы, установленные другими игроками, игнорируются."
+L["Name display"] = "Формат отображения имени"
+L["Choose how names are shown on your bars."] = "Выберите вариант отображения имени на полосах."
+L["Clear Cache"] = "Очистить кэш"
+L["Are you sure you want clear cached nicknames?"] = "Вы уверены, что хотите очистить кешированные никнеймы?"
+-- overkill module lines --
+L["Overkill"] = "Урон - Избыточный"
+-- tweaks module lines --
+L["Improvement"] = "Улучшение"
+L["Tweaks"] = "Настройки"
+L["First hit"] = "Первый удар"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00Первый удар\124r: %s от %s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00Первый удар\124r: *?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00Первая цель Босса\124r: %s"
+L["opt_tweaks_firsthit_desc"] = "Отображает в чате первый нанесенный удар.\nРаботает только для сражений с боссами."
+L["Filter DPS meters Spam"] = "Фильтр спама счетчиков урона"
+L["opt_tweaks_spamage_desc"] = "Подавляет сообщения чата от счетчиков урона и предоставляет статистику в одном всплывающем окне."
+L["Reported by: %s"] = "Отчет от: %s"
+L["Smart Stop"] = "Останавливать после смерти босса"
+L["opt_tweaks_smarthalt_desc"] = "Автоматически останавливает текущий сегмент после смерти босса.\nПолезно для остановки сбора данных при зависании режима боя."
+L["Duration"] = "Время ожидания"
+L["opt_tweaks_smartwait_desc"] = "Как долго Skada должен ждать, прежде чем остановить сегмент?"
+L["Modes Icons"] = "Значки режимов"
+L["Show modes icons on bars and menus."] = "Показывать значки режимов на барах и в меню."
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "Включите эту опцию, если хотите игнорировать \124cffffbb00%s\124r."
+L["Custom Colors"] = "Нестандартные цвета"
+L["Arena Teams"] = "Команды арены"
+L["Are you sure you want to reset all colors?"] = "Вы уверены, что хотите сбросить все цвета?"
+L["Announce %s"] = "Объявить: %s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "Сообщает, сколько времени потребовалось для применения %d стеков %s, и объявляет, когда он истекает."
+L["%s dropped from %s!"] = "%s истек %s!"
+L["%s stacks of %s applied on %s in %s sec!"] = "На %3$s нанесено %1$s стаканов %2$s за %4$s секунд!"
+L["My Spells"] = "Мои заклинания"
+-- total data options
+L["Total Segment"] = "Всего сегмент"
+L["All Segments"] = "Все сегменты"
+L["Raid Bosses"] = "Рейдовые боссы"
+L["Raid Trash"] = "Рейдовый мусор"
+L["Dungeon Bosses"] = "Боссы подземелья"
+L["Dungeon Trash"] = "Мусор подземелья"
+L["opt_tweaks_total_all_desc"] = "Все сегменты добавляются к всего данным."
+L["opt_tweaks_total_fmt_desc"] = "Сегменты с %s добавляются к всего данным."
+L["Detailed total segment"] = "Детальный сегмент \"Всего\""
+L["opt_tweaks_total_full_desc"] = "Если включено, Skada будет записывать детали и цели способностей в сегмент \"Всего\" (по умолчанию детальная запись не ведется, только общие цифры)."
+-- arena
+L["mod_pvp_desc"] = "Добавляет определение специализации для арен и мест сражений, а также отображение противников на арене в одном окне."
+L["Gold Team"] = "Золотая команда"
+L["Green Team"] = "Зеленая команда"
+L["Color for %s."] = "Цвет %s."
+-- notifications
+L["Notifications"] = "Уведомления"
+L["opt_toast_desc"] = "По возможности использует визуальные уведомления вместо сообщений в окне чата."
+L["Test Notifications"] = "Тестовые уведомления"
+-- comparison module
+L["Comparison"] = "Сравнение"
+L["%s vs %s: %s"] = "%s vs %s: %s"
+L["%s vs %s: Spells"] = "%s vs %s: Заклинания"
+L["%s vs %s: Targets"] = "%s vs %s: Цели"
+-- spellcast module
+L["Casts"] = "Произнесено"
+L["%s's spells"] = "Заклинания %s"
+L["%s's spells on %s"] = "Заклинания %s на %s"
+L["Spells on %s"] = "Заклинания на %s"
+-- about
+L["Author"] = "Автор"
+L["Credits"] = "Благодарности"
+L["Date"] = "Дата"
+L["License"] = "Лицензия"
+L["Version"] = "Версия"
+L["Website"] = "Сайт"
+-- some bosses entries
+L["World Boss"] = "Босс вне подземелья"
+L["Auriaya"] = "Ауриайя"
+L["Blood Prince Council"] = "Совет Принцев Крови"
+L["Faction Champions"] = "Чемпионы фракций"
+L["Hogger"] = "Дробитель"
+L["Icecrown Gunship Battle"] = "Бой на кораблях"
+L["Kologarn"] = "Кологарн"
+L["Mimiron"] = "Мимирон"
+L["Thaddius"] = "Таддиус"
+L["The Four Horsemen"] = "Четыре Всадника"
+L["The Iron Council"] = "Железное собрание"
+L["The Northrend Beasts"] = "Чудовища Нордскола"
+L["Thorim"] = "Торим"
+L["Twin Val'kyr"] = "Валь'киры-близнецы"
+L["Valithria Dreamwalker"] = "Валитрия Сноходица"
+L["Yogg-Saron"] = "Йогг-Сарон"
diff --git a/Skada/Locales/zhCN.lua b/Skada/Locales/zhCN.lua
new file mode 100644
index 0000000..16ed79a
--- /dev/null
+++ b/Skada/Locales/zhCN.lua
@@ -0,0 +1,754 @@
+--[[ Translator: meatgaga#9470 ]] --
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "zhCN")
+if not L then return end
+
+L["A damage meter."] = "模块化伤害统计。"
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "内存使用率高。你可能想要重置Skada,并启用一个自动重置选项。"
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada已过期。你可以在\124cffffbb00%s\124r下载到最新的版本。"
+L["Skada: Modes"] = "Skada:模式"
+L["Skada: Fights"] = "Skada:战斗"
+L["Data Collection"] = "数据收集"
+L["ENABLED"] = "已启用"
+L["DISABLED"] = "已禁用"
+L["Enable All"] = "全部启用"
+L["Disable All"] = "全部禁用"
+L["Stopping for wipe."] = "因团灭而停止统计。"
+L["Usage:"] = "用法:"
+L["Commands:"] = "指令:"
+L["Import"] = "导入"
+L["Export"] = "导出"
+L["Import/Export"] = "导入/导出"
+-- profiles
+L["Profiles"] = "配置文件"
+L["Profile Import/Export"] = "配置文件导入/导出"
+L["Import Profile"] = "导入配置文件"
+L["Export Profile"] = "导出配置文件"
+L["Paste here a profile in text format."] = "在此处粘贴文本格式的配置文件。"
+L["Press CTRL-V to paste the text from your clipboard."] = "按 CTRL-V 从剪贴板粘贴文本。"
+L["This is your current profile in text format."] = "这是您当前的文本格式的个人资料。"
+L["Press CTRL-C to copy the text to your clipboard."] = "按 CTRL-C 将文本复制到剪贴板。"
+L["Network Sharing"] = "網絡共享"
+L["Player Name"] = "选手姓名"
+L["Send Profile"] = "发送个人资料"
+L["Accept profiles from other players."] = "接受来自其他玩家的个人资料。"
+L["opt_profile_received"] = "%s 發送一份設定檔給你,你是否想啟用他?"
+L["Progress"] = "进展"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "资料量:\124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "传输进度:%d%%"
+L["Transmission Completed"] = "传输完成"
+-- common lines
+L["Options"] = "选项"
+L["Options for %s."] = "%s状态的选项。"
+L["General"] = "常规"
+L["General options for %s."] = "%s 的常规选项。"
+L["Text"] = "文字"
+L["Text options for %s."] = "%s 的文本选项。"
+L["Format"] = "格式"
+L["Format options for %s."] = "%s 的格式选项。"
+L["Appearance"] = "外观"
+L["Appearance options for %s."] = "%s 的外观选项。"
+L["Advanced"] = "高级"
+L["Advanced options for %s."] = "%s 的高级选项。"
+L["Position"] = "位置"
+L["Position settings for %s."] = "%s 的位置选项。"
+L["Width"] = "宽度"
+L["The width of %s."] = "%s 的宽度。"
+L["Height"] = "高度"
+L["The height of %s."] = "%s 的高度。"
+L["Active Time"] = "活跃时间"
+L["Segment Time"] = "分段时间"
+L["Click for \124cff00ff00%s\124r"] = "点击后为 \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift+点击后为 \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Ctrl+点击后为 \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt+点击后为 \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "切换职业筛选"
+L["Average"] = "平均"
+L["Count"] = "计数"
+L["Refresh"] = "刷新"
+L["Percent"] = "百分比"
+L["sPercent"] = "百分比 (子模块)"
+L["General Options"] = "常规选项"
+L["HoT"] = "治疗/跳"
+L["DoT"] = "伤害/跳"
+L["Hits"] = "命中"
+L["Normal Hits"] = "普通攻击"
+L["Critical"] = "暴击"
+L["Critical Hits"] = "暴击一击"
+L["Crushing"] = "碾压"
+L["Glancing"] = "穿刺"
+L["ABSORB"] = "吸收"
+L["BLOCK"] = "格挡"
+L["DEFLECT"] = "偏斜"
+L["DODGE"] = "躲闪"
+L["EVADE"] = "闪避"
+L["IMMUNE"] = "免疫"
+L["MISS"] = "未命中"
+L["PARRY"] = "招架"
+L["REFLECT"] = "反射"
+L["RESIST"] = "抵制"
+L["Only for bosses."] = "只针对老板。"
+L["Enable this only against bosses."] = "只对老板启用此。"
+-- segment info
+L["Start"] = "开始"
+L["End"] = "结束"
+-- windows section:
+L["Window"] = "窗口"
+L["Windows"] = "窗口"
+L["Create Window"] = "创建窗口"
+L["Window Name"] = "窗口名称"
+L["Enter the name for the new window."] = "输入新窗口的名字。"
+L["Delete Window"] = "删除窗口"
+L["Choose the window to be deleted."] = "选择要删除的窗口。"
+L["Are you sure you want to delete this window?"] = "确定要删除此窗口?"
+L["Delete All Windows"] = "删除所有窗口"
+L["Are you sure you want to delete all windows?"] = "您确定要删除所有窗口吗?"
+L["Rename Window"] = "重命名窗口"
+L["Enter the name for the window."] = "输入窗口的名字。"
+L["Test Mode"] = "测试模式"
+L["Creates fake data to help you configure your windows."] = "创建虚假数据以帮助您配置窗口。"
+L["Child Window"] = "子窗口"
+L["A child window will replicate the parent window actions."] = "子窗口将复制父窗口的动作。"
+-- L["Child Window Mode"] = ""
+L["Lock Window"] = "锁定窗口"
+L["Locks the bar window in place."] = "在当前位置锁定统计条窗口。"
+L["Hide Window"] = "隐藏窗口"
+L["Hides the window."] = "隐藏此窗口。"
+L["Sticky Window"] = "黏附窗口"
+L["Allows the window to stick to other Skada windows."] = "允许窗口黏附到其他Skada窗口。"
+L["Snap to best fit"] = "自动适应大小"
+L["Snaps the window size to best fit when resizing."] = "在调整大小时自动根据最适合的大小依附窗口。"
+L["Disable Resize Buttons"] = "禁用缩放按钮"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "当您将鼠标悬停在窗口上时,不会出现缩放和锁定/解锁按钮。"
+L["Disable stretch button"] = "禁用拉伸按钮"
+L["Stretch button won't show up when you hover over the window."] = "当您将鼠标悬停在窗口上时,不会显示拉伸按钮。"
+L["Reverse window stretch"] = "向下拉伸窗口"
+L["opt_botstretch_desc"] = "将拉伸按钮放置在窗口底部,并使后者向下拉伸。"
+L["Display System"] = "显示系统"
+L["Choose the system to be used for displaying data in this window."] = "选择在窗口中显示数据的系统。"
+L["Copy Settings"] = "复制设置"
+L["Choose the window from which you want to copy the settings."] = "选择要从中复制设置的窗口。"
+-- bars
+L["Bars"] = "统计条"
+L["Left Text"] = "左侧文本"
+L["Right Text"] = "右侧文本"
+L["Font"] = "字体"
+L["The font used by %s."] = "%s 使用的字体。"
+L["Font Size"] = "字体大小"
+L["The font size of %s."] = "%s 的字体大小。"
+L["Font Outline"] = "字体轮廓"
+L["Sets the font outline."] = "设置字体轮廓。"
+L["Outline"] = "轮廓"
+L["Thick"] = "粗"
+L["Thick outline"] = "粗轮廓"
+L["Monochrome"] = "单色"
+L["Outlined monochrome"] = "轮廓单色"
+L["Bar Texture"] = "统计条材质"
+L["The texture used by all bars."] = "全部统计条所使用的材质。"
+L["Spacing"] = "间距"
+L["Distance between %s."] = "%s 之间的距离。"
+L["Displacement"] = "位移"
+L["The distance between the edge of the window and the first bar."] = "窗口边缘与第一个栏之间的距离。"
+L["Bar Orientation"] = "统计条方向"
+L["The direction the bars are drawn in."] = "统计条的绘制方向。"
+L["Left to right"] = "从左到右"
+L["Right to left"] = "从右到左"
+L["Reverse bar growth"] = "反转增长方向"
+L["Bars will grow up instead of down."] = "统计条向上增长。"
+L["Disable bar highlight"] = "禁用计量条高亮"
+L["Hovering a bar won't make it brighter."] = "鼠标悬浮在计量条上不会高亮显示。"
+L["Bar Color"] = "统计条颜色"
+L["Choose the default color of the bars."] = "选择统计条的默认颜色。"
+L["Background Color"] = "背景颜色"
+L["The color of the background."] = "背景的颜色。"
+L["Custom Color"] = "自定义颜色"
+L["Use a different color for my bar."] = "为我的酒吧使用不同的颜色。"
+L["My Color"] = "我的颜色"
+L["Spell school colors"] = "法术派系颜色"
+L["Use spell school colors where applicable."] = "在适用处使用法术派系颜色。"
+L["When possible, bars will be colored according to player class."] = "若有可能,统计条按玩家职业着色。"
+L["When possible, bar text will be colored according to player class."] = "若有可能,统计条文字按玩家职业着色。"
+L["Class Icons"] = "职业图标"
+L["Use class icons where applicable."] = "在适用处使用职业图标。"
+L["Spec Icons"] = "天赋图标"
+L["Use specialization icons where applicable."] = "在适用处使用天赋图标。"
+L["Role Icons"] = "职责图标"
+L["Use role icons where applicable."] = "在适用处使用职责图标。"
+L["Show Spark Effect"] = "显示光斑效果"
+L["Click Through"] = "禁用点击"
+L["Disables mouse clicks on bars."] = "在统计条上禁用鼠标点击。"
+L["Smooth Bars"] = "平滑效果"
+L["Animate bar changes smoothly rather than immediately."] = "以动画平滑显示统计条变化。"
+-- title bar
+L["Title Bar"] = "标题栏"
+L["Enables the title bar."] = "启用标题栏。"
+L["Include set"] = "包括集合"
+L["Include set name in title bar"] = "在标题栏中包括集合名称。"
+L["Encounter Timer"] = "战斗计时器"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "启用后,在文字左侧显示一个秒表。"
+L["Mode Icon"] = "模式图标"
+L["Shows mode's icon in the title bar."] = "在标题栏中显示模式的图标。"
+L["The texture used as the background of the title."] = "用于标题背景的材质。"
+L["Border texture"] = "边框材质"
+L["The texture used for the borders."] = "用于边框的材质。"
+L["Border Color"] = "边框颜色"
+L["The color used for the border."] = "边框所使用的颜色。"
+L["Buttons"] = "按钮"
+L["Auto Hide Buttons"] = "自动隐藏菜单"
+L["Show window buttons only if the cursor is over the title bar."] = "仅当光标在标题栏上方时才显示窗口按钮。"
+L["Buttons Style"] = "按钮样式"
+-- general window
+L["Background"] = "背景"
+L["Background Texture"] = "背景材质"
+L["The texture used as the background."] = "用于背景的材质。"
+L["Tile"] = "平铺"
+L["Tile the background texture."] = "平铺背景材质。"
+L["Tile Size"] = "平铺尺寸"
+L["The size of the texture pattern."] = "材质图案的尺寸。"
+L["Border"] = "边框"
+L["Border Thickness"] = "边框粗细"
+L["The thickness of the borders."] = "边框的粗细。"
+L["Border Insets"] = "边界距离"
+L["The distance between the window and its border."] = "窗口和它的边界之间的距离。"
+L["Scale"] = "缩放"
+L["Sets the scale of the window."] = "设定窗口的缩放比例。"
+L["Strata"] = "层级"
+L["This determines what other frames will be in front of the frame."] = "此项指定其他哪些框架将位于此框架的前面。"
+L["Clamped To Screen"] = "限制在屏幕內"
+L["Toggle whether to permit movement out of screen."] = "切换是否允许把框架移出屏幕。"
+L["X Offset"] = "X 偏移"
+L["Y Offset"] = "Y 偏移"
+-- switching
+L["Mode Switching"] = "模式切换"
+L["Combat Mode"] = "战斗模式"
+L["opt_combatmode_desc"] = "进入战斗时自动切换到\124cffffbb00当前\124r集合和此模式。"
+L["Wipe Mode"] = "团灭模式"
+L["opt_wipemode_desc"] = "团灭后自动切换到\124cffffbb00当前\124r集合和此模式。"
+L["Return after combat"] = "战斗后返回"
+L["Return to the previous set and mode after combat ends."] = "战斗结束后返回原先的集合和模式。"
+L["Auto switch to current"] = "自动切换到当前"
+L["opt_autocurrent_desc"] = "每当战斗开始这个窗口自动切换到\124cffffbb00当前\124r片段。"
+L["Auto Hide"] = "自动隐藏"
+L["While in combat"] = "在战斗中"
+L["While out of combat"] = "脱离战斗"
+L["While not in a group"] = "当退出队伍"
+L["While inside an instance"] = "当在副本中"
+L["While not inside an instance"] = "当不在副本中"
+L["In Battlegrounds"] = "在战场中"
+L["Inline Bar Display"] = "直排统计条显示"
+L["mod_inline_desc"] = "直排显示是一种水平窗口样式。"
+L["Font Color"] = "字体颜色"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "字体的颜色。\n点击“班级颜色”开始。"
+L["opt_barwidth_desc"] = "统计条的宽度。此项仅在“固定统计条宽度”选项启用后生效。"
+L["Fixed bar width"] = "固定统计条宽度"
+L["opt_fixedbarwidth_desc"] = "勾选后,统计条的宽度固定。否则,统计条宽度取决于文字长度。"
+L["Use class colors for %s."] = "对 %s 使用职业颜色。"
+L["opt_isusingclasscolors_desc"] = "随着:%s - 5.71M (21.7K)\n不带:%s - 5.71M (21.7K)"
+L["Put values on new line."] = "提行显示数值"
+L["opt_isonnewline_desc"] = "提行:\n%1$s\n5.71M (21.7K)\n\n单行:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = "可用时使用ElvUI皮肤。"
+L["opt_isusingelvuiskin_desc"] = "勾选此项以使用ElvUI皮肤。\n默认:勾选"
+L["Use solid background."] = "使用纯色背景。"
+L["Un-check this for an opaque background."] = "不勾选此项将使用不透明背景。"
+L["Data Text"] = "数据文字"
+L["mod_broker_desc"] = "数据文本作为一个 LDB 数据聚合。可以集成在任何 LDB 显示,如 Titan Panel 或 ChocolateBar。它也有一个可选的内部框架。"
+L["Use frame"] = "使用窗口"
+L["opt_useframe_desc"] = "显示一个独立的框架。 如果您使用的是 LDB 显示提供程序,例如 Titan Panel 或 ChocolateBar,则不需要。"
+L["Text Color"] = "文字颜色"
+L["Choose the default color."] = "选择默认颜色。"
+L["Hint: Left-Click to set active mode."] = "提示:左键点击:设定活跃模式。"
+L["Right-Click to set active set."] = "右键点击:设定活跃集合。"
+L["Shift+Left-Click to open menu."] = "Shift+左键点击:打开菜单。"
+-- data resets
+L["Data Resets"] = "数据重置"
+L["Reset on entering instance"] = "进本重置"
+L["Controls if data is reset when you enter an instance."] = "控制是否在进入副本时重置数据。"
+L["Reset on joining a group"] = "入队重置"
+L["Controls if data is reset when you join a group."] = "控制是否在加入队伍时重置数据。"
+L["Reset on leaving a group"] = "离队重置"
+L["Controls if data is reset when you leave a group."] = "控制是否在离开队伍时重置数据。"
+L["Ask"] = "询问"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "是否要重置数据?\n按住 SHIFT 重置所有。"
+L["All data has been reset."] = "全部数据已重置。"
+L["There is no data to reset."] = "没有要重置的数据。"
+L["Skip reset dialog"] = "跳过重置对话框"
+L["opt_skippopup_desc"] = "如果您希望Skada在没有确认对话框的情况下进行重置,请启用此选项。"
+L["Are you sure you want to reinstall Skada?"] = "您确定要重新安装 Skada 吗?"
+-- general options
+L["Show minimap button"] = "显示小地图按钮"
+L["Toggles showing the minimap button."] = "切换小地图按钮的显示。"
+L["Transliterate"] = "音译"
+L["Converts Cyrillic letters into Latin letters."] = "将西里尔字母转换为拉丁字母。"
+L["Remove realm name"] = "移除服务器名字"
+L["opt_realmless_desc"] = "当启动角色后不显示服务器名字。"
+L["Merge pets"] = "合并宠物"
+L["Merges pets with their owners. Changing this only affects new data."] = "宠物数据与其主人合并。此项变更仅对新数据生效。"
+L["Show totals"] = "显示总计"
+L["Shows a extra row with a summary in certain modes."] = "在某些模式下显示带有摘要的额外行。"
+L["Only keep boss fighs"] = "只保留首领战"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "启用后将保留首领战数据,而非首领战数据则将被丢弃。"
+L["Always save boss fights"] = "总是保留BOSS战"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "启用后首领战将被保存,不会受到Skada重置的影响。"
+L["Hide when solo"] = "单练时隐藏"
+L["Hides Skada's window when not in a party or raid."] = "不在队伍中时隐藏Skada窗口。"
+L["Hide in PvP"] = "PvP中隐藏"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "在战场/竞技场中隐藏Skada窗口。"
+L["Hide in combat"] = "战斗中隐藏"
+L["Hides Skada's window when in combat."] = "在战斗中隐藏Skada窗口。"
+L["Show in combat"] = "战斗中显示"
+L["Shows Skada's window when in combat."] = "在战斗中显示Skada窗口。"
+L["Disable while hidden"] = "隐藏时禁用"
+L["Skada will not collect any data when automatically hidden."] = "自动隐藏时Skada将不收集任何数据。"
+L["Sort modes by usage"] = "按用途排序模式"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "模式列表将进行排序以反映用途,而不是按字母顺序。"
+L["Show rank numbers"] = "显示序号"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "在适用处根据模式中的相对等级显示数字编号。"
+L["Aggressive combat detection"] = "激进式战斗侦测(Recount模式)"
+L["opt_tentativecombatstart_desc"] = [[Skada通常使用非常保守(简单)的战斗侦测方案,在团队副本中效果最佳。通过此选项,Skada可尝试模拟其他伤害统计插件。这在五人本中很有效, 但对于首领战则毫无意义。]]
+L["Autostop"] = "自动停止"
+L["opt_autostop_desc"] = "团队成员超过半数阵亡时自动停止当前分段记录。"
+L["Always show self"] = "总是显示自己"
+L["opt_showself_desc"] = "即使没有足够空行,仍然将玩家显示在最后。"
+L["Number format"] = "数字格式"
+L["Controls the way large numbers are displayed."] = "控制大数字的显示方式。"
+L["Condensed"] = "简短"
+L["Detailed"] = "详细"
+L["Combined"] = "合计"
+L["Comma"] = "逗号"
+L["Numeral system"] = "数字显示"
+L["Select which numeral system to use."] = "选择数字显示系统。"
+L["Auto"] = "自动"
+L["Western"] = "西方"
+L["East Asia"] = "东亚"
+L["Brackets"] = "括号"
+L["Choose which type of brackets to use."] = "选择要使用的括号类型。"
+L["Separator"] = "分隔符"
+L["Choose which character is used to separator values between brackets."] = "选择使用哪个字符来分隔括号之间的值。"
+L["Number of decimals"] = "小数位数"
+L["Controls the way percentages are displayed."] = "控制百分比的显示方式。"
+L["Data Feed"] = "数据反馈"
+L["opt_feed_desc"] = "选择显示在DataBroker上的数据反馈。需要一个LDB显示插件,例如Titan Panel泰坦信息条。"
+L["Time Measure"] = "时间测量"
+L["Activity Time"] = "活跃时间"
+L["Effective Time"] = "有效时间"
+L["opt_timemesure_desc"] = [=[|cffffff00活跃|r:每个团队成员的计时器将在其活动停止后暂停,并在恢复活跃时再次计时。这是测量DPS和HPS的常用方法。
+|cffffff00有效|r:用于排名,此方法使用经历的战斗时间来测量全部团队成员的DPS和HPS。]=]
+L["Number set duplicates"] = "数字集重复"
+L["Append a count to set names with duplicate mob names."] = "在集合名称中附加一个重复怪物名字的计数。"
+L["Set Format"] = "集合格式"
+L["Controls the way set names are displayed."] = "控制集合名称的显示方式。"
+L["Links in reports"] = "报告中的链接"
+L["When possible, use links in the report messages."] = "如果可能,请使用报告消息中的链接。"
+L["Segments to keep"] = "数据分段保留"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "需要保留的战斗数据分段数量。不包括连续的分段数据。"
+L["Persistent segments"] = "持久段"
+L["The number of persistent fight segments to keep."] = "要保留的持久段数。"
+L["Memory Check"] = "内存检查"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "检查内存占用,并在高于%dmb时发出警告。"
+L["Disable Comms"] = "禁用通信"
+L["Minimum segment length"] = "最小分段长度"
+L["The minimum length required in seconds for a segment to be saved."] = "保存段所需的最小长度(秒)。"
+L["Update frequency"] = "更新频率"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "窗口的更新频率。数字越小更新越快,但同时CPU占用越高。"
+-- columns
+L["Columns"] = "列"
+-- tooltips
+L["Tooltips"] = "提示框"
+L["Show Tooltips"] = "显示提示框"
+L["Shows tooltips with extra information in some modes."] = "在某些模式下显示包含额外信息的提示框。"
+L["Informative Tooltips"] = "信息性提示框"
+L["Shows subview summaries in the tooltips."] = "在提示框中显示子视图摘要。"
+L["Subview Rows"] = "子视图行"
+L["The number of rows from each subview to show when using informative tooltips."] = "使用信息性提示框时每个子视图的显示行数。"
+L["Tooltip Position"] = "提示框位置"
+L["Position of the tooltips."] = "提示框的位置。"
+L["Top Right"] = "右上"
+L["Top Left"] = "左上"
+L["Bottom Right"] = "右下"
+L["Bottom Left"] = "左下"
+L["Smart"] = "智能"
+L["Follow Cursor"] = "跟随光标"
+L["Top"] = "上"
+L["Bottom"] = "下"
+L["Right"] = "右"
+L["Left"] = "左"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00需要\124r:%s"
+L["Modules"] = "组件"
+L["Disabled Modules"] = "禁用模块"
+L["Modules Options"] = "模块选项"
+L["Tick the modules you want to disable."] = "勾选要禁用的模块。"
+L["This change requires a UI reload. Are you sure?"] = "此更改需要重载界面。确定重载?"
+-- themes options
+L["Theme"] = "主题"
+L["Themes"] = "主题"
+L["Manage Themes"] = "题材管理"
+L["All Windows"] = "所有窗口"
+L["Apply Theme"] = "应用主题"
+L["Theme applied!"] = "主题已应用!"
+L["Name of your new theme."] = "新主题的名称。"
+L["Save Theme"] = "保存主题"
+L["Delete Theme"] = "删除主题"
+L["Are you sure you want to delete this theme?"] = "确定要删除此样式吗?"
+L["Paste here a theme in text format."] = "在此处粘贴文本格式的题材。"
+L["This is your current theme in text format."] = "这是您当前主题的文本。"
+-- scroll options
+L["Scroll"] = "滚动"
+L["Wheel Speed"] = "轮速"
+L["opt_wheelspeed_desc"] = "更改在窗口上滚动鼠标滚轮时滚动的速度。"
+L["Scroll Icon"] = "滚动图标"
+L["Scroll mouse button"] = "滚动鼠标按钮"
+-- minimap button
+L["Skada Summary"] = "Skada概要"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00左键\124r:开关窗口"
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+左键\124r:显示/隐藏窗口。"
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+左键\124r:重置"
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00右键\124r:打开菜单"
+-- skada menu
+L["Skada Menu"] = "Skada菜单"
+L["Select Segment"] = "选择分段"
+L["Delete Segment"] = "删除分段"
+L["Keep Segment"] = "保留分段"
+L["Toggle Windows"] = "开关窗口"
+L["Show/Hide Windows"] = "显示/隐藏窗口"
+L["New Segment"] = "新板块"
+L["Starts a new segment."] = "开始新的段"
+L["New Phase"] = "新相"
+L["Starts a new phase."] = "开始新的阶段。"
+L["Select All"] = "全选"
+L["Deselect All"] = "取消全选"
+-- window buttons
+L["Configure"] = "配置"
+L["Open Config"] = "打开配置"
+L["btn_config_desc"] = "打开配置窗口。"
+L["btn_reset_desc"] = [[重置除标记为保留之外的全部数据。
+|cff00ff00Shift 点击|r:删除分段。]]
+L["Segment"] = "分段"
+L["btn_segment_desc"] = [[跳转至一个指定分段。
+|cff00ff00Shift 点击|r:|cffffbb00下一个|r片段。
+|cff00ff00Shift 右键单击|r:|cffffbb00以前的|r片段。
+|cff00ff00中键|r:|cffffbb00当前|r片段。]]
+L["Mode"] = "模式"
+L["Jump to a specific mode."] = "跳转至一个指定模式。"
+L["Report"] = "报告"
+L["btn_report_desc"] = [[打开一个可以通过各种方式向他人报告数据的对话框。
+|cff00ff00Shift-点击后为|r:快速报告。]]
+L["Stop"] = "停止"
+L["btn_stop_desc"] = "停止或继续当前分段。在团灭后很有用。可在设置中设为自动停止。"
+L["Segment Stopped."] = "区段已停止。"
+L["Segment Paused."] = "区段已暂停。"
+L["Segment Resumed."] = "区段已恢复。"
+L["Quick Access"] = "快速访问"
+-- default segments
+L["Total"] = "总计"
+L["Current"] = "当前战斗"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada:%s 对于 %s:"
+L["Self"] = "自己"
+L["Whisper Target"] = "密语对象"
+L["Copy & Paste"] = "复制和粘贴"
+L["[General]"] = "综合"
+L["[LocalDefense]"] = "本地防务"
+L["[LookingForGroup]"] = "寻求组队"
+L["[Trade]"] = "交易"
+L["Line"] = "线路"
+L["Lines"] = "线路"
+L["There is nothing to report."] = "没有可报告的内容。"
+L["No mode or segment selected for report."] = "没有为报告选定模式或分段。"
+-- Bar Display Module --
+L["Bar Display"] = "条形图显示"
+L["mod_bar_desc"] = "条形图显示是被大多数伤害统计插件所采用的普通条形图窗口。可以高度样式化。"
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "条形图显示(旧)"
+L["Max Bars"] = "最大条数量"
+L["The maximum number of bars shown."] = "显示条的最大数量"
+L["Show Menu Button"] = "显示菜单按钮"
+L["Shows a button for opening the menu in the window title bar."] = "在窗口标题条显示打开菜单的按钮。"
+L["Class Color Bars"] = "按职业着色计量条"
+L["Class Color Text"] = "按职业着色文本"
+-- Threat Module --
+L["Threat"] = "威胁"
+L["Threat Warning"] = "威胁警告"
+L["Flash Screen"] = "屏幕闪烁"
+L["This will cause the screen to flash as a threat warning."] = "以屏幕闪烁作为威胁警告。"
+L["Shake Screen"] = "屏幕晃动"
+L["This will cause the screen to shake as a threat warning."] = "以屏幕晃动作为威胁警告。"
+L["Warning Message"] = "警报消息"
+L["Print a message to screen when you accumulate too much threat."] = "当你仇恨过高时在屏幕上显示警报消息。"
+L["Play sound"] = "播放音效"
+L["This will play a sound as a threat warning."] = "以播放音效作为威胁警告。"
+L["Message Output"] = "输出模式"
+L["Choose where warning messages should be displayed."] = "选择应在何处显示警告消息。"
+L["Chat Frame"] = "聊天框体"
+L["Blizzard Error Frame"] = "Blizzard 错误框体"
+L["Threat sound"] = "威胁音效"
+L["opt_threat_soundfile_desc"] = "当你的威胁比率达到某个点时播放的音效。"
+L["Warning Frequency"] = "警告频率"
+L["Threat Threshold"] = "威胁比率"
+L["opt_threat_threshold_desc"] = "当你的威胁相对于坦克达到此级别时,将显示警告。"
+L["Show raw threat"] = "显示原始威胁"
+L["opt_threat_rawvalue_desc"] = "显示相对于坦克的原始威胁比率,而不是范围的修改。"
+L["Use focus target"] = "使用焦点"
+L["opt_threat_focustarget_desc"] = "让 Skada 额外检查您的“焦点”和“焦点目标”位于“目标”和“目标的目标”之前的顺序显示威胁。"
+L["Disable while tanking"] = "作为坦克时不警告"
+L["opt_threat_notankwarnings_desc"] = "如果存在防御姿态、熊形态、正义之怒与冰霜系时,不显示警报。"
+L["Ignore Pets"] = "忽略宠物"
+L["opt_threat_ignorepets_desc"] = [=[让 Skada 忽略敌对玩家宠物以决定显示哪些单位的威胁。
+
+玩家宠物|cffffff78攻击|r或者|cffffff78防御|r状态保持威胁与正常的怪物相同,正被攻击目标具有最高的威胁。如果宠物指定攻击一个具体目标,宠物仍然保持在威胁列表,但保持在指定的目标定义100%威胁之上。可以玩家宠物嘲讽以攻击你。
+
+然而,玩家宠物在|cffffff78被动|r模式并没有威胁列表,嘲讽依然不起作用。它们只攻击指定的目标和指令时没有仇恨列表。
+
+当玩家宠物处于|cffffff78跟随|r状态时,宠物的威胁列表被消除并立刻停止攻击,虽然它可能会立即重新指定目标位于攻击/防御模式。]=]
+L["> Pull Aggro <"] = ">获得仇恨<"
+L["Show Pull Aggro Bar"] = "显示获得仇恨计量条"
+L["opt_threat_showaggrobar_desc"] = "显示一个数值威胁计量条,以帮助获得仇恨。"
+L["Test Warnings"] = "测试警报"
+L["TPS"] = "TPS"
+L["Threat: Personal Threat"] = "威胁:个人威胁"
+-- Absorbs & Healing Module --
+L["Healing"] = "治疗"
+L["Healing Done"] = "造成治疗"
+L["Healing Taken"] = "受到治疗"
+L["HPS"] = "HPS"
+L["sHPS"] = "HPS (子模块)"
+L["Healing: Personal HPS"] = "治疗:个人HPS"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "治疗:团队HPS"
+L["Total Healing"] = "总计治疗"
+L["Overheal"] = "过量治疗"
+L["Overhealing"] = "过量治疗"
+L["Absorbs"] = "吸收"
+L["Target List"] = "目标清单"
+L["Spell List"] = "法术列表"
+L["APS"] = "APS"
+L["sAPS"] = "APS (子模块)"
+L["Absorbs and Healing"] = "吸收和治疗"
+L["Healing Done By Spell"] = "法术造成的治疗"
+L["Source List"] = "源列表"
+-- Auras Module --
+L["Uptime"] = "持续时间"
+L["Buffs and Debuffs"] = "Buff和Debuff"
+L["Buffs"] = "Buff"
+L["Debuffs"] = "Debuff"
+L["%s's <%s> targets"] = "%s的<%s>目标"
+L["%s's <%s> sources"] = "%s的<%s>的来源"
+L["Enemy Buffs"] = "敌人增益"
+L["Enemy Debuffs"] = "敌人减益"
+-- CC Tracker Module --
+L["Crowd Control"] = "控制"
+L["CC Done"] = "成功控制"
+L["CC Taken"] = "受到控制"
+L["CC Breaks"] = "打破控制"
+L["Ignore Main Tanks"] = "忽略主坦克"
+L["%s on %s removed by %s"] = "%s位于%s已被%s移除"
+L["%s on %s removed by %s's %s"] = "%s位于%s已被%s的%s移除"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "环境"
+-- damage done module
+L["Damage"] = "伤害"
+L["Spell Details"] = "法术详情"
+L["Damage Done"] = "造成伤害"
+L["Useful Damage"] = "有用伤害"
+L["Useful damage on %s"] = "对于%s有用伤害"
+L["Damage Done By Spell"] = "法术造成伤害"
+L["%s's sources"] = "%s的来源"
+L["DPS"] = "DPS"
+L["sDPS"] = "DPS (子模块)"
+L["Damage: Personal DPS"] = "伤害:个人DPS"
+L["RDPS"] = "RDPS"
+L["Damage: Raid DPS"] = "伤害:团队DPS"
+L["Absorbed Damage"] = "吸收伤害"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "启用此选项,如果你想算入吸收伤害。"
+L["Damage Done By School"] = "学校造成的伤害"
+-- killing blows module
+L["Only PvP Kills"] = "仅 PvP 杀戮"
+L["When enabled, only kills against enemy players count."] = "启用后,只有杀死敌方玩家才算数。"
+L["Announce killing blows after combat ends. Only works for boss fights."] = "战斗结束后宣布致命一击。 只对boss起作用。"
+-- damage taken module
+L["Damage Taken"] = "承受伤害"
+L["Damage Taken By Spell"] = "承受法术伤害"
+L["%s's targets"] = "%s的目标"
+L["DTPS"] = "DTPS"
+L["sDTPS"] = "DTPS (子模块)"
+-- enemy damage done module
+L["Enemies"] = "敌方相关"
+L["Enemy Damage Done"] = "敌方造成伤害"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "敌方承受伤害"
+L["%s below %s%%"] = "%s - %s%%"
+L["%s - %s%% to %s%%"] = "%s - %s%% 到 %s%%"
+L["Phase %s"] = "第 %s 阶段"
+L["%s - Phase %s"] = "%s - 第 %s 阶段"
+L["%s - Phase 1"] = "%s - 第 1 阶段"
+L["%s - Phase 2"] = "%s - 第 2 阶段"
+L["%s - Phase 3"] = "%s - 第 3 阶段"
+L["%s (Main Boss)"] = "%s (老板)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00第 %s\124r 开始。"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00第 %s\124r 停止。"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00第 %s\124r 恢复。"
+-- enemy healing done module
+L["Enemy Healing Done"] = "敌方的治疗"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "规避和缓解"
+L["More Details"] = "更多细节"
+L["%s's details"] = "%s的详情"
+-- friendly fire module
+L["Friendly Fire"] = "误伤"
+-- useful damage targets
+L["Important targets"] = "重要目标"
+L["Oozes"] = "软泥怪"
+L["Princes overkilling"] = "王子过度伤害"
+L["Adds"] = "小怪"
+L["Halion and Inferno"] = "海里昂和地狱火"
+L["Valkyrs overkilling"] = "瓦格里过度伤害"
+-- Deaths Module --
+L["%s's deaths"] = "%s的死亡"
+L["Death log"] = "死亡记录"
+L["%s's death log"] = "%s的死亡记录"
+L["Player's deaths"] = "玩家的死亡"
+L["%s dies"] = "%s死亡了"
+L["buff"] = "buff"
+L["debuff"] = "减益"
+L["Spell details"] = "法术详情"
+L["Spell"] = "法术"
+L["Amount"] = "数量"
+L["Source"] = "来源"
+L["Change"] = "改变"
+L["Time"] = "时间"
+L["Survivability"] = "生存"
+L["Events Amount"] = "事件数量"
+L["Set the amount of events the death log should record."] = "设置死亡日志应记录的事件数量。"
+L["Minimum Healing"] = "最小愈合"
+L["Ignore heal events that are below this threshold."] = "忽略低于此阈值的治疗事件。"
+L["Announce Deaths"] = "宣布死亡"
+L["Announces information about the last hit the player took before they died."] = "宣布导致玩家死亡的最后一击。"
+L["Alternative Display"] = "另类显示"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "如果玩家多次死亡,每次死亡都会显示为单独的条形图。"
+-- activity module
+L["Activity"] = "活跃"
+L["Activity per Target"] = "每个目标的活动"
+L["%s's activity"] = "%s 的活动"
+-- dispels module lines --
+L["Dispel Spells"] = "驱散咒语"
+L["%s's dispelled spells"] = "%s的已驱散法术"
+-- interrupts module lines --
+L["Interrupt Spells"] = "打断法术"
+L["%s's interrupted spells"] = "%s的已打断法术"
+L["%s interrupted!"] = "%s已打断!"
+-- Power gained module --
+L["Resources"] = "能量"
+L["Mana Restored"] = "法力恢复"
+L["Rage Generated"] = "怒气生成"
+L["Energy Generated"] = "能量生成"
+L["Runic Power Generated"] = "符文能量生成"
+-- Parry module lines --
+L["Parry-Haste"] = "招架-急速"
+L["%s parried %s (%s)"] = "%s招架%s (%s)"
+-- Potions module lines --
+L["Potions"] = "药水"
+L["%s's potions"] = "%s的药水"
+L["Pre-potion"] = "预使用药水"
+L["pre-potion: %s"] = "预使用药水:%s"
+L["Prints pre-potion after the end of the combat."] = "战斗结束后发布预使用药水信息。"
+-- healthstone --
+L["Healthstones"] = "治疗石"
+-- resurrect module lines --
+L["Resurrects"] = "复活"
+-- nickname module lines --
+L["Nickname"] = "昵称"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "昵称已发送给队员,Skada可使用它取代你的角色名字。"
+L["Set a nickname for you."] = "给自己设定一个昵称。"
+L["Nickname isn't a valid string."] = "此昵称不是有效字符串。"
+L["Your nickname is too long, max of 12 characters is allowed."] = "你的昵称太长,最多允许12个字符。"
+L["Only letters and two spaces are allowed."] = "仅允许字母及2个空格。"
+L["Your nickname contains a forbidden word."] = "您的昵称包含禁止词。"
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "同一个字母不能连续使用3次,不能连续使用2个空格且不能超过2个空格。"
+L["Ignore Nicknames"] = "忽略昵称"
+L["When enabled, nicknames set by Skada users are ignored."] = "勾选后,Skada用户设定的昵称将被忽略。"
+L["Name display"] = "名字显示"
+L["Choose how names are shown on your bars."] = "选择统计条上名字的显示方式。"
+L["Clear Cache"] = "清除缓存"
+L["Are you sure you want clear cached nicknames?"] = "您确定要清除缓存的昵称吗?"
+-- overkill module lines --
+L["Overkill"] = "过度杀伤"
+-- tweaks module lines --
+L["Improvement"] = "提升"
+L["Tweaks"] = "调整"
+L["First hit"] = "第一击"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00第一击\124r:从%2$s%1$s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00First Hit\124r:*?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00BOSS第一个目标\124r:%s"
+L["opt_tweaks_firsthit_desc"] = "发布一条信息,显示是谁施放了第一次攻击。\n仅对首领战有效。"
+L["Filter DPS meters Spam"] = "过滤DPS统计的垃圾信息"
+L["opt_tweaks_spamage_desc"] = "阻止来自于伤害统计插件的聊天信息,并提供一条简单的聊天链接,在弹出窗口中显示伤害统计信息。"
+L["Reported by: %s"] = "报告者:%s"
+L["Smart Stop"] = "智能停止"
+L["opt_tweaks_smarthalt_desc"] = "首领死亡后自动停止当前分段。\n有助于避免在发生战斗BUG时收集数据。"
+L["Duration"] = "等待時間"
+L["opt_tweaks_smartwait_desc"] = "Skada 在停止该区段之前应等待多长时间。"
+L["Modes Icons"] = "模式图标"
+L["Show modes icons on bars and menus."] = "在统计条和菜单上显示模式图标。"
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "如果您想忽略\124cffffbb00%s\124r,请启用此功能。"
+L["Custom Colors"] = "定制色彩"
+L["Arena Teams"] = "竞技场队伍"
+L["Are you sure you want to reset all colors?"] = "确定要重置所有颜色?"
+L["Announce %s"] = "宣布:%s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "宣布施放 %d 层 %s 所用的时间,并宣布它何时过期。"
+L["%s dropped from %s!"] = "%s 已于 %s 过期!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%4$s 秒内将 %1$s 叠 %2$s 涂抹在 %3$s 上!"
+L["My Spells"] = "我的技能"
+-- total data options
+L["Total Segment"] = "总区段" -- needs review
+L["All Segments"] = "所有区段" -- needs review
+L["Raid Bosses"] = "突袭首领" -- needs review
+L["Raid Trash"] = "突袭垃圾" -- needs review
+L["Dungeon Bosses"] = "地牢首领" -- needs review
+L["Dungeon Trash"] = "地牢垃圾" -- needs review
+L["opt_tweaks_total_all_desc"] = "将所有段添加到总区段的数据中。" -- needs review
+L["opt_tweaks_total_fmt_desc"] = "将带有 %s 的段添加到总区段的数据中。" -- needs review
+L["Detailed total segment"] = "详细的总区段"
+-- L["opt_tweaks_total_full_desc"] = "When enabled, Skada will record everything to the total segment, instead of total numbers (record spell details, their targets as their sources)."
+-- arena
+L["mod_pvp_desc"] = "为竞技场和战场增加了专业化检测,并在同一窗口上显示竞技场的对手。"
+L["Gold Team"] = "金队"
+L["Green Team"] = "绿队"
+L["Color for %s."] = "%s 的颜色。"
+-- notifications
+L["Notifications"] = "通知"
+L["opt_toast_desc"] = "在适用时使用视觉通知而不是聊天窗口消息。"
+L["Test Notifications"] = "测试通知"
+-- comparison module
+L["Comparison"] = "比较"
+L["%s vs %s: %s"] = "%s 与 %s:%s"
+L["%s vs %s: Spells"] = "%s 与 %s:法术"
+L["%s vs %s: Targets"] = "%s 与 %s:目标"
+-- spellcast module
+L["Casts"] = "施放"
+L["%s's spells"] = "%s的咒语"
+L["%s's spells on %s"] = "%s 对 %s 的咒语"
+L["Spells on %s"] = "%s 上的咒语"
+-- about
+L["Author"] = "作者"
+L["Credits"] = "鸣谢"
+L["Date"] = "日期"
+L["License"] = "许可"
+L["Version"] = "版本"
+L["Website"] = "网站"
+-- some bosses entries
+L["World Boss"] = "世界首领"
+L["Auriaya"] = "欧尔莉亚"
+L["Blood Prince Council"] = "鲜血王子议会"
+L["Faction Champions"] = "阵营冠军"
+L["Hogger"] = "霍格"
+L["Icecrown Gunship Battle"] = "冰冠炮舰战斗"
+L["Kologarn"] = "科隆加恩"
+L["Mimiron"] = "米米尔隆"
+L["Thaddius"] = "塔迪乌斯"
+L["The Four Horsemen"] = "四骑士"
+L["The Iron Council"] = "钢铁议会"
+L["The Northrend Beasts"] = "诺森德猛兽"
+L["Thorim"] = "托里姆"
+L["Twin Val'kyr"] = "瓦格里双子"
+L["Valithria Dreamwalker"] = "踏梦者瓦莉瑟瑞娅"
+L["Yogg-Saron"] = "尤格-萨隆"
diff --git a/Skada/Locales/zhTW.lua b/Skada/Locales/zhTW.lua
new file mode 100644
index 0000000..d6e68ea
--- /dev/null
+++ b/Skada/Locales/zhTW.lua
@@ -0,0 +1,754 @@
+local L = LibStub("AceLocale-3.0"):NewLocale(..., "zhTW")
+if not L then return end
+
+L["A damage meter."] = "模組化的傷害統計。"
+L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."] = "記憶體使用過高,你或許想要重置Skada,並且啟用一個自動重設的選項。"
+L["Skada is out of date. You can download the newest version from \124cffffbb00%s\124r"] = "Skada 已過期. 你可以在 \124cffffbb00%s\124r 下載到最新的版本."
+L["Skada: Modes"] = "Skada:模組"
+L["Skada: Fights"] = "Skada:戰鬥"
+L["Data Collection"] = "數據收集"
+L["ENABLED"] = "啟用"
+L["DISABLED"] = "停用"
+L["Enable All"] = "全部啟用"
+L["Disable All"] = "禁用所有"
+L["Stopping for wipe."] = "因擦拭而停止。"
+L["Usage:"] = "利用:"
+L["Commands:"] = "指令:"
+L["Import"] = "导入"
+L["Export"] = "导出"
+L["Import/Export"] = "导入/导出"
+-- profiles
+L["Profiles"] = "設定檔"
+L["Profile Import/Export"] = "匯入/匯出設定檔"
+L["Import Profile"] = "匯入設定檔"
+L["Export Profile"] = "匯出設定檔"
+L["Paste here a profile in text format."] = "將設定檔以文字格式貼在這。"
+L["Press CTRL-V to paste the text from your clipboard."] = "按下 CTRL-V 從剪貼板粘貼文本。"
+L["This is your current profile in text format."] = "這是你目前的設定文字."
+L["Press CTRL-C to copy the text to your clipboard."] = "按下 CTRL-C 將文本複製到剪貼板。"
+L["Network Sharing"] = "網絡共享"
+L["Player Name"] = "選手姓名"
+L["Send Profile"] = "發送個人資料"
+L["Accept profiles from other players."] = "接受来自其他玩家的个人资料。"
+L["opt_profile_received"] = "%s 發送一份設定檔給你,你是否想啟用他?"
+L["Progress"] = "進展"
+L["Data Size: \124cffffffff%.1f\124rKB"] = "資料量:\124cffffffff%.1f\124rKB"
+L["Transmision Progress: %02.f%%"] = "傳輸進度:%d%%"
+L["Transmission Completed"] = "傳輸完成"
+-- common lines
+L["Options"] = "選項"
+L["Options for %s."] = "%s狀態的選項。"
+L["General"] = "一般"
+L["General options for %s."] = "%s 的常規選項。"
+L["Text"] = "文本"
+L["Text options for %s."] = "%s 的文本選項。"
+L["Format"] = "格式"
+L["Format options for %s."] = "%s 的格式選項。"
+L["Appearance"] = "外貌"
+L["Appearance options for %s."] = "%s 的外觀選項。"
+L["Advanced"] = "進階"
+L["Advanced options for %s."] = "%s 的高級選項。"
+L["Position"] = "位置"
+L["Position settings for %s."] = "%s 的位置選項。"
+L["Width"] = "寬度"
+L["The width of %s."] = "%s 的寬度。"
+L["Height"] = "高度"
+L["The height of %s."] = "%s 的高度。"
+L["Active Time"] = "活躍時間"
+L["Segment Time"] = "分段時間"
+L["Click for \124cff00ff00%s\124r"] = "點擊後為 \124cff00ff00%s\124r"
+L["Shift-Click for \124cff00ff00%s\124r"] = "Shift+點擊後為 \124cff00ff00%s\124r"
+L["Control-Click for \124cff00ff00%s\124r"] = "Ctrl+點擊後為 \124cff00ff00%s\124r"
+L["Alt-Click for \124cff00ff00%s\124r"] = "Alt+點擊後為 \124cff00ff00%s\124r"
+L["Toggle Class Filter"] = "按类筛选"
+L["Average"] = "平均"
+L["Count"] = "計數"
+L["Refresh"] = "刷新"
+L["Percent"] = "百分比"
+L["sPercent"] = "百分比 (子模塊)"
+L["General Options"] = "一般選項"
+L["HoT"] = "治療/跳"
+L["DoT"] = "傷害/跳"
+L["Hits"] = "命中"
+L["Normal Hits"] = "一般命中"
+L["Critical"] = "致命"
+L["Critical Hits"] = "致命一擊"
+L["Crushing"] = "碾壓"
+L["Glancing"] = "偏斜"
+L["ABSORB"] = "吸收"
+L["BLOCK"] = "格檔"
+L["DEFLECT"] = "避開"
+L["DODGE"] = "閃躲"
+L["EVADE"] = "閃避"
+L["IMMUNE"] = "免疫"
+L["MISS"] = "未擊中"
+L["PARRY"] = "招架"
+L["REFLECT"] = "反射"
+L["RESIST"] = "抵制"
+L["Only for bosses."] = "只針對老闆。"
+L["Enable this only against bosses."] = "只對老闆啟用此。"
+-- segment info
+L["Start"] = "開始"
+L["End"] = "結束"
+-- windows section:
+L["Window"] = "視窗"
+L["Windows"] = "視窗"
+L["Create Window"] = "建立視窗"
+L["Window Name"] = "窗口名稱"
+L["Enter the name for the new window."] = "為新視窗輸入名稱。"
+L["Delete Window"] = "刪除視窗"
+L["Choose the window to be deleted."] = "選擇的視窗已刪除。"
+L["Are you sure you want to delete this window?"] = "確定要刪除此窗口?"
+L["Delete All Windows"] = "刪除所有窗口"
+L["Are you sure you want to delete all windows?"] = "您確定要刪除所有視窗嗎?"
+L["Rename Window"] = "重新命名視窗"
+L["Enter the name for the window."] = "輸入視窗名稱。"
+L["Test Mode"] = "測試模式"
+L["Creates fake data to help you configure your windows."] = "創建虛假數據以幫助您配置窗口。"
+L["Child Window"] = "子窗口"
+L["A child window will replicate the parent window actions."] = "子窗口將復制父窗口的動作。"
+-- L["Child Window Mode"] = ""
+L["Lock Window"] = "鎖定視窗"
+L["Locks the bar window in place."] = "鎖定計量條視窗位置。"
+L["Hide Window"] = "隱藏視窗"
+L["Hides the window."] = "隱藏此窗口。"
+L["Sticky Window"] = "粘窗"
+L["Allows the window to stick to other Skada windows."] = "允許窗口捕捉到其他Skada窗口。"
+L["Snap to best fit"] = "適合比例"
+L["Snaps the window size to best fit when resizing."] = "視窗比例自動調整到適合比例。"
+L["Disable Resize Buttons"] = "停用調整大小按鈕"
+L["Resize and lock/unlock buttons won't show up when you hover over the window."] = "將鼠標懸停在窗口上時不會出現調整大小和鎖定/解鎖。"
+L["Disable stretch button"] = "禁用拉伸按鈕"
+L["Stretch button won't show up when you hover over the window."] = "當您將鼠標懸停在窗口上時,不會顯示拉伸按鈕。"
+L["Reverse window stretch"] = "向下拉伸窗口"
+L["opt_botstretch_desc"] = "将拉伸按钮放置在窗口底部,并使后者向下拉伸。"
+L["Display System"] = "顯示方式"
+L["Choose the system to be used for displaying data in this window."] = "在視窗中選擇顯示資料的使用方式。"
+L["Copy Settings"] = "複製設定"
+L["Choose the window from which you want to copy the settings."] = "選擇要從中復制設置的窗口。"
+-- bars
+L["Bars"] = "計量條"
+L["Left Text"] = "左文字"
+L["Right Text"] = "右文字"
+L["Font"] = "字體"
+L["The font used by %s."] = "%s 使用的字體。"
+L["Font Size"] = "字體大小"
+L["The font size of %s."] = "%s 的字體大小。"
+L["Font Outline"] = "字体轮廓"
+L["Sets the font outline."] = "設置字體輪廓。"
+L["Outline"] = "輪廓"
+L["Thick"] = "粗"
+L["Thick outline"] = "粗體"
+L["Monochrome"] = "單色"
+L["Outlined monochrome"] = "單色字體"
+L["Bar Texture"] = "計量條的材質"
+L["The texture used by all bars."] = "所有計量條使用這個材質。"
+L["Spacing"] = "間距"
+L["Distance between %s."] = "%s 之間的距離。"
+L["Displacement"] = "位移"
+L["The distance between the edge of the window and the first bar."] = "窗口邊緣與第一個欄之間的距離。"
+L["Bar Orientation"] = "計量條的方向"
+L["The direction the bars are drawn in."] = "計量條的增長方向。"
+L["Left to right"] = "由左到右"
+L["Right to left"] = "由右到左"
+L["Reverse bar growth"] = "計量條反向增長"
+L["Bars will grow up instead of down."] = "計量條將向上增長。"
+L["Disable bar highlight"] = "禁用計量條高亮"
+L["Hovering a bar won't make it brighter."] = "鼠標懸浮在計量條上不會高亮顯示。"
+L["Bar Color"] = "計量條的顏色"
+L["Choose the default color of the bars."] = "變更計量條預設的顏色。"
+L["Background Color"] = "背景的顏色"
+L["The color of the background."] = "背景的顏色。"
+L["Custom Color"] = "自定義顏色"
+L["Use a different color for my bar."] = "為我的酒吧使用不同的顏色。"
+L["My Color"] = "我的顏色"
+L["Spell school colors"] = "法術派別顏色"
+L["Use spell school colors where applicable."] = "適合的法術使用派別顏色。"
+L["When possible, bars will be colored according to player class."] = "依照玩家職業來調整計量條的顏色。"
+L["When possible, bar text will be colored according to player class."] = "依照玩家職業來調整計量條文字的顏色。"
+L["Class Icons"] = "職業圖示"
+L["Use class icons where applicable."] = "使用職業圖示(如果適用)."
+L["Spec Icons"] = "天賦圖標"
+L["Use specialization icons where applicable."] = "在適用處使用天賦圖標。"
+L["Role Icons"] = "角色類型圖標"
+L["Use role icons where applicable."] = "使用適用的角色類型圖標。"
+L["Show Spark Effect"] = "顯示觸發效果"
+L["Click Through"] = "點擊穿透"
+L["Disables mouse clicks on bars."] = "在計量條上停用滑鼠點擊。"
+L["Smooth Bars"] = "平滑計量條"
+L["Animate bar changes smoothly rather than immediately."] = "計量條動態平滑變化而非立即的。"
+-- title bar
+L["Title Bar"] = "標題條"
+L["Enables the title bar."] = "啟用標題條。"
+L["Include set"] = "包含設定"
+L["Include set name in title bar"] = "在標題欄包含設定名稱"
+L["Encounter Timer"] = "首領戰鬥計時器"
+L["When enabled, a stopwatch is shown on the left side of the text."] = "如果開啟,在文字的左側將出現一個計時器"
+L["Mode Icon"] = "模式圖標"
+L["Shows mode's icon in the title bar."] = "在標題欄中顯示模式的圖標。"
+L["The texture used as the background of the title."] = "使用於標題的背景材質。"
+L["Border texture"] = "邊框的材質"
+L["The texture used for the borders."] = "使用於邊框的材質。"
+L["Border Color"] = "外框顏色"
+L["The color used for the border."] = "使用在外框的顏色。"
+L["Buttons"] = "按鈕"
+L["Auto Hide Buttons"] = "自動隱藏按鈕"
+L["Show window buttons only if the cursor is over the title bar."] = "仅当光标在标题栏上方时才显示窗口按钮。"
+L["Buttons Style"] = "按鈕樣式"
+-- general window
+L["Background"] = "背景"
+L["Background Texture"] = "背景的材質"
+L["The texture used as the background."] = "使用於背景的材質。"
+L["Tile"] = "標題"
+L["Tile the background texture."] = "標題的背景材質。"
+L["Tile Size"] = "標題大小"
+L["The size of the texture pattern."] = "材質圖案的大小"
+L["Border"] = "外框"
+L["Border Thickness"] = "邊框的厚度"
+L["The thickness of the borders."] = "邊框的厚度。"
+L["Border Insets"] = "邊界距離"
+L["The distance between the window and its border."] = "窗口和它的边界之间的距离。"
+L["Scale"] = "比例"
+L["Sets the scale of the window."] = "設定視窗比例。"
+L["Strata"] = "層級"
+L["This determines what other frames will be in front of the frame."] = "這決定了那些其他的框架會在此框架之前。"
+L["Clamped To Screen"] = "限制在螢幕內"
+L["Toggle whether to permit movement out of screen."] = "打開/關閉是否允許把框架移到超出螢幕的位置。"
+L["X Offset"] = "水平位置"
+L["Y Offset"] = "垂直位置"
+-- switching
+L["Mode Switching"] = "轉換模組"
+L["Combat Mode"] = "戰鬥模組"
+L["opt_combatmode_desc"] = "當進入戰鬥時,自動切換\124cffffbb00目前的\124r以及選擇的模組。"
+L["Wipe Mode"] = "清除模組"
+L["opt_wipemode_desc"] = "清除後,自動切換至\124cffffbb00目前的\124r模組。"
+L["Return after combat"] = "戰鬥後返回"
+L["Return to the previous set and mode after combat ends."] = "戰鬥結束後返回原先的設定和模組。"
+L["Auto switch to current"] = "自動轉換到目前"
+L["opt_autocurrent_desc"] = "不管何時進入戰鬥,這個視窗會自動切換到\124cffffbb00目前的\124r片段"
+L["Auto Hide"] = "自動隱藏"
+L["While in combat"] = "戰鬥中"
+L["While out of combat"] = "脫離戰鬥"
+L["While not in a group"] = "當不在隊伍時"
+L["While inside an instance"] = "當在副本時"
+L["While not inside an instance"] = "當不在副本時"
+L["In Battlegrounds"] = "戰場"
+L["Inline Bar Display"] = "內置條顯示"
+L["mod_inline_desc"] = "內置顯示是一個水平視窗樣式。"
+L["Font Color"] = "文字顏色"
+L["Font Color.\nClick \"Class Colors\" to begin."] = "字體的顏色。\n點擊“班級顏色”開始。"
+L["opt_barwidth_desc"] = "統計條的寬度。此項僅在“固定統計條寬度”選項啟用後生效。"
+L["Fixed bar width"] = "固定條列寬度"
+L["opt_fixedbarwidth_desc"] = "勾選後,條列寬度將會固定。否則條列寬度取決於文字寬度。"
+L["Use class colors for %s."] = "對 %s 使用類顏色。"
+L["opt_isusingclasscolors_desc"] = "和:%s - 5.71M (21.7K)\n沒:%s - 5.71M (21.7K)"
+L["Put values on new line."] = "提行顯示數值"
+L["opt_isonnewline_desc"] = "提行:\n%1$s\n5.71M (21.7K)\n\n單行:\n%1$s - 5.71M (21.7K)"
+L["Use ElvUI skin if avaliable."] = "可用時使用ElvUI皮膚。"
+L["opt_isusingelvuiskin_desc"] = "勾選此項以使用ElvUI皮膚。\n默認:勾選"
+L["Use solid background."] = "使用純色背景。"
+L["Un-check this for an opaque background."] = "不勾選此項將使用不透明背景。"
+L["Data Text"] = "數據文字"
+L["mod_broker_desc"] = "數據文字行為類似LDB數據輸出。它可以整合在任何像是泰坦面板與巧克力棒的LDB顯示中。它也有一個可選的內部框架。"
+L["Use frame"] = "使用窗口"
+L["opt_useframe_desc"] = "顯示一個獨立的框架。 如果您使用的是 LDB 顯示提供程序,例如 Titan Panel 或 ChocolateBar,則不需要。"
+L["Text Color"] = "文字顏色"
+L["Choose the default color."] = "選擇預設顏色。"
+L["Hint: Left-Click to set active mode."] = "提示:左鍵點擊來設定啟動模式。"
+L["Right-Click to set active set."] = "右鍵點擊設定啟動設置。"
+L["Shift+Left-Click to open menu."] = "Shift+左鍵點擊開啟選單。"
+-- data resets
+L["Data Resets"] = "資料重置"
+L["Reset on entering instance"] = "進入副本時重置"
+L["Controls if data is reset when you enter an instance."] = "當你進入副本時資料是否要重置。"
+L["Reset on joining a group"] = "加入團體時重置"
+L["Controls if data is reset when you join a group."] = "當你加入團體時資料是否要重置。"
+L["Reset on leaving a group"] = "離開團體時重置"
+L["Controls if data is reset when you leave a group."] = "當你離開團體時控制資料是否要重置。"
+L["Ask"] = "詢問"
+L["Do you want to reset Skada?\nHold SHIFT to reset all data."] = "你要重置Skada嗎?\n按住 SHIFT 重置所有。"
+L["All data has been reset."] = "所有資料已重置。"
+L["There is no data to reset."] = "沒有要重置的數據。"
+L["Skip reset dialog"] = "跳過重置確認"
+L["opt_skippopup_desc"] = "如果您希望 Skada 在沒有確認對話框的情況下重置,請啟用此選項。"
+L["Are you sure you want to reinstall Skada?"] = "您確定要重新安裝 Skada 嗎?"
+-- general options
+L["Show minimap button"] = "顯示小地圖按鈕"
+L["Toggles showing the minimap button."] = "切換顯示小地圖按鈕。"
+L["Transliterate"] = "音譯"
+L["Converts Cyrillic letters into Latin letters."] = "將西里爾字母轉換為拉丁字母。"
+L["Remove realm name"] = "移除伺服器名"
+L["opt_realmless_desc"] = "如果開啟,將不會顯示角色的伺服器名。"
+L["Merge pets"] = "合併寵物"
+L["Merges pets with their owners. Changing this only affects new data."] = "合併寵物與主人的資料,此只影響改變後的資料。"
+L["Show totals"] = "顯示總計"
+L["Shows a extra row with a summary in certain modes."] = "在某些模式顯示額外一行的總計。"
+L["Only keep boss fighs"] = "只保留首領戰"
+L["Boss fights will be kept with this on, and non-boss fights are discarded."] = "保留與首領之間的戰鬥紀錄,與非首領的戰鬥紀錄將會被消除。"
+L["Always save boss fights"] = "總是保留BOSS戰"
+L["Boss fights will be kept with this on and will not be affected by Skada reset."] = "啟用後BOSS戰將被保存,不會受到Skada重置的影響。"
+L["Hide when solo"] = "單練時隱藏"
+L["Hides Skada's window when not in a party or raid."] = "當不在隊伍或團隊時隱藏Skada的視窗。"
+L["Hide in PvP"] = "在PvP中隱藏"
+L["Hides Skada's window when in Battlegrounds/Arenas."] = "當處於戰場/競技場時隱藏Skada的視窗。"
+L["Hide in combat"] = "戰鬥中隱藏"
+L["Hides Skada's window when in combat."] = "當處於戰鬥狀態時隱藏Skada的視窗。"
+L["Show in combat"] = "在戰鬥中顯示"
+L["Shows Skada's window when in combat."] = "在戰鬥中顯示Skada窗口。"
+L["Disable while hidden"] = "停用時隱藏"
+L["Skada will not collect any data when automatically hidden."] = "當自動隱藏時,Skada將不會紀錄任何資料。"
+L["Sort modes by usage"] = "根據使用率對模組排序"
+L["The mode list will be sorted to reflect usage instead of alphabetically."] = "模組列表將依照使用率排序而非字母順序"
+L["Show rank numbers"] = "顯示排名"
+L["Shows numbers for relative ranks for modes where it is applicable."] = "在模組適當位置顯示相對排名。"
+L["Aggressive combat detection"] = "雜兵戰鬥檢測"
+L["opt_tentativecombatstart_desc"] = [[Skada在團隊副本中經常性的使用一種非常傳統(簡易)的戰鬥檢測機制。勾選此選項Skada將嘗試模仿其他的傷害統計插件,使其有效運用在雜兵戰, 但與首領戰則是無效的。]]
+L["Autostop"] = "自動停止"
+L["opt_autostop_desc"] = "當有一半以上的團員已死時自動停止當前區段。"
+L["Always show self"] = "總是顯示自己"
+L["opt_showself_desc"] = "保持玩家顯示在最後即使沒有足夠的空間。"
+L["Number format"] = "數字位數"
+L["Controls the way large numbers are displayed."] = "控制數字的顯示位數。"
+L["Condensed"] = "簡易的"
+L["Detailed"] = "詳細的"
+L["Combined"] = "組合的"
+L["Comma"] = "逗號"
+L["Numeral system"] = "數字系統"
+L["Select which numeral system to use."] = "選擇要使用的數字縮寫系統。"
+L["Auto"] = "自動"
+L["Western"] = "西方"
+L["East Asia"] = "亞洲"
+L["Brackets"] = "框架符號"
+L["Choose which type of brackets to use."] = "選擇要使用的括號類型。"
+L["Separator"] = "分隔符號"
+L["Choose which character is used to separator values between brackets."] = "選擇使用哪個字符來分隔括號之間的值。"
+L["Number of decimals"] = "小數位數"
+L["Controls the way percentages are displayed."] = "控制百分比的顯示方式。"
+L["Data Feed"] = "資料來源"
+L["opt_feed_desc"] = "選擇需要顯示在DataBroker上的資料來源。需要一個LDB的顯示插件,例如Titan Panel。"
+L["Time Measure"] = "時間測量方式"
+L["Activity Time"] = "活躍時間"
+L["Effective Time"] = "介面效果微調"
+L["opt_timemesure_desc"] = [=[|cffffff00活躍時間|r: 每一位團隊成員停止活動時,便會暫停各自的計時,並在恢復後再次開始計時。這是用來測量 DPS 和 HPS 最常用的方法。
+
+|cffffff00有效時間|r: 用於排名,此方法會使用整場戰鬥時間來測量所有團隊成員的 DPS 和 HPS。]=]
+L["Number set duplicates"] = "重複數字設置"
+L["Append a count to set names with duplicate mob names."] = "追加一個統計以設置重複的怪物名稱。"
+L["Set Format"] = "設定格式"
+L["Controls the way set names are displayed."] = "控制設定名稱顯示的方式。"
+L["Links in reports"] = "報告中的鏈接"
+L["When possible, use links in the report messages."] = "如果可能,請使用報告消息中的鏈接。"
+L["Segments to keep"] = "保留分段資料"
+L["The number of fight segments to keep. Persistent segments are not included in this."] = "保留多少戰鬥資料分段的數量,不包含連續的片段。"
+L["Persistent segments"] = "持久段"
+L["The number of persistent fight segments to keep."] = "要保留的持久段數。"
+L["Memory Check"] = "內存檢查"
+L["Checks memory usage and warns you if it is greater than or equal to %dmb."] = "檢查內存使用情況並在它大於或等於 %dmb 時向您發出警告。"
+L["Disable Comms"] = "禁用通訊"
+L["Minimum segment length"] = "最小分段長度"
+L["The minimum length required in seconds for a segment to be saved."] = "保存段所需的最小长度(秒)。"
+L["Update frequency"] = "更新頻率"
+L["How often windows are updated. Shorter for faster updates. Increases CPU usage."] = "視窗更新有多頻繁。較短時間更新快速,但增加CPU的負擔。"
+-- columns
+L["Columns"] = "計量條上"
+-- tooltips
+L["Tooltips"] = "提示訊息"
+L["Show Tooltips"] = "顯示提示訊息"
+L["Shows tooltips with extra information in some modes."] = "在一些模組中顯示提示訊息以及額外的訊息。"
+L["Informative Tooltips"] = "提示訊息的資訊"
+L["Shows subview summaries in the tooltips."] = "在提示訊息中顯示即時資訊。"
+L["Subview Rows"] = "資訊行數"
+L["The number of rows from each subview to show when using informative tooltips."] = "當使用提示訊息的資訊時需要多少行數來顯示資訊。"
+L["Tooltip Position"] = "提示訊息的位置"
+L["Position of the tooltips."] = "提示訊息的位置。"
+L["Top Right"] = "右上"
+L["Top Left"] = "左上"
+L["Bottom Right"] = "右下"
+L["Bottom Left"] = "左下"
+L["Smart"] = "智能"
+L["Follow Cursor"] = "跟隨光標"
+L["Top"] = "上"
+L["Bottom"] = "下"
+L["Right"] = "右"
+L["Left"] = "左"
+-- disabled modules
+L["\124cff00ff00Requires\124r: %s"] = "\124cff00ff00需要\124r:%s"
+L["Modules"] = "组件"
+L["Disabled Modules"] = "停用模組"
+L["Modules Options"] = "模塊選項"
+L["Tick the modules you want to disable."] = "勾選您想要停用的模組。"
+L["This change requires a UI reload. Are you sure?"] = "這些改變需要重載UI,你確認嗎?"
+-- themes options
+L["Theme"] = "主題"
+L["Themes"] = "主題"
+L["Manage Themes"] = "管理風格"
+L["All Windows"] = "所有窗口"
+L["Apply Theme"] = "套用主題"
+L["Theme applied!"] = "主題已應用!"
+L["Name of your new theme."] = "你新主題的名稱。"
+L["Save Theme"] = "儲存主題"
+L["Delete Theme"] = "刪除主題"
+L["Are you sure you want to delete this theme?"] = "確定要刪除此樣式嗎?"
+L["Paste here a theme in text format."] = "將風格以文字格式貼在這。"
+L["This is your current theme in text format."] = "這是您當前主題的文本。"
+-- scroll options
+L["Scroll"] = "滾動"
+L["Wheel Speed"] = "鼠標滾輪速度"
+L["opt_wheelspeed_desc"] = "更改鼠標滾輪在視窗上滾動的速度。"
+L["Scroll Icon"] = "滾動圖標"
+L["Scroll mouse button"] = "滾動鼠標按鈕"
+-- minimap button
+L["Skada Summary"] = "Skada一覽"
+L["\124cff00ff00Left-Click\124r to toggle windows."] = "\124cff00ff00左鍵\124r:開關窗口"
+L["\124cff00ff00Ctrl+Left-Click\124r to show/hide windows."] = "\124cff00ff00Ctrl+左鍵點\124r顯示/隱藏窗口。"
+L["\124cff00ff00Shift+Left-Click\124r to reset."] = "\124cff00ff00Shift+左鍵點\124r擊進行重置。"
+L["\124cff00ff00Right-Click\124r to open menu."] = "\124cff00ff00右鍵點擊\124r開啟選單。"
+-- skada menu
+L["Skada Menu"] = "Skada 選單"
+L["Delete Segment"] = "刪除分段資料"
+L["Select Segment"] = "选择细分"
+L["Keep Segment"] = "保留分段資料"
+L["Toggle Windows"] = "切換窗口"
+L["Show/Hide Windows"] = "顯示/隱藏窗口"
+L["New Segment"] = "新段"
+L["Starts a new segment."] = "開始一個新的段。"
+L["New Phase"] = "新階段"
+L["Starts a new phase."] = "開始新的階段。"
+L["Select All"] = "全選"
+L["Deselect All"] = "取消全選"
+-- window buttons
+L["Configure"] = "設定"
+L["Open Config"] = "打開配置"
+L["btn_config_desc"] = "讓你配置此啟用的Skada視窗。"
+L["btn_reset_desc"] = [[除標記為保留外重置全部戰鬥數據。
+|cff00ff00Shift 點擊|r:刪除分段資料。]]
+L["Segment"] = "分段"
+L["btn_segment_desc"] = [[跳至特定區段。
+|cff00ff00Shift 點擊|r:|cffffbb00下一個|r片段。
+|cff00ff00Shift 右鍵單擊|r:|cffffbb00以前的|r片段。
+|cff00ff00中鍵|r:|cffffbb00目前的|r片段。]]
+L["Mode"] = "模組"
+L["Jump to a specific mode."] = "跳至特定模組。"
+L["Report"] = "報告"
+L["btn_report_desc"] = [[打開一個對話框,讓你以各種方式報告數據給他人。
+|cff00ff00Shift-點擊後為|r:快速報告。]]
+L["Stop"] = "停止"
+L["btn_stop_desc"] = "停止或恢復當前區段。用於滅團後停止收集數據。也可在設置中設為自動停止。"
+L["Segment Stopped."] = "段已停止。"
+L["Segment Paused."] = "段已暫停。"
+L["Segment Resumed."] = "段已恢復。"
+L["Quick Access"] = "快速訪問"
+-- default segments
+L["Total"] = "總體的"
+L["Current"] = "目前的"
+-- report module and window
+L["Skada: %s for %s:"] = "Skada:%s來自%s:"
+L["Self"] = "自己"
+L["Whisper Target"] = "悄悄話目標"
+L["Copy & Paste"] = "複製 & 貼上"
+L["[General]"] = "綜合"
+L["[LocalDefense]"] = "本地防務"
+L["[LookingForGroup]"] = "尋求組隊"
+L["[Trade]"] = "交易"
+L["Line"] = "排"
+L["Lines"] = "行數"
+L["There is nothing to report."] = "沒有資料可以報告。"
+L["No mode or segment selected for report."] = "沒有選擇可報告的模組或分段資料。"
+-- Bar Display Module --
+L["Bar Display"] = "顯示計量條"
+L["mod_bar_desc"] = "條列顯示是大多數傷害統計使用的一般條列視窗。它可以是廣泛的樣式。"
+-- Bar Display (Legacy)
+L["Legacy Bar Display"] = "顯示計量條(舊)"
+L["Max Bars"] = "最多計量條數量"
+L["The maximum number of bars shown."] = "顯示最多數量的計量條。"
+L["Show Menu Button"] = "顯示選單按鈕"
+L["Shows a button for opening the menu in the window title bar."] = "在視窗標題條上顯示一個按鈕以開啟選單。"
+L["Class Color Bars"] = "計量條的職業顏色"
+L["Class Color Text"] = "文字的職業顏色"
+-- Threat Module --
+L["Threat"] = "威脅值"
+L["Threat Warning"] = "威脅值的警告"
+L["Flash Screen"] = "螢幕閃爍"
+L["This will cause the screen to flash as a threat warning."] = "威脅值警告時讓螢幕閃爍。"
+L["Shake Screen"] = "螢幕震動"
+L["This will cause the screen to shake as a threat warning."] = "威脅值警告時讓螢幕震動。"
+L["Warning Message"] = "警报消息"
+L["Print a message to screen when you accumulate too much threat."] = "當你仇恨過高時在螢幕上顯示警報消息。"
+L["Play sound"] = "播放音效"
+L["This will play a sound as a threat warning."] = "威脅值警告時會撥放音效。"
+L["Message Output"] = "顯示模式"
+L["Choose where warning messages should be displayed."] = "選擇應在何處顯示警告消息。"
+L["Chat Frame"] = "聊天視窗"
+L["Blizzard Error Frame"] = "Blizzard 錯誤訊息框架"
+L["Threat sound"] = "威脅值的音效"
+L["opt_threat_soundfile_desc"] = "當你的威脅值達到一定的百分比時播放音效。"
+L["Warning Frequency"] = "警告頻率"
+L["Threat Threshold"] = "威脅值的條件"
+L["opt_threat_threshold_desc"] = "當你的威脅值與坦克相同時顯示警告。"
+L["Show raw threat"] = "顯示原始威脅值"
+L["opt_threat_rawvalue_desc"] = "顯示與坦克之間的原始威脅值百分比。"
+L["Use focus target"] = "使用專注目標"
+L["opt_threat_focustarget_desc"] = "讓 Skada 額外檢查您的「focus」和「focus目標」位於「目標」和「目標的目標」之前的順序顯示威脅."
+L["Disable while tanking"] = "當為坦克時關閉警報"
+L["opt_threat_notankwarnings_desc"] = "如果在防禦姿態,熊形態,正義之怒與冰霜系時,不顯示警報."
+L["Ignore Pets"] = "忽略寵物"
+L["opt_threat_ignorepets_desc"] = [=[讓 Skada 忽略敵對玩家寵物以確定顯示哪些單位的威脅。
+
+玩家寵物|cffffff78攻擊|r或者|cffffff78防禦|r狀態保持威脅與正常的怪物相同,正被攻擊目標具有最高的威脅。如果寵物指定攻擊一個具體目標,寵物仍然保持在威脅列表,但保持在指定的目標定義100%威脅之上。玩家寵物可以被嘲諷以攻擊你。
+
+然而,玩家寵物在|cffffff78被動|r模式並沒有威脅列表,嘲諷依然不起作用。它們只攻擊玩家所指定的目標且沒有仇恨列表。
+
+當玩家寵物處於|cffffff78跟隨|r狀態時,寵物的威脅列表被消除並立刻停止攻擊,雖然它可能會立即重新指定目標位於攻擊/防禦模式。]=]
+L["> Pull Aggro <"] = ">獲得仇恨<"
+L["Show Pull Aggro Bar"] = "顯示獲得仇恨棒條"
+L["opt_threat_showaggrobar_desc"] = "顯示獲得仇恨所需威脅數值的棒條。"
+L["Test Warnings"] = "測試警報"
+L["TPS"] = "每秒威脅值"
+L["Threat: Personal Threat"] = "威脅值:個人的威脅值"
+-- Absorbs & Healing Module --
+L["Healing"] = "治療"
+L["Healing Done"] = "造成治療"
+L["Healing Taken"] = "承受治療"
+L["HPS"] = "每秒治療"
+L["sHPS"] = "每秒治療 (子模塊)"
+L["Healing: Personal HPS"] = "治療:個人HPS"
+L["RHPS"] = "RHPS"
+L["Healing: Raid HPS"] = "治療:團隊HPS"
+L["Total Healing"] = "總體治療"
+L["Overheal"] = "過量治療"
+L["Overhealing"] = "過量治療"
+L["Absorbs"] = "吸收量"
+L["Target List"] = "目標清單"
+L["Spell List"] = "法术列表"
+L["APS"] = "每秒吸收"
+L["sAPS"] = "每秒吸收 (子模塊)"
+L["Absorbs and Healing"] = "吸收和治療"
+L["Healing Done By Spell"] = "法術造成的治療"
+L["Source List"] = "源列表"
+-- Auras Module --
+L["Uptime"] = "持續時間"
+L["Buffs and Debuffs"] = "增益和減益"
+L["Buffs"] = "增益"
+L["Debuffs"] = "減益"
+L["%s's <%s> targets"] = "%s的<%s>目標"
+L["%s's <%s> sources"] = "%s的<%s>的來源"
+L["Enemy Buffs"] = "敵人增益"
+L["Enemy Debuffs"] = "敵人減益"
+-- CC Tracker Module --
+L["Crowd Control"] = "控場"
+L["CC Done"] = "施放控場"
+L["CC Taken"] = "受到控場"
+L["CC Breaks"] = "移除控場"
+L["Ignore Main Tanks"] = "忽略主坦克"
+L["%s on %s removed by %s"] = "%s在%s被%s移除了"
+L["%s on %s removed by %s's %s"] = "%s在%s被%s的%s移除了"
+-- Damage Module --
+-- environmental damage
+L["Environment"] = "環境"
+-- damage done module
+L["Damage"] = "傷害"
+L["Spell Details"] = "法術細節"
+L["Damage Done"] = "總傷害"
+L["Useful Damage"] = "有用傷害"
+L["Useful damage on %s"] = "對於%s有用傷害"
+L["Damage Done By Spell"] = "法術造成傷害"
+L["%s's sources"] = "%s的來源"
+L["DPS"] = "每秒傷害"
+L["sDPS"] = "每秒傷害 (子模塊)"
+L["Damage: Personal DPS"] = "傷害:個人的DPS"
+L["RDPS"] = "團隊DPS"
+L["Damage: Raid DPS"] = "傷害:團隊的DPS"
+L["Absorbed Damage"] = "吸收傷害"
+L["Enable this if you want the damage absorbed to be included in the damage done."] = "如果你想包括吸收傷害到造成的傷害啟用此。"
+L["Damage Done By School"] = "学校造成的伤害"
+-- killing blows module
+L["Only PvP Kills"] = "僅限 PvP 殺"
+L["When enabled, only kills against enemy players count."] = "啟用後,僅對敵方玩家進行殺死才算數。"
+L["Announce killing blows after combat ends. Only works for boss fights."] = "戰鬥結束後宣布致命一擊。 僅對Boss有效。"
+-- damage taken module
+L["Damage Taken"] = "承受傷害"
+L["Damage Taken By Spell"] = "承受法術傷害"
+L["%s's targets"] = "%s的目標"
+L["DTPS"] = "每秒承受的傷害"
+L["sDTPS"] = "每秒承受的傷害 (子模塊)"
+-- enemy damage done module
+L["Enemies"] = "敵方"
+L["Enemy Damage Done"] = "敵方的傷害"
+-- enemy damage taken module
+L["Enemy Damage Taken"] = "敵方的承受傷害"
+L["%s below %s%%"] = "%s - %s%%"
+L["%s - %s%% to %s%%"] = "%s - %s%% 到 %s%%"
+L["Phase %s"] = "第 %s 階段"
+L["%s - Phase %s"] = "%s - 第 %s 階段"
+L["%s - Phase 1"] = "%s - 第 1 階段"
+L["%s - Phase 2"] = "%s - 第 2 階段"
+L["%s - Phase 3"] = "%s - 第 3 階段"
+L["%s (Main Boss)"] = "%s (老闆)"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r started."] = "\124cffffbb00%s\124r - \124cff00ff00第 %s\124r 開始。"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r stopped."] = "\124cffffbb00%s\124r - \124cff00ff00第 %s\124r 停止。"
+L["\124cffffbb00%s\124r - \124cff00ff00Phase %s\124r resumed."] = "\124cffffbb00%s\124r - \124cff00ff00第 %s\124r 恢復。"
+-- enemy healing done module
+L["Enemy Healing Done"] = "敵方造成治療"
+-- avoidance and mitigation module
+L["Avoidance & Mitigation"] = "規避和緩解"
+L["More Details"] = "更多細節"
+L["%s's details"] = "%s的細節"
+-- friendly fire module
+L["Friendly Fire"] = "隊友誤傷"
+-- useful damage targets
+L["Important targets"] = "重要目標"
+L["Oozes"] = "滲出"
+L["Princes overkilling"] = "王子過度傷害"
+L["Adds"] = "小怪"
+L["Halion and Inferno"] = "海里昂和地獄火"
+L["Valkyrs overkilling"] = "瓦格里過度傷害"
+-- Deaths Module --
+L["%s's deaths"] = "%s的死亡"
+L["Death log"] = "死亡記錄"
+L["%s's death log"] = "%s的死亡記錄"
+L["Player's deaths"] = "玩家的死亡"
+L["%s dies"] = "%s已死亡"
+L["buff"] = "buff"
+L["debuff"] = "減益"
+L["Spell details"] = "法術細節"
+L["Spell"] = "法術"
+L["Amount"] = "數量"
+L["Source"] = "來源"
+L["Change"] = "變更"
+L["Time"] = "時間"
+L["Survivability"] = "生存"
+L["Events Amount"] = "事件數量"
+L["Set the amount of events the death log should record."] = "設置死亡日誌應記錄的事件數量。"
+L["Minimum Healing"] = "最小癒合"
+L["Ignore heal events that are below this threshold."] = "忽略低於此閾值的修復事件。"
+L["Announce Deaths"] = "宣布死亡"
+L["Announces information about the last hit the player took before they died."] = "宣布玩家死前最後一次命中。"
+L["Alternative Display"] = "另类显示"
+L["If a player dies multiple times, each death will be displayed as a separate bar."] = "如果玩家多次死亡,每次死亡都会显示为单独的条形图。"
+-- activity module
+L["Activity"] = "活躍度"
+L["Activity per Target"] = "每個目標的活動"
+L["%s's activity"] = "%s 的活動"
+-- dispels module lines --
+L["Dispel Spells"] = "驅散咒語"
+L["%s's dispelled spells"] = "%s的已驅散法術"
+-- interrupts module lines --
+L["Interrupt Spells"] = "打斷法術"
+L["%s's interrupted spells"] = "%s的已打斷法術"
+L["%s interrupted!"] = "%s 打斷!"
+-- Power gained module --
+L["Resources"] = "能量"
+L["Mana Restored"] = "法力恢復"
+L["Rage Generated"] = "怒氣生成"
+L["Energy Generated"] = "能量生成"
+L["Runic Power Generated"] = "符能生成"
+-- Parry module lines --
+L["Parry-Haste"] = "招架-急速"
+L["%s parried %s (%s)"] = "%s招架%s (%s)"
+-- Potions module lines --
+L["Potions"] = "藥水"
+L["%s's potions"] = "%s的藥水"
+L["Pre-potion"] = "預使用藥水"
+L["pre-potion: %s"] = "預使用藥水:%s"
+L["Prints pre-potion after the end of the combat."] = "戰鬥結束後發布預使用藥水訊息。"
+-- healthstone --
+L["Healthstones"] = "治療石"
+-- resurrect module lines --
+L["Resurrects"] = "復活"
+-- nickname module lines --
+L["Nickname"] = "暱稱"
+L["Nicknames are sent to group members and Skada can use them instead of your character name."] = "在傳遞Skada數據之時,你的人物名將會被暱稱所代替。"
+L["Set a nickname for you."] = "給你自己設定一個暱稱。"
+L["Nickname isn't a valid string."] = "此暱稱不是有效字符串。"
+L["Your nickname is too long, max of 12 characters is allowed."] = "你的暱稱太長,最多允許12個字符。"
+L["Only letters and two spaces are allowed."] = "僅允許字母及2個空格。"
+L["Your nickname contains a forbidden word."] = "您的暱稱包含禁止詞。"
+L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."] = "同一個字母不能連續使用3次,不能連續使用2個空格且不能超過2個空格。"
+L["Ignore Nicknames"] = "忽略所有昵称"
+L["When enabled, nicknames set by Skada users are ignored."] = "如果启用,则Skada用户设置的所有昵称将被忽略。"
+L["Name display"] = "名字顯示"
+L["Choose how names are shown on your bars."] = "選擇統計條上名字的顯示方式。"
+L["Clear Cache"] = "Clear Cache"
+L["Are you sure you want clear cached nicknames?"] = "您确定要清除缓存的昵称吗?"
+-- overkill module lines --
+L["Overkill"] = "過度損壞"
+-- tweaks module lines --
+L["Improvement"] = "改進"
+L["Tweaks"] = "調整"
+L["First hit"] = "第一擊"
+L["\124cffffff00First Hit\124r: %s from %s"] = "\124cffffff00第一擊\124r:從%2$s%1$s"
+L["\124cffffbb00First Hit\124r: *?*"] = "\124cffffbb00First Hit\124r:*?*"
+L["\124cffffbb00Boss First Target\124r: %s"] = "\124cffffbb00BOSS第一個目標\124r:%s"
+L["opt_tweaks_firsthit_desc"] = "發布一條訊息,顯示是誰施放了第一次攻擊。 \n僅對BOSS戰有效。"
+L["Filter DPS meters Spam"] = "過濾DPS統計的垃圾訊息"
+L["opt_tweaks_spamage_desc"] = "阻止來自於傷害統計插件的聊天訊息,並提供一條簡單的聊天鏈接,在彈出窗口中顯示傷害統計信息。"
+L["Reported by: %s"] = "已回報由%s"
+L["Smart Stop"] = "智能停止"
+L["opt_tweaks_smarthalt_desc"] = "BOSS死亡後自動停止當前分段。 \n有助於避免在發生戰鬥BUG時收集數據。"
+L["Duration"] = "等待時間"
+L["opt_tweaks_smartwait_desc"] = "Skada 在停止該段之前應等待多長時間。"
+L["Modes Icons"] = "模式圖標"
+L["Show modes icons on bars and menus."] = "在欄和菜單上顯示模式圖標。"
+L["Enable this if you want to ignore \124cffffbb00%s\124r."] = "如果您想忽略\124cffffbb00%s\124r,請啟用此功能。"
+L["Custom Colors"] = "定制色彩"
+L["Arena Teams"] = "競技場隊伍"
+L["Are you sure you want to reset all colors?"] = "确定要重置所有颜色?"
+L["Announce %s"] = "宣布:%s"
+L["Announces how long it took to apply %d stacks of %s and announces when it drops."] = "宣布應用 %d 堆 %s 所用的時間,並宣布它何時到期。"
+L["%s dropped from %s!"] = "%s 已於 %s 過期!"
+L["%s stacks of %s applied on %s in %s sec!"] = "%4$s 秒內將 %1$s 疊 %2$s 塗抹在 %3$s 上!"
+L["My Spells"] = "我的法術"
+-- total data options
+L["Total Segment"] = "總段" -- needs review
+L["All Segments"] = "所有段" -- needs review
+L["Raid Bosses"] = "突襲首領" -- needs review
+L["Raid Trash"] = "突襲垃圾" -- needs review
+L["Dungeon Bosses"] = "地牢首領" -- needs review
+L["Dungeon Trash"] = "地牢垃圾" -- needs review
+L["opt_tweaks_total_all_desc"] = "将所有段添加到总段的数据中。" -- needs review
+L["opt_tweaks_total_fmt_desc"] = "将带有 %s 的段添加到总段的数据中。" -- needs review
+L["Detailed total segment"] = "詳細的總段"
+-- L["opt_tweaks_total_full_desc"] = "When enabled, Skada will record everything to the total segment, instead of total numbers (record spell details, their targets as their sources)."
+-- arena
+L["mod_pvp_desc"] = "為競技場和戰場添加專業化檢測,並在同一窗口顯示競技場對手。"
+L["Gold Team"] = "金隊"
+L["Green Team"] = "綠隊"
+L["Color for %s."] = "%s 的顏色。"
+-- notifications
+L["Notifications"] = "通知"
+L["opt_toast_desc"] = "在適用時使用視覺通知而不是聊天窗口消息。"
+L["Test Notifications"] = "測試通知"
+-- comparison module
+L["Comparison"] = "比較"
+L["%s vs %s: %s"] = "%s 與 %s:%s"
+L["%s vs %s: Spells"] = "%s 與 %s:法術"
+L["%s vs %s: Targets"] = "%s 與 %s:目標"
+-- spellcast module
+L["Casts"] = "施法"
+L["%s's spells"] = "%s的咒語"
+L["%s's spells on %s"] = "%s 的 %s 咒語"
+L["Spells on %s"] = "%s 上的咒語"
+-- about
+L["Author"] = "作者"
+L["Credits"] = "貢獻者"
+L["Date"] = "日期"
+L["License"] = "授權"
+L["Version"] = "版本"
+L["Website"] = "網站"
+-- some bosses entries
+L["World Boss"] = "世界首領"
+L["Auriaya"] = "奧芮雅"
+L["Blood Prince Council"] = "血親王議會"
+L["Faction Champions"] = "陣營勇士"
+L["Hogger"] = "霍格"
+L["Icecrown Gunship Battle"] = "寒冰皇冠空中艦艇戰"
+L["Kologarn"] = "柯洛剛恩"
+L["Mimiron"] = "彌米倫"
+L["Thaddius"] = "泰迪斯"
+L["The Four Horsemen"] = "四騎士"
+L["The Iron Council"] = "鐵之集會"
+L["The Northrend Beasts"] = "北裂境巨獸"
+L["Thorim"] = "索林姆"
+L["Twin Val'kyr"] = "華爾琪雙子"
+L["Valithria Dreamwalker"] = "瓦莉絲瑞雅·夢行者"
+L["Yogg-Saron"] = "尤格薩倫"
diff --git a/Skada/Media/Border/Glow.tga b/Skada/Media/Border/Glow.tga
new file mode 100644
index 0000000..62905cc
Binary files /dev/null and b/Skada/Media/Border/Glow.tga differ
diff --git a/Skada/Media/Border/Roth.tga b/Skada/Media/Border/Roth.tga
new file mode 100644
index 0000000..5cc2703
Binary files /dev/null and b/Skada/Media/Border/Roth.tga differ
diff --git a/Skada/Media/Fonts/ABF.ttf b/Skada/Media/Fonts/ABF.ttf
new file mode 100644
index 0000000..ce9546b
Binary files /dev/null and b/Skada/Media/Fonts/ABF.ttf differ
diff --git a/Skada/Media/Fonts/Accidental Presidency.ttf b/Skada/Media/Fonts/Accidental Presidency.ttf
new file mode 100644
index 0000000..8677fbc
Binary files /dev/null and b/Skada/Media/Fonts/Accidental Presidency.ttf differ
diff --git a/Skada/Media/Fonts/Adventure.ttf b/Skada/Media/Fonts/Adventure.ttf
new file mode 100644
index 0000000..0a460c4
Binary files /dev/null and b/Skada/Media/Fonts/Adventure.ttf differ
diff --git a/Skada/Media/Fonts/Diablo.ttf b/Skada/Media/Fonts/Diablo.ttf
new file mode 100644
index 0000000..aff5d96
Binary files /dev/null and b/Skada/Media/Fonts/Diablo.ttf differ
diff --git a/Skada/Media/Fonts/FORCED SQUARE.ttf b/Skada/Media/Fonts/FORCED SQUARE.ttf
new file mode 100644
index 0000000..f9a7bd2
Binary files /dev/null and b/Skada/Media/Fonts/FORCED SQUARE.ttf differ
diff --git a/Skada/Media/Fonts/Hooge.TTF b/Skada/Media/Fonts/Hooge.TTF
new file mode 100644
index 0000000..d10a4f1
Binary files /dev/null and b/Skada/Media/Fonts/Hooge.TTF differ
diff --git a/Skada/Media/Statusbar/Aluminium.tga b/Skada/Media/Statusbar/Aluminium.tga
new file mode 100644
index 0000000..058a950
Binary files /dev/null and b/Skada/Media/Statusbar/Aluminium.tga differ
diff --git a/Skada/Media/Statusbar/Armory.tga b/Skada/Media/Statusbar/Armory.tga
new file mode 100644
index 0000000..a8bd1a9
Binary files /dev/null and b/Skada/Media/Statusbar/Armory.tga differ
diff --git a/Skada/Media/Statusbar/BantoBar.tga b/Skada/Media/Statusbar/BantoBar.tga
new file mode 100644
index 0000000..1f001b9
Binary files /dev/null and b/Skada/Media/Statusbar/BantoBar.tga differ
diff --git a/Skada/Media/Statusbar/Flat.tga b/Skada/Media/Statusbar/Flat.tga
new file mode 100644
index 0000000..3b86aa2
Binary files /dev/null and b/Skada/Media/Statusbar/Flat.tga differ
diff --git a/Skada/Media/Statusbar/Gloss.tga b/Skada/Media/Statusbar/Gloss.tga
new file mode 100644
index 0000000..8a1dd5b
Binary files /dev/null and b/Skada/Media/Statusbar/Gloss.tga differ
diff --git a/Skada/Media/Statusbar/Graphite.tga b/Skada/Media/Statusbar/Graphite.tga
new file mode 100644
index 0000000..b72a598
Binary files /dev/null and b/Skada/Media/Statusbar/Graphite.tga differ
diff --git a/Skada/Media/Statusbar/Grid.tga b/Skada/Media/Statusbar/Grid.tga
new file mode 100644
index 0000000..a2bc7fc
Binary files /dev/null and b/Skada/Media/Statusbar/Grid.tga differ
diff --git a/Skada/Media/Statusbar/Healbot.tga b/Skada/Media/Statusbar/Healbot.tga
new file mode 100644
index 0000000..6999b0e
Binary files /dev/null and b/Skada/Media/Statusbar/Healbot.tga differ
diff --git a/Skada/Media/Statusbar/LiteStep.tga b/Skada/Media/Statusbar/LiteStep.tga
new file mode 100644
index 0000000..488c265
Binary files /dev/null and b/Skada/Media/Statusbar/LiteStep.tga differ
diff --git a/Skada/Media/Statusbar/Minimalist.tga b/Skada/Media/Statusbar/Minimalist.tga
new file mode 100644
index 0000000..030bc83
Binary files /dev/null and b/Skada/Media/Statusbar/Minimalist.tga differ
diff --git a/Skada/Media/Statusbar/Otravi.tga b/Skada/Media/Statusbar/Otravi.tga
new file mode 100644
index 0000000..d33bc54
Binary files /dev/null and b/Skada/Media/Statusbar/Otravi.tga differ
diff --git a/Skada/Media/Statusbar/Outline.tga b/Skada/Media/Statusbar/Outline.tga
new file mode 100644
index 0000000..d79f519
Binary files /dev/null and b/Skada/Media/Statusbar/Outline.tga differ
diff --git a/Skada/Media/Statusbar/Round.tga b/Skada/Media/Statusbar/Round.tga
new file mode 100644
index 0000000..d61db5b
Binary files /dev/null and b/Skada/Media/Statusbar/Round.tga differ
diff --git a/Skada/Media/Statusbar/Serenity.tga b/Skada/Media/Statusbar/Serenity.tga
new file mode 100644
index 0000000..12fd5af
Binary files /dev/null and b/Skada/Media/Statusbar/Serenity.tga differ
diff --git a/Skada/Media/Statusbar/Smooth.tga b/Skada/Media/Statusbar/Smooth.tga
new file mode 100644
index 0000000..9ad81ad
Binary files /dev/null and b/Skada/Media/Statusbar/Smooth.tga differ
diff --git a/Skada/Media/Statusbar/TukTex.tga b/Skada/Media/Statusbar/TukTex.tga
new file mode 100644
index 0000000..2d99837
Binary files /dev/null and b/Skada/Media/Statusbar/TukTex.tga differ
diff --git a/Skada/Media/Textures/icon-scroll.tga b/Skada/Media/Textures/icon-scroll.tga
new file mode 100644
index 0000000..b14c207
Binary files /dev/null and b/Skada/Media/Textures/icon-scroll.tga differ
diff --git a/Skada/Media/Textures/icons.blp b/Skada/Media/Textures/icons.blp
new file mode 100644
index 0000000..18bb27f
Binary files /dev/null and b/Skada/Media/Textures/icons.blp differ
diff --git a/Skada/Media/Textures/toolbar1/_prev.blp b/Skada/Media/Textures/toolbar1/_prev.blp
new file mode 100644
index 0000000..ae995d9
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/_prev.blp differ
diff --git a/Skada/Media/Textures/toolbar1/config.blp b/Skada/Media/Textures/toolbar1/config.blp
new file mode 100644
index 0000000..cf3d224
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/config.blp differ
diff --git a/Skada/Media/Textures/toolbar1/mode.blp b/Skada/Media/Textures/toolbar1/mode.blp
new file mode 100644
index 0000000..0506f6a
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/mode.blp differ
diff --git a/Skada/Media/Textures/toolbar1/phase.blp b/Skada/Media/Textures/toolbar1/phase.blp
new file mode 100644
index 0000000..173e87c
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/phase.blp differ
diff --git a/Skada/Media/Textures/toolbar1/report.blp b/Skada/Media/Textures/toolbar1/report.blp
new file mode 100644
index 0000000..e8311e2
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/report.blp differ
diff --git a/Skada/Media/Textures/toolbar1/reset.blp b/Skada/Media/Textures/toolbar1/reset.blp
new file mode 100644
index 0000000..7db0eb9
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/reset.blp differ
diff --git a/Skada/Media/Textures/toolbar1/segment.blp b/Skada/Media/Textures/toolbar1/segment.blp
new file mode 100644
index 0000000..763ac3a
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/segment.blp differ
diff --git a/Skada/Media/Textures/toolbar1/split.blp b/Skada/Media/Textures/toolbar1/split.blp
new file mode 100644
index 0000000..f79cff7
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/split.blp differ
diff --git a/Skada/Media/Textures/toolbar1/stop.blp b/Skada/Media/Textures/toolbar1/stop.blp
new file mode 100644
index 0000000..540b4c0
Binary files /dev/null and b/Skada/Media/Textures/toolbar1/stop.blp differ
diff --git a/Skada/Media/Textures/toolbar2/_prev.blp b/Skada/Media/Textures/toolbar2/_prev.blp
new file mode 100644
index 0000000..9375003
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/_prev.blp differ
diff --git a/Skada/Media/Textures/toolbar2/config.blp b/Skada/Media/Textures/toolbar2/config.blp
new file mode 100644
index 0000000..fa01bae
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/config.blp differ
diff --git a/Skada/Media/Textures/toolbar2/mode.blp b/Skada/Media/Textures/toolbar2/mode.blp
new file mode 100644
index 0000000..d043a38
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/mode.blp differ
diff --git a/Skada/Media/Textures/toolbar2/phase.blp b/Skada/Media/Textures/toolbar2/phase.blp
new file mode 100644
index 0000000..c8c9feb
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/phase.blp differ
diff --git a/Skada/Media/Textures/toolbar2/report.blp b/Skada/Media/Textures/toolbar2/report.blp
new file mode 100644
index 0000000..dc287f7
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/report.blp differ
diff --git a/Skada/Media/Textures/toolbar2/reset.blp b/Skada/Media/Textures/toolbar2/reset.blp
new file mode 100644
index 0000000..8da4188
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/reset.blp differ
diff --git a/Skada/Media/Textures/toolbar2/segment.blp b/Skada/Media/Textures/toolbar2/segment.blp
new file mode 100644
index 0000000..946d808
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/segment.blp differ
diff --git a/Skada/Media/Textures/toolbar2/split.blp b/Skada/Media/Textures/toolbar2/split.blp
new file mode 100644
index 0000000..b35ebe6
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/split.blp differ
diff --git a/Skada/Media/Textures/toolbar2/stop.blp b/Skada/Media/Textures/toolbar2/stop.blp
new file mode 100644
index 0000000..ee0e72d
Binary files /dev/null and b/Skada/Media/Textures/toolbar2/stop.blp differ
diff --git a/Skada/Modules/Absorbs.lua b/Skada/Modules/Absorbs.lua
new file mode 100644
index 0000000..82cd723
--- /dev/null
+++ b/Skada/Modules/Absorbs.lua
@@ -0,0 +1,1369 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+-- cache frequently used globals
+local pairs, format, uformat = pairs, string.format, Private.uformat
+local new, del = Private.newTable, Private.delTable
+local PercentToRGB = Private.PercentToRGB
+local tooltip_school = Skada.tooltip_school
+local hits_perc = "%s (\124cffffffff%s\124r)"
+local slash_fmt = "%s/%s"
+
+---------------------------------------------------------------------------
+-- Absorbs Module
+
+Skada:RegisterModule("Absorbs", function(L, P, G)
+ local mode = Skada:NewModule("Absorbs")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ tooltip_school = tooltip_school or Skada.tooltip_school
+ local ignored_spells = Skada.ignored_spells.absorb -- Edit Skada\Core\Tables.lua
+ local passive_spells = Skada.ignored_spells.time -- Edit Skada\Core\Tables.lua
+
+ local band, tsort, max = bit.band, table.sort, math.max
+ local wipe, clear = wipe, Private.clearTable
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local ABSORB_SPELLS = {
+ -- DEATHKNIGHT
+ [48707] = 0x20, -- Anti-Magic Shell
+ [51052] = 0x20, -- Anti-Magic Zone
+ [77535] = 0x20, -- Blood Shield
+ [115635] = 0x01, -- Death Barrier
+ [116888] = 0x20, -- Shroud of Purgatory
+ -- DRUID
+ [62606] = 0x08, -- Savage Defense
+ [28527] = 0x02, -- Fel Blossom
+ -- MAGE
+ [1463] = 0x40, -- Incanter's Ward
+ [11426] = 0x10, -- Ice Barrier
+ -- MONK
+ [115295] = 0x01, -- Guard (Brewmaster)
+ [116849] = 0x08, -- Life Cocoon (Mistweaver)
+ [118604] = 0x01, -- Guard (Brewmaster)
+ [145051] = 0x01, -- Protection of Niuzao
+ [145056] = 0x01, -- Purified Healing
+ [145439] = 0x01, -- Item - Monk T16 Mistweaver 2P Bonus
+ [145441] = 0x08, -- Yu'lon's Barrier
+ -- PALADIN
+ [31850] = 0x01, -- Ardent Defender
+ [65148] = 0x02, -- Sacred Shield
+ [86273] = 0x02, -- Illuminated Healing (Holy)
+ -- PRIEST
+ [17] = 0x02, -- Power Word: Shield (Discipline)
+ [47753] = 0x02, -- Divine Aegis (Discipline)
+ [47788] = 0x02, -- Guardian Spirit
+ [114908] = 0x02, -- Spirit Shell (Discipline)
+ [114214] = 0x02, -- Angelic Bulwark
+ [152118] = 0x02, -- Clarity of Will
+ -- SHAMAN
+ [114893] = 0x08, -- Stone Bulwark (Stone Bulwark Totem Passive)
+ [145378] = 0x01, -- Item - Shaman T16 Restoration 2P Bonus
+ [145379] = 0x08, -- Nature's Barrier
+ -- WARLOCK
+ [6229] = 0x20, -- Twilight Ward
+ [7812] = 0x20, -- Sacrifice
+ [108366] = 0x20, -- Soul Leech
+ [108416] = 0x20, -- Sacrificial Pact
+ [110913] = 0x01, -- Dark Bargain
+ -- WARRIOR
+ [112048] = 0x01, -- Shield Barrier (Protection)
+ [190456] = 0x01, -- Ignore Pain (Protection)
+ -- OTHER
+ [4057] = 0x04, -- Flame Deflector (Fire Resistance)
+ [4077] = 0x10, -- Ice Deflector (Frost Resistance)
+ [7233] = 0x08, -- Fire Protection Potion
+ [7239] = 0x10, -- Frost Protection Potion
+ [7242] = 0x20, -- Shadow Protection Potion
+ [7245] = 0x02, -- Holy Protection Potion
+ [7259] = 0x01, -- Nature Protection Potion
+ [10368] = 0x02, -- Uther's Light Effect
+ [11657] = 0x01, -- Jang'thraze
+ [12561] = 0x04, -- Goblin Construction Helmet (Fire Protection)
+ [17252] = 0x01, -- Mark of the Dragon Lord (LBRS epic ring)
+ [17543] = 0x04, -- Greater Fire Protection Potion
+ [17544] = 0x10, -- Greater Frost Protection Potion
+ [17545] = 0x02, -- Greater Holy Protection Potion
+ [17546] = 0x08, -- Greater Nature Protection Potion
+ [17548] = 0x20, -- Greater Shadow Protection Potion
+ [17549] = 0x04, -- Greater Arcane Protection Potion
+ [21956] = 0x02, -- Mark of Resolution (Physical Protection)
+ [23506] = 0x02, -- Arena Grand Master (Aura of Protection)
+ [23991] = 0x02, -- Defiler's Talisman/Talisman of Arathor
+ [25746] = 0x02, -- Defiler's Talisman/Talisman of Arathor
+ [25747] = 0x02, -- Defiler's Talisman/Talisman of Arathor
+ [25750] = 0x02, -- Defiler's Talisman/Talisman of Arathor
+ [26467] = 0x01, -- Scarab Brooch (Persistent Shield)
+ [27539] = 0x01, -- Thick Obsidian Breatplate (Obsidian Armor)
+ [27779] = 0x02, -- Divine Protection (Priest dungeon set 1/2)
+ [28511] = 0x08, -- Major Fire Protection Potion
+ [28512] = 0x10, -- Major Frost Protection Potion
+ [28513] = 0x08, -- Major Nature Protection Potion
+ [28536] = 0x04, -- Major Arcane Protection Potion
+ [28537] = 0x20, -- Major Shadow Protection Potion
+ [28538] = 0x02, -- Major Holy Protection Potion
+ [28810] = 0x02, -- Faith Set Proc (Armor of Faith)
+ [29432] = 0x04, -- Frozen Rune (Fire Protection)
+ [29506] = 0x02, -- The Burrower's Shell
+ [29674] = 0x40, -- Lesser Ward of Shielding
+ [29701] = 0x40, -- Greater Shielding
+ [29719] = 0x40, -- Greater Ward of Shielding
+ [30994] = 0x10, -- Pendant of Thawing (Frost Absorption)
+ [30997] = 0x04, -- Pendant of Frozen Flame (Fire Absorption)
+ [30999] = 0x08, -- Pendant of Withering (Nature Absorption)
+ [31000] = 0x20, -- Pendant of Shadow's End (Shadow Absorption)
+ [31002] = 0x40, -- Pendant of the Null Rune (Arcane Absorption)
+ [31771] = 0x02, -- Runed Fungalcap (Shell of Deterrence)
+ [36481] = 0x40, -- Arcane Barrier (TK Kael'Thas) Shield
+ [37515] = 0x02, -- Blade Turning
+ [39228] = 0x02, -- Argussian Compass
+ [40322] = 0x10, -- Teron's Vengeful Spirit Ghost - Spirit Shield
+ [42137] = 0x01, -- Greater Rune of Warding
+ [53910] = 0x04, -- Mighty Arcane Protection Potion
+ [53911] = 0x08, -- Mighty Fire Protection Potion
+ [53913] = 0x10, -- Mighty Frost Protection Potion
+ [53914] = 0x08, -- Mighty Nature Protection Potion
+ [53915] = 0x20, -- Mighty Shadow Protection Potion
+ [54808] = 0x01, -- Noise Machine (onic Shield)
+ [55019] = 0x01, -- Sonic Shield
+ [57350] = 0x01, -- Darkmoon Card: Illusion
+ [62618] = 0x02, -- Power Word: Barrier
+ [64413] = 0x08, -- Protection of Ancient Kings (Val'anyr, Hammer of Ancient Kings)
+ [65684] = 0x01, -- Twin Val'kyr: Dark Essence
+ [65686] = 0x01, -- Twin Val'kyr: Light Essence
+ [65858] = 0x04, -- Twin Val'kyr's Shield of Lights
+ [65874] = 0x20, -- Twin Val'kyr's: Shield of Darkness
+ [70845] = 0x01, -- Stoicism
+ [105801] = 0x02, -- Delayed Judgment
+ [105909] = 0x02, -- Shield of Fury
+ [108008] = 0x02,
+ [116631] = 0x02, -- Colossus (Enchant Weapon - Colossus)
+ [138925] = 0x01, -- Zandalari Warding
+ [140380] = 0x01, -- Shield of Hydra Sputum
+ }
+
+ local shields = {} -- holds the list of players shields and other stuff
+ local absorb = {}
+
+ local function format_valuetext(d, total, aps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Absorbs and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sAPS" or "APS"] and aps and Skada:FormatNumber(aps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function log_absorb(set, nocount)
+ if not absorb.amount or absorb.amount == 0 then return end
+
+ local actor = Skada:GetActor(set, absorb.actorname, absorb.actorid, absorb.actorflags)
+ if not actor then
+ return
+ elseif actor.role ~= "DAMAGER" and not passive_spells[absorb.spell] and not nocount then
+ Skada:AddActiveTime(set, actor, absorb.dstName)
+ end
+
+ -- add absorbs amount
+ actor.absorb = (actor.absorb or 0) + absorb.amount
+ set.absorb = (set.absorb or 0) + absorb.amount
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- record the spell
+ local spell = actor.absorbspells and actor.absorbspells[absorb.spellid]
+ if not spell then
+ actor.absorbspells = actor.absorbspells or {}
+ actor.absorbspells[absorb.spellid] = {amount = 0}
+ spell = actor.absorbspells[absorb.spellid]
+ end
+
+ spell.amount = spell.amount + absorb.amount
+
+ if not nocount then
+ spell.count = (spell.count or 0) + 1
+
+ if absorb.critical then
+ spell.c_num = (spell.c_num or 0) + 1
+ spell.c_amt = (spell.c_amt or 0) + absorb.amount
+ if not spell.c_max or absorb.amount > spell.c_max then
+ spell.c_max = absorb.amount
+ end
+ if not spell.c_min or absorb.amount < spell.c_min then
+ spell.c_min = absorb.amount
+ end
+ else
+ spell.n_num = (spell.n_num or 0) + 1
+ spell.n_amt = (spell.n_amt or 0) + absorb.amount
+ if not spell.n_max or absorb.amount > spell.n_max then
+ spell.n_max = absorb.amount
+ end
+ if not spell.n_min or absorb.amount < spell.n_min then
+ spell.n_min = absorb.amount
+ end
+ end
+ end
+
+ -- record the target
+ if not absorb.dstName then return end
+ spell.targets = spell.targets or {}
+ spell.targets[absorb.dstName] = (spell.targets[absorb.dstName] or 0) + absorb.amount
+ end
+
+ -- https://github.com/TrinityCore/TrinityCore/blob/5d82995951c2be99b99b7b78fa12505952e86af7/src/server/game/Spells/Auras/SpellAuraEffects.h#L316
+ local function shields_order_pred(a, b)
+ local a_spellid, b_spellid = a.spellid, b.spellid
+
+ if a_spellid == b_spellid then
+ return (a.ts < b.ts)
+ end
+
+ -- Twin Val'ky
+ if a_spellid == 65686 then
+ return true
+ end
+ if b_spellid == 65686 then
+ return false
+ end
+ if a_spellid == 65684 then
+ return true
+ end
+ if b_spellid == 65684 then
+ return false
+ end
+
+ -- Mage Ward
+ if a_spellid == 543 then
+ return true
+ end
+ if b_spellid == 543 then
+ return false
+ end
+
+ -- Shadow Ward
+ if a_spellid == 6229 then
+ return true
+ end
+ if b_spellid == 6229 then
+ return false
+ end
+
+ -- Sacred Shield | TODO: needs review (96263)
+ if a_spellid == 58597 then
+ return true
+ end
+ if b_spellid == 58597 then
+ return false
+ end
+
+ -- Fel Blossom
+ if a_spellid == 28527 then
+ return true
+ end
+ if b_spellid == 28527 then
+ return false
+ end
+
+ -- Divine Aegis
+ if a_spellid == 47753 then
+ return true
+ end
+ if b_spellid == 47753 then
+ return false
+ end
+
+ -- Ice Barrier
+ if a_spellid == 11426 then
+ return true
+ end
+ if b_spellid == 11426 then
+ return false
+ end
+
+ -- Sacrifice
+ if a_spellid == 7812 then
+ return true
+ end
+ if b_spellid == 7812 then
+ return false
+ end
+
+ -- Delayed Judgement | TODO: needs review
+ if a_spellid == 105801 then
+ return true
+ end
+ if b_spellid == 105801 then
+ return false
+ end
+
+ return (a.ts < b.ts)
+ end
+
+ local function remove_shield(dstName, srcGUID, spellid)
+ shields[dstName] = shields[dstName] or new()
+ for i = 1, #shields[dstName] do
+ local shield = shields[dstName][i]
+ if shield and shield.srcGUID == srcGUID and shield.spellid == spellid then
+ del(tremove(shields[dstName], i))
+ tsort(shields[dstName], shields_order_pred)
+ break
+ end
+ end
+ end
+
+ local function handle_shield(t)
+ if not t.spellid or not ABSORB_SPELLS[t.spellid] or not t.dstName then return end
+
+ local dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+ local srcGUID, srcName, srcFlags = t.srcGUID, t.srcName, t.srcFlags
+
+ -- shield removed?
+ if t.event == "SPELL_AURA_REMOVED" then
+ if shields[dstName] then
+ for i = 1, #shields[dstName] do
+ local shield = shields[dstName][i]
+ if shield and shield.srcGUID == srcGUID and shield.spellid == t.spellid then
+ Skada:ScheduleTimer(remove_shield, 0.1, dstName, srcGUID, t.spellid)
+ break
+ end
+ end
+ end
+ return
+ end
+
+ -- create player's shields table
+ shields[dstName] = shields[dstName] or new()
+
+ -- Soul Link
+ if t.spellid == 25228 then
+ srcGUID, srcName, srcFlags = Skada:FixMyPets(srcGUID, srcName, srcFlags)
+ end
+
+ -- shield refreshed
+ if t.event == "SPELL_AURA_REFRESH" then
+ local index = nil
+ for i = 1, #shields[dstName] do
+ local shield = shields[dstName][i]
+ if shield and shield.srcGUID == srcGUID and shield.spellid == t.spellid then
+ shield.ts = t.timestamp
+ index = i
+ break
+ end
+ end
+
+ -- not found? add it
+ if not index then
+ local shield = new()
+ shield.spellid = t.spellid
+ shield.string = t.spellstring
+ shield.srcGUID = srcGUID
+ shield.srcName = srcName
+ shield.srcFlags = srcFlags
+ shield.ts = t.timestamp
+ shields[dstName][#shields[dstName] + 1] = shield
+ else
+ shields[dstName][index].ts = t.timestamp
+ end
+
+ tsort(shields[dstName], shields_order_pred)
+ else
+ local shield = new()
+ shield.spellid = t.spellid
+ shield.string = t.spellstring
+ shield.srcGUID = srcGUID
+ shield.srcName = srcName
+ shield.srcFlags = srcFlags
+ shield.ts = t.timestamp
+
+ shields[dstName][#shields[dstName] + 1] = shield
+ tsort(shields[dstName], shields_order_pred)
+ end
+ end
+
+ local function process_shield(dstName, spellschool)
+ shields[dstName] = shields[dstName] or new()
+
+ for i = 1, #shields[dstName] do
+ local s = shields[dstName][i]
+ if s and s.spellid == 543 then -- Mage Ward (Mage)
+ if band(spellschool, 0x10) == spellschool or band(spellschool, 0x04) == spellschool or band(spellschool, 0x40) == spellschool then
+ return s
+ end
+ elseif s and s.spellid == 6229 then -- Shadow Ward (Warlock)
+ if band(spellschool, 0x20) == spellschool then
+ return s
+ end
+ elseif s then
+ return s
+ end
+ end
+ end
+
+ local function process_absorb(dstGUID, dstName, dstFlags, absorbed, spellschool, damage)
+ shields[dstName] = shields[dstName] or new()
+
+ local shield = process_shield(dstName, spellschool)
+ if shield and not ignored_spells[shield.spellid] then
+ absorb.actorid = shield.srcGUID
+ absorb.actorname = shield.srcName
+ absorb.actorflags = shield.srcFlags
+
+ absorb.dstGUID = dstGUID
+ absorb.dstName = dstName
+ absorb.dstFlags = dstFlags
+
+ absorb.spell = shield.spellid
+ absorb.spellid = shield.string
+ absorb.string = shield.string
+ absorb.amount = absorbed
+
+ Skada:DispatchSets(log_absorb)
+ end
+ end
+
+ local function spell_damage(t)
+ local dstName = t.dstName and Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+ if dstName and shields[dstName] and t.absorbed and t.absorbed > 0 then
+ process_absorb(t.dstGUID, dstName, t.dstFlags, t.absorbed, t.spellschool or 0x01, t.amount)
+ end
+ end
+
+ local function absorb_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local aps, damage = actor:GetAPS(set)
+
+ local activepercent = activetime / totaltime * 100
+ tooltip:AddDoubleLine(format(L["%s's activity"], classfmt(actor.class, label)), Skada:FormatPercent(activepercent), nil, nil, nil, PercentToRGB(activepercent))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(totaltime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Absorbs"], Skada:FormatNumber(damage), 1, 1, 1)
+
+ local suffix = Skada:FormatTime(P.timemesure == 1 and activetime or totaltime)
+ tooltip:AddDoubleLine(format(slash_fmt, Skada:FormatNumber(damage), suffix), Skada:FormatNumber(aps), 1, 1, 1)
+ end
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.absorbspells and actor.absorbspells[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ if not spell.count or spell.count == 0 then return end
+
+ -- hits and average
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.amount / spell.count), 1, 1, 1)
+
+ -- normal hits
+ if spell.n_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Normal Hits"], format(hits_perc, Skada:FormatNumber(spell.n_num), Skada:FormatPercent(spell.n_num, spell.count)))
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor or actor.enemy then return end -- unavailable for enemies yet
+
+ local total = actor.absorb
+ local spells = (total and total > 0) and actor.absorbspells
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sAPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[win.targetname]
+ if spell.targets and amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell)
+ d.value = amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = format(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor or actor.enemy then return end -- unavailable for enemies yet
+
+ local total = actor.absorb
+ local spells = (total and total > 0) and actor.absorbspells
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sAPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell)
+ d.value = spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor or actor.enemy then return end -- unavailable for enemies yet
+
+ local total = actor and actor.absorb or 0
+ local targets = (total > 0) and actor:GetAbsorbTargets(set)
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sAPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Absorbs"], L[win.class]) or L["Absorbs"]
+
+ local total = set and set:GetAbsorb(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.absorb then
+ local aps, amount = actor:GetAPS(set, nil, not mode_cols.APS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, total, aps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor or not actor.absorb then return end
+
+ local aps, amount = actor:GetAPS(set, false, not mode_cols.sAPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Absorbs and Skada:FormatNumber(amount),
+ mode_cols.sAPS and Skada:FormatNumber(aps)
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local aps, amount = set:GetAPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Absorbs and Skada:FormatNumber(amount),
+ mode_cols.APS and Skada:FormatNumber(aps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:UnitBuff(_, args)
+ if not args.auras or not args.timestamp then return end
+ local curtime = args.Time or Skada._Time
+
+ for _, aura in pairs(args.auras) do
+ if ABSORB_SPELLS[aura.id] then
+ local t = new()
+ t.event = "SPELL_AURA_APPLIED"
+ t.timestamp = args.timestamp + max(0, aura.expires - curtime)
+ t.srcGUID = aura.srcGUID
+ t.srcName = aura.srcName
+ t.srcFlags = aura.srcFlags
+ t.dstGUID = args.dstGUID
+ t.dstName = args.dstName
+ t.dstFlags = args.dstFlags
+ t.spellid = aura.id
+ t.spellstring = format("%s.%s", aura.id, ABSORB_SPELLS[aura.id])
+ t.__temp = true
+ handle_shield(t)
+ t = del(t)
+ end
+ end
+ end
+
+ function mode:CombatLeave()
+ wipe(absorb)
+ clear(shields)
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {tooltip = mode_spell_tooltip}
+ mode_target.metadata = {showspots = true, click1 = mode_target_spell}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = absorb_tooltip,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Absorbs = true, APS = true, Percent = true, sAPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_devineaegis]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ handle_shield,
+ {src_is_interesting = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_REMOVED"
+ )
+
+ Skada:RegisterForCL(
+ spell_damage,
+ {dst_is_interesting = true},
+ -- damage events
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ "ENVIRONMENTAL_DAMAGE",
+ -- missed events
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada.RegisterCallback(self, "Skada_UnitBuffs", "UnitBuff")
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllCallbacks(self)
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:SetComplete(set)
+ -- clean absorbspells table:
+ if not set.absorb or set.absorb == 0 then return end
+ for _, actor in pairs(set.actors) do
+ local amount = actor.absorb
+ if (not amount and actor.absorbspells) or amount == 0 then
+ actor.absorb = nil
+ actor.absorbspells = del(actor.absorbspells, true)
+ end
+ end
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Absorbs and Healing Module
+
+Skada:RegisterModule("Absorbs and Healing", function(L, P)
+ local mode = Skada:NewModule("Absorbs and Healing")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ tooltip_school = tooltip_school or Skada.tooltip_school
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, hps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sHPS" or "HPS"] and hps and Skada:FormatNumber(hps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function hps_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local hps, amount = actor:GetAHPS(set)
+
+ local activepercent = activetime / totaltime * 100
+ tooltip:AddDoubleLine(format(L["%s's activity"], classfmt(actor.class, label)), Skada:FormatPercent(activepercent), nil, nil, nil, PercentToRGB(activepercent))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(set:GetTime()), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Absorbs and Healing"], Skada:FormatNumber(amount), 1, 1, 1)
+
+ local suffix = Skada:FormatTime(P.timemesure == 1 and activetime or totaltime)
+ tooltip:AddDoubleLine(format(slash_fmt, Skada:FormatNumber(amount), suffix), Skada:FormatNumber(hps), 1, 1, 1)
+ end
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local spell = actor.healspells and actor.healspells[id] or actor.absorbspells and actor.absorbspells[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ if not spell.count or spell.count == 0 then return end
+
+ -- hits and average
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.amount / spell.count), 1, 1, 1)
+ if spell.o_amt and spell.o_amt > 0 then
+ tooltip:AddDoubleLine(L["Overheal"], format(hits_perc, Skada:FormatNumber(spell.o_amt), Skada:FormatPercent(spell.o_amt, spell.amount + spell.o_amt)), 1, 0.67, 0.67)
+ end
+
+ -- normal hits
+ if spell.n_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Normal Hits"], format(hits_perc, Skada:FormatNumber(spell.n_num), Skada:FormatPercent(spell.n_num, spell.count)))
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ end
+
+ -- critical hits
+ if spell.c_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Critical Hits"], format(hits_perc, Skada:FormatNumber(spell.c_num), Skada:FormatPercent(spell.c_num, spell.count)))
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetAbsorbHealOnTarget(win.targetname)
+
+ if not total or total == 0 or not (actor.healspells or actor.absorbspells) then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ local spells = actor.healspells -- heal spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[win.targetname]
+ amount = amount and (actor.enemy and amount or amount.amount)
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell, nil, true)
+ d.value = amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ spells = actor.absorbspells -- absorb spells
+ if not spells then return end
+
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[win.targetname]
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell)
+ d.value = amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = format(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not win.actorname then return end
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetAbsorbHeal()
+
+ if not total or total == 0 or not (actor.healspells or actor.absorbspells) then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ local spells = actor.healspells -- heal spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell, nil, true)
+ d.value = spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ spells = actor.absorbspells -- absorb spells
+ if not spells then return end
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell)
+ d.value = spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetAbsorbHeal()
+ local targets = (total and total > 0) and actor:GetAbsorbHealTargets(set)
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sAPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ if target.amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Absorbs and Healing"], L[win.class]) or L["Absorbs and Healing"]
+
+ local total = set and set:GetAbsorbHeal(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and (actor.absorb or actor.heal) then
+ local hps, amount = actor:GetAHPS(set, nil, not mode_cols.HPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, total, hps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local hps, amount = actor:GetAHPS(set, false, not mode_cols.sHPS)
+ if amount <= 0 then return end
+
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.sHPS and Skada:FormatNumber(hps)
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ local hps, amount = set:GetAHPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.HPS and Skada:FormatNumber(hps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if not set then return end
+ local hps, amount = set:GetAHPS()
+ if amount > 0 then
+ tooltip:AddDoubleLine(L["Healing"], Skada:FormatNumber(amount), 1, 1, 1)
+ tooltip:AddDoubleLine(L["HPS"], Skada:FormatNumber(hps), 1, 1, 1)
+ end
+ if set.overheal and set.overheal > 0 then
+ amount = amount + set.overheal
+ tooltip:AddDoubleLine(L["Overheal"], Skada:FormatPercent(set.overheal, amount), 1, 1, 1)
+ end
+ end
+
+ local function feed_personal_hps()
+ local set = Skada:GetSet("current")
+ local actor = set and set:GetActor(Skada.userName, Skada.userGUID)
+ if actor then
+ return format("%s %s", Skada:FormatNumber((actor:GetAHPS(set))), L["HPS"])
+ end
+ end
+
+ local function feed_raid_hps()
+ local set = Skada:GetSet("current")
+ return format("%s %s", Skada:FormatNumber(set and set:GetAHPS() or 0), L["RHPS"])
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {tooltip = mode_spell_tooltip}
+ mode_target.metadata = {showspots = true, click1 = mode_target_spell}
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:AddFeed(L["Healing: Personal HPS"], feed_personal_hps)
+ Skada:AddFeed(L["Healing: Raid HPS"], feed_raid_hps)
+
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveFeed(L["Healing: Personal HPS"])
+ Skada:RemoveFeed(L["Healing: Raid HPS"])
+ Skada:RemoveMode(self)
+ end
+
+ function mode:OnInitialize()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = hps_tooltip,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Healing = true, HPS = true, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_healingfocus]]
+ }
+ end
+end, "Absorbs", "Healing")
+
+---------------------------------------------------------------------------
+-- HPS Module
+
+Skada:RegisterModule("HPS", function(L, P)
+ local mode = Skada:NewModule("HPS")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, metadata)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.HPS and Skada:FormatNumber(d.value),
+ mode_cols.Percent and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function hps_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local hps, amount = actor:GetAHPS(set)
+
+ tooltip:AddLine(uformat(L["%s's activity"], classfmt(actor.class, label), L["HPS"]))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(set:GetTime()), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Absorbs and Healing"], Skada:FormatNumber(amount), 1, 1, 1)
+
+ local suffix = Skada:FormatTime(P.timemesure == 1 and activetime or totaltime)
+ tooltip:AddDoubleLine(format(slash_fmt, Skada:FormatNumber(amount), suffix), Skada:FormatNumber(hps), 1, 1, 1)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["HPS"], L[win.class]) or L["HPS"]
+
+ local total = set and set:GetAHPS(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and (actor.absorb or actor.heal) then
+ local amount = actor:GetAHPS(set, nil, not mode_cols.HPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, total, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ local value = set:GetAHPS(win and win.class)
+ return value, Skada:FormatNumber(value)
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = hps_tooltip,
+ columns = {HPS = true, Percent = true},
+ icon = [[Interface\ICONS\spell_nature_rejuvenation]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ local parent = Skada:GetModule("Absorbs and Healing", true)
+ if parent and parent.metadata then
+ self.metadata.click1 = parent.metadata.click1
+ self.metadata.click2 = parent.metadata.click2
+ end
+
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Absorbs", "Healing", "Absorbs and Healing")
+
+---------------------------------------------------------------------------
+-- Healing Done By Spell
+
+Skada:RegisterModule("Healing Done By Spell", function(L, _, _, C)
+ local mode = Skada:NewModule("Healing Done By Spell")
+ local mode_source = mode:NewModule("Source List")
+ local classfmt = Skada.classcolors.format
+ local clear = Private.clearTable
+ local get_absorb_heal_spells = nil
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, hps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sHPS" or "HPS"] and Skada:FormatNumber(hps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function mode_source_tooltip(win, id, label, tooltip)
+ local set = win.spellname and win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local spell = actor.healspells and actor.healspells[win.spellid]
+ spell = spell or actor.absorbspells and actor.absorbspells[win.spellid]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(actor.class, label), win.spellname))
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(win.spellid)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ if spell.count then
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+
+ if spell.c_num then
+ tooltip:AddDoubleLine(L["Critical"], Skada:FormatPercent(spell.c_num, spell.count), 1, 1, 1)
+ end
+
+ if spell.min and spell.max then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.min), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.max), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.amount / spell.count), 1, 1, 1)
+ end
+ end
+
+ if spell.o_amt then
+ tooltip:AddDoubleLine(L["Overheal"], format("%s (%s)", Skada:FormatNumber(spell.o_amt), Skada:FormatPercent(spell.o_amt, spell.amount + spell.o_amt)), nil, nil, nil, 1, 0.67, 0.67)
+ end
+ end
+
+ function mode_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's sources"], label)
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], win.spellname)
+ if not (win.spellid and set) then return end
+
+ -- let's go...
+ local total = 0
+ local overheal = 0
+ local sources = clear(C)
+
+ local actors = set.actors
+ for actorname, actor in pairs(actors) do
+ if actor and not actor.enemy and (actor.absorbspells or actor.healspells) then
+ local spell = actor.absorbspells and actor.absorbspells[win.spellid]
+ spell = spell or actor.healspells and actor.healspells[win.spellid]
+ if spell and spell.amount then
+ sources[actorname] = new()
+ sources[actorname].id = actor.id
+ sources[actorname].class = actor.class
+ sources[actorname].role = actor.role
+ sources[actorname].spec = actor.spec
+ sources[actorname].enemy = actor.enemy
+ sources[actorname].amount = spell.amount
+ sources[actorname].time = mode.metadata.columns.sHPS and actor:GetTime(set)
+ -- calculate the total.
+ total = total + spell.amount
+ if spell.o_amt then
+ overheal = overheal + spell.o_amt
+ end
+ end
+ end
+ end
+
+ if total == 0 and overheal == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for sourcename, source in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.amount
+ format_valuetext(d, total, source.time and (d.value / source.time), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Healing Done By Spell"]
+ local total = set and set:GetAbsorbHeal()
+ local spells = (total and total > 0) and get_absorb_heal_spells(set)
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local settime = mode_cols.HPS and set:GetTime()
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell, nil, true)
+ d.value = spell.amount
+ format_valuetext(d, total, settime and (d.value / settime), win.metadata)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_source.metadata = {showspots = true, tooltip = mode_source_tooltip}
+ self.metadata = {
+ click1 = mode_source,
+ columns = {Healing = true, HPS = false, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_nature_healingwavelesser]]
+ }
+ mode_cols = self.metadata.columns
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ ---------------------------------------------------------------------------
+
+ local function fill_spells_table(t, spellid, info)
+ if not info or not (info.amount or info.o_amt) then return end
+
+ local spell = t[spellid]
+ if not spell then
+ spell = new()
+ -- common
+ spell.amount = info.amount
+
+ -- for heals
+ spell.o_amt = info.o_amt
+
+ t[spellid] = spell
+ else
+ spell.amount = spell.amount + info.amount
+ if info.o_amt then -- for heals
+ spell.o_amt = (spell.o_amt or 0) + info.o_amt
+ end
+ end
+ end
+
+ get_absorb_heal_spells = function(self, tbl)
+ if not self.actors or not (self.absorb or self.heal) then return end
+
+ tbl = clear(tbl or C)
+ for _, actor in pairs(self.actors) do
+ if actor.healspells then
+ for spellid, spell in pairs(actor.healspells) do
+ fill_spells_table(tbl, spellid, spell)
+ end
+ end
+ if actor.absorbspells then
+ for spellid, spell in pairs(actor.absorbspells) do
+ fill_spells_table(tbl, spellid, spell)
+ end
+ end
+ end
+ return tbl
+ end
+end, "Absorbs", "Healing")
diff --git a/Skada/Modules/Activity.lua b/Skada/Modules/Activity.lua
new file mode 100644
index 0000000..96cd807
--- /dev/null
+++ b/Skada/Modules/Activity.lua
@@ -0,0 +1,146 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Activity", function(L, P, _, C)
+ local mode = Skada:NewModule("Activity")
+ local mode_target = mode:NewModule("Activity per Target")
+ local date, pairs, format = date, pairs, string.format
+ local uformat, new, clear = Private.uformat, Private.newTable, Private.clearTable
+ local classfmt = Skada.classcolors.format
+ local get_activity_targets = nil
+ local mode_cols = nil
+
+ local function format_valuetext(d, maxtime, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols["Active Time"] and Skada:FormatTime(d.value),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, maxtime)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function activity_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local settime = set:GetTime()
+ if settime == 0 then return end
+
+ local activetime = actor:GetTime(set, true)
+ tooltip:AddLine(uformat("%s - %s", classfmt(actor.class, label), L["Activity"]))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(settime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Activity"], Skada:FormatPercent(activetime, settime), nil, nil, nil, 1, 1, 1)
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's activity"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's activity"], classfmt(win.actorclass, win.actorname))
+ if not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local maxtime = actor and actor:GetTime(set, true)
+ local targets = maxtime and get_activity_targets(actor, set)
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for name, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, name)
+ d.value = target.time
+ format_valuetext(d, maxtime, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Activity"], L[win.class]) or L["Activity"]
+
+ local settime = set and set:GetTime()
+ if not settime or settime == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) then
+ local activetime = actor:GetTime(set, true)
+ if activetime > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = activetime
+ format_valuetext(d, settime, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_target:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor or not actor.time then return end
+ return actor.time, Skada:FormatTime(actor.time)
+ end
+
+ function mode:GetSetSummary(set)
+ if not set or not set.time then return end
+ local valuetext = Skada:FormatValueCols(
+ mode_cols["Active Time"] and Skada:FormatTime(set.time),
+ mode_cols.Percent and format("%s - %s", date("%H:%M", set.starttime), date("%H:%M", set.endtime))
+ )
+ return set.time, valuetext
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ tooltip = activity_tooltip,
+ click1 = mode_target,
+ columns = {["Active Time"] = true, Percent = true, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_borrowedtime]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_target.nototal = true
+
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_activity_targets = function(self, set, tbl)
+ if not set or not self.timespent then return end
+
+ tbl = clear(tbl or C)
+ for name, timespent in pairs(self.timespent) do
+ tbl[name] = new()
+ tbl[name].time = timespent
+ set:_fill_actor_table(tbl[name], name)
+ end
+ return tbl
+ end
+end)
diff --git a/Skada/Modules/Auras.lua b/Skada/Modules/Auras.lua
new file mode 100644
index 0000000..a033dca
--- /dev/null
+++ b/Skada/Modules/Auras.lua
@@ -0,0 +1,1054 @@
+local _, Skada = ...
+local Private = Skada.Private
+local L = Skada.Locale
+
+-- frequently used global (sort of...)
+local pairs, format, uformat = pairs, string.format, Private.uformat
+local time, min, floor = time, math.min, math.floor
+
+-- common functions and locals
+local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+local ignored_buffs, ignored_debuffs -- Edit Skada\Core\Tables.lua
+local aura, tooltip_school
+
+---------------------------------------------------------------------------
+-- Parent Module - Handles common stuff
+
+do
+ local main = Skada:NewModule("Buffs and Debuffs")
+ local band, next, wipe = bit.band, next, wipe
+ local player_flag, enemy_flag = 0x02, 0x04
+ local player_clear, enemy_clear = false, false
+ local main_flag = 0
+
+ function main:OnEnable()
+ if not Skada:IsDisabled("Buffs") or not Skada:IsDisabled("Debuffs") then
+ main_flag = main_flag + player_flag
+ end
+ if not Skada:IsDisabled("Enemy Buffs") or not Skada:IsDisabled("Enemy Debuffs") then
+ main_flag = main_flag + enemy_flag
+ end
+
+ if main_flag == 0 then return end
+
+ aura = {}
+ tooltip_school = Skada.tooltip_school
+ Skada.RegisterCallback(self, "Skada_SetComplete", "Clean")
+
+ -- what can be cleaned?
+ player_clear = (band(main_flag, player_flag) ~= 0)
+ enemy_clear = (band(main_flag, enemy_flag) ~= 0)
+
+ ignored_buffs = Skada.ignored_spells.buff
+ ignored_debuffs = Skada.ignored_spells.debuff
+ end
+
+ function main:OnDisable()
+ Skada.UnregisterAllCallbacks(self)
+ end
+
+ local function can_clear_actor(actor)
+ if not actor or not actor.auras then
+ return false
+ elseif actor.enemy and not enemy_clear then
+ return false
+ elseif not actor.enemy and not player_clear then
+ return false
+ else
+ return true
+ end
+ end
+
+ local function clear_actor_table(actor, curtime, maxtime)
+ if not can_clear_actor(actor) then return end
+
+ for spellid, spell in pairs(actor.auras) do
+ if spell.a and spell.a > 0 and spell.s then
+ spell.u = min(maxtime, spell.u + floor((curtime - spell.s) + 0.5))
+ end
+ -- remove temporary keys
+ spell.a, spell.s = nil, nil
+
+ if spell.u == 0 then
+ -- remove spell with 0 uptime.
+ actor.auras[spellid] = del(actor.auras[spellid], true)
+ elseif spell.t then
+ -- debuff targets
+ for name, target in pairs(spell.t) do
+ if target.a and target.a > 0 and target.s then
+ target.u = min(spell.u, target.u + floor((curtime - target.s) + 0.5))
+ end
+ -- remove temporary keys
+ target.a, target.s = nil, nil
+
+ -- remove targets with 0 uptime.
+ if target.u == 0 then
+ spell.t[name] = del(spell.t[name])
+ end
+ end
+
+ -- an empty targets table? Remove it
+ if next(spell.t) == nil then
+ actor.auras[spellid] = del(actor.auras[spellid])
+ end
+ end
+ end
+
+ -- remove table if no auras left
+ if next(actor.auras) == nil then
+ actor.auras = del(actor.auras)
+ end
+ end
+
+ function main:Clean(_, set, curtime)
+ wipe(aura) -- empty aura table first
+
+ local actors = set and set.actors
+ if not actors then return end
+
+ local maxtime = set and set:GetTime()
+ curtime = curtime or Skada._time or time()
+
+ for _, actor in pairs(actors) do
+ clear_actor_table(actor, curtime, maxtime)
+ end
+ end
+end
+
+---------------------------------------------------------------------------
+-- Common functions
+
+local format_valuetext
+local log_auraapplied, log_aurarefresh, log_auraremove, log_specialaura
+local main_update_func, spell_update_func, target_update_func
+local spelltarget_update_func, targetspell_update_func
+local spell_tooltip, spelltarget_tooltip
+
+-- list of spells that don't trigger SPELL_AURA_x events
+local special_buffs = {
+ [57669] = true -- Replenishment
+}
+
+do
+ local SpellSplit = Private.SpellSplit
+ local PercentToRGB = Private.PercentToRGB
+
+ -- formats value texts
+ function format_valuetext(d, cols, count, maxtime, metadata, subview, no_order)
+ d.valuetext = Skada:FormatValueCols(
+ cols.Uptime and Skada:FormatTime(d.value),
+ cols.Count and Skada:FormatNumber(count),
+ cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, maxtime)
+ )
+
+ if not no_order and metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function find_or_create_actor(set, info)
+ -- 1. make sure we can record to the segment.
+ if not set or (set == Skada.total and not Skada.profile.totalidc) then return end
+
+ -- 2. make sure we have valid data.
+ if not info or not info.spellid then return end
+
+ -- 3. retrieve the actor.
+ return Skada:GetActor(set, info.actorname, info.actorid, info.actorflags)
+ end
+
+ -- handles SPELL_AURA_APPLIED event
+ function log_auraapplied(set, curtime)
+ local actor = find_or_create_actor(set, aura)
+ if not actor then return end
+
+ curtime = curtime or Skada._time or time()
+ local spell = actor.auras and actor.auras[aura.spellid]
+ if not spell then
+ actor.auras = actor.auras or {}
+ actor.auras[aura.spellid] = {u = 0, n = 1, a = 1, s = curtime}
+ spell = actor.auras[aura.spellid]
+ else
+ spell.n = (spell.n or 0) + 1
+ spell.a = (spell.a or 0) + 1
+ spell.s = spell.s or curtime
+ end
+
+ -- only record targets for debuffs
+ local name = aura.type == "DEBUFF" and aura.dstName
+ if not name then return end
+
+ local target = spell.t and spell.t[name]
+ if not target then
+ spell.t = spell.t or {}
+ spell.t[name] = {u = 0, n = 1, a = 1, s = curtime}
+ else
+ target.a = (target.a or 0) + 1
+ target.n = (target.n or 0) + 1
+ target.s = target.s or curtime
+ end
+ end
+
+ -- handles SPELL_AURA_REFRESH and SPELL_AURA_APPLIED_DOSE events
+ function log_aurarefresh(set)
+ local actor = find_or_create_actor(set, aura)
+ if not actor then return end
+
+ -- spell
+ local spell = actor.auras and actor.auras[aura.spellid]
+ if not spell or not spell.a or spell.a == 0 then return end
+ spell.r = (spell.r or 0) + 1
+
+ -- target
+ local target = spell.t and aura.dstName and spell.t[aura.dstName]
+ if not target or not target.a or target.a == 0 then return end
+ target.r = (target.r or 0) + 1
+ end
+
+ -- handles SPELL_AURA_REMOVED event
+ function log_auraremove(set)
+ local actor = find_or_create_actor(set, aura)
+ if not actor then return end
+
+ -- spell
+ local spell = actor.auras and actor.auras[aura.spellid]
+ if not spell or not spell.a or spell.a == 0 then return end
+
+ local curtime = Skada._time or time()
+ spell.a = spell.a - 1
+ if spell.a == 0 and spell.s then
+ spell.u = spell.u + floor((curtime - spell.s) + 0.5)
+ spell.s = nil
+ end
+
+ -- target
+ local target = spell.t and aura.dstName and spell.t[aura.dstName]
+ if not target or not target.a or target.a == 0 then return end
+
+ target.a = target.a - 1
+ if target.a == 0 and target.s then
+ target.u = target.u + floor((curtime - target.s) + 0.5)
+ target.s = nil
+ end
+ end
+
+ function log_specialaura(set)
+ local actor = find_or_create_actor(set, aura)
+ if not actor then return end
+
+ -- spell
+ local spell = actor.auras and actor.auras[aura.spellid]
+ if not spell then
+ actor.auras = actor.auras or {}
+ actor.auras[aura.spellid] = {u = 1}
+ else
+ spell.u = (spell.u or 0) + 1
+ end
+ end
+
+ do
+ -- counts auras by the given type
+ local function count_auras_by_type(spells, auratype)
+ if not spells then return end
+
+ local count, uptime = 0, 0
+ for id, spell in pairs(spells) do
+ local spellid = SpellSplit(id)
+ if (auratype == "BUFF" and spellid > 0) or (auratype == "DEBUFF" and spellid < 0) then
+ count = count + 1
+ uptime = uptime + (spell.u or spell.uptime)
+ end
+ end
+ return count, uptime
+ end
+
+ -- whether to show the actor or not (player/enemy)
+ local function should_show_actor(win, actor, set, is_enemy)
+ if not actor or not actor.auras then
+ return false
+ elseif is_enemy and not actor.enemy then
+ return false
+ elseif not is_enemy and actor.enemy then
+ return false
+ else
+ return win:show_actor(actor, set)
+ end
+ end
+
+ -- module's main update function.
+ function main_update_func(self, auratype, win, set, cols, is_enemy)
+ local settime = auratype and set and set:GetTime()
+ if not settime or settime == 0 then return end
+
+ local actors = set.actors
+ if not actors then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for actorname, actor in pairs(actors) do
+ if should_show_actor(win, actor, set, is_enemy) then
+ local count, uptime = count_auras_by_type(actor.auras, auratype)
+ if count and count > 0 and uptime > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ local maxtime = floor(actor:GetTime(set))
+ d.value = min(floor(uptime / count), maxtime)
+ format_valuetext(d, cols, count, maxtime, win.metadata)
+ end
+ end
+ end
+ end
+ end
+
+ -- list actor's auras by type
+ function spell_update_func(self, auratype, win, set, cols)
+ local actor = set and auratype and set:GetActor(win.actorname, win.actorid)
+ local maxtime = actor and floor(actor:GetTime(set))
+ local spells = (maxtime and maxtime > 0) and actor.auras
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for id, spell in pairs(spells) do
+ local spellid = SpellSplit(id)
+ local spell_u = spell.u or spell.uptime
+ if
+ (auratype == "BUFF" and spellid > 0 and spell_u > 0) or
+ (auratype == "DEBUFF" and spellid < 0 and spell_u > 0)
+ then
+ nr = nr + 1
+
+ local d = win:spell(nr, id, false)
+ d.value = min(maxtime, spell_u)
+ format_valuetext(d, cols, spell.n, maxtime, win.metadata, true)
+ end
+ end
+ end
+
+ local function new_aura_table(info)
+ local t = new()
+ t.n = info.n or info.count
+ t.r = info.r or info.refresh
+ t.u = info.u or info.uptime
+ return t
+ end
+
+ do
+ local function get_actor_auras_targets(self, set, auratype, tbl)
+ local spells = set and auratype and self.auras
+ if not spells then return end
+
+ tbl = clear(tbl)
+ local maxtime = 0
+ for _, spell in pairs(spells) do
+ local targets = spell.t or spell.targets
+ if targets then
+ maxtime = maxtime + (spell.u or spell.uptime)
+ for name, target in pairs(targets) do
+ local t = tbl[name]
+ if not t then
+ t = new_aura_table(target)
+ tbl[name] = t
+ else
+ t.n = t.n + (target.n or target.count)
+ t.u = t.u + (target.u or target.uptime)
+ if target.r or target.refresh then
+ t.r = (t.r or 0) + (target.r or target.refresh)
+ end
+ end
+
+ set:_fill_actor_table(t, name)
+ end
+ end
+ end
+
+ return tbl, maxtime
+ end
+
+ -- list actor's auras targets by type
+ function target_update_func(self, auratype, win, set, cols, tbl)
+ local actor = set and auratype and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local targets, maxtime = get_actor_auras_targets(actor, set, auratype, tbl)
+ if not targets or maxtime == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for name, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, name)
+ d.value = target.u
+ format_valuetext(d, cols, target.n, maxtime, win.metadata, true)
+ end
+ end
+ end
+
+ do
+ local function get_actor_aura_targets(self, set, spellid, tbl)
+ local spell = set and spellid and self.auras and self.auras[spellid]
+ local targets = spell and (spell.t or spell.targets)
+ if not targets then return end
+
+ tbl = clear(tbl)
+ for name, target in pairs(targets) do
+ tbl[name] = new_aura_table(target)
+ set:_fill_actor_table(tbl[name], name)
+ end
+ return tbl, spell.u or spell.uptime
+ end
+
+ -- list targets of the given aura
+ function spelltarget_update_func(self, auratype, win, set, cols, tbl)
+ local actor = set and auratype and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local targets, maxtime = get_actor_aura_targets(actor, set, win.spellid, tbl)
+ if not targets or maxtime == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for name, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, name)
+ d.value = min(target.u or target.uptime, maxtime)
+ format_valuetext(d, cols, target.n or target.count, maxtime, win.metadata, true)
+ end
+ end
+ end
+
+ do
+ local function get_actor_target_auras(self, name, tbl)
+ local spells = name and self.auras
+ if not spells then return end
+
+ tbl = clear(tbl)
+ local maxtime = 0
+ for spellid, spell in pairs(spells) do
+ local target = (spell.t and spell.t[name]) or (spell.targets and spell.targets[name])
+ local uptime = target and (target.u or target.uptime)
+ if uptime then
+ maxtime = maxtime + uptime
+ tbl[spellid] = new_aura_table(target)
+ end
+ end
+
+ return tbl, maxtime
+ end
+
+ -- list auras done on the given target
+ function targetspell_update_func(self, auratype, win, set, cols, tbl)
+ local actor = set and auratype and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local spells, maxtime = get_actor_target_auras(actor, win.targetname, tbl)
+ if not spells or maxtime == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, false)
+ d.value = spell.u
+ format_valuetext(d, cols, spell.n, maxtime, win.metadata, true)
+ end
+ end
+ end
+
+ function spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local settime = set and set:GetTime()
+ if not settime or settime == 0 then return end
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.auras and actor.auras[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", Skada.classcolors.format(actor.class, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, 1, 1, 1)
+ end
+
+ local spell_n = spell.n or spell.count
+ if spell_n then
+ tooltip:AddDoubleLine(L["Count"], spell_n, nil, nil, nil, 1, 1, 1)
+ end
+
+ local spell_r = spell.r or spell.refresh
+ if spell_r then
+ tooltip:AddDoubleLine(L["Refresh"], spell_r, nil, nil, nil, 1, 1, 1)
+ end
+
+ -- add segment and active times
+ local spell_u = spell.u or spell.uptime
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(settime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(actor:GetTime(set, true)), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Duration"], Skada:FormatTime(spell_u), 1, 1, 1)
+
+ -- display aura uptime in colored percent
+ local uptime = 100 * (spell_u / actor:GetTime(set))
+ tooltip:AddDoubleLine(L["Uptime"], Skada:FormatPercent(uptime), nil, nil, nil, PercentToRGB(uptime, actor.enemy))
+ end
+
+ function spelltarget_tooltip(win, id, label, tooltip)
+ local set = win.spellid and win:GetSelectedSet()
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.auras and actor.auras[win.spellid]
+ local target = spell and spell.t and spell.t[label]
+ if not target then return end
+
+ tooltip:AddLine(uformat("%s - %s", Skada.classcolors.format(actor.class, win.actorname), win.spellname))
+ tooltip_school(tooltip, win.spellid)
+
+ if target.n then
+ tooltip:AddDoubleLine(L["Count"], target.n, 1, 1, 1)
+ end
+ if target.r then
+ tooltip:AddDoubleLine(L["Refresh"], target.r, 1, 1, 1)
+ end
+ end
+end
+
+---------------------------------------------------------------------------
+-- Buffs Module
+
+Skada:RegisterModule("Buffs", function(_, P, G, C)
+ local mode = Skada:NewModule("Buffs")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_target = mode_spell:NewModule("Target List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function handle_buff(t)
+ if t.__temp or (t.spellid and not ignored_buffs[t.spellid] and t.spellstring and (t.auratype == "BUFF" or special_buffs[t.spellid])) then
+ aura.actorid = t.dstGUID
+ aura.actorname = t.dstName
+ aura.actorflags = t.dstFlags
+ aura.dstName = nil
+
+ aura.spellid = t.spellstring
+ aura.type = t.auratype
+
+ if t.event == "SPELL_PERIODIC_ENERGIZE" then
+ Skada:DispatchSets(log_specialaura)
+ elseif t.event == "SPELL_AURA_APPLIED" then
+ Skada:DispatchSets(log_auraapplied, t.curtime)
+ elseif t.event == "SPELL_AURA_REMOVED" then
+ Skada:DispatchSets(log_auraremove)
+ else
+ Skada:DispatchSets(log_aurarefresh)
+ end
+ end
+ end
+
+ function mode_spell_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's targets"], label)
+ end
+
+ do
+ local function new_actor_table(info)
+ local t = new()
+ t.id = info.id
+ t.class = info.class
+ t.role = info.role
+ t.spec = info.spec
+ t.enemy = info.enemy
+ return t
+ end
+
+ local function get_aura_targets(self, spellid, tbl)
+ local actors = spellid and self.actors
+ if not actors then return end
+
+ tbl = clear(tbl or C)
+ for actorname, actor in pairs(actors) do
+ local spell = not actor.enemy and actor.auras and actor.auras[spellid]
+ if spell then
+ local t = new_actor_table(actor)
+ t.n = spell.n
+ t.m = floor(actor:GetTime(self))
+ t.u = min(t.m, spell.u or spell.uptime)
+ tbl[actorname] = t
+ end
+ end
+ return tbl
+ end
+
+ function mode_spell_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], win.spellname)
+
+ local targets = get_aura_targets(set, win.spellid)
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for name, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, name)
+ d.value = target.u
+ format_valuetext(d, mode_cols, target.n, target.m, win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ spell_update_func(self, "BUFF", win, set, mode_cols)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Buffs"], L[win.class]) or L["Buffs"]
+ main_update_func(self, "BUFF", win, set, mode_cols)
+ end
+
+ do
+ -- per-session spell strings cache
+ local spellstrings = G.spellstrings or {}
+ G.spellstrings = spellstrings
+
+ local cache_events = {SPELL_AURA_APPLIED = true, SPELL_AURA_REFRESH = true}
+ Skada:RegisterCallback("Skada_SpellString", function(_, t, spellid, spellstring)
+ if cache_events[t.event] and t.auratype == "BUFF" and not spellstrings[spellid] then
+ spellstrings[spellid] = spellstring
+ end
+ end)
+
+ function mode:UnitBuff(_, args)
+ if args.owner or not args.auras then return end
+
+ local dstGUID, dstName, dstFlags = args.dstGUID, args.dstName, args.dstFlags
+ for _, aura in pairs(args.auras) do
+ local t = new()
+ t.event = args.event
+ t.dstGUID = dstGUID
+ t.dstName = dstName
+ t.dstFlags = dstFlags
+ t.spellid = aura.id
+ t.spellstring = spellstrings[aura.id]
+ t.auratype = "BUFF"
+ t.__temp = true
+ handle_buff(t)
+ t = del(t)
+ end
+ end
+ end
+
+ function mode:OnEnable()
+ mode_spell_target.metadata = {showspots = true, ordersort = true, tooltip = spelltarget_tooltip}
+ mode_spell.metadata = {valueorder = true, tooltip = spell_tooltip, click1 = mode_spell_target}
+ self.metadata = {
+ filterclass = true,
+ click1 = mode_spell,
+ columns = {Uptime = true, Count = false, Percent = true, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_divinespirit]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+
+ Skada:RegisterForCL(
+ handle_buff,
+ {dst_is_interesting_nopets = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REMOVED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_APPLIED_DOSE",
+ "SPELL_PERIODIC_ENERGIZE"
+ )
+
+ Skada.RegisterCallback(self, "Skada_UnitBuffs", "UnitBuff")
+ Skada:AddMode(self, "Buffs and Debuffs")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Debuffs Module
+
+Skada:RegisterModule("Debuffs", function(_, _, _, C)
+ local mode = Skada:NewModule("Debuffs")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_target = mode_spell:NewModule("Target List")
+ local mode_spell_source = mode_spell:NewModule("Source List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function handle_debuff(t)
+ if t.auratype ~= "DEBUFF" or not t.spellid or ignored_debuffs[t.spellid] then return end
+
+ aura.actorid = t.srcGUID
+ aura.actorname = t.srcName
+ aura.actorflags = t.srcFlags
+ aura.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+
+ aura.spellid = t.spellstring
+ aura.type = t.auratype
+ Skada:FixPets(aura)
+
+ if t.event == "SPELL_AURA_APPLIED" then
+ Skada:DispatchSets(log_auraapplied)
+ elseif t.event == "SPELL_AURA_REMOVED" then
+ Skada:DispatchSets(log_auraremove)
+ else
+ Skada:DispatchSets(log_aurarefresh)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label or L["Unknown"], class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, win.targetname))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ targetspell_update_func(self, "DEBUFF", win, set, mode_cols, C)
+ end
+
+ function mode_spell_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_target:Update(win, set)
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), win.spellname)
+ spelltarget_update_func(self, "DEBUFF", win, set, mode_cols, C)
+ end
+
+ function mode_spell_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's sources"], label)
+ end
+
+ function mode_spell_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], win.spellname)
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ if not win.spellid then return end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ local auras = win:show_actor(actor, set, true) and not actor.enemy and actor.auras
+ local spell = auras and auras[win.spellid]
+ if spell then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = spell.u
+ format_valuetext(d, mode_cols, spell.n, actor:GetTime(set), win.metadata, true, true)
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ target_update_func(self, "DEBUFF", win, set, mode_cols, C)
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ spell_update_func(self, "DEBUFF", win, set, mode_cols)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Debuffs"], L[win.class]) or L["Debuffs"]
+ main_update_func(self, "DEBUFF", win, set, mode_cols)
+ end
+
+ local function spellsource_tooltip(win, id, label, tooltip)
+ local set = win.spellid and win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ local spell = actor and actor.auras and actor.auras[win.spellid]
+ if not (spell and spell.n) then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(actor.class, label), win.spellname))
+ tooltip_school(tooltip, win.spellid)
+
+ tooltip:AddDoubleLine(L["Count"], spell.n, 1, 1, 1)
+ if spell.r then
+ tooltip:AddDoubleLine(L["Refresh"], spell.r, 1, 1, 1)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_spell_source.metadata = {
+ filterclass = true,
+ tooltip = spellsource_tooltip
+ }
+
+ mode_spell_target.metadata = {tooltip = spelltarget_tooltip}
+ mode_spell.metadata = {click1 = mode_spell_target, click2 = mode_spell_source, tooltip = spell_tooltip}
+ mode_target.metadata = {click1 = mode_target_spell}
+ self.metadata = {
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Uptime = true, Count = false, Percent = true, sPercent = true},
+ icon = [[Interface\ICONS\spell_shadow_shadowwordpain]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ handle_debuff,
+ {src_is_interesting = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REMOVED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_APPLIED_DOSE"
+ )
+
+ Skada:AddMode(self, "Buffs and Debuffs")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Enemy Buffs Module
+
+Skada:RegisterModule("Enemy Buffs", function(_, P, _, C)
+ local mode = Skada:NewModule("Enemy Buffs")
+ local mode_spell = mode:NewModule("Spell List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function handle_buff(t)
+ if t.spellid and not ignored_buffs[t.spellid] and (t.auratype == "BUFF" or special_buffs[t.spellid]) then
+ aura.actorid = t.dstGUID
+ aura.actorname = t.dstName
+ aura.actorflags = t.dstFlags
+ aura.dstName = nil
+
+ aura.spellid = t.spellstring
+ aura.type = t.auratype
+
+ if t.event == "SPELL_PERIODIC_ENERGIZE" then
+ Skada:DispatchSets(log_specialaura)
+ elseif t.event == "SPELL_AURA_APPLIED" then
+ Skada:DispatchSets(log_auraapplied)
+ elseif t.event == "SPELL_AURA_REMOVED" then
+ Skada:DispatchSets(log_auraremove)
+ else
+ Skada:DispatchSets(log_aurarefresh)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ spell_update_func(self, "BUFF", win, set, mode_cols)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Enemy Buffs"], L[win.class]) or L["Enemy Buffs"]
+ main_update_func(self, "BUFF", win, set, mode_cols, true)
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {valueorder = true, tooltip = spell_tooltip}
+ self.metadata = {
+ filterclass = true,
+ click1 = mode_spell,
+ columns = {Uptime = true, Count = false, Percent = true, sPercent = true},
+ icon = [[Interface\ICONS\ability_paladin_beaconoflight]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+
+ Skada:RegisterForCL(
+ handle_buff,
+ {src_is_not_interesting = true, dst_is_not_interesting = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REMOVED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_APPLIED_DOSE",
+ "SPELL_PERIODIC_ENERGIZE"
+ )
+
+ Skada:AddMode(self, "Enemies")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Enemy Debuffs Module
+
+Skada:RegisterModule("Enemy Debuffs", function(_, _, _, C)
+ local mode = Skada:NewModule("Enemy Debuffs")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_target = mode_spell:NewModule("Target List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function handle_debuff(t)
+ if t.auratype ~= "DEBUFF" or not t.spellid or ignored_debuffs[t.spellid] then return end
+
+ aura.actorid = t.srcGUID
+ aura.actorname = t.srcName
+ aura.actorflags = t.srcFlags
+ aura.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+
+ aura.spellid = t.spellstring
+ aura.type = t.auratype
+
+ if t.event == "SPELL_AURA_APPLIED" then
+ Skada:DispatchSets(log_auraapplied)
+ elseif t.event == "SPELL_AURA_REMOVED" then
+ Skada:DispatchSets(log_auraremove)
+ else
+ Skada:DispatchSets(log_aurarefresh)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label or L["Unknown"], class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, win.targetname))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ targetspell_update_func(self, "DEBUFF", win, set, mode_cols, C)
+ end
+
+ function mode_spell_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_target:Update(win, set)
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), win.spellname)
+ spelltarget_update_func(self, "DEBUFF", win, set, mode_cols, C)
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ target_update_func(self, "DEBUFF", win, set, mode_cols, C)
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = format(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ spell_update_func(self, "DEBUFF", win, set, mode_cols)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Enemy Debuffs"], L[win.class]) or L["Enemy Debuffs"]
+ main_update_func(self, "DEBUFF", win, set, mode_cols, true)
+ end
+
+ function mode:OnEnable()
+ mode_spell_target.metadata = {tooltip = spelltarget_tooltip}
+ mode_spell.metadata = {click1 = mode_spell_target, tooltip = spell_tooltip}
+ mode_target.metadata = {click1 = mode_target_spell}
+ self.metadata = {
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Uptime = true, Count = false, Percent = true, sPercent = true},
+ icon = [[Interface\ICONS\ability_warlock_improvedsoulleech]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ handle_debuff,
+ {src_is_not_interesting = true, dst_is_interesting = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_REMOVED",
+ "SPELL_AURA_APPLIED_DOSE"
+ )
+
+ Skada:AddMode(self, "Enemies")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end)
diff --git a/Skada/Modules/CCTracker.lua b/Skada/Modules/CCTracker.lua
new file mode 100644
index 0000000..9470921
--- /dev/null
+++ b/Skada/Modules/CCTracker.lua
@@ -0,0 +1,803 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+local pairs, format, uformat = pairs, string.format, Private.uformat
+local SpellLink = Private.SpellLink or GetSpellLink
+local new, clear = Private.newTable, Private.clearTable
+local cc_table = {} -- holds stuff from cleu
+
+local function format_valuetext(d, columns, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ columns.Count and d.value,
+ columns[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+end
+
+---------------------------------------------------------------------------
+-- CC Done Module
+
+Skada:RegisterModule("CC Done", function(L, P, _, C)
+ local mode = Skada:NewModule("CC Done")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_source = mode_spell:NewModule("Source List")
+ local classfmt = Skada.classcolors.format
+ local cc_spells = Skada.extra_cc_spells -- extended list
+ local get_actor_cc_targets = nil
+ local get_cc_done_sources = nil
+ local mode_cols = nil
+
+ local function log_ccdone(set)
+ local actor = Skada:GetActor(set, cc_table.actorname, cc_table.actorid, cc_table.actorflags)
+ if not actor then return end
+
+ -- increment the count.
+ actor.ccdone = (actor.ccdone or 0) + 1
+ set.ccdone = (set.ccdone or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- record the spell.
+ local spell = actor.ccdonespells and actor.ccdonespells[cc_table.spellid]
+ if not spell then
+ actor.ccdonespells = actor.ccdonespells or {}
+ actor.ccdonespells[cc_table.spellid] = {n = 0}
+ spell = actor.ccdonespells[cc_table.spellid]
+ end
+ spell.n = spell.n + 1
+
+ -- record the target.
+ if cc_table.dstName then
+ spell.t = spell.t or {}
+ spell.t[cc_table.dstName] = (spell.t[cc_table.dstName] or 0) + 1
+ end
+ end
+
+ local function aura_applied(t)
+ if t.spellid and cc_spells[t.spellid] then
+ cc_table.actorid = t.srcGUID
+ cc_table.actorname = t.srcName
+ cc_table.actorflags = t.srcFlags
+
+ cc_table.spellid = t.spellstring
+ cc_table.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+ cc_table.srcName = nil
+
+ Skada:FixPets(cc_table)
+ Skada:DispatchSets(log_ccdone)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.ccdone
+ local spells = (total and total > 0) and actor.ccdonespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, false)
+ d.value = spell.n or spell.count
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ local targets, total, actor = get_actor_cc_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.n
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's sources"], label)
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], win.spellname)
+ if not set or not win.spellid then return end
+
+ local total, sources = get_cc_done_sources(set, win.spellid)
+ if not sources or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for sourcename, source in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.n
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["CC Done"], L[win.class]) or L["CC Done"]
+
+ local total = set and set:GetTotal(win.class, nil, "ccdone")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.ccdone then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.ccdone
+ format_valuetext(d, mode_cols, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ return set and set:GetTotal(win and win.class, nil, "ccdone") or 0
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.ccdone and set.ccdone > 0 then
+ tooltip:AddDoubleLine(L["CC Done"], set.ccdone, 1, 1, 1)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {click1 = mode_source}
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\spell_frost_chainsofice]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_source.nototal = true
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ aura_applied,
+ {src_is_interesting = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REFRESH"
+ )
+
+ Skada:AddMode(self, "Crowd Control")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ get_cc_done_sources = function(self, spellid, tbl)
+ if not self.ccdone or not spellid then return end
+
+ tbl = clear(tbl or C)
+
+ local total = 0
+ local actors = self.actors
+ for actorname, actor in pairs(actors) do
+ local spell = not actor.enemy and actor.ccdonespells and actor.ccdonespells[spellid]
+ local spell_n = spell and (spell.n or spell.count)
+ if spell_n then
+ tbl[actorname] = new()
+ tbl[actorname].id = actor.id
+ tbl[actorname].class = actor.class
+ tbl[actorname].role = actor.role
+ tbl[actorname].spec = actor.spec
+ tbl[actorname].enemy = actor.enemy
+ tbl[actorname].n = spell_n
+ total = total + spell_n
+ end
+ end
+
+ return total, tbl
+ end
+
+ get_actor_cc_targets = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local spells = actor and actor.ccdone and actor.ccdonespells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ local targets = spell.t or spell.targets
+ if targets then
+ for targetname, count in pairs(targets) do
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.n = count
+ tbl[targetname] = t
+ else
+ t.n = t.n + count
+ end
+ self:_fill_actor_table(t, targetname)
+ end
+ end
+ end
+
+ return tbl, actor.ccdone, actor
+ end
+end)
+
+---------------------------------------------------------------------------
+-- CC Taken Module
+
+Skada:RegisterModule("CC Taken", function(L, P, _, C)
+ local mode = Skada:NewModule("CC Taken")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_source = mode:NewModule("Source List")
+ local mode_target = mode_spell:NewModule("Target List")
+ local classfmt = Skada.classcolors.format
+ local get_actor_cc_sources = nil
+ local get_cc_taken_targets = nil
+ local mode_cols = nil
+
+ -- few raid spells added to the extended list of cc spells
+ local cc_spells = setmetatable({
+ [16869] = 0x10, -- Maleki the Pallid/Ossirian the Unscarred: Ice Tomb (Stratholme/??)
+ [29670] = 0x10, -- Frostwarden Sorceress: Ice Tomb (Karazhan) / Skeletal Usher: Ice Tomb (Karazhan)
+ [69065] = 0x01, -- Bone Spike: Impale (Icecrown Citadel: Lord Marrowgar)
+ [70157] = 0x10, -- Sindragosa: Ice Tomb (Icecrown Citadel)
+ [70447] = 0x40, -- Green Ooze: Volatile Ooze Adhesive (Icecrown Citadel: Professor Putricide)
+ [71289] = 0x20 -- Lady Deathwhisper: Dominate Mind (Icecrown Citadel)
+ }, {__index = Skada.extra_cc_spells})
+
+ local function log_cctaken(set)
+ local actor = Skada:GetActor(set, cc_table.actorname, cc_table.actorid, cc_table.actorflags)
+ if not actor then return end
+
+ -- increment the count.
+ actor.cctaken = (actor.cctaken or 0) + 1
+ set.cctaken = (set.cctaken or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- record the spell.
+ local spell = actor.cctakenspells and actor.cctakenspells[cc_table.spellid]
+ if not spell then
+ actor.cctakenspells = actor.cctakenspells or {}
+ actor.cctakenspells[cc_table.spellid] = {n = 0}
+ spell = actor.cctakenspells[cc_table.spellid]
+ end
+ spell.n = spell.n + 1
+
+ -- record the source.
+ if cc_table.srcName then
+ spell.sources = spell.sources or {}
+ spell.sources[cc_table.srcName] = (spell.sources[cc_table.srcName] or 0) + 1
+ end
+ end
+
+ local function aura_applied(t)
+ if t.spellid and cc_spells[t.spellid] then
+ cc_table.actorid = t.dstGUID
+ cc_table.actorname = t.dstName
+ cc_table.actorflags = t.dstFlags
+
+ cc_table.spellid = t.spellstring
+ cc_table.srcName = Skada:FixPetsName(t.srcGUID, t.srcName, t.srcFlags)
+ cc_table.dstName = nil
+
+ Skada:DispatchSets(log_cctaken)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.cctaken
+ local spells = (total and total > 0) and actor.cctakenspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, false)
+ d.value = spell.n or spell.count
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode_source:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's sources"], classfmt(class, label))
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], classfmt(win.actorclass, win.actorname))
+
+ local sources, total, actor = get_actor_cc_sources(set, win.actorname, win.actorid)
+ if not sources or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for sourcename, source in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, true, sourcename)
+ d.value = source.n
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's targets"], label)
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], win.spellname)
+ if not set or not win.spellid then return end
+
+ local total, targets = get_cc_taken_targets(set, win.spellid)
+ if not targets or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.n
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["CC Taken"], L[win.class]) or L["CC Taken"]
+
+ local total = set and set:GetTotal(win.class, nil, "cctaken")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.cctaken then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.cctaken
+ format_valuetext(d, mode_cols, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ return set and set:GetTotal(win and win.class, nil, "cctaken") or 0
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.cctaken and set.cctaken > 0 then
+ tooltip:AddDoubleLine(L["CC Taken"], set.cctaken, 1, 1, 1)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {click1 = mode_target}
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_source,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\spell_magic_polymorphrabbit]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_source.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ aura_applied,
+ {dst_is_interesting_nopets = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REFRESH"
+ )
+
+ Skada:AddMode(self, "Crowd Control")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ get_cc_taken_targets = function(self, spellid, tbl)
+ if not self.cctaken or not spellid then return end
+
+ tbl = clear(tbl or C)
+
+ local total = 0
+ local actors = self.actors
+ for actorname, actor in pairs(actors) do
+ local spell = not actor.enemy and actor.cctakenspells and actor.cctakenspells[spellid]
+ local spell_n = spell and (spell.n or spell.count)
+ if spell_n then
+ tbl[actorname] = new()
+ tbl[actorname].id = actor.id
+ tbl[actorname].class = actor.class
+ tbl[actorname].role = actor.role
+ tbl[actorname].spec = actor.spec
+ tbl[actorname].enemy = actor.enemy
+ tbl[actorname].n = spell_n
+ total = total + spell_n
+ end
+ end
+
+ return total, tbl
+ end
+
+ get_actor_cc_sources = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local spells = actor and actor.cctaken and actor.cctakenspells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ if spell.sources then
+ for sourcename, count in pairs(spell.sources) do
+ local t = tbl[sourcename]
+ if not t then
+ t = new()
+ t.n = count
+ tbl[sourcename] = t
+ else
+ t.n = t.n + count
+ end
+ self:_fill_actor_table(t, sourcename)
+ end
+ end
+ end
+
+ return tbl, actor.cctaken, actor
+ end
+end)
+
+---------------------------------------------------------------------------
+-- CC Breaks Module
+
+Skada:RegisterModule("CC Breaks", function(L, P, _, C, M, O)
+ local mode = Skada:NewModule("CC Breaks")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local classfmt = Skada.classcolors.format
+ local cc_spells = Skada.cc_spells
+ local get_actor_cc_break_targets = nil
+ local mode_cols = nil
+
+ local UnitName, UnitInRaid, IsInRaid = UnitName, UnitInRaid, IsInRaid
+ local GetPartyAssignment, UnitIterator = GetPartyAssignment, Skada.UnitIterator
+
+ local function log_ccbreak(set)
+ local actor = Skada:GetActor(set, cc_table.actorname, cc_table.actorid, cc_table.actorflags)
+ if not actor then return end
+
+ -- increment the count.
+ actor.ccbreak = (actor.ccbreak or 0) + 1
+ set.ccbreak = (set.ccbreak or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- record the spell.
+ local spell = actor.ccbreakspells and actor.ccbreakspells[cc_table.spellid]
+ if not spell then
+ actor.ccbreakspells = actor.ccbreakspells or {}
+ actor.ccbreakspells[cc_table.spellid] = {n = 0}
+ spell = actor.ccbreakspells[cc_table.spellid]
+ end
+ spell.n = spell.n + 1
+
+ -- record the target.
+ if cc_table.dstName then
+ spell.t = spell.t or {}
+ spell.t[cc_table.dstName] = (spell.t[cc_table.dstName] or 0) + 1
+ end
+ end
+
+ local function aura_broken(t)
+ if not t.spellid or not cc_spells[t.spellid] then return end
+
+ local srcGUID, srcName, srcFlags = t.srcGUID, t.srcName, t.srcFlags
+ local _srcGUID, _srcName, _srcFlags = Skada:FixMyPets(srcGUID, srcName, srcFlags)
+
+ cc_table.actorid = _srcGUID
+ cc_table.actorname = _srcName
+ cc_table.actorflags = _srcFlags
+
+ cc_table.spellid = t.spellstring
+ cc_table.dstName = t.dstName
+ cc_table.srcName = nil
+
+ Skada:DispatchSets(log_ccbreak)
+
+ -- Optional announce
+ if M.ccannounce and IsInRaid() and UnitInRaid(srcName) then
+ if Skada.insType == "pvp" then return end
+
+ -- Ignore main tanks and main assist?
+ if M.ccignoremaintanks then
+ -- Loop through our raid and return if src is a main tank.
+ for unit in UnitIterator(true) do -- exclude pets
+ if UnitName(unit) == srcName and (GetPartyAssignment("MAINTANK", unit) or GetPartyAssignment("MAINASSIST", unit)) then
+ return
+ end
+ end
+ end
+
+ -- Prettify pets.
+ if srcName ~= _srcName then
+ srcName = format("%s <%s>", srcName, _srcName)
+ end
+
+ -- Go ahead and announce it.
+ if t.extraspellid or t.extraspellname then
+ Skada:SendChat(format(L["%s on %s removed by %s's %s"], t.spellname, t.dstName, srcName, SpellLink(t.extraspellid or t.extraspellname)), "RAID", "preset")
+ else
+ Skada:SendChat(format(L["%s on %s removed by %s"], t.spellname, t.dstName, srcName), "RAID", "preset")
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.ccbreak
+ local spells = (total and total > 0) and actor.ccbreakspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, false)
+ d.value = spell.n or spell.count
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ local targets, total, actor = get_actor_cc_break_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.n
+ format_valuetext(d, mode_cols, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["CC Breaks"], L[win.class]) or L["CC Breaks"]
+
+ local total = set and set:GetTotal(win.class, nil, "ccbreak")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.ccbreak then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.ccbreak
+ format_valuetext(d, mode_cols, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ return set and set:GetTotal(win and win.class, nil, "ccbreak") or 0
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.ccbreak and set.ccbreak > 0 then
+ tooltip:AddDoubleLine(L["CC Breaks"], set.ccbreak, 1, 1, 1)
+ end
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\spell_holy_sealofvalor]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ aura_broken,
+ {src_is_interesting = true},
+ "SPELL_AURA_BROKEN",
+ "SPELL_AURA_BROKEN_SPELL"
+ )
+
+ Skada:AddMode(self, "Crowd Control")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ function mode:OnInitialize()
+ O.modules.args.ccoptions = {
+ type = "group",
+ name = self.localeName,
+ desc = format(L["Options for %s."], self.localeName),
+ args = {
+ header = {
+ type = "description",
+ name = self.localeName,
+ fontSize = "large",
+ image = [[Interface\ICONS\spell_holy_sealofvalor]],
+ imageWidth = 18,
+ imageHeight = 18,
+ imageCoords = Skada.cropTable,
+ width = "full",
+ order = 0
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ ccannounce = {
+ type = "toggle",
+ name = format(L["Announce %s"], self.localeName),
+ order = 10,
+ width = "double"
+ },
+ ccignoremaintanks = {
+ type = "toggle",
+ name = L["Ignore Main Tanks"],
+ order = 20,
+ width = "double"
+ }
+ }
+ }
+ end
+
+ get_actor_cc_break_targets = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local spells = actor and actor.ccbreak and actor.ccbreakspells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ local targets = spell.t or spell.targets
+ if targets then
+ for targetname, count in pairs(targets) do
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.n = count
+ tbl[targetname] = t
+ else
+ t.n = t.n + count
+ end
+ self:_fill_actor_table(t, targetname)
+ end
+ end
+ end
+
+ return tbl, actor.ccbreak, actor
+ end
+end)
diff --git a/Skada/Modules/Comparison.lua b/Skada/Modules/Comparison.lua
new file mode 100644
index 0000000..ff3bd95
--- /dev/null
+++ b/Skada/Modules/Comparison.lua
@@ -0,0 +1,830 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Comparison", function(L, P)
+ local parent = Skada:GetModule("Damage", true)
+ if not parent then return end
+
+ local mode = parent:NewModule("Comparison")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_details = mode_spell:NewModule("Spell Details")
+ local mode_spell_breakdown = mode_spell:NewModule("More Details")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local C = Skada.cacheTable2
+
+ local pairs, max = pairs, math.max
+ local format, uformat = string.format, Private.uformat
+ local tooltip_school = Skada.tooltip_school
+ local classfmt = Skada.classcolors.format
+ local COLOR_GOLD = {r = 1, g = 0.82, b = 0, colorStr = "ffffd100"}
+ local userid = Skada.userGUID
+ local username = Skada.userName
+ local userclass = Skada.userClass
+ local mode_cols = nil
+
+ -- damage miss types
+ local missTypes = Skada.missTypes
+
+ -- percentage colors
+ local red = "\124cffffaaaa-%s\124r"
+ local green = "\124cffaaffaa+%s\124r"
+ local grey = "\124cff808080%s\124r"
+
+ local function format_percent(value1, value2, cond)
+ if cond == false then return end
+
+ value1, value2 = value1 or 0, value2 or 0
+ if value1 == value2 then
+ return format(grey, Skada:FormatPercent(0))
+ elseif value1 > value2 then
+ return format(green, Skada:FormatPercent(value1 - value2, value2))
+ else
+ return format(red, Skada:FormatPercent(value2 - value1, value1))
+ end
+ end
+
+ local function format_value_percent(val, oval, disabled)
+ val, oval = val or 0, oval or 0
+ return Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatPercent(val),
+ (mode_cols.Comparison and not disabled) and Skada:FormatPercent(oval),
+ format_percent(oval, val, mode_cols.Percent and not disabled)
+ )
+ end
+
+ local function format_value_number(val, oval, fmt, disabled)
+ val, oval = val or 0, oval or 0 -- sanity check
+ return Skada:FormatValueCols(
+ mode_cols.Damage and (fmt and Skada:FormatNumber(val) or val),
+ (mode_cols.Comparison and not disabled) and (fmt and Skada:FormatNumber(oval) or oval),
+ format_percent(oval, val, mode_cols.Percent and not disabled)
+ )
+ end
+
+ local function can_compare(actor, otherclass)
+ return (actor and not actor.enemy and actor.class == otherclass and actor.role == "DAMAGER")
+ end
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ if label == L["Critical Hits"] or label == L["Normal Hits"] or label == L["Glancing"] then
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor.damagespells and actor.damagespells[win.spellid]
+ local otherid = win.otherid
+
+ if actor.id == otherid then
+ if spell then
+ tooltip:AddLine(uformat("%s - %s", win.actorname, win.spellname))
+ tooltip_school(tooltip, win.spellid)
+
+ if label == L["Critical Hits"] and spell.c_amt then
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ elseif label == L["Normal Hits"] and spell.n_amt then
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ elseif label == L["Glancing"] and spell.g_amt then
+ if spell.g_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.g_min), 1, 1, 1)
+ end
+ if spell.g_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.g_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.g_amt / spell.g_num), 1, 1, 1)
+ end
+ end
+ return
+ end
+
+ local othername = win.othername
+ local oactor = set and set:GetActor(othername, otherid)
+ local ospell = oactor and oactor.damagespells and oactor.damagespells[win.spellid]
+
+ if spell or ospell then
+ tooltip:AddLine(uformat(L["%s vs %s: %s"], win.actorname, othername, win.spellname))
+ tooltip_school(tooltip, win.spellid)
+
+ if label == L["Critical Hits"] and (spell and spell.c_amt or ospell.c_amt) then
+ if (spell and spell.c_min) or (ospell and ospell.c_min) then
+ tooltip:AddDoubleLine(L["Minimum"], format_value_number(spell and spell.c_min, ospell and ospell.c_min, true), 1, 1, 1)
+ end
+
+ if (spell and spell.c_max) or (ospell and ospell.c_max) then
+ tooltip:AddDoubleLine(L["Maximum"], format_value_number(spell and spell.c_max, ospell and ospell.c_max, true), 1, 1, 1)
+ end
+
+ local num = (spell and spell.c_amt) and (spell.c_amt / spell.c_num)
+ local onum = (ospell and ospell.c_amt) and (ospell.c_amt / ospell.c_num)
+ tooltip:AddDoubleLine(L["Average"], format_value_number(num, onum, true), 1, 1, 1)
+ elseif label == L["Normal Hits"] and ((spell and spell.n_amt) or (ospell and ospell.n_amt)) then
+ if (spell and spell.n_min) or (ospell and ospell.n_min) then
+ tooltip:AddDoubleLine(L["Minimum"], format_value_number(spell and spell.n_min, ospell and ospell.n_min, true), 1, 1, 1)
+ end
+
+ if (spell and spell.n_max) or (ospell and ospell.n_max) then
+ tooltip:AddDoubleLine(L["Maximum"], format_value_number(spell and spell.n_max, ospell and ospell.n_max, true), 1, 1, 1)
+ end
+
+ local num = (spell and spell.n_amt) and (spell.n_amt / spell.n_num)
+ local onum = (ospell and ospell.n_amt) and (ospell.n_amt / ospell.n_num)
+ tooltip:AddDoubleLine(L["Average"], format_value_number(num, onum, true), 1, 1, 1)
+ elseif label == L["Glancing"] and ((spell and spell.g_amt) or (ospell and ospell.g_amt)) then
+ local num = (spell and spell.g_amt) and (spell.g_amt / spell.g_num)
+ local onum = (ospell and ospell.g_amt) and (ospell.g_amt / ospell.g_num)
+
+ if (spell and spell.g_min) or (ospell and ospell.g_min) then
+ tooltip:AddDoubleLine(L["Minimum"], format_value_number(spell and spell.g_min, ospell and ospell.g_min, true), 1, 1, 1)
+ end
+
+ if (spell and spell.g_max) or (ospell and ospell.g_max) then
+ tooltip:AddDoubleLine(L["Maximum"], format_value_number(spell and spell.g_max, ospell and ospell.g_max, true), 1, 1, 1)
+ end
+
+ tooltip:AddDoubleLine(L["Average"], format_value_number(num, onum, true), 1, 1, 1)
+ end
+ end
+ end
+ end
+
+ local function activity_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ local otherid = actor and win.otherid
+ if otherid then
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local oactivetime = set:GetActorTime(win.othername, otherid, true)
+
+ tooltip:AddDoubleLine(L["Activity"], format_value_percent(100 * activetime / totaltime, 100 * oactivetime / totaltime, actor.id == otherid), nil, nil, nil, 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], format(actor.id ~= otherid and "%s (%s)" or "%s", Skada:FormatTime(activetime), Skada:FormatTime(oactivetime)), 1, 1, 1)
+ end
+ end
+
+ -- local nr = add_detail_bar(win, 0, L["Hits"], spell.count, ospell.count)
+ local function add_detail_bar(win, nr, title, value, ovalue, fmt, disabled)
+ nr = nr + 1
+ local d = win:nr(nr)
+
+ d.id = title
+ d.label = title
+ d.value = value or 0
+
+ d.valuetext = format_value_number(value, ovalue or 0, fmt, disabled)
+
+ if win.metadata and (not win.metadata.maxvalue or d.value > win.metadata.maxvalue) then
+ win.metadata.maxvalue = d.value
+ end
+
+ return nr
+ end
+
+ function mode_spell_details:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+
+ if win.actorname == win.othername then
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), format(L["%s's details"], label))
+ else
+ win.title = uformat(L["%s vs %s: %s"], classfmt(win.actorclass, win.actorname), classfmt(win.otherclass, win.othername), uformat(L["%s's details"], win.spellname))
+ end
+ end
+
+ function mode_spell_details:Tooltip(win, set, id, label, tooltip)
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagespells and actor.damagespells[id]
+ local otherid = win.otherid
+
+ if spell and actor.id == otherid then
+ if spell.count then
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ end
+
+ return actor, spell
+ end
+
+ local oactor = set and set:GetActor(win.othername, win.otherid)
+ local ospell = oactor and oactor.damagespells and oactor.damagespells[id]
+
+ -- hits
+ if (spell and spell.count) or (ospell and ospell.count) then
+ tooltip:AddDoubleLine(L["Hits"], format_value_number(spell and spell.count, ospell and ospell.count, true), 1, 1, 1)
+ end
+
+ return actor, spell, oactor, ospell
+ end
+
+ function mode_spell_details:Update(win, set, actor, spell, oactor, ospell)
+ if not actor or not spell then
+ actor = set and set:GetActor(win.actorname, win.actorid)
+ spell = actor and actor.damagespells and actor.damagespells[win.spellid]
+ end
+
+ -- same actor?
+ local otherid = win.otherid
+ if spell and actor and actor.id == otherid then
+ win.title = format("%s: %s", classfmt(win.actorclass, win.actorname), format(L["%s's details"], win.spellname))
+
+ if win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+
+ if spell.n_num and spell.n_num > 0 then
+ nr = add_detail_bar(win, nr, L["Normal Hits"], spell.n_num, nil, nil, true)
+ end
+
+ if spell.c_num and spell.c_num > 0 then
+ nr = add_detail_bar(win, nr, L["Critical Hits"], spell.c_num, nil, nil, true)
+ end
+
+ if spell.g_num and spell.g_num > 0 then
+ nr = add_detail_bar(win, nr, L["Glancing"], spell.g_num, nil, nil, true)
+ end
+
+ for k, v in pairs(missTypes) do
+ if spell[v] or spell[k] then
+ nr = add_detail_bar(win, nr, L[k], spell[v] or spell[k], nil, nil, true)
+ end
+ end
+
+ return
+ end
+
+ win.title = uformat(L["%s vs %s: %s"], classfmt(win.actorclass, win.actorname), classfmt(win.otherclass, win.othername), uformat(L["%s's details"], win.spellname))
+
+ if not oactor or not ospell then
+ oactor = set and set:GetActor(win.othername, otherid)
+ ospell = oactor and oactor.damagespells and oactor.damagespells[win.spellid]
+ end
+
+ if spell or ospell then
+ if win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+
+ if (spell and spell.n_num and spell.n_num > 0) or (ospell and ospell.n_num and ospell.n_num > 0) then
+ nr = add_detail_bar(win, nr, L["Normal Hits"], spell and spell.n_num, ospell and ospell.n_num)
+ end
+
+ if (spell and spell.c_num and spell.c_num > 0) or (ospell and ospell.c_num and ospell.c_num > 0) then
+ nr = add_detail_bar(win, nr, L["Critical Hits"], spell and spell.c_num, ospell and ospell.c_num)
+ end
+
+ if (spell and spell.g_num and spell.g_num > 0) or (ospell and ospell.g_num and ospell.g_num > 0) then
+ nr = add_detail_bar(win, nr, L["Glancing"], spell and spell.g_num, ospell and ospell.g_num)
+ end
+
+ for k, v in pairs(missTypes) do
+ if (spell and (spell[v] or spell[k])) or (ospell and (ospell[v] or ospell[k])) then
+ nr = add_detail_bar(win, nr, L[k], spell and (spell[v] or spell[k]), ospell and (ospell[v] or ospell[k]))
+ end
+ end
+ end
+ end
+
+ function mode_spell_breakdown:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s vs %s: %s"], classfmt(win.actorclass, win.actorname), classfmt(win.otherclass, win.othername), label)
+ end
+
+ function mode_spell_breakdown:Tooltip(win, set, id, label, tooltip)
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagespells and actor.damagespells[id]
+ local otherid = win.otherid
+
+ if spell and actor.id == otherid then
+ local total = spell.total or spell.amount
+ if spell.r_amt then
+ total = total + spell.r_amt
+ end
+ if spell.b_amt then
+ total = total + spell.b_amt
+ end
+
+ tooltip:AddDoubleLine(L["Total"], Skada:FormatNumber(total), 1, 1, 1)
+ return actor, spell, total
+ end
+
+ local oactor = set and set:GetActor(win.othername, otherid)
+ local ospell = oactor and oactor.damagespells and oactor.damagespells[id]
+ if spell or ospell then
+ local total = spell and (spell.total or spell.amount) or 0
+ if spell and spell.r_amt then
+ total = total + spell.r_amt
+ end
+ if spell and spell.b_amt then
+ total = total + spell.b_amt
+ end
+
+ local ototal = ospell and (ospell.total or ospell.amount) or 0
+ if ospell and ospell.r_amt then
+ ototal = ototal + ospell.r_amt
+ end
+ if ospell and ospell.b_amt then
+ ototal = ototal + ospell.b_amt
+ end
+
+ tooltip:AddDoubleLine(L["Total"], format_value_number(total, ototal, true), 1, 1, 1)
+ return actor, spell, oactor, ospell
+ end
+
+ end
+
+ function mode_spell_breakdown:Update(win, set, actor, spell, oactor, ospell)
+ local othername, otherclass = win.othername, win.otherclass
+ win.title = uformat(L["%s vs %s: %s"], classfmt(win.actorclass, win.actorname), classfmt(otherclass, othername), win.spellname)
+
+ if not set or not win.spellid then return end
+
+ if not actor or not spell then
+ actor = set:GetActor(win.actorname, win.actorid)
+ spell = actor and actor.damagespells and actor.damagespells[win.spellid]
+ end
+
+ local otherid = win.otherid
+ if spell and actor and actor.id == otherid then
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), win.spellname)
+
+ local nr = add_detail_bar(win, 0, L["Damage"], spell.amount, nil, true, true)
+
+ -- absorbed damage
+ if spell.total and spell.total ~= spell.amount then
+ nr = add_detail_bar(win, nr, L["ABSORB"], max(0, spell.total - spell.amount), nil, true, true)
+ end
+
+ -- resisted damage
+ if spell.r_amt and spell.r_amt > 0 then
+ nr = add_detail_bar(win, nr, L["RESIST"], spell.r_amt, nil, true, true)
+ end
+
+ -- blocked damage
+ if spell.b_amt and spell.b_amt > 0 then
+ nr = add_detail_bar(win, nr, L["BLOCK"], spell.b_amt, nil, true, true)
+ end
+
+ -- overkill damage
+ if spell.o_amt and spell.o_amt > 0 then
+ nr = add_detail_bar(win, nr, L["Overkill"], spell.o_amt, nil, true, true)
+ end
+
+ return
+ end
+
+ if not oactor or not ospell then
+ oactor = set and set:GetActor(othername, otherid)
+ ospell = oactor and oactor.damagespells and oactor.damagespells[win.spellid]
+ end
+
+ if spell or ospell then
+ -- damage done
+ local nr = add_detail_bar(win, 0, L["Damage"], spell and spell.amount, ospell and ospell.amount, true)
+
+ -- resisted damage
+ local r_amt1 = spell and spell.r_amt
+ local r_amt2 = ospell and ospell.r_amt
+ if (r_amt1 and r_amt1 > 0) or (r_amt2 and r_amt2 > 0) then
+ nr = add_detail_bar(win, nr, L["RESIST"], r_amt1, r_amt2, true)
+ end
+
+ -- blocked damage
+ local b_amt1 = spell and spell.b_amt
+ local b_amt2 = ospell and ospell.b_amt
+ if (b_amt1 and b_amt1 > 0) or (b_amt2 and b_amt2 > 0) then
+ nr = add_detail_bar(win, nr, L["RESIST"], b_amt1, b_amt2, true)
+ end
+
+ -- overkill damage
+ local o_amt1 = spell and spell.o_amt
+ local o_amt2 = ospell and ospell.o_amt
+ if (o_amt1 and o_amt1 > 0) or (o_amt2 and o_amt2 > 0) then
+ nr = add_detail_bar(win, nr, L["Overkill"], o_amt1, o_amt2, true)
+ end
+
+ -- absorbed damage
+ local a_amt1 = spell and spell.total and spell.total ~= spell.amount and max(0, spell.total - spell.amount)
+ local a_amt2 = ospell and ospell.total and ospell.total ~= ospell.amount and max(0, ospell.total - ospell.amount)
+ if (a_amt1 and a_amt1 > 0) or (a_amt2 and a_amt2 > 0) then
+ nr = add_detail_bar(win, nr, L["ABSORB"], a_amt1, a_amt2, true)
+ end
+
+ -- glancing
+ local g_amt1 = spell and spell.g_amt
+ local g_amt2 = ospell and ospell.g_amt
+ if (g_amt1 and g_amt1 > 0) or (g_amt2 and g_amt2 > 0) then
+ nr = add_detail_bar(win, nr, L["Glancing"], g_amt1, g_amt2, true)
+ end
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s vs %s: %s"], classfmt(win.actorclass, win.actorname), classfmt(win.otherclass, win.othername), format(L["Spells on %s"], classfmt(class, label)))
+ end
+
+ function mode_target_spell:Update(win, set)
+ local othername, otherclass = win.othername, win.otherclass
+ win.title = uformat(L["%s vs %s: %s"], classfmt(win.actorclass, win.actorname), classfmt(otherclass, othername), uformat(L["Spells on %s"], classfmt(win.targetclass, win.targetname)))
+
+ if not set or not win.targetname then return end
+
+ local targets, _, actor = set:GetActorDamageTargets(win.actorname, win.actorid)
+ if not targets then return end
+
+ local otherid = win.otherid
+ if actor.id == otherid then
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+
+ local total = targets[win.targetname] and targets[win.targetname].amount
+ if P.absdamage and targets[win.targetname].total then
+ total = targets[win.targetname].total
+ end
+
+ local spells = (total and total > 0) and actor.damagespells
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ local target = spell.targets and spell.targets[win.targetname]
+ local amount = target and (P.absdamage and target.total or target.amount)
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = amount
+ d.valuetext = Skada:FormatValueCols(mode_cols.Damage and Skada:FormatNumber(d.value))
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+
+ return
+ end
+
+ local otargets, _, oactor = set:GetActorDamageTargets(othername, otherid, C)
+
+ -- the compared actor
+ local total = targets[win.targetname] and targets[win.targetname].amount
+ if P.absdamage and targets[win.targetname].total then
+ total = targets[win.targetname].total
+ end
+
+ -- existing targets.
+ local spells = (total and total > 0) and actor.damagespells
+ if spells then
+ if win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ if spell.targets and spell.targets[win.targetname] then
+ nr = nr + 1
+ local d = win:spell(nr, spellid)
+
+ d.value = spell.targets[win.targetname].amount or 0
+ local oamount = 0
+ if
+ oactor and
+ oactor.damagespells and
+ oactor.damagespells[spellid] and
+ oactor.damagespells[spellid].targets and
+ oactor.damagespells[spellid].targets[win.targetname]
+ then
+ oamount = oactor.damagespells[spellid].targets[win.targetname].amount or oamount
+ end
+
+ if P.absdamage then
+ if spell.targets[win.targetname].total then
+ d.value = spell.targets[win.targetname].total
+ end
+ if
+ oactor and
+ oactor.damagespells and
+ oactor.damagespells[spellid] and
+ oactor.damagespells[spellid].targets and
+ oactor.damagespells[spellid].targets[win.targetname] and
+ oactor.damagespells[spellid].targets[win.targetname].total
+ then
+ oamount = oactor.damagespells[spellid].targets[win.targetname].total
+ end
+ end
+
+ d.valuetext = format_value_number(d.value, oamount, true)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+
+ return
+ end
+
+ -- unexisting targets.
+ if not otargets then return end
+ total = otargets[win.targetname] and otargets[win.targetname].amount
+ if P.absdamage and otargets[win.targetname].total then
+ total = otargets[win.targetname].total
+ end
+
+ spells = (total and total > 0) and oactor.damagespells
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ local target = spell.targets and spell.targets[win.targetname]
+ local amount = target and (P.absdamage and target.total or target.amount)
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = amount
+ d.valuetext = format_value_number(0, amount, true)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ if label == win.othername then
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ else
+ win.title = uformat(L["%s vs %s: Spells"], classfmt(class, label), classfmt(win.otherclass, win.othername))
+ end
+ end
+
+ function mode_spell:Update(win, set)
+ local othername, otherclass = win.othername, win.otherclass
+ win.title = uformat(L["%s vs %s: Spells"], classfmt(win.actorclass, win.actorname), classfmt(otherclass, othername))
+
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local spells = actor and actor.damagespells
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local otherid = win.otherid
+
+ -- same actor?
+ if actor.id == otherid then
+ win.title = uformat(L["%s's spells"], classfmt(otherclass, othername))
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount or 0
+ d.valuetext = Skada:FormatValueCols(mode_cols.Damage and Skada:FormatNumber(d.value))
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+
+ return
+ end
+
+ -- collect compared actor's spells.
+ local oactor = set and set:GetActor(othername, otherid)
+ local ospells = oactor and oactor.damagespells
+
+ -- iterate comparison actor's spells.
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+
+ local ospell = ospells and ospells[spellid]
+ local oamount = ospell and (P.absdamage and ospell.total or ospell.amount)
+ d.valuetext = format_value_number(d.value, oamount, true)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+
+ -- any other left spells.
+ if not ospells then return end
+ for spellid, spell in pairs(ospells) do
+ if not spells[spellid] then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+ d.valuetext = format_value_number(0, d.value, true)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ if label == win.othername then
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ else
+ win.title = uformat(L["%s vs %s: Targets"], classfmt(class, label), classfmt(win.otherclass, win.othername))
+ end
+ end
+
+ function mode_target:Update(win, set)
+ local othername, otherclass = win.othername, win.otherclass
+ win.title = uformat(L["%s vs %s: Targets"], classfmt(win.actorclass, win.actorname), classfmt(otherclass, othername))
+
+ if not set or not win.actorname then return end
+
+ local targets, _, actor = set:GetActorDamageTargets(win.actorname, win.actorid)
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local otherid = win.otherid
+
+ -- same actor?
+ if actor.id == otherid then
+ win.title = format(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = P.absdamage and target.total or target.amount
+ d.valuetext = Skada:FormatValueCols(mode_cols.Damage and Skada:FormatNumber(d.value))
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+
+ return
+ end
+
+ -- collect compared actor's targets.
+ local otargets = set:GetActorDamageTargets(othername, otherid, C)
+
+ -- iterate comparison actor's targets.
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = P.absdamage and target.total or target.amount
+
+ local otarget = otargets and otargets[targetname]
+ local oamount = otarget and (P.absdamage and otarget.total or otarget.amount)
+ d.valuetext = format_value_number(d.value, oamount, true, actor.id == otherid)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+
+ -- any other left targets.
+ if not otargets then return end
+ for targetname, target in pairs(otargets) do
+ if not targets[targetname] then
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = P.absdamage and target.total or target.amount
+ d.valuetext = format_value_number(0, d.value, true, actor.id == otherid)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ local othername, otherclass = win.othername, win.otherclass
+ win.title = format("%s: %s", L["Comparison"], classfmt(otherclass, othername))
+
+ local total = set and set:GetDamage()
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local otherid, nr = win.otherid, 0
+ local oamount = set:GetActorDamage(othername, otherid)
+
+ for actorname, actor in pairs(set.actors) do
+ if can_compare(actor, otherclass) then
+ local dps, amount = actor:GetDPS(set, false, false, not mode_cols.DPS)
+ if amount > 0 then
+ nr = nr + 1
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+
+ d.value = amount
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(d.value),
+ mode_cols.DPS and Skada:FormatNumber(dps),
+ format_percent(oamount, d.value, mode_cols.Percent and actor.id ~= otherid)
+ )
+
+ -- a valid window, not a tooltip
+ if win.metadata then
+ -- color the selected actor's bar.
+ if actor.id == otherid then
+ d.color = COLOR_GOLD
+ elseif d.color then
+ d.color = nil
+ end
+
+ -- order bars.
+ if not win.metadata.maxvalue or d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+ end
+ end
+ end
+
+ local function set_actor(win, id, label, class)
+ if not win or not win.DisplayMode then return end
+
+ userid = userid or Skada.userGUID
+ username = username or Skada.userName
+ userclass = userclass or Skada.userClass
+
+ -- same actor or me? reset to the actor
+ if id == userid or (id == win.otherid and win.selectedmode == mode) then
+ win.otherid, win.othername, win.otherclass = userid, username, userclass
+ win:DisplayMode(mode)
+ return
+ end
+
+ win.otherid, win.othername, win.otherclass = id, label, class
+ win:DisplayMode(mode)
+ end
+
+ function mode:OnEnable()
+ mode_spell_details.metadata = {tooltip = mode_spell_tooltip}
+ mode_target.metadata = {click1 = mode_target_spell}
+ mode_spell.metadata = {click1 = mode_spell_details, click2 = mode_spell_breakdown}
+ self.metadata = {
+ showspots = true,
+ tooltip = activity_tooltip,
+ click1 = mode_spell,
+ click2 = mode_target,
+ click3 = set_actor,
+ click3_label = L["Comparison"],
+ columns = {Damage = true, DPS = true, Comparison = true, Percent = true},
+ icon = [[Interface\ICONS\Ability_Warrior_OffensiveStance]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ self.nototal = true
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ self.category = parent.category or L["Damage Done"]
+ Skada:AddColumnOptions(self)
+
+ parent.metadata.click3 = set_actor
+ parent.metadata.click3_label = L["Comparison"]
+ parent:Reload()
+ end
+end, "Damage")
diff --git a/Skada/Modules/Damage.lua b/Skada/Modules/Damage.lua
new file mode 100644
index 0000000..d29fd9a
--- /dev/null
+++ b/Skada/Modules/Damage.lua
@@ -0,0 +1,1785 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+local pairs, format, max, uformat = pairs, string.format, math.max, Private.uformat
+local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+
+local function format_valuetext(d, columns, total, dps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ columns.Damage and Skada:FormatNumber(d.value),
+ columns[subview and "sDPS" or "DPS"] and dps and Skada:FormatNumber(dps),
+ columns[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+end
+
+---------------------------------------------------------------------------
+-- Damage Done Module
+
+Skada:RegisterModule("Damage", function(L, P)
+ local mode = Skada:NewModule("Damage")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_details = mode_spell:NewModule("Spell Details")
+ local mode_spell_breakdown = mode_spell:NewModule("More Details")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+
+ local wipe, min = wipe, math.min
+ local PercentToRGB = Private.PercentToRGB
+ local GetCreatureId = Skada.GetCreatureId
+ local classfmt = Skada.classcolors.format
+ local tooltip_school = Skada.tooltip_school
+ local ignored_spells = Skada.ignored_spells.damage -- Edit Skada\Core\Tables.lua
+ local passive_spells = Skada.ignored_spells.time -- Edit Skada\Core\Tables.lua
+ local ignored_creatures = Skada.ignored_creatures -- Edit Skada\Core\Tables.lua
+ local missTypes = Skada.missTypes
+ local mode_cols = nil
+
+ -- spells on the list below are used to update actor's active time
+ -- no matter their role or damage amount, since pets aren't considered.
+ local whitelist = {}
+
+ local function add_actor_time(set, actor, spellid, target)
+ if whitelist[spellid] then
+ Skada:AddActiveTime(set, actor, target, tonumber(whitelist[spellid]))
+ elseif actor.role ~= "HEALER" and not passive_spells[spellid] then
+ Skada:AddActiveTime(set, actor, target, tonumber(whitelist[spellid]))
+ end
+ end
+
+ local dmg = {}
+ local function log_damage(set)
+ if not dmg.amount then return end
+
+ local actor = Skada:GetActor(set, dmg.actorname, dmg.actorid, dmg.actorflags)
+ if not actor then
+ return
+ elseif dmg.amount > 0 and not dmg.petname then
+ add_actor_time(set, actor, dmg.spell, dmg.dstName)
+ end
+
+ actor.damage = (actor.damage or 0) + dmg.amount
+ set.damage = (set.damage or 0) + dmg.amount
+
+ -- add pet damage
+ if dmg.petname then
+ actor.petdamage = (actor.petdamage or 0) + dmg.amount
+ end
+
+ -- absorbed damage
+ local absorbed = dmg.absorbed or 0
+
+ if actor.totaldamage then
+ actor.totaldamage = actor.totaldamage + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ actor.totaldamage = actor.damage + absorbed
+ end
+
+ if set.totaldamage then
+ set.totaldamage = set.totaldamage + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ set.totaldamage = set.damage + absorbed
+ end
+
+ if dmg.petname and actor.pettotaldamage then
+ actor.pettotaldamage = actor.pettotaldamage + dmg.amount + absorbed
+ elseif dmg.petname and absorbed > 0 then
+ actor.pettotaldamage = actor.petdamage + absorbed
+ end
+
+ -- add the damage overkill
+ local overkill = (dmg.overkill and dmg.overkill > 0) and dmg.overkill or nil
+ if overkill then
+ set.overkill = (set.overkill or 0) + dmg.overkill
+ actor.overkill = (actor.overkill or 0) + dmg.overkill
+ end
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- spell
+ local spell = actor.damagespells and actor.damagespells[dmg.spellid]
+ if not spell then
+ actor.damagespells = actor.damagespells or {}
+ actor.damagespells[dmg.spellid] = {amount = 0}
+ spell = actor.damagespells[dmg.spellid]
+ end
+
+ spell.count = (spell.count or 0) + 1
+ spell.amount = spell.amount + dmg.amount
+
+ if spell.total then
+ spell.total = spell.total + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ spell.total = spell.amount + absorbed
+ end
+
+ if overkill then
+ spell.o_amt = (spell.o_amt or 0) + overkill
+ end
+
+ if dmg.critical then
+ spell.c_num = (spell.c_num or 0) + 1
+ spell.c_amt = (spell.c_amt or 0) + dmg.amount
+
+ if not spell.c_max or dmg.amount > spell.c_max then
+ spell.c_max = dmg.amount
+ end
+
+ if not spell.c_min or dmg.amount < spell.c_min then
+ spell.c_min = dmg.amount
+ end
+ elseif dmg.misstype ~= nil and missTypes[dmg.misstype] then
+ spell[missTypes[dmg.misstype]] = (spell[missTypes[dmg.misstype]] or 0) + 1
+ elseif dmg.glancing then
+ spell.g_num = (spell.g_num or 0) + 1
+ spell.g_amt = (spell.g_amt or 0) + dmg.amount
+ if not spell.g_max or dmg.amount > spell.g_max then
+ spell.g_max = dmg.amount
+ end
+ if not spell.g_min or dmg.amount < spell.g_min then
+ spell.g_min = dmg.amount
+ end
+ elseif not dmg.misstype then
+ spell.n_num = (spell.n_num or 0) + 1
+ spell.n_amt = (spell.n_amt or 0) + dmg.amount
+ if not spell.n_max or dmg.amount > spell.n_max then
+ spell.n_max = dmg.amount
+ end
+ if not spell.n_min or dmg.amount < spell.n_min then
+ spell.n_min = dmg.amount
+ end
+ end
+
+ if dmg.blocked and dmg.blocked > 0 then
+ spell.b_amt = (spell.b_amt or 0) + dmg.blocked
+ end
+
+ if dmg.resisted and dmg.resisted > 0 then
+ spell.r_amt = (spell.r_amt or 0) + dmg.resisted
+ end
+
+ -- target
+ if not dmg.dstName then return end
+ local target = spell.targets and spell.targets[dmg.dstName]
+ if not target then
+ spell.targets = spell.targets or {}
+ spell.targets[dmg.dstName] = {amount = 0}
+ target = spell.targets[dmg.dstName]
+ end
+ target.amount = target.amount + dmg.amount
+
+ if target.total then
+ target.total = target.total + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ target.total = target.amount + absorbed
+ end
+
+ if overkill then
+ target.o_amt = (target.o_amt or 0) + overkill
+ end
+ end
+
+ local function spell_damage(t)
+ if
+ t.srcGUID ~= t.dstGUID and
+ not ignored_creatures[GetCreatureId(t.dstGUID)] and
+ t.spellid and not ignored_spells[t.spellid]
+ then
+ dmg.actorid = t.srcGUID
+ dmg.actorname = t.srcName
+ dmg.actorflags = t.srcFlags
+ dmg.dstName = t.dstName
+
+ dmg.spell = t.spellid
+ dmg.spellid = t.spellstring
+ dmg.is_dot = t.is_dot
+
+ dmg.amount = t.amount
+ dmg.overkill = t.overkill
+ dmg.resisted = t.resisted
+ dmg.blocked = t.blocked
+ dmg.absorbed = t.absorbed
+ dmg.critical = t.critical
+ dmg.glancing = t.glancing
+ dmg.crushing = t.crushing
+ dmg.misstype = t.misstype
+
+ Skada:FixPets(dmg)
+ Skada:DispatchSets(log_damage)
+ end
+ end
+
+ local function damage_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local dps, damage = actor:GetDPS(set)
+
+ local activepercent = activetime / totaltime * 100
+ tooltip:AddDoubleLine(format(L["%s's activity"], classfmt(actor.class, label)), Skada:FormatPercent(activepercent), nil, nil, nil, PercentToRGB(activepercent))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(totaltime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Damage Done"], Skada:FormatNumber(damage), 1, 1, 1)
+
+ local suffix = Skada:FormatTime(P.timemesure == 1 and activetime or totaltime)
+ tooltip:AddDoubleLine(format("%s/%s", Skada:FormatNumber(damage), suffix), Skada:FormatNumber(dps), 1, 1, 1)
+
+ local petdamage = P.absdamage and actor.pettotaldamage or actor.petdamage
+ if not petdamage then return end
+ petdamage = format("%s (\124cffffffff%s\124r)", Skada:FormatNumber(petdamage), Skada:FormatPercent(petdamage, damage))
+ tooltip:AddDoubleLine(L["Pet Damage"], petdamage)
+ end
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagespells and actor.damagespells[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ -- show the aura uptime in case of a debuff.
+ local uptime = actor.auras and actor.auras[id] and actor.auras[id].u
+ if uptime and uptime > 0 then
+ local actortime = actor:GetTime(set)
+ uptime = 100 * (min(uptime, actortime) / actortime)
+ tooltip:AddDoubleLine(L["Uptime"], Skada:FormatPercent(uptime), nil, nil, nil, PercentToRGB(uptime))
+ end
+
+ if spell.n_min then
+ local spellmin = spell.n_min
+ if spell.c_min and spell.c_min < spellmin then
+ spellmin = spell.c_min
+ end
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spellmin), 1, 1, 1)
+ end
+
+ if spell.n_max then
+ local spellmax = spell.n_max
+ if spell.c_max and spell.c_max > spellmax then
+ spellmax = spell.c_max
+ end
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spellmax), 1, 1, 1)
+ end
+
+ if spell.count and spell.count > 0 then
+ local amount = P.absdamage and spell.total or spell.amount
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(amount / spell.count), 1, 1, 1)
+ end
+ end
+
+ local function mode_spell_details_tooltip(win, id, label, tooltip)
+ if label == L["Critical Hits"] or label == L["Normal Hits"] or label == L["Glancing"] then
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor.damagespells and actor.damagespells[win.spellid]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), win.spellname))
+ tooltip_school(tooltip, win.spellid)
+
+ if label == L["Critical Hits"] and spell.c_amt then
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ elseif label == L["Normal Hits"] and spell.n_amt then
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ elseif label == L["Glancing"] and spell.g_amt then
+ if spell.g_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.g_min), 1, 1, 1)
+ end
+ if spell.g_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.g_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.g_amt / spell.g_num), 1, 1, 1)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetDamage()
+ local spells = (total and total > 0) and actor.damagespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, total, actor = set:GetActorDamageTargets(win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = P.absdamage and target.total or target.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ local function add_detail_bar(win, nr, title, value, total, percent, fmt)
+ nr = nr + 1
+ local d = win:nr(nr)
+
+ d.id = title
+ d.label = title
+ d.value = value
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and (fmt and Skada:FormatNumber(value) or value),
+ (mode_cols.sPercent and percent) and Skada:FormatPercent(d.value, total)
+ )
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+
+ return nr
+ end
+
+ function mode_spell_details:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), uformat(L["%s's details"], label))
+ end
+
+ function mode_spell_details:Tooltip(win, set, id, label, tooltip)
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagespells and actor.damagespells[id]
+ if not spell then return end
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ local count = spell.count
+ if count then
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ end
+
+ return spell, count, cast
+ end
+
+ function mode_spell_details:Update(win, set, spell, count)
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), uformat(L["%s's details"], win.spellname))
+ if not win.spellid then return end
+
+ -- details only available for actors
+ if not spell then
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ spell = actor and actor.damagespells and actor.damagespells[win.spellid]
+ count = spell and spell.count
+ end
+
+ if not spell or not count or count == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+
+ if spell.n_num and spell.n_num > 0 then
+ nr = add_detail_bar(win, nr, L["Normal Hits"], spell.n_num, spell.count, true)
+ end
+
+ if spell.c_num and spell.c_num > 0 then
+ nr = add_detail_bar(win, nr, L["Critical Hits"], spell.c_num, spell.count, true)
+ end
+
+ if spell.g_num and spell.g_num > 0 then
+ nr = add_detail_bar(win, nr, L["Glancing"], spell.g_num, spell.count, true)
+ end
+
+ for k, v in pairs(missTypes) do
+ if spell[v] or spell[k] then
+ nr = add_detail_bar(win, nr, L[k], spell[v] or spell[k], spell.count, true)
+ end
+ end
+ end
+
+ function mode_spell_breakdown:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_breakdown:Tooltip(win, set, id, label, tooltip)
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagespells and actor.damagespells[id]
+ if spell then
+ local total = spell.amount
+
+ -- absorbed damage
+ local absorbed = spell.total and (spell.total - total)
+ if absorbed then
+ total = spell.total
+ end
+
+ -- blocked damge
+ local blocked = spell.b_amt
+ if blocked then
+ total = total + blocked
+ end
+
+ -- resisted damage
+ local resisted = spell.r_amt
+ if resisted then
+ total = total + resisted
+ end
+
+ tooltip:AddDoubleLine(spell.amount == total and L["Damage"] or L["Total"], Skada:FormatNumber(total), 1, 1, 1)
+ return spell, total, resisted, blocked, absorbed
+ end
+ end
+
+ function mode_spell_breakdown:Update(win, set, spell, total, resisted, blocked, absorbed)
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), win.spellname)
+ if not win.spellid then return end
+
+ if not spell then
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ spell = actor and actor.damagespells and actor.damagespells[win.spellid]
+ if not spell then return end
+
+ total = spell.amount
+
+ absorbed = spell.total and (spell.total - spell.amount)
+ if absorbed then
+ total = spell.total
+ end
+
+ blocked = spell.b_amt or spell.blocked
+ if blocked then
+ total = total + blocked
+ end
+
+ resisted = spell.r_amt or spell.resisted
+ if resisted then
+ total = total + resisted
+ end
+
+ if win.metadata then
+ win.metadata.maxvalue = total
+ end
+ end
+
+ local nr = 0
+
+ if win.metadata then
+ win.metadata.maxvalue = 0
+ nr = add_detail_bar(win, nr, L["Damage"], spell.amount, total, true, true)
+ elseif spell.amount ~= total then
+ nr = add_detail_bar(win, nr, L["Damage"], spell.amount, total, true, true)
+ end
+
+ if spell.o_amt and spell.o_amt > 0 then
+ nr = add_detail_bar(win, nr, L["Overkill"], spell.o_amt, total, true, true)
+ end
+
+ if resisted and resisted > 0 then
+ nr = add_detail_bar(win, nr, L["RESIST"], resisted, total, true, true)
+ end
+
+ if blocked and blocked > 0 then
+ nr = add_detail_bar(win, nr, L["BLOCK"], blocked, total, true, true)
+ end
+
+ if absorbed and absorbed > 0 then
+ nr = add_detail_bar(win, nr, L["ABSORB"], absorbed, total, true, true)
+ end
+
+ if spell.g_amt and spell.g_amt > 0 then
+ nr = add_detail_bar(win, nr, L["Glancing"], spell.g_amt, total, true, true)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local targets = actor and actor:GetDamageTargets(set)
+ if not targets or not targets[win.targetname] then return end
+
+ local total = P.absdamage and targets[win.targetname].total or targets[win.targetname].amount
+ local spells = (total and total > 0) and actor.damagespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ local target = spell.targets and spell.targets[win.targetname]
+ local amount = target and (P.absdamage and target.total or target.amount)
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Damage"], L[win.class]) or L["Damage"]
+
+ local total = set and set:GetDamage(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.damage then
+ local dps, amount = actor:GetDPS(set, false, false, not mode_cols.DPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, dps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local dps, amount = actor:GetDPS(set, false, false, not mode_cols.sDPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.sDPS and Skada:FormatNumber(dps)
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local dps, amount = set:GetDPS(nil, win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.DPS and Skada:FormatNumber(dps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if not set then return end
+ local dps, amount = set:GetDPS()
+ tooltip:AddDoubleLine(L["Damage"], Skada:FormatNumber(amount), 1, 1, 1)
+ tooltip:AddDoubleLine(L["DPS"], Skada:FormatNumber(dps), 1, 1, 1)
+ end
+
+ local function feed_personal_dps()
+ local set = Skada:GetSet("current")
+ local actor = set and set:GetActor(Skada.userName, Skada.userGUID)
+ return format("%s %s", Skada:FormatNumber(actor and actor:GetDPS(set) or 0), L["DPS"])
+ end
+
+ local function feed_raid_dps()
+ local set = Skada:GetSet("current")
+ return format("%s %s", Skada:FormatNumber(set and set:GetDPS() or 0), L["DPS"])
+ end
+
+ function mode:OnEnable()
+ mode_spell_details.metadata = {tooltip = mode_spell_details_tooltip}
+ mode_spell.metadata = {click1 = mode_spell_details, click2 = mode_spell_breakdown, tooltip = mode_spell_tooltip}
+ mode_target.metadata = {click1 = mode_target_spell}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = damage_tooltip,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Damage = true, DPS = true, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_fire_firebolt]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ local flags_src_dst = {src_is_interesting = true, dst_is_not_interesting = true}
+ Skada:RegisterForCL(
+ spell_damage,
+ flags_src_dst,
+ -- damage events
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ -- missed events
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddFeed(L["Damage: Personal DPS"], feed_personal_dps)
+ Skada:AddFeed(L["Damage: Raid DPS"], feed_raid_dps)
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveFeed(L["Damage: Personal DPS"])
+ Skada:RemoveFeed(L["Damage: Raid DPS"])
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(dmg)
+ end
+
+ function mode:SetComplete(set)
+ -- clean set from garbage before it is saved.
+ local total = set.totaldamage or set.damage
+ if not total or total == 0 then return end
+
+ for _, actor in pairs(set.actors) do
+ local amount = actor.totaldamage or actor.damage
+ if (not amount and actor.damagespells) or amount == 0 then
+ actor.damage, actor.totaldamage = nil, nil
+ actor.damagespells = del(actor.damagespells, true)
+ end
+ end
+ end
+
+ function mode:OnInitialize()
+ -- The Oculus
+ whitelist[49840] = true -- Shock Lance (Amber Drake)
+ whitelist[50232] = true -- Searing Wrath (Ruby Drake)
+ whitelist[50341] = true -- Touch the Nightmare (Emerald Drake)
+ whitelist[50344] = true -- Dream Funnel (Emerald Drake)
+
+ -- Eye of Eternity: Wyrmrest Skytalon
+ whitelist[56091] = true -- Flame Spike
+ whitelist[56092] = true -- Engulf in Flames
+
+ -- Naxxramas: Instructor Razuvious
+ whitelist[61696] = true -- Blood Strike (Death Knight Understudy)
+
+ -- Ulduar - Flame Leviathan
+ whitelist[62306] = true -- Salvaged Demolisher: Hurl Boulder
+ whitelist[62308] = true -- Salvaged Demolisher: Ram
+ whitelist[62490] = true -- Salvaged Demolisher: Hurl Pyrite Barrel
+ whitelist[62634] = true -- Salvaged Demolisher Mechanic Seat: Mortar
+ whitelist[64979] = true -- Salvaged Demolisher Mechanic Seat: Anti-Air Rocket
+ whitelist[62345] = true -- Salvaged Siege Engine: Ram
+ whitelist[62346] = true -- Salvaged Siege Engine: Steam Rush
+ whitelist[62522] = true -- Salvaged Siege Engine: Electroshock
+ whitelist[62358] = true -- Salvaged Siege Turret: Fire Cannon
+ whitelist[62359] = true -- Salvaged Siege Turret: Anti-Air Rocket
+ whitelist[62974] = true -- Salvaged Chopper: Sonic Horn
+
+ -- Icecrown Citadel
+ whitelist[69399] = true -- Cannon Blast (Gunship Battle Cannons)
+ whitelist[70175] = true -- Incinerating Blast (Gunship Battle Cannons)
+ whitelist[70539] = 5.5 -- Regurgitated Ooze (Mutated Abomination)
+ whitelist[70542] = true -- Mutated Slash (Mutated Abomination)
+ end
+end)
+
+---------------------------------------------------------------------------
+-- DPS Module
+
+Skada:RegisterModule("DPS", function(L, P)
+ local mode = Skada:NewModule("DPS")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function dps_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local dps, damage = actor:GetDPS(set)
+ tooltip:AddLine(uformat("%s - %s", classfmt(actor.class, label), L["DPS"]))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(totaltime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Damage Done"], Skada:FormatNumber(damage), 1, 1, 1)
+
+ local petdamage = P.absdamage and actor.pettotaldamage or actor.petdamage
+ if not petdamage then return end
+ petdamage = format("%s (\124cffffffff%s\124r)", Skada:FormatNumber(petdamage), Skada:FormatPercent(petdamage, damage))
+ tooltip:AddDoubleLine(L["Pet Damage"], petdamage)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["DPS"], L[win.class]) or L["DPS"]
+
+ local total = set and set:GetDPS(nil, win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.damage then
+ local dps = actor:GetDPS(set)
+ if dps > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = dps
+ format_valuetext(d, mode_cols, max(dps, total), dps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ local dps = set:GetDPS(nil, win and win.class)
+ return dps, Skada:FormatNumber(dps)
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ tooltip = dps_tooltip,
+ columns = {DPS = true, Percent = true},
+ icon = [[Interface\ICONS\achievement_bg_topdps]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ local parent = Skada:GetModule("Damage", true)
+ if parent and parent.metadata then
+ self.metadata.click1 = parent.metadata.click1
+ self.metadata.click2 = parent.metadata.click2
+ self.metadata.filterclass = parent.metadata.filterclass
+ end
+
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Damage")
+
+---------------------------------------------------------------------------
+-- Damage Done By Spell Module
+
+Skada:RegisterModule("Damage Done By Spell", function(L, P, _, C)
+ local mode = Skada:NewModule("Damage Done By Spell")
+ local mode_source = mode:NewModule("Source List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function mode_source_tooltip(win, id, label, tooltip)
+ local set = win.spellname and win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ local spell = actor and actor.damagespells and actor.damagespells[win.spellid]
+ if not spell then return end
+
+ tooltip:AddLine(format("%s - %s", classfmt(actor.class, label), win.spellname))
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(win.spellid)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ if not spell.count or spell.count == 0 then return end
+
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ local diff = spell.count -- used later
+
+ if spell.n_num then
+ tooltip:AddDoubleLine(L["Normal Hits"], Skada:FormatPercent(spell.n_num, spell.count), 1, 1, 1)
+ diff = diff - spell.n_num
+ end
+
+ if spell.c_num then
+ tooltip:AddDoubleLine(L["Critical Hits"], Skada:FormatPercent(spell.c_num, spell.count), 1, 1, 1)
+ diff = diff - spell.c_num
+ end
+
+ if spell.g_num then
+ tooltip:AddDoubleLine(L["Glancing"], Skada:FormatPercent(spell.g_num, spell.count), 1, 1, 1)
+ diff = diff - spell.g_num
+ end
+
+ if diff > 0 then
+ tooltip:AddDoubleLine(L["Other"], Skada:FormatPercent(diff, spell.count), nil, nil, nil, 1, 1, 1)
+ end
+ end
+
+ function mode_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = format(L["%s's sources"], label)
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], win.spellname)
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ if not win.spellid then return end
+
+ local total = 0
+ local sources = clear(C)
+ local actors = set.actors
+ for actorname, actor in pairs(actors) do
+ local spell = win:show_actor(actor, set, true) and actor.damagespells and actor.damagespells[win.spellid]
+ if spell then
+ local amount = P.absdamage and spell.total or spell.amount
+ if amount > 0 then
+ sources[actorname] = new()
+ sources[actorname].id = actor.id
+ sources[actorname].class = actor.class
+ sources[actorname].role = actor.role
+ sources[actorname].spec = actor.spec
+ sources[actorname].amount = amount
+ sources[actorname].time = mode_cols.sDPS and actor:GetTime(set)
+
+ total = total + amount
+ end
+ end
+ end
+
+ if total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for actorname, actor in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.amount
+ format_valuetext(d, mode_cols, total, actor.time and (d.value / actor.time), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Damage Done By Spell"]
+
+ local total = set and set:GetDamage()
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local spells = clear(C)
+ for _, actor in pairs(set.actors) do
+ local _spells = not actor.enemy and actor.damagespells
+ if _spells then
+ for spellid, spell in pairs(_spells) do
+ local amount = P.absdamage and spell.total or spell.amount
+ if amount and amount > 0 then
+ if not spells[spellid] then
+ spells[spellid] = new()
+ spells[spellid].amount = amount
+ else
+ spells[spellid].amount = spells[spellid].amount + amount
+ end
+ end
+ end
+ end
+ end
+
+ local nr = 0
+ local settime = mode_cols.DPS and set:GetTime()
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.amount
+ format_valuetext(d, mode_cols, total, settime and (d.value / settime), win.metadata)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_source.metadata = {showspots = true, filterclass = true, tooltip = mode_source_tooltip}
+ self.metadata = {
+ showspots = true,
+ click1 = mode_source,
+ columns = {Damage = true, DPS = false, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_nature_lightning]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Damage")
+
+---------------------------------------------------------------------------
+-- Useful Damage Module
+
+Skada:RegisterModule("Useful Damage", function(L, P)
+ local mode = Skada:NewModule("Useful Damage")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetDamage(true)
+ local spells = (total and total > 0) and actor.damagespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+ if spell.o_amt then
+ d.value = max(0, d.value - spell.o_amt)
+ end
+
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, total, actor = set:GetActorDamageTargets(win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = P.absdamage and target.total or target.amount
+ if target.o_amt then
+ d.value = max(0, d.value - target.o_amt)
+ end
+
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class, tooltip)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local sources, total, actor = set:GetActorDamageSources(win.targetname, win.targetid)
+ if not sources or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(sources) do
+ local amount = P.absdamage and source.total or source.amount
+ if source.o_amt then
+ amount = max(0, amount - source.o_amt)
+ end
+
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, source, actor.enemy, sourcename)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Useful Damage"], L[win.class]) or L["Useful Damage"]
+
+ local total = set and set:GetDamage(win.class, true)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.damage then
+ local dps, amount = actor:GetDPS(set, true, false, not mode_cols.DPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, dps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local dps, amount = actor:GetDPS(set, true, false, not mode_cols.sDPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.sDPS and Skada:FormatNumber(dps)
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ local dps, amount = set:GetDPS(true, win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.DPS and Skada:FormatNumber(dps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_target_spell.metadata = {showspots = true}
+ mode_target.metadata = {click1 = mode_target_spell}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Damage = true, DPS = true, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_shaman_stormearthfire]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Damage")
+
+---------------------------------------------------------------------------
+-- Overkill Module
+
+Skada:RegisterModule("Overkill", function(L, _, _, C)
+ local mode = Skada:NewModule("Overkill")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_spell_target = mode_spell:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local classfmt = Skada.classcolors.format
+ local get_actor_spell_overkill_targets = nil
+ local mode_cols = nil
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.overkill
+ local spells = (total and total > 0) and actor.damagespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(actor.damagespells) do
+ if spell.o_amt and spell.o_amt > 0 then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.o_amt
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, _, actor, total = set:GetActorDamageTargets(win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ if target.o_amt and target.o_amt > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.o_amt
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_target:Update(win, set)
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), win.spellname)
+ if not win.spellname or not win.actorname then return end
+
+ local targets, total, actor = get_actor_spell_overkill_targets(set, win.actorname, win.actorid, win.spellid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ if target.o_amt and target.o_amt > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.o_amt
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor or not actor.overkill or actor.overkill == 0 then return end
+
+ local targets = actor:GetDamageTargets(set)
+ local total = targets and targets[win.targetname] and targets[win.targetname].o_amt
+
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(actor.damagespells) do
+ local o_amt = spell.targets and spell.targets[win.targetname] and spell.targets[win.targetname].o_amt
+ if o_amt and o_amt > 0 then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = o_amt
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Overkill"], L[win.class]) or L["Overkill"]
+
+ local total = set and set:GetOverkill(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.overkill then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.overkill
+ format_valuetext(d, mode_cols, total, mode_cols.DPS and (d.value / actor:GetTime(set)), win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ local overkill = actor and actor.overkill
+ if not overkill then return end
+ return overkill, Skada:FormatNumber(overkill)
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local overkill = set:GetOverkill(win and win.class)
+ return overkill, Skada:FormatNumber(overkill)
+ end
+
+ function mode:OnEnable()
+ mode_target.metadata = {click1 = mode_target_spell}
+ mode_spell.metadata = {click1 = mode_spell_target}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Damage = true, DPS = false, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_fire_incinerate]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actor_spell_overkill_targets = function(self, name, id, spellid, tbl)
+ local actor = self:GetActor(name, id)
+ if not actor or not actor.overkill or actor.overkill == 0 then return end
+
+ local spell = actor.damagespells and actor.damagespells[spellid]
+ local total = spell and spell.targets and spell.o_amt
+ if not total or total == 0 then return end
+
+ tbl = clear(tbl or C)
+ for targetname, target in pairs(spell.targets) do
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.o_amt = target.o_amt
+ tbl[targetname] = t
+ elseif target.o_amt then
+ t.o_amt = (t.o_amt or 0) + target.o_amt
+ end
+ self:_fill_actor_table(t, targetname)
+ end
+
+ return tbl, total, actor
+ end
+end, "Damage")
+
+---------------------------------------------------------------------------
+-- Damage Done By School
+
+Skada:RegisterModule("Damage Done By School", function(L, P, _, C)
+ local mode = Skada:NewModule("Damage Done By School")
+ local mode_source = mode:NewModule("Source List")
+
+ local SpellSplit = Private.SpellSplit
+ local spellschools = Skada.spellschools
+
+ local get_schools_for_set = nil
+ local get_damage_for_school = nil
+ local mode_cols = nil
+
+ function mode_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = format(L["%s's sources"], label)
+ end
+
+ function mode_source:Update(win, set)
+ win.title = format(L["%s's sources"], win.spellname)
+ if not set or not win.spellname then return end
+
+ local total, actors = get_damage_for_school(set, win.spellid)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for actorname, actor in pairs(actors) do
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, false, actorname)
+ d.value = actor.amount
+ format_valuetext(d, mode_cols, total, actor.time and d.value / actor.time, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Damage Done By School"]
+
+ local total, schools = get_schools_for_set(set)
+ if not total or not schools then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local settime = mode_cols.DPS and set:GetTime()
+
+ for school, amount in pairs(schools) do
+ nr = nr + 1
+
+ local d = win:nr(nr)
+ d.id = school
+ d.label = spellschools(school)
+ d.spellschool = school
+ d.value = amount
+
+ format_valuetext(d, mode_cols, total, settime and amount / settime, win.metadata)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_source.metadata = {showspots = true}
+ self.metadata = {
+ click1 = mode_source,
+ showspots = true,
+ columns = {Damage = true, DPS = false, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_fire_firebolt]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ get_schools_for_set = function(self, tbl)
+ local total = self.damage or 0
+ local actors = total > 0 and self.actors
+ if not actors then return end
+
+ tbl = clear(tbl or C)
+
+ for _, actor in pairs(actors) do
+ if actor.damagespells and not actor.enemy then
+ for spellid, spell in pairs(actor.damagespells) do
+ local _, school = SpellSplit(spellid)
+ if school and P.absdamage and spell.total then
+ tbl[school] = (tbl[school] or 0) + spell.total
+ elseif school and spell.amount then
+ tbl[school] = (tbl[school] or 0) + spell.amount
+ end
+
+ end
+ end
+ end
+
+ return total, tbl
+ end
+
+ get_damage_for_school = function(self, school, tbl)
+ local actors = self.damage and school and self.actors
+ if not actors then return end
+
+ local total = 0
+
+ tbl = clear(tbl or C)
+
+ for actorname, actor in pairs(actors) do
+ if actor.damagespells and not actor.enemy then
+ for spellid, spell in pairs(actor.damagespells) do
+ local _, s = SpellSplit(spellid)
+ if s == school then
+ local amount = P.absdamage and spell.total or spell.amount
+ local t = tbl[actorname]
+
+ if not t then
+ t = new()
+
+ t.id = actor.id
+ t.class = actor.class
+ t.role = actor.role
+ t.spec = actor.spec
+
+ t.amount = amount
+ t.time = mode_cols.sDPS and actor:GetTime(self)
+ tbl[actorname] = t
+ else
+ t.amount = t.amount + amount
+ end
+
+ total = total + amount
+ end
+ end
+ end
+ end
+
+ return total, tbl
+ end
+end, "Damage")
+
+---------------------------------------------------------------------------
+-- Absorbed Damage Module
+
+Skada:RegisterModule("Absorbed Damage", function(L, _, _, C)
+ local mode = Skada:NewModule("Absorbed Damage")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local classfmt = Skada.classcolors.format
+ local get_set_absorbed_damage = nil
+ local get_actor_absorbed_damage_targets = nil
+ local mode_cols = nil
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = (actor and actor.totaldamage and actor.damage) and max(0, actor.totaldamage - actor.damage)
+ local spells = (total and total > 0) and actor.damagespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ if spell.total and spell.amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = max(0, spell.total - spell.amount)
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, total, actor = get_actor_absorbed_damage_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Absorbed Damage"], L[win.class]) or L["Absorbed Damage"]
+
+ local total = set and get_set_absorbed_damage(set, win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.totaldamage and actor.damage then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = max(0, actor.totaldamage - actor.damage)
+ format_valuetext(d, mode_cols, total, mode_cols.DPS and (d.value / actor:GetTime(set)), win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Damage = true, DPS = false, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_fire_playingwithfire]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor or not actor.totaldamage then return end
+
+ local amount = max(0, actor.totaldamage - actor.damage)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.sDPS and Skada:FormatNumber(amount / set:GetTime())
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local amount = set and get_set_absorbed_damage(set, win and win.class) or 0
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.DPS and Skada:FormatNumber(amount / set:GetTime())
+ )
+ return amount, valuetext
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_set_absorbed_damage = function(self, class)
+ -- no actors?
+ if not self.actors then return end
+
+ local total = 0
+ local combined = (Skada.forPVP and self.type == "arena")
+
+ -- no class filter?
+ if not class then
+ -- group members.
+ if self.totaldamage and self.damage then
+ total = max(0, self.totaldamage - self.damage)
+ end
+
+ -- arena enemies
+ if combined and self.etotaldamage and self.edamage then
+ total = total + max(0, self.etotaldamage - self.edamage)
+ end
+
+ return total
+ end
+
+ -- filtered by class
+ for _, actor in pairs(self.actors) do
+ if actor.class == class and actor.totaldamage and actor.damage and (combined or not actor.enemy) then
+ total = total + max(0, actor.totaldamage - actor.damage)
+ end
+ end
+ return total
+ end
+
+ get_actor_absorbed_damage_targets = function(set, name, id, tbl)
+ local actor = name and id and set:GetActor(name, id)
+ local spells = actor and actor.damagespells
+ if not spells then return end
+
+ local total = (actor.totaldamage and actor.damage) and max(0, actor.totaldamage - actor.damage)
+ if not total or total == 0 then return end -- not total or 0
+
+ tbl = clear(tbl or C)
+
+ for _, spell in pairs(spells) do
+ if spell.total and spell.amount and spell.targets then
+ for targetname, target in pairs(spell.targets) do
+ if target.total and target.amount then
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.amount = max(0, target.total - target.amount)
+ tbl[targetname] = t
+ else
+ t.amount = t.amount + max(0, target.total - target.amount)
+ end
+
+ set:_fill_actor_table(tbl[targetname], targetname)
+ end
+ end
+ end
+ end
+
+ return tbl, total, actor
+ end
+end, "Damage")
diff --git a/Skada/Modules/DamageTaken.lua b/Skada/Modules/DamageTaken.lua
new file mode 100644
index 0000000..bbdfcea
--- /dev/null
+++ b/Skada/Modules/DamageTaken.lua
@@ -0,0 +1,1067 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+-- cache frequently used globals
+local pairs, format, uformat = pairs, string.format, Private.uformat
+local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+
+local function format_valuetext(d, columns, total, dtps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ columns.Damage and Skada:FormatNumber(d.value),
+ columns[subview and "sDTPS" or "DTPS"] and dtps and Skada:FormatNumber(dtps),
+ columns[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+end
+
+---------------------------------------------------------------------------
+-- Damage Taken Module
+
+Skada:RegisterModule("Damage Taken", function(L, P)
+ local mode = Skada:NewModule("Damage Taken")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_details = mode_spell:NewModule("Spell Details")
+ local mode_spell_breakdown = mode_spell:NewModule("More Details")
+ local mode_source = mode:NewModule("Source List")
+ local mode_source_spell = mode_source:NewModule("Spell List")
+
+ local min, wipe = math.min, wipe
+ local PercentToRGB = Private.PercentToRGB
+ local GetCreatureId = Skada.GetCreatureId
+ local classfmt = Skada.classcolors.format
+ local tooltip_school = Skada.tooltip_school
+ local ignored_spells = Skada.ignored_spells.damage -- Edit Skada\Core\Tables.lua
+ local ignored_creatures = Skada.ignored_creatures -- Edit Skada\Core\Tables.lua
+ local missTypes = Skada.missTypes
+ local mode_cols = nil
+
+ local dmg = {}
+ local function log_damage(set)
+ local actor = Skada:GetActor(set, dmg.actorname, dmg.actorid, dmg.actorflags)
+ if not actor then return end
+
+ actor.damaged = (actor.damaged or 0) + dmg.amount
+ set.damaged = (set.damaged or 0) + dmg.amount
+
+ -- add absorbed damage to total damage
+ local absorbed = dmg.absorbed or 0
+
+ if actor.totaldamaged then
+ actor.totaldamaged = actor.totaldamaged + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ actor.totaldamaged = actor.damaged + absorbed
+ end
+
+ if set.totaldamaged then
+ set.totaldamaged = set.totaldamaged + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ set.totaldamaged = set.damaged + absorbed
+ end
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ local spell = actor.damagedspells and actor.damagedspells[dmg.spellid]
+ if not spell then
+ actor.damagedspells = actor.damagedspells or {}
+ actor.damagedspells[dmg.spellid] = {amount = 0}
+ spell = actor.damagedspells[dmg.spellid]
+ end
+
+ spell.count = (spell.count or 0) + 1
+ spell.amount = spell.amount + dmg.amount
+
+ if spell.total then
+ spell.total = spell.total + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ spell.total = spell.amount + absorbed
+ end
+
+ if dmg.critical then
+ spell.c_num = (spell.c_num or 0) + 1
+ spell.c_amt = (spell.c_amt or 0) + dmg.amount
+
+ if not spell.c_max or dmg.amount > spell.c_max then
+ spell.c_max = dmg.amount
+ end
+
+ if not spell.c_min or dmg.amount < spell.c_min then
+ spell.c_min = dmg.amount
+ end
+ elseif dmg.misstype ~= nil and missTypes[dmg.misstype] then
+ spell[missTypes[dmg.misstype]] = (spell[missTypes[dmg.misstype]] or 0) + 1
+ elseif dmg.glancing then
+ spell.g_num = (spell.g_num or 0) + 1
+ spell.g_amt = (spell.g_amt or 0) + dmg.amount
+ if not spell.g_max or dmg.amount > spell.g_max then
+ spell.g_max = dmg.amount
+ end
+ if not spell.g_min or dmg.amount < spell.g_min then
+ spell.g_min = dmg.amount
+ end
+ elseif dmg.crushing then
+ spell.crushing = (spell.crushing or 0) + 1
+ elseif not dmg.misstype then
+ spell.n_num = (spell.n_num or 0) + 1
+ spell.n_amt = (spell.n_amt or 0) + dmg.amount
+ if not spell.n_max or dmg.amount > spell.n_max then
+ spell.n_max = dmg.amount
+ end
+ if not spell.n_min or dmg.amount < spell.n_min then
+ spell.n_min = dmg.amount
+ end
+ end
+
+ if dmg.blocked and dmg.blocked > 0 then
+ spell.b_amt = (spell.b_amt or 0) + dmg.blocked
+ end
+
+ if dmg.resisted and dmg.resisted > 0 then
+ spell.r_amt = (spell.r_amt or 0) + dmg.resisted
+ end
+
+ local overkill = (dmg.overkill and dmg.overkill > 0) and dmg.overkill or nil
+ if overkill then
+ spell.o_amt = (spell.o_amt or 0) + dmg.overkill
+ end
+
+ -- record the source
+ if not dmg.srcName then return end
+ local source = spell.sources and spell.sources[dmg.srcName]
+ if not source then
+ spell.sources = spell.sources or {}
+ spell.sources[dmg.srcName] = {amount = 0}
+ source = spell.sources[dmg.srcName]
+ end
+ source.amount = source.amount + dmg.amount
+
+ if source.total then
+ source.total = source.total + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ source.total = source.amount + absorbed
+ end
+
+ if overkill then
+ source.o_amt = (source.o_amt or 0) + overkill
+ end
+ end
+
+ local function spell_damage(t)
+ if
+ t.srcGUID ~= t.dstGUID and
+ not ignored_creatures[GetCreatureId(t.srcGUID)] and
+ t.spellid and not ignored_spells[t.spellid]
+ then
+ dmg.actorid = t.dstGUID
+ dmg.actorname = t.dstName
+ dmg.actorflags = t.dstFlags
+ dmg.spellid = t.spellstring
+
+ dmg.amount = t.amount
+ dmg.overkill = t.overkill
+ dmg.resisted = t.resisted
+ dmg.blocked = t.blocked
+ dmg.absorbed = t.absorbed
+ dmg.critical = t.critical
+ dmg.glancing = t.glancing
+ dmg.crushing = t.crushing
+ dmg.misstype = t.misstype
+
+ dmg.srcName = Skada:FixPetsName(t.srcGUID, t.srcName, t.srcFlags)
+ Skada:DispatchSets(log_damage)
+ end
+ end
+
+ local function damage_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local dtps, damage = actor:GetDTPS(set)
+
+ local activepercent = activetime / totaltime * 100
+ tooltip:AddDoubleLine(format(L["%s's activity"], classfmt(actor.class, label)), Skada:FormatPercent(activepercent), nil, nil, nil, PercentToRGB(activepercent))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(totaltime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Damage Taken"], Skada:FormatNumber(damage), 1, 1, 1)
+
+ local suffix = Skada:FormatTime(P.timemesure == 1 and activetime or totaltime)
+ tooltip:AddDoubleLine(format("%s/%s", Skada:FormatNumber(damage), suffix), Skada:FormatNumber(dtps), 1, 1, 1)
+ end
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagedspells and actor.damagedspells[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ if spell.n_min then
+ local spellmin = spell.n_min
+ if spell.c_min and spell.c_min < spellmin then
+ spellmin = spell.c_min
+ end
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spellmin), 1, 1, 1)
+ end
+
+ if spell.n_max then
+ local spellmax = spell.n_max
+ if spell.c_max and spell.c_max > spellmax then
+ spellmax = spell.c_max
+ end
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spellmax), 1, 1, 1)
+ end
+
+ if spell.count then
+ local amount = P.absdamage and spell.total or spell.amount
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(amount / spell.count), 1, 1, 1)
+ end
+ end
+
+ local function mode_spell_details_tooltip(win, id, label, tooltip)
+ if label == L["Critical Hits"] or label == L["Normal Hits"] or label == L["Glancing"] then
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagedspells and actor.damagedspells[win.spellid]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", win.actorname, win.spellname))
+ tooltip_school(tooltip, win.spellid)
+
+ if label == L["Critical Hits"] and spell.c_amt then
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ elseif label == L["Normal Hits"] and spell.n_amt then
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ elseif label == L["Glancing"] and spell.g_amt then
+ if spell.g_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.g_min), 1, 1, 1)
+ end
+ if spell.g_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.g_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.g_amt / spell.g_num), 1, 1, 1)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetDamageTaken()
+ local spells = (total and total > 0) and actor.damagedspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = min(total, P.absdamage and spell.total or spell.amount)
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_source:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's sources"], classfmt(class, label))
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], classfmt(win.actorclass, win.actorname))
+
+ local sources, total, actor = set:GetActorDamageSources(win.actorname, win.actorid)
+ if not sources or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = P.absdamage and source.total or source.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ local function add_detail_bar(win, nr, title, value, total, percent, fmt)
+ nr = nr + 1
+
+ local d = win:nr(nr)
+ d.id = title
+ d.label = title
+ d.value = value
+ format_valuetext(d, mode.metadata.columns, total, nil, win.metadata, true)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+
+ return nr
+ end
+
+ function mode_spell_details:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), format(L["%s's details"], label))
+ end
+
+ function mode_spell_details:Tooltip(win, set, id, label, tooltip)
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagedspells and actor.damagedspells[id]
+ if spell and spell.count then
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ return spell, spell.count
+ end
+ end
+
+ function mode_spell_details:Update(win, set, spell, count)
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), uformat(L["%s's details"], win.spellname))
+ if not win.spellid then return end
+
+ if not spell then
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ spell = actor and actor.damagedspells and actor.damagedspells[win.spellid]
+ count = spell and spell.count
+ end
+
+ if not spell or not count or count == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+
+ if spell.n_num and spell.n_num > 0 then
+ nr = add_detail_bar(win, nr, L["Normal Hits"], spell.n_num, count, true)
+ end
+
+ if spell.c_num and spell.c_num > 0 then
+ nr = add_detail_bar(win, nr, L["Critical Hits"], spell.c_num, count, true)
+ end
+
+ if spell.g_num and spell.g_num > 0 then
+ nr = add_detail_bar(win, nr, L["Glancing"], spell.g_num, count, true)
+ end
+
+ if spell.crushing and spell.crushing > 0 then
+ nr = add_detail_bar(win, nr, L["Crushing"], spell.crushing, count, true)
+ end
+
+ for k, v in pairs(missTypes) do
+ if spell[v] or spell[k] then
+ nr = add_detail_bar(win, nr, L[k], spell[v] or spell[k], count, true)
+ end
+ end
+ end
+
+ function mode_spell_breakdown:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_breakdown:Tooltip(win, set, id, label, tooltip)
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.damagedspells and actor.damagedspells[id]
+ if spell then
+ local total = spell.amount
+
+ -- absorbed damage
+ local absorbed = spell.total and (spell.total - total)
+ if absorbed then
+ total = spell.total
+ end
+
+ -- blocked damge
+ local blocked = spell.b_amt
+ if blocked then
+ total = total + blocked
+ end
+
+ -- resisted damage
+ local resisted = spell.r_amt
+ if resisted then
+ total = total + resisted
+ end
+
+ tooltip:AddDoubleLine(spell.amount == total and L["Damage"] or L["Total"], Skada:FormatNumber(total), 1, 1, 1)
+ return spell, total, resisted, blocked, absorbed
+ end
+ end
+
+ function mode_spell_breakdown:Update(win, set, spell, total, resisted, blocked, absorbed)
+ win.title = uformat("%s: %s", classfmt(win.actorclass, win.actorname), win.spellname)
+ if not win.spellid then return end
+
+ if not spell then
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ spell = actor and actor.damagedspells and actor.damagedspells[win.spellid]
+ if not spell then return end
+
+ total = spell.amount
+
+ absorbed = spell.total and (spell.total - spell.amount)
+ if absorbed then
+ total = spell.total
+ end
+
+ blocked = spell.b_amt or spell.blocked
+ if blocked then
+ total = total + blocked
+ end
+
+ resisted = spell.r_amt or spell.resisted
+ if resisted then
+ total = total + resisted
+ end
+
+ if win.metadata then
+ win.metadata.maxvalue = total
+ end
+ end
+
+ local nr = 0
+
+ if win.metadata then
+ win.metadata.maxvalue = 0
+ nr = add_detail_bar(win, nr, L["Damage"], spell.amount, total, true, true)
+ elseif spell.amount ~= total then
+ nr = add_detail_bar(win, nr, L["Damage"], spell.amount, total, true, true)
+ end
+
+ if spell.o_amt and spell.o_amt > 0 then
+ nr = add_detail_bar(win, nr, L["Overkill"], spell.o_amt, total, true, true)
+ end
+
+ if resisted and resisted > 0 then
+ nr = add_detail_bar(win, nr, L["RESIST"], resisted, total, true, true)
+ end
+
+ if blocked and blocked > 0 then
+ nr = add_detail_bar(win, nr, L["BLOCK"], blocked, total, true, true)
+ end
+
+ if absorbed and absorbed > 0 then
+ nr = add_detail_bar(win, nr, L["ABSORB"], absorbed, total, true, true)
+ end
+
+ if spell.g_amt and spell.g_amt > 0 then
+ nr = add_detail_bar(win, nr, L["Glancing"], spell.g_amt, total, true, true)
+ end
+ end
+
+ function mode_source_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(class, label), classfmt(win.actorclass, win.actorname))
+ end
+
+ function mode_source_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.targetclass, win.targetname), classfmt(win.actorclass, win.actorname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local sources = actor and actor:GetDamageSources(set)
+ if not sources or not sources[win.targetname] then return end
+
+ local total = P.absdamage and sources[win.targetname].total or sources[win.targetname].amount
+ local spells = (total and total > 0) and actor.damagedspells
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ local source = spell.sources and spell.sources[win.targetname]
+ local amount = source and (P.absdamage and source.total or source.amount)
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Damage Taken"], L[win.class]) or L["Damage Taken"]
+
+ local total = set and set:GetDamageTaken(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.damaged then
+ local dtps, amount = actor:GetDTPS(set, not mode_cols.DTPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, dtps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local dtps, amount = actor:GetDTPS(set, not mode_cols.sDTPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.sDTPS and Skada:FormatNumber(dtps)
+ )
+ return amount, valuetext
+ end
+ mode_source.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local dtps, amount = set:GetDTPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.DTPS and Skada:FormatNumber(dtps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if not set then return end
+ local dtps, amount = set:GetDTPS()
+ if not amount then return end
+ tooltip:AddDoubleLine(L["Damage Taken"], Skada:FormatNumber(amount), 1, 1, 1)
+ tooltip:AddDoubleLine(L["DTPS"], Skada:FormatNumber(dtps), 1, 1, 1)
+ end
+
+ function mode:OnEnable()
+ mode_spell_details.metadata = {tooltip = mode_spell_details_tooltip}
+ mode_spell.metadata = {click1 = mode_spell_details, click2 = mode_spell_breakdown, tooltip = mode_spell_tooltip}
+ mode_source.metadata = {click1 = mode_source_spell}
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_source.nototal = true
+
+ local flags_dst = {dst_is_interesting_nopets = true}
+
+ Skada:RegisterForCL(
+ spell_damage,
+ flags_dst,
+ -- damage events
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ "ENVIRONMENTAL_DAMAGE",
+ -- missed events
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self, "Damage Taken")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(dmg)
+ end
+
+ function mode:SetComplete(set)
+ -- clean set from garbage before it is saved.
+ local total = set.totaldamaged or set.damaged
+ if not total or total == 0 then return end
+
+ for _, actor in pairs(set.actors) do
+ local amount = actor.totaldamaged or actor.damaged
+ if (not amount and actor.damagedspells) or amount == 0 then
+ actor.damaged, actor.totaldamaged = nil, nil
+ actor.damagedspells = del(actor.damagedspells, true)
+ end
+ end
+ end
+
+ function mode:OnInitialize()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = damage_tooltip,
+ click1 = mode_spell,
+ click2 = mode_source,
+ columns = {Damage = true, DTPS = false, Percent = true, sDTPS = false, sPercent = true},
+ icon = [[Interface\ICONS\ability_mage_frostfirebolt]]
+ }
+ end
+end)
+
+---------------------------------------------------------------------------
+-- DTPS Module
+
+Skada:RegisterModule("DTPS", function(L, P)
+ local mode = Skada:NewModule("DTPS")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function dtps_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local dtps, damage = actor:GetDTPS(set, nil, false)
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(actor.class, label), L["DTPS"]))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(totaltime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Damage Taken"], Skada:FormatNumber(damage), 1, 1, 1)
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["DTPS"], L[win.class]) or L["DTPS"]
+
+ local total = set and set:GetDTPS(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.damaged then
+ local dtps = actor:GetDTPS(set)
+ if dtps > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = dtps
+ format_valuetext(d, mode_cols, total, dtps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ local dtps = set:GetDTPS(win and win.class)
+ return dtps, Skada:FormatNumber(dtps)
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = dtps_tooltip,
+ columns = {DTPS = true, Percent = true},
+ icon = [[Interface\ICONS\inv_weapon_shortblade_06]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ local parent = Skada:GetModule("Damage Taken", true)
+ if parent and parent.metadata then
+ self.metadata.click1 = parent.metadata.click1
+ self.metadata.click2 = parent.metadata.click2
+ end
+
+ Skada:AddMode(self, "Damage Taken")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Damage Taken")
+
+---------------------------------------------------------------------------
+-- Damage Taken By Spell Module
+
+Skada:RegisterModule("Damage Taken By Spell", function(L, P)
+ local mode = Skada:NewModule("Damage Taken By Spell")
+ local mode_target = mode:NewModule("Target List")
+ local mode_source = mode:NewModule("Source List")
+ local C, classfmt = Skada.cacheTable2, Skada.classcolors.format
+ local mode_cols = nil
+
+ local function actor_tooltip(win, id, label, tooltip)
+ local set = win.spellid and win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local spell = actor.damagedspells and actor.damagedspells[win.spellid]
+ if not spell or not spell.count then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(actor.class, label), win.spellname))
+
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ local diff = spell.count -- used later
+
+ if spell.n_num then
+ tooltip:AddDoubleLine(L["Normal Hits"], Skada:FormatPercent(spell.n_num, spell.count), 1, 1, 1)
+ diff = diff - spell.n_num
+ end
+
+ if spell.c_num then
+ tooltip:AddDoubleLine(L["Critical Hits"], Skada:FormatPercent(spell.c_num, spell.count), 1, 1, 1)
+ diff = diff - spell.c_num
+ end
+
+ if spell.g_num then
+ tooltip:AddDoubleLine(L["Glancing"], Skada:FormatPercent(spell.g_num, spell.count), 1, 1, 1)
+ diff = diff - spell.g_num
+ end
+
+ if diff > 0 then
+ tooltip:AddDoubleLine(L["Other"], Skada:FormatPercent(diff, spell.count), nil, nil, nil, 1, 1, 1)
+ end
+ end
+
+ function mode_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = format(L["%s's sources"], label)
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], win.spellname)
+ if not win.spellid then return end
+
+ local total = 0
+ local sources = clear(C)
+ local actors = set.actors
+ for _, actor in pairs(actors) do
+ local spell = not actor.enemy and actor.damagedspells and actor.damagedspells[win.spellid]
+
+ if spell and spell.sources then
+ for sourcename, source in pairs(spell.sources) do
+ local amount = P.absdamage and source.total or source.amount or 0
+ if amount > 0 then
+ local src = sources[sourcename]
+ if not src then
+ src = new()
+ src.amount = amount
+ sources[sourcename] = src
+ else
+ src.amount = src.amount + amount
+ end
+
+ total = total + amount
+
+ set:_fill_actor_table(src, sourcename, true)
+ end
+ end
+ end
+ end
+
+ if total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for sourcename, source in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.amount
+ format_valuetext(d, mode_cols, total, source.time and (d.value / source.time), win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = format(L["%s's targets"], label)
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], win.spellname)
+ win.title = win.class and format("%s (%s)", win.title, L[win.class]) or win.title
+ if not win.spellid then return end
+
+ local total = 0
+ local targets = clear(C)
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ local spell = win:show_actor(actor, set, true) and actor.damagedspells and actor.damagedspells[win.spellid]
+ if spell then
+ local amount = P.absdamage and spell.total or spell.amount or 0
+ if amount > 0 then
+ targets[actorname] = new()
+ targets[actorname].id = actor.id
+ targets[actorname].class = actor.class
+ targets[actorname].role = actor.role
+ targets[actorname].spec = actor.spec
+ targets[actorname].enemy = actor.enemy
+ targets[actorname].amount = amount
+ targets[actorname].time = mode_cols.sDTPS and actor:GetTime(set)
+
+ total = total + amount
+ end
+ end
+ end
+
+ if total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for actorname, actor in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.amount
+ format_valuetext(d, mode_cols, total, actor.time and (d.value / actor.time), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Damage Taken By Spell"]
+
+ local total = set and set:GetDamageTaken()
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local spells = clear(C)
+ local actors = set.actors
+ for _, actor in pairs(actors) do
+ local _spells = not actor.enemy and actor.damagedspells
+ if _spells then
+ for spellid, spell in pairs(_spells) do
+ local amount = P.absdamage and spell.total or spell.amount or 0
+ if amount > 0 then
+ local sp = spells[spellid]
+ if not sp then
+ sp = new()
+ sp.amount = amount
+ spells[spellid] = sp
+ else
+ sp.amount = sp.amount + amount
+ end
+ end
+ end
+ end
+ end
+
+ local nr = 0
+ local settime = mode_cols.DTPS and set:GetTime()
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.amount
+ format_valuetext(d, mode_cols, total, settime and (d.value / settime), win.metadata)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_target.metadata = {showspots = true, filterclass = true, tooltip = actor_tooltip}
+ self.metadata = {
+ showspots = true,
+ click1 = mode_target,
+ click2 = mode_source,
+ columns = {Damage = true, DTPS = false, Percent = true, sDTPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_arcane_starfire]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:AddMode(self, "Damage Taken")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Damage Taken")
+
+---------------------------------------------------------------------------
+-- Avoidance & Mitigation Module
+
+Skada:RegisterModule("Avoidance & Mitigation", function(L)
+ local mode = Skada:NewModule("Avoidance & Mitigation")
+ local mode_breakdown = mode:NewModule("More Details")
+ local classfmt = Skada.classcolors.format
+ local missTypes = Skada.missTypes
+ local C = Skada.cacheTable2
+ local mode_cols = nil
+
+ local function fmt_valuetext(d, columns, total, count, metadata)
+ d.valuetext = Skada:FormatValueCols(
+ columns.Percent and Skada:FormatPercent(d.value),
+ columns.Count and count and Skada:FormatNumber(count),
+ columns.Total and Skada:FormatNumber(total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ function mode_breakdown:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's details"], classfmt(class, label))
+ end
+
+ function mode_breakdown:Update(win, set)
+ win.title = uformat(L["%s's details"], classfmt(win.actorclass, win.actorname))
+
+ local actor = win.actorid and C[win.actorid]
+ if not actor then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for event, count in pairs(actor.data) do
+ nr = nr + 1
+
+ local d = win:nr(nr)
+ d.id = event
+ d.label = L[event]
+ d.value = 100 * count / actor.total
+ fmt_valuetext(d, mode_cols, actor.total, count, win.metadata)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Avoidance & Mitigation"], L[win.class]) or L["Avoidance & Mitigation"]
+
+ local total = set and set.totaldamaged
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ clear(C) -- used later
+
+ local nr = 0
+
+ local actors = set.actors
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.damagedspells then
+ local tmp = new()
+ tmp.name = actorname
+
+ local count, avoid = 0, 0
+ for _, spell in pairs(actor.damagedspells) do
+ count = count + (spell.count or 0)
+
+ for k, v in pairs(missTypes) do
+ local num = spell[v] or spell[k]
+ if num then
+ avoid = avoid + num
+ tmp.data = tmp.data or new()
+ tmp.data[k] = (tmp.data[k] or 0) + num
+ end
+ end
+ end
+
+ if avoid > 0 then
+ tmp.total = count
+ tmp.avoid = avoid
+ C[actor.id] = tmp
+
+ nr = nr + 1
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+
+ d.value = 100 * avoid / count
+ fmt_valuetext(d, mode_cols, count, avoid, win.metadata)
+ win:color(d, set, actor.enemy)
+ elseif C[actor.id] then
+ C[actor.id] = del(C[actor.id])
+ end
+ end
+ end
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_breakdown,
+ columns = {Percent = true, Count = true, Total = true},
+ icon = [[Interface\ICONS\ability_warlock_avoidance]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:AddMode(self, "Damage Taken")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Damage Taken")
diff --git a/Skada/Modules/Deaths.lua b/Skada/Modules/Deaths.lua
new file mode 100644
index 0000000..8dd6dbe
--- /dev/null
+++ b/Skada/Modules/Deaths.lua
@@ -0,0 +1,1153 @@
+local folder, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Deaths", function(L, P, _, _, M, O)
+ local mode = Skada:NewModule("Deaths")
+ local mode_actor = mode:NewModule("Player's deaths")
+ local mode_deathlog = mode:NewModule("Death log")
+ local WATCH = nil -- true to watch those alive
+
+ --------------------------------------------------------------------------
+ -- cache most used functions
+ --------------------------------------------------------------------------
+ local tinsert, tremove, tsort, tconcat = table.insert, Private.tremove, table.sort, table.concat
+ local strmatch, format, uformat = strmatch, string.format, Private.uformat
+ local max, floor, abs = math.max, math.floor, math.abs
+ local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+ local UnitIsFeignDeath, UnitHealthInfo = UnitIsFeignDeath, Skada.UnitHealthInfo
+ local IsInGroup, IsInPvP, spellnames = IsInGroup, Skada.IsInPvP, Skada.spellnames
+ local GetTime, time, date, wipe = GetTime, time, date, wipe
+ local classfmt = Skada.classcolors.format
+ local mode_cols, submode_cols = nil, nil
+ local death_timers -- holds Spirit of Redemption scheduled death timers
+
+ --------------------------------------------------------------------------
+ -- colors and icons
+ --------------------------------------------------------------------------
+ local GREEN_COLOR = GREEN_FONT_COLOR
+ local ORANGE_COLOR = ORANGE_FONT_COLOR
+ local RED_COLOR = RED_FONT_COLOR
+ local YELLOW_COLOR = YELLOW_FONT_COLOR
+ local PURPLE_COLOR = {r = 0.69, g = 0.38, b = 1}
+ local BLUE_COLOR = {r = 0.176, g = 0.318, b = 1}
+ local icon_mode = [[Interface\ICONS\Ability_Rogue_FeignDeath]]
+ local icon_death = [[Interface\ICONS\Spell_Shadow_Soulleech_1]]
+
+ -- returns a color table by its key
+ local function get_color(key)
+ if P.usecustomcolors and P.customcolors and P.customcolors[format("deathlog_%s", key)] then
+ return P.customcolors[format("deathlog_%s", key)]
+ elseif key == "orange" then
+ return ORANGE_COLOR
+ elseif key == "yellow" then
+ return YELLOW_COLOR
+ elseif key == "green" then
+ return GREEN_COLOR
+ elseif key == "purple" then
+ return PURPLE_COLOR
+ elseif key == "blue" then
+ return BLUE_COLOR
+ else
+ return RED_COLOR
+ end
+ end
+
+ --------------------------------------------------------------------------
+ -- logger functions
+ --------------------------------------------------------------------------
+
+ local data = {} -- holds what's to log
+ local function log_deathlog(set, override)
+ if not set or (set == Skada.total and not P.totalidc) then return end
+
+ local actor = Skada:GetActor(set, data.actorname, data.actorid, data.actorflags)
+ if not actor then return end
+
+ local deathlog = actor.deathlog and actor.deathlog[1]
+ if not deathlog or (deathlog.timeod and not override) then
+ actor.deathlog = actor.deathlog or {}
+ tinsert(actor.deathlog, 1, {log = new()})
+ deathlog = actor.deathlog[1]
+ end
+
+ -- seet actor maxhp if not already set
+ if not deathlog.hpm or deathlog.hpm == 0 then
+ _, _, deathlog.hpm = UnitHealthInfo(data.actorname, actor.id, "group")
+ deathlog.hpm = deathlog.hpm or 0
+ end
+
+ local log = new()
+ log.id = data.spellid
+ log.src = data.srcName
+ log.cri = data.critical
+ log.time = Skada._Time or GetTime()
+ _, log.hp = UnitHealthInfo(data.actorname, actor.id, "group")
+
+ if data.amount then
+ deathlog.time = log.time
+ log.aur = nil
+ log.rem = nil
+
+ if data.amount == true then -- instakill
+ log.amt = -log.hp
+ deathlog.id = log.id
+ deathlog.src = log.src
+ elseif data.amount ~= 0 then
+ log.amt = data.amount
+
+ if log.amt < 0 then
+ deathlog.id = log.id
+ deathlog.src = log.src
+ end
+ end
+ elseif data.aura then
+ log.aur = 1
+ log.rem = data.remove and 1 or nil
+ end
+
+ if data.overheal and data.overheal > 0 then
+ log.ovh = data.overheal
+ end
+ if data.overkill and data.overkill > 0 then
+ log.ovk = data.overkill
+ end
+ if data.resisted and data.resisted > 0 then
+ log.res = data.resisted
+ end
+ if data.blocked and data.blocked > 0 then
+ log.blo = data.blocked
+ end
+ if data.absorbed and data.absorbed > 0 then
+ log.abs = data.absorbed
+ end
+
+ tinsert(deathlog.log, 1, log)
+
+ -- trim things and limit to deathlogevents (defaul: 14)
+ if #deathlog.log > M.deathlogevents then
+ del(tremove(deathlog.log))
+ end
+ end
+
+ local function log_death(set, actorname, actorid, actorflags)
+ local actor = Skada:GetActor(set, actorname, actorid, actorflags)
+ if not actor then return end
+
+ set.death = (set.death or 0) + 1
+ actor.death = (actor.death or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ local deathlog = actor.deathlog and actor.deathlog[1]
+ if not deathlog then return end
+
+ deathlog.time = Skada._Time or GetTime()
+ deathlog.timeod = Skada._time or time()
+
+ for i = #deathlog.log, 1, -1 do
+ local e = deathlog.log[i]
+ if (deathlog.time - e.time) >= 60 then
+ -- in certain situations, such us The Ruby Sanctum,
+ -- deathlog contain old data which are irrelevant to keep.
+ del(tremove(deathlog.log, i))
+ else
+ -- sometimes multiple close events arrive with the same timestamp
+ -- so we add a small correction to ensure sort stability.
+ e.time = e.time + (i * 0.001)
+ end
+ end
+
+ -- no entry left? insert an unknown entry
+ if #deathlog.log == 0 then
+ local log = new()
+ log.amt = -deathlog.hpm
+ log.time = deathlog.time - 0.001
+ log.hp = deathlog.hpm
+ deathlog.log[#deathlog.log + 1] = log
+ end
+
+ -- announce death
+ if M.deathannounce and set ~= Skada.total then
+ mode:Announce(deathlog.log, actorname)
+ end
+ end
+
+ --------------------------------------------------------------------------
+ -- damage handlers
+ --------------------------------------------------------------------------
+
+ local spell_damage
+ local spell_missed
+ do
+ local ignored_spells = Skada.ignored_spells.damage -- Edit Skada\Core\Tables.lua
+ local misstypes = {RESIST = true, BLOCK = true, ABSORB = true}
+
+ function spell_damage(t)
+ if t.spellid and t.amount and not ignored_spells[t.spellid] then
+ data.srcName = t.srcName
+ data.actorid = t.dstGUID
+ data.actorname = t.dstName
+ data.actorflags = t.dstFlags
+
+ data.spellid = t.spellstring
+ data.amount = t.amount
+ data.overkill = t.overkill
+ data.resisted = t.resisted
+ data.blocked = t.blocked
+ data.absorbed = t.absorbed
+ data.critical = t.critical
+ data.overheal = nil
+
+ if t.event == "SPELL_INSTAKILL" then
+ data.amount = true
+ else
+ data.amount = 0 - data.amount
+ end
+
+ Skada:DispatchSets(log_deathlog)
+ end
+ end
+
+ function spell_missed(t)
+ if t.spellid and not ignored_spells[t.spellid] and t.misstype and misstypes[t.misstype] then
+ data.srcName = t.srcName
+ data.actorid = t.dstGUID
+ data.actorname = t.dstName
+ data.actorflags = t.dstFlags
+ data.spellid = t.spellstring
+
+ data.amount = nil
+ data.overkill = nil
+ data.overheal = nil
+ data.critical = nil
+ data.aura = nil
+ data.remove = nil
+
+ if t.misstype == "RESIST" then
+ data.resisted = t.resisted
+ data.blocked = nil
+ data.absorbed = nil
+ elseif t.misstype == "BLOCK" then
+ data.resisted = nil
+ data.blocked = t.blocked
+ data.absorbed = nil
+ elseif t.misstype == "ABSORB" then
+ data.resisted = nil
+ data.blocked = nil
+ data.absorbed = t.absorbed
+ end
+
+ Skada:DispatchSets(log_deathlog)
+ end
+ end
+ end
+
+ --------------------------------------------------------------------------
+ -- heal handler
+ --------------------------------------------------------------------------
+
+ local spell_heal
+ do
+ -- Edit Skada\Core\Tables.lua
+ local ignored_spells = setmetatable({
+ [spellnames[15290]] = true, -- Vampiric Embrace
+ [spellnames[23881]] = true, -- Bloodthirst
+ [spellnames[52042]] = true, -- Healing Stream Totem
+ }, {__index = Skada.ignored_spells.heal})
+
+ function spell_heal(t)
+ -- no spell id or ignored healing spell? (Tables.lua)
+ if not t.spellid or ignored_spells[t.spellid] then return end
+ -- no spellstring or ignored healing spell? (top)
+ if not t.spellstring or ignored_spells[t.spellname] then return end
+ -- no amount or less than set threshold?
+ if not t.amount or t.amount < M.deathlogthreshold then return end
+
+ -- all tests passed?
+ data.actorid = t.dstGUID
+ data.actorname = t.dstName
+ data.actorflags = t.dstFlags
+ _, data.srcName = Skada:FixMyPets(t.srcGUID, t.srcName, t.srcFlags)
+ data.spellid = t.spellstring
+ data.amount = t.amount
+
+ data.overheal = nil
+ data.overkill = nil
+ data.resisted = nil
+ data.blocked = nil
+ data.absorbed = nil
+ data.critical = nil
+ data.aura = nil
+ data.remove = nil
+
+ if t.overheal and t.overheal > 0 then
+ data.amount = max(0, data.amount - t.overheal)
+ data.overheal = t.overheal
+ end
+
+ Skada:DispatchSets(log_deathlog)
+ end
+ end
+
+ --------------------------------------------------------------------------
+ -- death and resurrect handlers
+ --------------------------------------------------------------------------
+
+ local dead = {}
+ local function unit_died(t)
+ if not UnitIsFeignDeath(t.dstName) then
+ dead[t.dstName] = true
+ Skada:DispatchSets(log_death, t.dstName, t.dstGUID, t.dstFlags)
+ end
+ if death_timers and t.dstGUID and death_timers[t.dstGUID] then
+ Skada:CancelTimer(death_timers[t.dstGUID], true)
+ death_timers[t.dstGUID] = nil
+ if not next(death_timers) then
+ death_timers = del(death_timers)
+ end
+ end
+ end
+
+ local function sor_applied(t)
+ if t.spellid == 27827 then -- Spirit of Redemption (Holy Priest)
+ local args = new()
+ args.dstGUID = t.dstGUID
+ args.dstName = t.dstName
+ args.dstFlags = t.dstFlags
+
+ death_timers = death_timers or new()
+ death_timers[t.dstGUID] = Skada:ScheduleTimer(unit_died, 0.01, args)
+ end
+ end
+
+ local ress_spells = Skada.ress_spells
+ local function spell_resurrect(t)
+ if t.spellid and (t.event == "SPELL_RESURRECT" or ress_spells[t.spellid]) then
+ data.spellid = t.spellstring
+
+ if t.event == "SPELL_RESURRECT" then
+ data.srcName = t.srcName
+ data.actorid = t.dstGUID
+ data.actorname = t.dstName
+ data.actorflags = t.dstFlags
+ else
+ data.srcName = t.srcName
+ data.actorid = t.srcGUID
+ data.actorname = t.srcName
+ data.actorflags = t.srcFlags
+ end
+
+ data.amount = nil
+ data.overkill = nil
+ data.overheal = nil
+ data.resisted = nil
+ data.blocked = nil
+ data.absorbed = nil
+ data.critical = nil
+ data.aura = nil
+ data.remove = nil
+
+ dead[data.actorid] = nil
+ Skada:DispatchSets(log_deathlog, true)
+ end
+ end
+
+ --------------------------------------------------------------------------
+ -- buff and debuff handlers
+ --------------------------------------------------------------------------
+
+ local handle_debuff
+ local handle_buff
+ do
+ local ignored_debuff = Skada.ignored_spells.debuff -- Edit Skada\Core\Tables.lua
+ local ignored_buff = Skada.ignored_spells.buff -- Edit Skada\Core\Tables.lua
+ local tracked_buff = Skada.deathlog_tracked_buff -- Edit Skada\Core\Tables.lua
+
+ local function handle_aura(dstGUID, dstName, dstFlags, srcName, spellid, removed)
+ data.spellid = spellid
+ data.aura = true
+ data.remove = removed or nil
+
+ data.srcName = (srcName ~= dstName) and srcName or nil
+ data.actorid = dstGUID
+ data.actorname = dstName
+ data.actorflags = dstFlags
+
+ data.amount = nil
+ data.overkill = nil
+ data.overheal = nil
+ data.resisted = nil
+ data.blocked = nil
+ data.absorbed = nil
+ data.critical = nil
+
+ Skada:DispatchSets(log_deathlog)
+ end
+
+ function handle_debuff(t)
+ -- not a debuff or an ignored one?
+ if t.auratype ~= "DEBUFF" or not t.spellid or ignored_debuff[t.spellid] then return end
+ -- invalid destination or already dead?
+ if not t.dstName or dead[t.dstName] then return end
+
+ -- all tests passed.
+ handle_aura(t.dstGUID, t.dstName, t.dstFlags, t.srcName, t.spellstring, t.event == "SPELL_AURA_REMOVED")
+ end
+
+ function handle_buff(t)
+ -- not a buff or the spell isn't tracked?
+ if t.auratype ~= "BUFF" or not t.spellname or not tracked_buff[t.spellname] then return end
+ -- no spellid, an ignored spell or the destination isn't valid or is dead?
+ if not t.spellid or ignored_buff[t.spellid] or not t.dstGUID or dead[t.dstName] then return end
+
+ -- all tests passed.
+ handle_aura(t.dstGUID, t.dstName, t.dstFlags, t.srcName, t.spellstring, t.event == "SPELL_AURA_REMOVED")
+ end
+ end
+
+ --------------------------------------------------------------------------
+ -- module functions
+ --------------------------------------------------------------------------
+
+ function mode_deathlog:Enter(win, id, label)
+ if M.alternativedeaths then
+ win.actorid, win.datakey = strmatch(id, "(%w+)::(%d+)")
+ win.datakey = tonumber(win.datakey or 0)
+ win.actorname = label
+ else
+ win.datakey = id
+ end
+
+ win.title = uformat(L["%s's death log"], classfmt(win.actorclass, win.actorname))
+ end
+
+ do
+ local function sort_logs(a, b)
+ return a and b and a.time > b.time
+ end
+
+ function mode_deathlog:Update(win, set)
+ win.title = uformat(L["%s's death log"], classfmt(win.actorclass, win.actorname))
+
+ local actor = win.datakey and Skada:FindActor(set, win.actorname, win.actorid)
+ local deathlog = actor and actor.deathlog and actor.deathlog[win.datakey]
+ if not deathlog then return end
+
+ if M.alternativedeaths then
+ local num = #actor.deathlog
+ if win.datakey ~= num then
+ win.title = format("%s (%d)", win.title, num - win.datakey + 1)
+ end
+ end
+
+ if win.metadata then
+ win.metadata.maxvalue = deathlog.hpm
+ end
+
+ -- 1. remove "datakey" from ended logs.
+ -- 2. postfix empty table
+ -- 3. add a fake entry for the actual death
+ if deathlog.timeod then
+ -- win.datakey = nil -- [1] -- TODO: needs review
+
+ if #deathlog.log == 0 then -- [2]
+ local log = new()
+ log.time = deathlog.time - 0.001
+ if deathlog.hpm then
+ log.amt = -deathlog.hpm
+ log.hp = deathlog.hpm
+ else
+ log.amt = 0
+ log.hp = 0
+ end
+ deathlog.log[1] = log
+ end
+
+ if win.metadata then -- [3]
+ local d = win:nr(0)
+
+ d.id = 0
+ d.label = date("%H:%M:%S", deathlog.timeod)
+ d.icon = icon_mode
+ d.color = nil
+ d.value = 0
+ d.valuetext = format(L["%s dies"], win.actorname)
+ end
+ end
+
+ tsort(deathlog.log, sort_logs)
+
+ local nr = 0
+ local curtime = deathlog.time or Skada._Time or GetTime()
+ for i = #deathlog.log, 1, -1 do
+ local log = deathlog.log[i]
+ local diff = tonumber(log.time) - tonumber(curtime)
+ if diff > -60 then
+ nr = i + 1
+
+ local d = log.id and win:spell(nr, log.id, false) or win:nr(nr)
+ d.id = i
+ d.label = d.label or L["Unknown"]
+ d.icon = d.icon or icon_death
+ d.text = format("%s%02.2fs: %s", diff > 0 and "+" or "", diff, d.label)
+ d.value = log.hp or 0 -- used for tooltip
+
+ local src = log.src or L["Unknown"]
+ if d.spellid and ress_spells[d.spellid] then
+ d.color = nil
+ d.valuetext = src
+ else
+ local color = get_color("red")
+ local change = log.amt or 0
+
+ if log.aur and d.spellid > 0 then
+ change = format("%s %s", log.rem and "-" or "+", L["buff"])
+ color = get_color("blue")
+ elseif log.aur then
+ change = format("%s %s", log.rem and "-" or "+", L["debuff"])
+ color = get_color("purple")
+ elseif change > 0 then
+ change = format("+%s", Skada:FormatNumber(change))
+ color = get_color("green")
+ elseif change == 0 and (log.res or log.blo or log.abs) then
+ change = format("+%s", Skada:FormatNumber(log.res or log.blo or log.abs))
+ color = get_color("orange")
+ elseif log.ovh then
+ change = format("+%s", Skada:FormatNumber(log.ovh))
+ color = get_color("yellow")
+ elseif log.cri then
+ change = format("%s (%s)", Skada:FormatNumber(change), L["Crit"])
+ else
+ change = Skada:FormatNumber(change)
+ end
+
+ d.changed = (WATCH and color ~= d.color) and true or (WATCH and d.changed) and nil
+ d.color = color
+
+ -- only format report for ended logs
+ if deathlog.timeod ~= nil then
+ d.reportlabel = d.text
+ d.reportvalue = format("%s [%s]", change, Skada:FormatNumber(d.value))
+
+ local extra = new()
+
+ if log.ovh and log.ovh > 0 then
+ extra[#extra + 1] = format("O:%s", Skada:FormatNumber(log.ovh))
+ end
+ if log.ovk and log.ovk > 0 then
+ extra[#extra + 1] = format("O:%s", Skada:FormatNumber(log.ovk))
+ end
+ if log.res and log.res > 0 then
+ extra[#extra + 1] = format("R:%s", Skada:FormatNumber(log.res))
+ end
+ if log.blo and log.blo > 0 then
+ extra[#extra + 1] = format("B:%s", Skada:FormatNumber(log.blo))
+ end
+ if log.abs and log.abs > 0 then
+ extra[#extra + 1] = format("A:%s", Skada:FormatNumber(log.abs))
+ end
+
+ if next(extra) then
+ d.reportvalue = format("%s (%s)", d.reportvalue, tconcat(extra, " - "))
+ end
+
+ extra = del(extra)
+ end
+
+ d.valuetext = Skada:FormatValueCols(
+ submode_cols.Change and change,
+ submode_cols.Health and Skada:FormatNumber(d.value),
+ submode_cols.Percent and Skada:FormatPercent(log.hp or 0, deathlog.hpm or 1)
+ )
+ end
+ else
+ del(tremove(deathlog.log, i))
+ end
+ end
+ end
+ end
+
+ function mode_actor:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's deaths"], classfmt(class, label))
+ end
+
+ function mode_actor:Update(win, set)
+ win.title = uformat(L["%s's deaths"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorid then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor or actor.enemy then return end
+
+ local deathlog = (actor.death or WATCH) and actor.deathlog
+ if not deathlog then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local curtime = Skada._Time or GetTime()
+
+ for i = 1, #deathlog do
+ local death = deathlog[i]
+ if death and (death.timeod or WATCH) then
+ nr = nr + 1
+
+ local d = death.id and win:spell(nr, death.id, false) or win:nr(nr)
+ d.id = i
+ d.icon = d.icon or icon_death
+ d.label = d.label or L["Unknown"]
+ if mode_cols.Source and death.src then
+ d.text = format("%s (%s)", d.label, death.src)
+ d.reportlabel = d.text
+ end
+
+ d.value = death.time or curtime
+ if death.timeod then
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Time and date("%H:%M:%S", death.timeod),
+ mode_cols.Survivability and Skada:FormatTime(death.timeod - set.starttime, true)
+ )
+ else
+ d.valuetext = "..."
+ end
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+ end
+
+ -- default Deaths module:
+ local function mod_update(self, win, set)
+ win.title = win.class and format("%s (%s)", L["Deaths"], L[win.class]) or L["Deaths"]
+
+ if not set or not (set.death or WATCH) then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local curtime = Skada._Time or GetTime()
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.deathlog and (actor.death or WATCH) then
+ nr = nr + 1
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+
+ if actor.death then
+ d.value = actor.death
+ d.valuetext = actor.death
+
+ if actor.deathlog then
+ local first_death = actor.deathlog[#actor.deathlog]
+ if first_death and first_death.time then
+ d.value = first_death.time
+ end
+ end
+ else
+ d.value = curtime
+ d.valuetext = "..."
+ end
+ end
+ end
+ end
+
+ -- alternative Deaths module:
+ local function alt_update(self, win, set)
+ win.title = win.class and format("%s (%s)", L["Deaths"], L[win.class]) or L["Deaths"]
+
+ if not set or not (set.death or WATCH) then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local curtime = Skada._Time or GetTime()
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.deathlog and (actor.death or WATCH) then
+ local num = #actor.deathlog
+ for j = 1, num do
+ local death = actor.deathlog[j]
+ if death and (death.timeod or WATCH) then
+ nr = nr + 1
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.id = format("%s::%d", actor.id, j)
+
+ if death.timeod then
+ d.value = death.time
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Time and date("%H:%M:%S", death.timeod),
+ mode_cols.Survivability and Skada:FormatTime(death.timeod - set.starttime, true)
+ )
+ else
+ d.value = curtime or GetTime()
+ d.valuetext = "..."
+ end
+
+ local src = mode_cols.Source and death.src
+ if num ~= 1 then
+ d.text = format(src and "%s (%d) (%s)" or "%s (%d)", d.label, num, src)
+ d.reportlabel = d.text
+ else
+ d.text = src and format("%s (%s)", d.label, src) or d.label
+ d.reportlabel = d.text
+ end
+
+ num = num - 1
+ end
+ end
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ if M.alternativedeaths and (set ~= Skada.total or P.totalidc) then
+ alt_update(self, win, set)
+ else
+ mod_update(self, win, set)
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ local deaths = set:GetTotal(win and win.class, nil, "death") or 0
+ return set.endtime or Skada._time or time(), deaths
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.death and set.death > 0 then
+ tooltip:AddDoubleLine(L["Deaths"], set.death, 1, 1, 1)
+ end
+ end
+
+ local function entry_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local deathlog = actor and actor.deathlog and win.datakey and actor.deathlog[win.datakey]
+ local entry = deathlog and deathlog.log and deathlog.log[id]
+ if not entry or not entry.id then return end
+
+ tooltip:AddLine(L["Spell details"])
+ tooltip:AddDoubleLine(L["Spell"], label, 1, 1, 1, 1, 1, 1)
+
+ if entry.src then
+ tooltip:AddDoubleLine(L["Source"], entry.src, 1, 1, 1, 1, 1, 1)
+ end
+
+ if entry.hp and entry.hp ~= 0 then
+ tooltip:AddDoubleLine(L["Health"], Skada:FormatNumber(entry.hp), 1, 1, 1)
+ end
+
+ local c = nil
+
+ if entry.amt and entry.amt ~= 0 then
+ c = get_color(entry.amt < 0 and "red" or "green")
+ tooltip:AddDoubleLine(L["Amount"], Skada:FormatNumber(entry.amt), 1, 1, 1, c.r, c.g, c.b)
+ end
+
+ if entry.ovk and entry.ovk > 0 then
+ tooltip:AddDoubleLine(L["Overkill"], Skada:FormatNumber(entry.ovk), 1, 1, 1, 0.77, 0.64, 0)
+ elseif entry.ovh and entry.ovh > 0 then
+ c = get_color("yellow")
+ tooltip:AddDoubleLine(L["Overheal"], Skada:FormatNumber(entry.ovh), 1, 1, 1, c.r, c.g, c.b)
+ end
+
+ if entry.res and entry.res > 0 then
+ c = get_color("orange")
+ tooltip:AddDoubleLine(L["RESIST"], Skada:FormatNumber(entry.res), 1, 1, 1, c.r, c.g, c.b)
+ end
+
+ if entry.blo and entry.blo > 0 then
+ c = get_color("orange")
+ tooltip:AddDoubleLine(L["BLOCK"], Skada:FormatNumber(entry.blo), 1, 1, 1, c.r, c.g, c.b)
+ end
+
+ if entry.abs and entry.abs > 0 then
+ c = get_color("orange")
+ tooltip:AddDoubleLine(L["ABSORB"], Skada:FormatNumber(entry.abs), 1, 1, 1, c.r, c.g, c.b)
+ end
+ end
+
+ function mode:OnEnable()
+ mode_deathlog.metadata = {
+ ordersort = true,
+ tooltip = entry_tooltip,
+ columns = {Change = true, Health = true, Percent = true},
+ icon = icon_death
+ }
+ mode_actor.metadata = {click1 = mode_deathlog}
+ self.metadata = {
+ filterclass = true,
+ click1 = mode_actor,
+ columns = {Time = true, Survivability = false, Source = false},
+ icon = icon_mode
+ }
+
+ -- alternative display
+ if M.alternativedeaths then
+ mode_actor.metadata.click1 = nil
+ self.metadata.click1 = mode_deathlog
+ end
+
+ mode_cols = self.metadata.columns
+ submode_cols = mode_deathlog.metadata.columns
+
+ -- no total click.
+ mode_deathlog.nototal = true
+ mode_actor.nototal = true
+
+ local flags_dst_nopets = {dst_is_interesting_nopets = true}
+
+ Skada:RegisterForCL(
+ sor_applied,
+ flags_dst_nopets,
+ "SPELL_AURA_APPLIED"
+ )
+
+ Skada:RegisterForCL(
+ spell_damage,
+ flags_dst_nopets,
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ "ENVIRONMENTAL_DAMAGE",
+ "SPELL_INSTAKILL"
+ )
+
+ Skada:RegisterForCL(
+ spell_missed,
+ flags_dst_nopets,
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada:RegisterForCL(
+ spell_heal,
+ flags_dst_nopets,
+ "SPELL_HEAL",
+ "SPELL_PERIODIC_HEAL"
+ )
+
+ Skada:RegisterForCL(
+ unit_died,
+ flags_dst_nopets,
+ "UNIT_DIED",
+ "UNIT_DESTROYED",
+ "UNIT_DISSIPATES"
+ )
+
+ Skada:RegisterForCL(
+ spell_resurrect,
+ flags_dst_nopets,
+ "SPELL_RESURRECT"
+ )
+
+ Skada:RegisterForCL(
+ spell_resurrect,
+ {src_is_interesting = true, dst_is_not_interesting = true},
+ "SPELL_CAST_SUCCESS"
+ )
+
+ Skada:RegisterForCL(
+ handle_buff,
+ {dst_is_interesting_nopets = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_REMOVED",
+ "SPELL_AURA_APPLIED_DOSE"
+ )
+
+ Skada:RegisterForCL(
+ handle_debuff,
+ {src_is_not_interesting = true, dst_is_interesting_nopets = true},
+ "SPELL_AURA_APPLIED",
+ "SPELL_AURA_REFRESH",
+ "SPELL_AURA_REMOVED",
+ "SPELL_AURA_APPLIED_DOSE"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(data)
+ wipe(dead)
+ end
+
+ function mode:SetComplete(set)
+ -- clean deathlogs.
+ for _, actor in pairs(set.actors) do
+ if not actor.enemy and (not set.death or not actor.death) then
+ actor.death, actor.deathlog = nil, del(actor.deathlog, true)
+ elseif not actor.enemy and actor.deathlog then
+ while #actor.deathlog > (actor.death or 0) do
+ del(tremove(actor.deathlog, 1), true)
+ end
+ if #actor.deathlog == 0 then
+ actor.deathlog = del(actor.deathlog)
+ end
+ end
+ end
+ end
+
+ local announce_fmt1 = "%s > %s (%s) %s"
+ local announce_fmt2 = format("%s: %%s > %%s (%%s) %%s", folder)
+
+ function mode:Announce(logs, actorname)
+ -- announce only if:
+ -- 1. we have a valid deathlog.
+ -- 2. actor is not in a pvp (spam caution).
+ -- 3. actor is in a group or channel set to self or guild.
+ if not logs or IsInPvP() then return end
+
+ local channel = M.deathchannel
+ if channel ~= "SELF" and channel ~= "GUILD" and not IsInGroup() then return end
+
+ local log = nil
+ for i = 1, #logs do
+ local l = logs[i]
+ if l and l.amt and l.amt < 0 then
+ log = l
+ break
+ end
+ end
+
+ if not log then return end
+
+ -- prepare the output.
+ local output = format(
+ (channel == "SELF") and announce_fmt1 or announce_fmt2,
+ log.src or L["Unknown"], -- source name
+ actorname or L["Unknown"], -- actor name
+ log.id and spellnames[abs(log.id)] or L["Unknown"], -- spell name
+ log.amt and Skada:FormatNumber(0 - log.amt, 1) or 0 -- spell amount
+ )
+
+ -- prepare any extra info.
+ if log.ovk or log.res or log.blo or log.abs then
+ local extra = new()
+
+ if log.ovk then
+ extra[#extra + 1] = format("O:%s", Skada:FormatNumber(log.ovk, 1))
+ end
+ if log.res then
+ extra[#extra + 1] = format("R:%s", Skada:FormatNumber(log.res, 1))
+ end
+ if log.blo then
+ extra[#extra + 1] = format("B:%s", Skada:FormatNumber(log.blo, 1))
+ end
+ if log.abs then
+ extra[#extra + 1] = format("A:%s", Skada:FormatNumber(log.abs, 1))
+ end
+ if next(extra) then
+ output = format("%s [%s]", output, tconcat(extra, " - "))
+ end
+
+ extra = del(extra)
+ end
+
+ Skada:SendChat(output, channel, "preset")
+ end
+
+ do
+ local options
+ local function get_options()
+ if not options then
+ options = {
+ type = "group",
+ name = mode.localeName,
+ desc = format(L["Options for %s."], L["Death log"]),
+ args = {
+ header = {
+ type = "description",
+ name = mode.localeName,
+ fontSize = "large",
+ image = icon_mode,
+ imageWidth = 18,
+ imageHeight = 18,
+ imageCoords = Skada.cropTable,
+ width = "full",
+ order = 0
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ deathlog = {
+ type = "group",
+ name = L["Death log"],
+ inline = true,
+ order = 10,
+ args = {
+ deathlogevents = {
+ type = "range",
+ name = L["Events Amount"],
+ desc = L["Set the amount of events the death log should record."],
+ min = 4,
+ max = 34,
+ step = 1,
+ order = 10
+ },
+ deathlogthreshold = {
+ type = "range",
+ name = L["Minimum Healing"],
+ desc = L["Ignore heal events that are below this threshold."],
+ min = 0,
+ max = 10000,
+ step = 1,
+ bigStep = 10,
+ order = 20
+ }
+ }
+ },
+ announce = {
+ type = "group",
+ name = L["Announce Deaths"],
+ inline = true,
+ order = 20,
+ args = {
+ anndesc = {
+ type = "description",
+ name = L["Announces information about the last hit the player took before they died."],
+ fontSize = "medium",
+ width = "full",
+ order = 10
+ },
+ deathannounce = {
+ type = "toggle",
+ name = L["Enable"],
+ order = 20
+ },
+ deathchannel = {
+ type = "select",
+ name = L["Channel"],
+ values = {AUTO = L["Instance"], SELF = L["Self"], GUILD = L["Guild"]},
+ order = 30,
+ disabled = function()
+ return not M.deathannounce
+ end
+ }
+ }
+ },
+ alternativedeaths = {
+ type = "toggle",
+ name = L["Alternative Display"],
+ desc = L["If a player dies multiple times, each death will be displayed as a separate bar."],
+ set = function(_, value)
+ if M.alternativedeaths then
+ M.alternativedeaths = nil
+ mode.metadata.click1 = mode_actor
+ mode_actor.metadata.click1 = mode_deathlog
+ else
+ M.alternativedeaths = true
+ mode.metadata.click1 = mode_deathlog
+ mode_actor.metadata.click1 = nil
+ end
+
+ mode:Reload()
+ Skada:Wipe(true)
+ Skada:UpdateDisplay(true)
+ end,
+ width = "full",
+ order = 30
+ }
+ }
+ }
+ end
+ return options
+ end
+
+ function mode:OnInitialize()
+ M.deathlogevents = M.deathlogevents or 14
+ M.deathlogthreshold = M.deathlogthreshold or 1000
+ M.deathchannel = M.deathchannel or "AUTO"
+
+ O.modules.args.deathlog = get_options()
+
+ -- add colors to tweaks
+ local color_opt = O.tweaks.args.advanced.args.colors
+ if not color_opt then return end
+ color_opt.args.deathlog = {
+ type = "group",
+ name = L["Death log"],
+ order = 50,
+ hidden = O.tweaks.args.advanced.args.colors.args.custom.disabled,
+ disabled = O.tweaks.args.advanced.args.colors.args.custom.disabled,
+ get = function(i)
+ local color = get_color(i[#i])
+ return color.r, color.g, color.b
+ end,
+ set = function(i, r, g, b)
+ P.customcolors = P.customcolors or {}
+ local key = format("deathlog_%s", i[#i])
+ P.customcolors[key] = P.customcolors[key] or {}
+ P.customcolors[key].r = r
+ P.customcolors[key].g = g
+ P.customcolors[key].b = b
+ end,
+ args = {
+ green = {
+ type = "color",
+ name = L["Healing Taken"],
+ desc = format(L["Color for %s."], L["Healing Taken"]),
+ order = 10
+ },
+ red = {
+ type = "color",
+ name = L["Damage Taken"],
+ desc = format(L["Color for %s."], L["Damage Taken"]),
+ order = 20
+ },
+ yellow = {
+ type = "color",
+ name = L["Overheal"],
+ desc = format(L["Color for %s."], L["Overhealing"]),
+ order = 20
+ },
+ orange = {
+ type = "color",
+ name = L["Avoidance & Mitigation"],
+ desc = format(L["Color for %s."], L["Avoidance & Mitigation"]),
+ order = 20
+ },
+ purple = {
+ type = "color",
+ name = L["Debuffs"],
+ desc = format(L["Color for %s."], L["Debuffs"]),
+ order = 30
+ },
+ blue = {
+ type = "color",
+ name = L["Buffs"],
+ desc = format(L["Color for %s."], L["Debuffs"]),
+ order = 40
+ }
+ }
+ }
+ end
+ end
+end)
diff --git a/Skada/Modules/Dispels.lua b/Skada/Modules/Dispels.lua
new file mode 100644
index 0000000..0865694
--- /dev/null
+++ b/Skada/Modules/Dispels.lua
@@ -0,0 +1,262 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Dispels", function(L, P, _, C)
+ local mode = Skada:NewModule("Dispels")
+ local mode_extraspell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_spell = mode:NewModule("Dispel Spells")
+ local classfmt = Skada.classcolors.format
+ local ignored_spells = Skada.ignored_spells.dispel -- Edit Skada\Core\Tables.lua
+ local get_actor_dispelled_spells = nil
+ local get_actor_dispelled_targets = nil
+
+ -- cache frequently used globals
+ local pairs, format = pairs, string.format
+ local uformat, new, clear = Private.uformat, Private.newTable, Private.clearTable
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local dispel = {}
+ local function log_dispel(set)
+ local actor = Skada:GetActor(set, dispel.actorname, dispel.actorid, dispel.actorflags)
+ if not actor then return end
+
+ -- increment actor's and set's dispels count
+ actor.dispel = (actor.dispel or 0) + 1
+ set.dispel = (set.dispel or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if (set == Skada.total and not P.totalidc) or not dispel.spellid then return end
+
+ local spell = actor.dispelspells and actor.dispelspells[dispel.spellid]
+ if not spell then
+ actor.dispelspells = actor.dispelspells or {}
+ actor.dispelspells[dispel.spellid] = {count = 1}
+ spell = actor.dispelspells[dispel.spellid]
+ else
+ spell.count = spell.count + 1
+ end
+
+ -- the dispelled spell
+ if dispel.extraspellid then
+ spell.spells = spell.spells or {}
+ spell.spells[dispel.extraspellid] = (spell.spells[dispel.extraspellid] or 0) + 1
+ end
+
+ -- the dispelled target
+ if dispel.dstName then
+ spell.targets = spell.targets or {}
+ spell.targets[dispel.dstName] = (spell.targets[dispel.dstName] or 0) + 1
+ end
+ end
+
+ local function spell_dispel(t)
+ if t.spellid and not ignored_spells[t.spellid] and not ignored_spells[t.extraspellid] then
+ dispel.actorid = t.srcGUID
+ dispel.actorname = t.srcName
+ dispel.actorflags = t.srcFlags
+
+ dispel.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+ dispel.spellid = t.spellstring
+ dispel.extraspellid = t.extrastring
+
+ Skada:FixPets(dispel)
+ Skada:DispatchSets(log_dispel)
+ end
+ end
+
+ function mode_extraspell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's dispelled spells"], classfmt(class, label))
+ end
+
+ function mode_extraspell:Update(win, set)
+ win.title = uformat(L["%s's dispelled spells"], classfmt(win.actorclass, win.actorname))
+
+ local spells, total, actor = get_actor_dispelled_spells(set, win.actorname, win.actorid)
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, count in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ local targets, total, actor = get_actor_dispelled_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.dispel
+ local spells = (total and total > 0) and actor.dispelspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Dispels"], L[win.class]) or L["Dispels"]
+
+ local total = set and set:GetTotal(win.class, nil, "dispel")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.dispel then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.dispel
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ local value = set:GetTotal(win and win.class, nil, "dispel") or 0
+ return value, Skada:FormatNumber(value)
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.dispel and set.dispel > 0 then
+ tooltip:AddDoubleLine(L["Dispels"], set.dispel, 1, 1, 1)
+ end
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_target,
+ click2 = mode_extraspell,
+ click3 = mode_spell,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\spell_holy_dispelmagic]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_extraspell.nototal = true
+ mode_target.nototal = true
+ mode_spell.nototal = true
+
+ Skada:RegisterForCL(spell_dispel, {src_is_interesting = true}, "SPELL_DISPEL", "SPELL_STOLEN")
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actor_dispelled_spells = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local total = actor and actor.dispel
+ local spells = total and total > 0 and actor.dispelspells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ if spell.spells then
+ for spellid, count in pairs(spell.spells) do
+ tbl[spellid] = (tbl[spellid] or 0) + count
+ end
+ end
+ end
+ return tbl, total, actor
+ end
+
+ get_actor_dispelled_targets = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local total = actor and actor.dispel
+ local spells = total and total > 0 and actor.dispelspells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for targetname, count in pairs(spell.targets) do
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.count = count
+ tbl[targetname] = t
+ else
+ t.count = t.count + count
+ end
+ self:_fill_actor_table(t, targetname, nil, true)
+ end
+ end
+ end
+ return tbl, total, actor
+ end
+end)
diff --git a/Skada/Modules/Enemies.lua b/Skada/Modules/Enemies.lua
new file mode 100644
index 0000000..725071c
--- /dev/null
+++ b/Skada/Modules/Enemies.lua
@@ -0,0 +1,1519 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+-- frequently used globals --
+local pairs, type, format, max = pairs, type, string.format, math.max
+local wipe, uformat, new, clear = wipe, Private.uformat, Private.newTable, Private.clearTable
+local setPrototype, enemyPrototype = Skada.setPrototype, Skada.enemyPrototype
+
+---------------------------------------------------------------------------
+-- Enemy Damage Taken
+
+Skada:RegisterModule("Enemy Damage Taken", function(L, P, _, C)
+ local mode = Skada:NewModule("Enemy Damage Taken")
+ local mode_source = mode:NewModule("Source List")
+ local mode_source_spell = mode_source:NewModule("Spell List")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_source = mode_spell:NewModule("Source List")
+ local mode_useful = mode:NewModule("Useful Damage")
+ local mode_cols = nil
+
+ local GetUnitIdFromGUID, GetCreatureId = Skada.GetUnitIdFromGUID, Skada.GetCreatureId
+ local UnitExists, UnitGUID = UnitExists, UnitGUID
+ local UnitHealthMax, UnitPowerMax = UnitHealthMax, UnitPowerMax
+ local del, copy = Private.delTable, Private.copyTable
+ local classfmt = Skada.classcolors.format
+
+ local ignored_spells = Skada.ignored_spells.damage -- Edit Skada\Core\Tables.lua
+ local grouped_units = Skada.grouped_units -- Edit Skada\Core\Tables.lua
+ local user_units = Skada.custom_units -- Edit Skada\Core\Tables.lua
+ local ignored_creatures = Skada.ignored_creatures -- Edit Skada\Core\Tables.lua
+ local trash_n_boss = grouped_units.BOSS or grouped_units.TRASH -- Edit Skada\Core\Tables.lua
+
+ local totalset = L["Total"]
+ local instance_diff, instance_type
+ local max_health, max_power
+ local custom_units = {}
+ local custom_groups = {}
+ local instance_units = {}
+ local ignored_units = {}
+ local ignored_instance_units = {}
+
+ -- table of acceptable/trackable instance difficulties
+ -- uncomment those you want to use or add custom ones.
+ local allowed_diffs = {
+ -- ["5n"] = false, -- 5man Normal
+ -- ["5h"] = false, -- 5man Heroic
+ -- ["mc"] = false, -- Mythic Dungeons
+ -- ["tw"] = false, -- Time Walker
+ -- ["wb"] = false, -- World Boss
+ ["10n"] = true, -- 10man Normal
+ ["10h"] = true, -- 10man Heroic
+ ["25n"] = true, -- 25man Normal
+ ["25h"] = true, -- 25man Heroic
+ }
+
+ local function format_valuetext(d, total, dtps, metadata, subview, dont_sort)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sDTPS" or "DTPS"] and Skada:FormatNumber(dtps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if not dont_sort and metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function get_instance_diff()
+ if not instance_diff then
+ instance_diff = Skada:GetInstanceDiff() or "NaN"
+ end
+ return instance_diff
+ end
+
+ local function get_custom_unit_maxval(guid, unit, name)
+ if not unit then return end -- no user-defined custom unit?
+
+ local creatureId = GetCreatureId(guid)
+ local diff = get_instance_diff()
+
+ if unit.power ~= nil then
+ -- already cached power?
+ if max_power and max_power[creatureId] and max_power[creatureId][diff] then
+ return max_power[creatureId][diff]
+ end
+
+ -- try to grab UnitID
+ local uid = GetUnitIdFromGUID(guid)
+ if not uid then return end
+
+ local maxval = UnitPowerMax(uid, unit.power)
+ if not maxval then return end
+
+ max_power = max_power or {}
+ max_power[creatureId] = max_power[creatureId] or {}
+ max_power[creatureId][diff] = maxval
+ Skada:Debug(format("[%s:%s] \124cffffbb00Max Power\124r: %s (diff: %s)", name, creatureId, maxval, diff))
+
+ return maxval
+ end
+
+ -- already cached health?
+ if max_health and max_health[creatureId] and max_health[creatureId][diff] then
+ return max_health[creatureId][diff]
+ end
+
+ -- try to grab UnitID
+ local uid = GetUnitIdFromGUID(guid)
+ if not uid then return end
+
+ local maxval = UnitHealthMax(uid)
+ if not maxval then return end
+
+ max_health = max_health or {}
+ max_health[creatureId] = max_health[creatureId] or {}
+ max_health[creatureId][diff] = maxval
+ Skada:Debug(format("[%s:%s] \124cffffbb00Max Health\124r: %s (diff: %s)", name, creatureId, maxval, diff))
+
+ return maxval
+ end
+
+ local function get_custom_unit_name(unit, text, start, stop, oname)
+ local str = type(text) == "string" and text or stop and L["%s - %s%% to %s%%"] or L["%s below %s%%"]
+ return format(str, oname, start * 100, stop * 100)
+ end
+
+ local function create_unit_table(unit, guid, creatureId, name, maxval, curval)
+ local start = (unit.start or 1)
+ local stop = (unit.stop or 0)
+
+ -- ignore units below minimum required.
+ local minval = floor(maxval * stop)
+ if curval <= minval then
+ ignored_units[guid] = true
+ return false
+ end
+
+ local t = new()
+ t.oname = name or L["Unknown"]
+ t.name = unit.name or get_custom_unit_name(unit, unit.text, start, stop, t.oname)
+ t.id = creatureId
+ t.guid = guid
+ t.curval = curval
+ t.minval = minval
+ t.maxval = floor(maxval * start)
+ t.full = maxval
+ t.power = (unit.power ~= nil)
+ t.useful = unit.useful
+
+ return t
+ end
+
+ local function start_custom_unit(unit, creatureId, guid, name, amount, overkill)
+ if unit.diff ~= nil and ((type(unit.diff == "table") and not unit.diff[get_instance_diff()]) or (type(unit.diff) ~= "table" and unit.diff ~= get_instance_diff())) then
+ ignored_units[guid] = true
+ return false
+ end
+
+ -- get the unit max value.
+ local maxval = get_custom_unit_maxval(guid, unit, name)
+ if not maxval or maxval == 0 then
+ ignored_units[guid] = true
+ return false
+ end
+
+ -- calculate current value then create unit table
+ local curval = maxval - amount - overkill
+ return create_unit_table(unit, guid, creatureId, name, maxval, curval)
+ end
+
+ local function get_custom_units(guid, name, amount, overkill)
+ -- invalid or ignored?
+ if not guid or ignored_units[guid] then return end
+
+ -- already cached?
+ local units = custom_units[guid]
+ if units then
+ return units
+ end
+
+ local creatureId = GetCreatureId(guid)
+ local my_units = user_units[creatureId]
+ if not my_units then
+ ignored_units[guid] = true
+ return
+ end
+
+ if type(my_units[1]) ~= "table" then
+ local to_copy = copy(my_units)
+ wipe(user_units[creatureId])
+ user_units[creatureId][1] = to_copy
+ my_units = user_units[creatureId]
+ end
+
+ units = new()
+ for i = 1, #my_units do
+ local unit = start_custom_unit(my_units[i], creatureId, guid, name, amount, overkill, i)
+ if unit then
+ units[#units + 1] = unit
+ end
+ end
+
+ custom_units[guid] = units
+ return units
+ end
+
+ local function log_custom_unit(set, name, playername, spellid, amount, absorbed)
+ local e = Skada:GetActor(set, name, name, true)
+ if not e then return end
+
+ e.damaged = (e.damaged or 0) + amount
+ e.totaldamaged = (e.totaldamaged or 0) + amount
+ if absorbed > 0 then
+ e.totaldamaged = e.totaldamaged + absorbed
+ end
+
+ if not spellid then return end
+
+ -- spell
+ local spell = e.damagedspells and e.damagedspells[spellid]
+ if not spell then
+ e.damagedspells = e.damagedspells or {}
+ e.damagedspells[spellid] = {amount = amount}
+ spell = e.damagedspells[spellid]
+ else
+ spell.amount = spell.amount + amount
+ end
+
+ if spell.total then
+ spell.total = spell.total + amount + absorbed
+ elseif absorbed > 0 then
+ spell.total = spell.amount + absorbed
+ end
+
+ -- source
+ local source = spell.sources and spell.sources[playername]
+ if not source then
+ spell.sources = spell.sources or {}
+ spell.sources[playername] = {amount = amount}
+ source = spell.sources[playername]
+ else
+ source.amount = source.amount + amount
+ end
+
+ if source.total then
+ source.total = source.total + amount + absorbed
+ elseif absorbed > 0 then
+ source.total = source.amount + absorbed
+ end
+ end
+
+ local function log_custom_group(set, name, id, playername, spellid, amount, overkill, absorbed, isboss)
+ if trash_n_boss and set.name == totalset and name and not ignored_instance_units[name] then
+ -- see if it was cached already
+ local trash_or_boss = instance_units[name]
+ if not trash_or_boss then -- process if not cached.
+ if grouped_units.BOSS and isboss then
+ trash_or_boss = instance_type == "raid" and L["Raid Bosses"] or L["Dungeon Bosses"]
+ elseif grouped_units.TRASH and not isboss then
+ trash_or_boss = instance_type == "raid" and L["Raid Trash"] or L["Dungeon Trash"]
+ end
+ instance_units[name] = trash_or_boss -- cache if found.
+ end
+ if trash_or_boss then -- record if found.
+ log_custom_unit(set, trash_or_boss, playername, spellid, amount, absorbed)
+ else -- otherwise, ignore it.
+ ignored_instance_units[name] = true
+ end
+ end
+
+ -- we use ignored units table to ignore grouped units
+ -- if not needed in order to reduce useless processing.
+ if not name or ignored_units[name] then return end
+
+ -- a custom unit with useful damage (i.e: Valkyr overkilling)
+ if id and custom_groups[id] then return end
+
+ -- see if it was cached already..
+ local group_name = grouped_units[name]
+ if not group_name then -- a little bit of processing if not cached.
+ group_name = grouped_units[GetCreatureId(id)]
+ if not group_name then -- not found?
+ ignored_units[name] = true -- ignore it so we only process once.
+ return
+ end
+ grouped_units[name] = group_name -- cache it.
+ end
+
+ -- Halion and Inferno are only considered for 25 heroic mode.
+ if group_name == L["Halion and Inferno"] and get_instance_diff() ~= "25h" then return end
+
+ -- log the damage as custom fake unit.
+ -- PS: we use "overkill" instead of "amount" for "Princes overkilling"
+ log_custom_unit(set, group_name, playername, spellid, group_name == L["Princes overkilling"] and overkill or amount, absorbed)
+ end
+
+ local dmg = {}
+ local function log_damage(set, isboss)
+ local amount = dmg.amount
+ if not amount then return end
+
+ local absorbed = dmg.absorbed or 0
+ if (amount + absorbed) == 0 then return end
+
+ local actorid, actorname = dmg.actorid, dmg.actorname
+ local e = Skada:GetActor(set, actorname, actorid, dmg.actorflags)
+ if not e then return end
+
+ e.damaged = (e.damaged or 0) + amount
+ set.edamaged = (set.edamaged or 0) + amount
+
+ if e.totaldamaged then
+ e.totaldamaged = e.totaldamaged + amount + absorbed
+ elseif absorbed > 0 then
+ e.totaldamaged = e.damaged + absorbed
+ end
+
+ if set.etotaldamaged then
+ set.etotaldamaged = set.etotaldamaged + amount + absorbed
+ elseif absorbed > 0 then
+ set.etotaldamaged = set.edamaged + absorbed
+ end
+
+ local srcName = dmg.srcName
+ local spellid = dmg.spellid
+ local overkill = dmg.overkill or 0
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set.name == totalset and not P.totalidc then
+ log_custom_group(set, actorname, actorid, srcName, spellid, amount, overkill, absorbed, isboss)
+ return
+ end
+
+ -- damage spell.
+ local spell = e.damagedspells and e.damagedspells[spellid]
+ if not spell then
+ e.damagedspells = e.damagedspells or {}
+ e.damagedspells[spellid] = {amount = amount}
+ spell = e.damagedspells[spellid]
+ else
+ spell.amount = spell.amount + amount
+ end
+
+ if spell.total then
+ spell.total = spell.total + amount + absorbed
+ elseif absorbed > 0 then
+ spell.total = spell.amount + absorbed
+ end
+
+ if overkill > 0 then
+ spell.o_amt = (spell.o_amt or 0) + overkill
+ end
+
+ -- damage source.
+ if not srcName then return end
+
+ -- the source
+ local source = spell.sources and spell.sources[srcName]
+ if not source then
+ spell.sources = spell.sources or {}
+ spell.sources[srcName] = {amount = amount}
+ source = spell.sources[srcName]
+ else
+ source.amount = source.amount + amount
+ end
+
+ if source.total then
+ source.total = source.total + amount + absorbed
+ elseif absorbed > 0 then
+ source.total = source.amount + absorbed
+ end
+
+ if overkill > 0 then
+ source.o_amt = (source.o_amt or 0) + overkill
+ end
+
+ -- custom groups
+ log_custom_group(set, actorname, actorid, srcName, spellid, amount, overkill, absorbed, isboss)
+
+ -- the rest of the code is only for allowed instance diffs.
+ if not allowed_diffs[get_instance_diff()] then return end
+
+ -- until a better and simple way is found to handle custom units
+ -- this is temporarily disabled, only recorded to the current set.
+ if set.name == totalset then return end
+
+ -- custom units.
+ local units = get_custom_units(actorid, actorname, amount, overkill)
+ if not units then return end
+
+ for i = 1, #units do
+ local unit = units[i]
+ if not unit or unit.done then
+ -- nothing to do
+ elseif unit.full then -- started with less than max?
+ amount = unit.full - unit.curval
+ if unit.useful then
+ e.usefuldamaged = (e.usefuldamaged or 0) + amount
+ spell.useful = (spell.useful or 0) + amount
+ source.useful = (source.useful or 0) + amount
+ end
+ if unit.maxval == unit.full then
+ log_custom_unit(set, unit.name, srcName, spellid, amount, absorbed)
+ end
+ unit.full = nil
+ elseif unit.curval >= unit.maxval then -- still above max value?
+ amount = amount - overkill
+ unit.curval = unit.curval - amount
+
+ if unit.curval <= unit.maxval then
+ log_custom_unit(set, unit.name, srcName, spellid, unit.maxval - unit.curval, absorbed)
+ amount = amount - (unit.maxval - unit.curval)
+ if grouped_units[unit.oname] and unit.useful then
+ log_custom_group(set, unit.oname, unit.guid, srcName, spellid, amount, overkill, absorbed)
+ custom_groups[unit.guid] = true
+ end
+ if grouped_units[unit.name] then
+ log_custom_group(set, unit.name, unit.guid, srcName, spellid, unit.maxval - unit.curval, overkill, absorbed)
+ end
+ end
+ if unit.useful then
+ e.usefuldamaged = (e.usefuldamaged or 0) + amount
+ spell.useful = (spell.useful or 0) + amount
+ source.useful = (source.useful or 0) + amount
+ end
+ elseif unit.curval >= unit.minval then -- astill above min value?
+ amount = amount - overkill
+ unit.curval = unit.curval - amount
+
+ if grouped_units[unit.name] then
+ log_custom_group(set, unit.name, unit.guid, srcName, spellid, amount, overkill, absorbed)
+ end
+
+ if unit.curval <= unit.minval then
+ local delta = unit.minval - unit.curval
+ log_custom_unit(set, unit.name, srcName, spellid, amount - delta, absorbed)
+ Skada:Debug(format("[%s] \124cffffbb00Stopped\124r", unit.name))
+ unit.done = true
+ else
+ log_custom_unit(set, unit.name, srcName, spellid, amount, absorbed)
+ end
+ elseif unit.power then -- tracking power instead?
+ log_custom_unit(set, unit.name, srcName, spellid, amount - (unit.useful and overkill or 0), absorbed)
+ end
+ end
+ end
+
+ local function spell_damage(t)
+ if
+ t.srcName and t.dstName and
+ not ignored_creatures[GetCreatureId(t.dstGUID)] and
+ t.spellid and not ignored_spells[t.spellid] and
+ (not t.misstype or t.misstype == "ABSORB")
+ then
+ dmg.actorid = t.dstGUID
+ dmg.actorname = t.dstName
+ dmg.actorflags = t.dstFlags
+
+ dmg.spellid = t.spellstring
+ dmg.amount = t.amount
+ dmg.overkill = t.overkill
+ dmg.absorbed = t.absorbed
+
+ _, dmg.srcName = Skada:FixMyPets(t.srcGUID, t.srcName, t.srcFlags)
+ Skada:DispatchSets(log_damage, t:DestIsBoss())
+ end
+ end
+
+ local function mode_source_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local damage, overkill, useful = set:GetActorDamageFromSource(win.targetname, win.targetid, label)
+ if damage == 0 then return end
+
+ tooltip:AddLine(format(L["%s's details"], label))
+ tooltip:AddDoubleLine(L["Damage Done"], Skada:FormatNumber(damage), 1, 1, 1)
+ if useful > 0 then
+ tooltip:AddDoubleLine(L["Useful Damage"], format("%s (%s)", Skada:FormatNumber(useful), Skada:FormatPercent(useful, damage)), 1, 1, 1)
+
+ -- override overkill
+ overkill = max(0, damage - useful)
+ tooltip:AddDoubleLine(L["Overkill"], format("%s (%s)", Skada:FormatNumber(overkill), Skada:FormatPercent(overkill, damage)), 1, 1, 1)
+ elseif overkill > 0 then
+ tooltip:AddDoubleLine(L["Overkill"], format("%s (%s)", Skada:FormatNumber(overkill), Skada:FormatPercent(overkill, damage)), 1, 1, 1)
+ end
+ end
+
+ local function mode_useful_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local e = set and set:GetActor(label, id)
+ local amount, total, useful = e:GetDamageTakenBreakdown(set)
+ if not useful or useful == 0 then return end
+
+ tooltip:AddLine(format(L["%s's details"], label))
+ tooltip:AddDoubleLine(L["Damage Done"], Skada:FormatNumber(total), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Useful Damage"], format("%s (%s)", Skada:FormatNumber(useful), Skada:FormatPercent(useful, total)), 1, 1, 1)
+ local overkill = max(0, total - useful)
+ tooltip:AddDoubleLine(L["Overkill"], format("%s (%s)", Skada:FormatNumber(overkill), Skada:FormatPercent(overkill, total)), 1, 1, 1)
+ end
+
+ function mode_spell_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> sources"], classfmt(win.targetclass, win.targetname), label)
+ end
+
+ function mode_spell_source:Update(win, set)
+ win.title = uformat(L["%s's <%s> sources"], classfmt(win.targetclass, win.targetname), win.spellname)
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ if not win.spellid then return end
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ if not (actor and actor.GetDamageSpellSources) then return end
+
+ local sources, total = actor:GetDamageSpellSources(set, win.spellid)
+ if not sources or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(sources) do
+ if not win.class or win.class == source.class then
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_source:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["%s's sources"], classfmt(class, label))
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat(L["%s's sources"], classfmt(win.targetclass, win.targetname))
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ local sources, total, actor = set:GetActorDamageSources(win.targetname, win.targetid)
+ if not sources or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(sources) do
+ if not win.class or win.class == source.class then
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = P.absdamage and source.total or source.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_source_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(class, label), classfmt(win.targetclass, win.targetname))
+ end
+
+ function mode_source_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not win.actorname or not win.targetname then return end
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ local sources = actor and actor:GetDamageSources(set)
+ local source = sources and sources[win.actorname]
+ if not source then return end
+
+ local total = P.absdamage and source.total or source.amount
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+ local spells = actor.damagedspells
+
+ for spellid, spell in pairs(spells) do
+ local src = spell.sources and spell.sources[win.actorname]
+ if src then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and src.total or src.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["Spells on %s"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["Spells on %s"], classfmt(win.targetclass, win.targetname))
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ local total = actor and actor:GetDamageTaken()
+ local spells = (total and total > 0) and actor.damagedspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_useful:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["Useful damage on %s"], classfmt(class, label))
+ end
+
+ function mode_useful:Update(win, set)
+ win.title = uformat(L["Useful damage on %s"], classfmt(win.targetclass, win.targetname))
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ local total = actor and actor.usefuldamaged
+ local sources = (total and total > 0) and actor:GetDamageSources(set)
+
+ if not sources then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDTPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(sources) do
+ if win:show_actor(source, set) and source.useful and source.useful > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.useful
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Enemy Damage Taken"]
+
+ local total = set and set:GetDamageTaken(win.class, true)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if actor.enemy then
+ local dtps, amount = actor:GetDTPS(set, nil, not mode_cols.sDTPS)
+ if amount and amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, total, dtps, win.metadata, nil, actor.fake)
+ end
+ end
+ end
+ end
+
+ function mode_source:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.targetname, win.targetid)
+ if not actor then return end
+
+ local dtps, amount = actor:GetDTPS(set, not mode_cols.sDTPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.sDTPS and Skada:FormatNumber(dtps)
+ )
+ return amount, valuetext
+ end
+ mode_spell.GetSetSummary = mode_source.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local dtps, amount = set:GetDTPS(win and win.class, true)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.DTPS and Skada:FormatNumber(dtps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_spell_source.metadata = {showspots = true, filterclass = true}
+ mode_useful.metadata = {showspots = true, filterclass = true}
+ mode_source.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_source_spell,
+ post_tooltip = mode_source_tooltip
+ }
+ mode_spell.metadata = {click1 = mode_spell_source, valueorder = true}
+ self.metadata = {
+ click1 = mode_source,
+ click2 = mode_spell,
+ click3 = mode_useful,
+ post_tooltip = mode_useful_tooltip,
+ columns = {Damage = true, DTPS = false, Percent = true, sDTPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_fire_felflamebolt]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_source.nototal = true
+ mode_spell.nototal = true
+ mode_useful.nototal = true
+
+ Skada:RegisterForCL(
+ spell_damage,
+ {src_is_interesting = true, dst_is_not_interesting = true},
+ -- damage events
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ "ENVIRONMENTAL_DAMAGE",
+ -- missed events
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada.RegisterMessage(self, "ZONE_TYPE_CHANGED", "CheckZone")
+ Skada:AddMode(self, "Enemies")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ instance_diff = nil
+ wipe(dmg)
+ clear(custom_units)
+ clear(custom_groups)
+ clear(instance_units)
+ clear(ignored_units)
+ clear(ignored_instance_units)
+ end
+
+ function mode:CheckZone(_, insType)
+ instance_type = insType
+ trash_n_boss = (insType == "raid" or insType == "party") and (grouped_units.BOSS or grouped_units.TRASH)
+ end
+
+ ---------------------------------------------------------------------------
+
+ function enemyPrototype:GetDamageSpellSources(set, spellid, tbl)
+ local spell = set and spellid and self.damagedspells and self.damagedspells[spellid]
+ if not spell or not spell.sources then return end
+
+ tbl = clear(tbl or C)
+ for name, source in pairs(spell.sources) do
+ local t = tbl[name]
+ if not t then
+ t = new()
+ t.amount = P.absdamage and source.total or source.amount or 0
+ tbl[name] = t
+ else
+ t.amount = t.amount + (P.absdamage and source.total or source.amount or 0)
+ end
+
+ set:_fill_actor_table(t, name)
+ end
+
+ return tbl, P.absdamage and spell.total or spell.amount
+ end
+
+ function enemyPrototype:GetDamageTakenBreakdown(set)
+ local sources = self:GetDamageSources(set)
+ if not sources then return end
+
+ local amount, total, useful = 0, 0, 0
+ for _, src in pairs(sources) do
+ if src.amount then
+ amount = amount + src.amount
+ end
+ if src.total then
+ total = total + src.total
+ elseif src.amount then
+ total = total + src.amount
+ end
+ if src.useful then
+ useful = useful + src.useful
+ end
+ end
+ return amount, total, useful
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Enemy Damage Done
+
+Skada:RegisterModule("Enemy Damage Done", function(L, P, _, C)
+ local mode = Skada:NewModule("Enemy Damage Done")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Target List")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_target = mode_spell:NewModule("Target List")
+ local mode_cols = nil
+
+ local GetCreatureId = Skada.GetCreatureId
+ local classfmt = Skada.classcolors.format
+ local ignored_spells = Skada.ignored_spells.damage -- Edit Skada\Core\Tables.lua
+ local passive_spells = Skada.ignored_spells.time -- Edit Skada\Core\Tables.lua
+ local ignored_creatures = Skada.ignored_creatures -- Edit Skada\Core\Tables.lua
+
+ local function format_valuetext(d, total, dps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sDPS" or "DPS"] and dps and Skada:FormatNumber(dps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function add_actor_time(set, actor, spellid, target)
+ if not spellid or passive_spells[spellid] then
+ return -- missing spellid or passive spell?
+ elseif not Skada.validclass[actor.class] or actor.role == "HEALER" then
+ return -- missing/invalid actor class or actor is a healer?
+ else
+ Skada:AddActiveTime(set, actor, target)
+ end
+ end
+
+ local dmg = {}
+ local function log_damage(set)
+ if not dmg.amount then return end
+
+ local absorbed = dmg.absorbed or 0
+ if (dmg.amount + absorbed) == 0 then return end
+
+ local e = Skada:GetActor(set, dmg.actorname, dmg.actorid, dmg.actorflags)
+ if not e then
+ return
+ elseif (set.type == "arena" or set.type == "pvp") and dmg.amount > 0 then
+ add_actor_time(set, e, dmg.spell, dmg.dstName)
+ end
+
+ e.damage = (e.damage or 0) + dmg.amount
+ set.edamage = (set.edamage or 0) + dmg.amount
+
+ if e.totaldamage then
+ e.totaldamage = e.totaldamage + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ e.totaldamage = e.damage + absorbed
+ end
+
+ if set.etotaldamage then
+ set.etotaldamage = set.etotaldamage + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ set.etotaldamage = set.edamage + absorbed
+ end
+
+ local overkill = dmg.overkill or 0
+ if overkill > 0 then
+ set.eoverkill = (set.eoverkill or 0) + dmg.overkill
+ e.overkill = (e.overkill or 0) + dmg.overkill
+ end
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set.name == L["Total"] and not P.totalidc then return end
+
+ -- damage spell.
+ local spell = e.damagespells and e.damagespells[dmg.spellid]
+ if not spell then
+ e.damagespells = e.damagespells or {}
+ e.damagespells[dmg.spellid] = {amount = dmg.amount}
+ spell = e.damagespells[dmg.spellid]
+ else
+ spell.amount = spell.amount + dmg.amount
+ end
+
+ if spell.total then
+ spell.total = spell.total + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ spell.total = spell.amount + absorbed
+ end
+
+ if overkill > 0 then
+ spell.o_amt = (spell.o_amt or 0) + dmg.overkill
+ end
+
+ -- damage target.
+ if not dmg.dstName then return end
+
+ local target = spell.targets and spell.targets[dmg.dstName]
+ if not target then
+ spell.targets = spell.targets or {}
+ spell.targets[dmg.dstName] = {amount = dmg.amount}
+ target = spell.targets[dmg.dstName]
+ else
+ target.amount = target.amount + dmg.amount
+ end
+
+ if target.total then
+ target.total = target.total + dmg.amount + absorbed
+ elseif absorbed > 0 then
+ target.total = target.amount + absorbed
+ end
+
+ if overkill > 0 then
+ target.o_amt = (target.o_amt or 0) + dmg.overkill
+ end
+ end
+
+ local function spell_damage(t)
+ if
+ t.srcName and t.dstName and
+ not ignored_creatures[GetCreatureId(t.srcGUID)] and
+ t.spellid and not ignored_spells[t.spellid] and
+ (not t.misstype or t.misstype == "ABSORB")
+ then
+ dmg.actorid = t.srcGUID
+ dmg.actorname = t.srcName
+ dmg.actorflags = t.srcFlags
+
+ dmg.spell = t.spellid
+ dmg.spellid = t.spellstring
+ dmg.amount = t.amount
+ dmg.overkill = t.overkill
+ dmg.absorbed = t.absorbed
+
+ dmg.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+ Skada:DispatchSets(log_damage)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.targetclass, win.targetname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.targetclass, win.targetname), classfmt(win.actorclass, win.actorname))
+ if not (win.targetname and win.actorname) then return end
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ if not (actor and actor.GetDamageTargetSpells) then return end
+ local spells, total = actor:GetDamageTargetSpells(win.actorname)
+
+ if not spells or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_spell_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.targetclass, win.targetname), label)
+ end
+
+ function mode_spell_target:Update(win, set)
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.targetclass, win.targetname), win.spellname)
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ if not win.spellid then return end
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ if not (actor and actor.GetDamageSpellTargets) then return end
+
+ local targets, total = actor:GetDamageSpellTargets(set, win.spellid)
+ if not targets or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ if not win.class or win.class == target.class then
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.targetclass, win.targetname))
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ local targets, total, actor = set:GetActorDamageTargets(win.targetname, win.targetid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ if not win.class or win.class == target.class then
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = P.absdamage and target.total or target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.targetclass, win.targetname))
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ local total = actor and actor:GetDamage()
+ local spells = (total and total > 0) and actor.damagespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Enemy Damage Done"]
+
+ local total = set and set:GetEnemyDamage()
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors -- enemies
+
+ for actorname, actor in pairs(actors) do
+ if actor.enemy and not actor.fake then
+ local dps, amount = actor:GetDPS(set, false, false, not mode_cols.DPS)
+ if amount and amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, total, dps, win.metadata)
+ end
+ end
+ end
+ end
+
+ function mode_target:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.targetname, win.targetid)
+ if not actor then return end
+
+ local dps, amount = actor:GetDPS(set, false, false, not mode_cols.sDPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.sDPS and Skada:FormatNumber(dps)
+ )
+ return amount, valuetext
+ end
+ mode_spell.GetSetSummary = mode_target.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local dps, amount = set:GetEnemyDPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(amount),
+ mode_cols.DPS and Skada:FormatNumber(dps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_spell_target.metadata = {showspots = true, filterclass = true}
+ mode_target.metadata = {showspots = true, filterclass = true, click1 = mode_target_spell}
+ mode_spell.metadata = {click1 = mode_spell_target, valueorder = true}
+ self.metadata = {
+ click1 = mode_target,
+ click2 = mode_spell,
+ columns = {Damage = true, DPS = false, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_shadow_shadowbolt]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_target.nototal = true
+ mode_spell.nototal = true
+
+ Skada:RegisterForCL(
+ spell_damage,
+ {src_is_not_interesting = true, dst_is_interesting = true},
+ -- damage events
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ -- missed events
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self, "Enemies")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(dmg)
+ end
+
+ ---------------------------------------------------------------------------
+
+ function setPrototype:GetEnemyDamage(class)
+ return P.absdamage and self:GetTotal(class, nil, "etotaldamage") or self:GetTotal(class, nil, "edamage")
+ end
+
+ function setPrototype:GetEnemyDPS(class, no_calc)
+ local total = self:GetEnemyDamage(class)
+ if not total or total == 0 or no_calc then
+ return 0, total or 0
+ end
+ return total / self:GetTime(), total
+ end
+
+ function enemyPrototype:GetDamageTargetSpells(name, tbl)
+ local spells = name and self.damagespells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+
+ local total = 0
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[name] and (P.absdamage and spell.targets[name].total or spell.targets[name].amount)
+ if amount then
+ local t = tbl[spellid]
+ if not tbl[spellid] then
+ t = new()
+ t.amount = amount
+ tbl[spellid] = t
+ else
+ t.amount = t.amount + amount
+ end
+
+ total = total + amount
+ end
+ end
+ return tbl, total
+ end
+
+ function enemyPrototype:GetDamageSpellTargets(set, spellid, tbl)
+ local spell = set and spellid and self.damagespells and self.damagespells[spellid]
+ if not spell or not spell.targets then return end
+
+ tbl = clear(tbl or C)
+
+ local total = P.absdamage and spell.total or spell.amount or 0
+ for name, target in pairs(spell.targets) do
+ local amount = P.absdamage and target.total or target.amount
+ local t = tbl[name]
+ if not t then
+ t = new()
+ t.amount = amount
+ tbl[name] = t
+ else
+ t.amount = t.amount + amount
+ end
+ set:_fill_actor_table(t, name)
+ end
+ return tbl, total
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Enemy Healing Done
+
+Skada:RegisterModule("Enemy Healing Done", function(L, P)
+ local mode = Skada:NewModule("Enemy Healing Done")
+ local mode_target = mode:NewModule("Target List")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_cols = nil
+
+ local classfmt = Skada.classcolors.format
+ local ignored_spells = Skada.ignored_spells.heal -- Edit Skada\Core\Tables.lua
+ local passive_spells = Skada.ignored_spells.time -- Edit Skada\Core\Tables.lua
+
+ local function format_valuetext(d, total, dps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sHPS" or "HPS"] and dps and Skada:FormatNumber(dps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function add_actor_time(set, actor, spellid, target)
+ if passive_spells[spellid] then
+ return -- missing spellid or passive spell?
+ elseif not actor.class or not Skada.validclass[actor.class] or actor.role ~= "HEALER" then
+ return -- missing/invalid actor class or actor is not a healer?
+ else
+ Skada:AddActiveTime(set, actor, target)
+ end
+ end
+
+ local heal = {}
+ local function log_heal(set)
+ if not heal.amount then return end
+
+ local actor = Skada:GetActor(set, heal.actorname, heal.actorid, heal.actorflags)
+ if not actor then return end
+
+ -- get rid of overheal
+ if (set.type == "arena" or set.type == "pvp") and heal.amount > 0 then
+ add_actor_time(set, actor, heal.spell, heal.dstName)
+ end
+
+ actor.heal = (actor.heal or 0) + heal.amount
+ set.eheal = (set.eheal or 0) + heal.amount
+
+ local overheal = (heal.overheal > 0) and heal.overheal or nil
+ if overheal then
+ actor.overheal = (actor.overheal or 0) + overheal
+ set.eoverheal = (set.eoverheal or 0) + overheal
+ end
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set.name == L["Total"] and not P.totalidc then return end
+
+ local spell = actor.healspells and actor.healspells[heal.spellid]
+ if not spell then
+ actor.healspells = actor.healspells or {}
+ actor.healspells[heal.spellid] = {amount = heal.amount, count = 1}
+ spell = actor.healspells[heal.spellid]
+ else
+ spell.amount = spell.amount + heal.amount
+ spell.count = spell.count + 1
+ end
+
+ if overheal then
+ spell.o_amt = (spell.o_amt or 0) + overheal
+ end
+
+ if not heal.dstName then return end
+
+ local target = spell.targets and spell.targets[heal.dstName]
+ if not target then
+ spell.targets = spell.targets or {}
+ spell.targets[heal.dstName] = {amount = heal.amount}
+ target = spell.targets[heal.dstName]
+ else
+ target.amount = target.amount + heal.amount
+ end
+
+ if overheal then
+ target.o_amt = (target.o_amt or 0) + overheal
+ end
+ end
+
+ local function spell_heal(t)
+ if t.spellid and not ignored_spells[t.spellid] then
+ heal.actorid = t.srcGUID
+ heal.actorname = t.srcName
+ heal.actorflags = t.srcFlags
+ heal.dstName = t.dstName
+
+ heal.spell = t.spellid
+ heal.spellid = t.spellstring
+ heal.overheal = t.overheal or 0
+ heal.amount = max(0, t.amount - heal.overheal)
+
+ Skada:DispatchSets(log_heal)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.targetclass, win.targetname))
+
+ local targets, total, actor = set:GetActorHealTargets(win.targetname, win.targetid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.targetclass, win.targetname))
+
+ local actor = set and set:GetActor(win.targetname, win.targetid)
+ local total = actor and actor.heal
+ local spells = (total and total > 0) and actor.healspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", win.title, L[win.class]) or L["Enemy Healing Done"]
+
+ local total = set and set:GetHeal(win.class, true)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors -- enemies
+
+ for actorname, actor in pairs(actors) do
+ if actor.enemy and not actor.fake then
+ local hps, amount = actor:GetHPS(set, nil, not mode_cols.HPS)
+ if amount and amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, total, hps, win.metadata)
+ end
+ end
+ end
+ end
+
+ function mode_target:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.targetname, win.targetid)
+ if not actor then return end
+
+ local hps, amount = actor:GetHPS(set, false, not mode_cols.sHPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.sHPS and Skada:FormatNumber(hps)
+ )
+ return amount, valuetext
+ end
+ mode_spell.GetSetSummary = mode_target.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local hps, amount = set:GetHPS(win and win.class, true)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.HPS and Skada:FormatNumber(hps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {valueorder = true}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Healing = true, HPS = true, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_blessedlife]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ spell_heal,
+ {src_is_not_interesting = true, dst_is_not_interesting = true},
+ "SPELL_HEAL",
+ "SPELL_PERIODIC_HEAL"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self, "Enemies")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(heal)
+ end
+end)
diff --git a/Skada/Modules/FriendlyFire.lua b/Skada/Modules/FriendlyFire.lua
new file mode 100644
index 0000000..719a4fc
--- /dev/null
+++ b/Skada/Modules/FriendlyFire.lua
@@ -0,0 +1,318 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Friendly Fire", function(L, P, _, C)
+ local mode = Skada:NewModule("Friendly Fire")
+ local mode_target = mode:NewModule("Target List")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_target = mode_spell:NewModule("Target List")
+ local get_actor_friendfire_targets = nil
+ local get_spell_friendfire_targets = nil
+ local mode_cols = nil
+
+ local pairs, wipe, format, uformat = pairs, wipe, string.format, Private.uformat
+ local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+ local classfmt = Skada.classcolors.format
+ local ignored_spells = Skada.ignored_spells.damage -- Edit Skada\Core\Tables.lua
+ local passive_spells = Skada.ignored_spells.time -- Edit Skada\Core\Tables.lua
+
+ local function format_valuetext(d, total, dps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sDPS" or "DPS"] and dps and Skada:FormatNumber(dps),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local dmg = {}
+ local function log_damage(set)
+ if not dmg.amount or dmg.amount == 0 then return end
+
+ local actor = Skada:GetActor(set, dmg.actorname, dmg.actorid, dmg.actorflags)
+ if not actor then
+ return
+ elseif not passive_spells[dmg.spell] then
+ Skada:AddActiveTime(set, actor, dmg.dstName)
+ end
+
+ actor.friendfire = (actor.friendfire or 0) + dmg.amount
+ set.friendfire = (set.friendfire or 0) + dmg.amount
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- spell
+ local spell = actor.friendfirespells and actor.friendfirespells[dmg.spellid]
+ if not spell then
+ actor.friendfirespells = actor.friendfirespells or {}
+ actor.friendfirespells[dmg.spellid] = {amount = 0}
+ spell = actor.friendfirespells[dmg.spellid]
+ end
+ spell.amount = spell.amount + dmg.amount
+
+ -- target
+ if dmg.dstName then
+ spell.targets = spell.targets or {}
+ spell.targets[dmg.dstName] = (spell.targets[dmg.dstName] or 0) + dmg.amount
+ end
+ end
+
+ local function spell_damage(t)
+ if t.srcGUID ~= t.dstGUID and t.spellid and not ignored_spells[t.spellid] and (not t.misstype or t.misstype == "ABSORB") then
+ dmg.actorid = t.srcGUID
+ dmg.actorname = t.srcName
+ dmg.actorflags = t.srcFlags
+ dmg.dstName = t.dstName
+
+ dmg.spell = t.spellid
+ dmg.spellid = t.spellstring
+
+ dmg.amount = t.amount
+ if t.absorbed and t.absorbed > 0 then
+ dmg.amount = dmg.amount + t.absorbed
+ end
+
+ Skada:DispatchSets(log_damage)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ local targets, total, actor = get_actor_friendfire_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.friendfire
+ local spells = (total and total > 0) and actor.friendfirespells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = spell.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_spell_target:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_target:Update(win, set)
+ win.title = uformat(L["%s's <%s> targets"], classfmt(win.actorclass, win.actorname), win.spellname)
+ if not win.spellid then return end
+
+ local targets, total, actor = get_spell_friendfire_targets(set, win.actorname, win.actorid, win.spellid)
+ if not targets or not actor then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sDPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Friendly Fire"], L[win.class]) or L["Friendly Fire"]
+
+ local total = set and set:GetTotal(win.class, nil, "friendfire")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.friendfire then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.friendfire
+ format_valuetext(d, total, mode_cols.DPS and (d.value / actor:GetTime(set)), win.metadata)
+ end
+ end
+ end
+
+ function mode_target:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ local value = actor and actor.friendfire
+ if not value or value == 0 then return end
+
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(value),
+ mode_cols.sDPS and Skada:FormatNumber(value / actor:GetTime())
+ )
+ return value, valuetext
+ end
+ mode_spell.GetSetSummary = mode_target.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ local value = set:GetTotal(win and win.class, nil, "friendfire") or 0
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Damage and Skada:FormatNumber(value),
+ mode_cols.DPS and Skada:FormatNumber(value / set:GetTime())
+ )
+ return value, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {click1 = mode_spell_target}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Damage = true, DPS = false, Percent = true, sDPS = false, sPercent = true},
+ icon = [[Interface\ICONS\inv_gizmo_supersappercharge]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ local flags_src_dst = {src_is_interesting_nopets = true, dst_is_interesting_nopets = true}
+
+ Skada:RegisterForCL(
+ spell_damage,
+ flags_src_dst,
+ -- damage events
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE",
+ -- missed events
+ "DAMAGE_SHIELD_MISSED",
+ "RANGE_MISSED",
+ "SPELL_BUILDING_MISSED",
+ "SPELL_MISSED",
+ "SPELL_PERIODIC_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(dmg)
+ end
+
+ function mode:SetComplete(set)
+ if not set.friendfire or set.friendfire == 0 then return end
+ for _, actor in pairs(set.actors) do
+ local amount = not actor.enemy and actor.friendfire
+ if (not amount and actor.friendfirespells) or amount == 0 then
+ actor.friendfire = nil
+ actor.friendfirespells = del(actor.friendfirespells, true)
+ end
+ end
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actor_friendfire_targets = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local total = actor and actor.friendfire
+ local spells = total and actor.friendfirespells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for targetname, amount in pairs(spell.targets) do
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.amount = amount
+ tbl[targetname] = t
+ else
+ t.amount = t.amount + amount
+ end
+ self:_fill_actor_table(t, targetname)
+ end
+ end
+ end
+ return tbl, total, actor
+ end
+
+ get_spell_friendfire_targets = function(self, name, id, spellid, tbl)
+ local actor = spellid and self:GetActor(name, id)
+ local spell = actor and actor.friendfirespells and actor.friendfirespells[spellid]
+ if not spell or not spell.targets then return end
+
+ tbl = clear(tbl or C)
+ for targetname, amount in pairs(spell.targets) do
+ local t = new()
+ t.amount = amount
+ self:_fill_actor_table(t, targetname)
+ tbl[targetname] = t
+ end
+ return tbl, spell.amount, actor
+ end
+end)
diff --git a/Skada/Modules/Healing.lua b/Skada/Modules/Healing.lua
new file mode 100644
index 0000000..33dcb05
--- /dev/null
+++ b/Skada/Modules/Healing.lua
@@ -0,0 +1,1275 @@
+local _, Skada = ...
+local Private = Skada.Private
+
+-- cache frequently used globals
+local pairs, max = pairs, math.max
+local format, uformat = string.format, Private.uformat
+local tooltip_school = Skada.tooltip_school
+local hits_perc = "%s (\124cffffffff%s\124r)"
+
+local function format_valuetext(d, columns, total, hps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ columns.Healing and Skada:FormatNumber(d.value),
+ columns[subview and "sHPS" or "HPS"] and hps and Skada:FormatNumber(hps),
+ columns[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+end
+
+---------------------------------------------------------------------------
+-- Healing Module
+
+Skada:RegisterModule("Healing", function(L, P)
+ local mode = Skada:NewModule("Healing")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local ignored_spells = Skada.ignored_spells.heal -- Edit Skada\Core\Tables.lua
+ local passive_spells = Skada.ignored_spells.time -- Edit Skada\Core\Tables.lua
+ tooltip_school = tooltip_school or Skada.tooltip_school
+ local wipe, del = wipe, Private.delTable
+ local PercentToRGB = Private.PercentToRGB
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local heal = {}
+ local function log_heal(set)
+ if not heal.amount then return end
+
+ local actor = Skada:GetActor(set, heal.actorname, heal.actorid, heal.actorflags)
+ if not actor then return end
+
+ -- get rid of overheal
+ local amount = max(0, heal.amount - heal.overheal)
+ if actor.role == "HEALER" and amount > 0 and not heal.petname and not passive_spells[heal.spell] then
+ Skada:AddActiveTime(set, actor, heal.dstName)
+ end
+
+ -- record the healing
+ actor.heal = (actor.heal or 0) + amount
+ set.heal = (set.heal or 0) + amount
+
+ -- record the overheal
+ local overheal = (heal.overheal > 0) and heal.overheal or nil
+ if overheal then
+ actor.overheal = (actor.overheal or 0) + overheal
+ set.overheal = (set.overheal or 0) + overheal
+ end
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ -- record the spell
+ local spell = actor.healspells and actor.healspells[heal.spellid]
+ if not spell then
+ actor.healspells = actor.healspells or {}
+ actor.healspells[heal.spellid] = {amount = 0}
+ spell = actor.healspells[heal.spellid]
+ end
+
+ spell.count = (spell.count or 0) + 1
+ spell.amount = spell.amount + amount
+
+ if overheal then
+ spell.o_amt = (spell.o_amt or 0) + overheal
+ end
+
+ if heal.critical then
+ spell.c_num = (spell.c_num or 0) + 1
+ spell.c_amt = (spell.c_amt or 0) + amount
+ if not spell.c_max or amount > spell.c_max then
+ spell.c_max = amount
+ end
+ if not spell.c_min or amount < spell.c_min then
+ spell.c_min = amount
+ end
+ else
+ spell.n_num = (spell.n_num or 0) + 1
+ spell.n_amt = (spell.n_amt or 0) + amount
+ if not spell.n_max or amount > spell.n_max and amount > 0 then
+ spell.n_max = amount
+ end
+ if not spell.n_min or amount < spell.n_min and amount > 0 then
+ spell.n_min = amount
+ end
+ end
+
+ -- record the target
+ if not heal.dstName then return end
+ local target = spell.targets and spell.targets[heal.dstName]
+ if not target then
+ spell.targets = spell.targets or {}
+ spell.targets[heal.dstName] = {amount = 0}
+ target = spell.targets[heal.dstName]
+ end
+ target.amount = target.amount + amount
+
+ if overheal then
+ target.o_amt = (target.o_amt or 0) + overheal
+ end
+ end
+
+ local function spell_heal(t)
+ if not t.spellid or ignored_spells[t.spellid] then return end
+
+ heal.actorid = t.srcGUID
+ heal.actorname = t.srcName
+ heal.actorflags = t.srcFlags
+ heal.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+
+ heal.spell = t.spellid
+ heal.spellid = t.spellstring
+ heal.amount = t.amount
+ heal.overheal = t.overheal
+ heal.critical = t.critical
+
+ Skada:FixPets(heal)
+ Skada:DispatchSets(log_heal)
+ end
+
+ local function healing_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(label, id)
+ if not actor then return end
+
+ local totaltime = set:GetTime()
+ local activetime = actor:GetTime(set, true)
+ local hps, amount = actor:GetHPS(set)
+
+ local activepercent = activetime / totaltime * 100
+ tooltip:AddDoubleLine(format(L["%s's activity"], classfmt(actor.class, label)), Skada:FormatPercent(activepercent), nil, nil, nil, PercentToRGB(activepercent))
+ tooltip:AddDoubleLine(L["Segment Time"], Skada:FormatTime(totaltime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Active Time"], Skada:FormatTime(activetime), 1, 1, 1)
+ tooltip:AddDoubleLine(L["Healing"], Skada:FormatNumber(amount), 1, 1, 1)
+
+ local suffix = Skada:FormatTime(P.timemesure == 1 and activetime or totaltime)
+ tooltip:AddDoubleLine(format("%s/%s", Skada:FormatNumber(amount), suffix), Skada:FormatNumber(hps), 1, 1, 1)
+ end
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ if not set then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.healspells and actor.healspells[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ if not spell.count or spell.count == 0 then return end
+
+ -- hits and average
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.amount / spell.count), 1, 1, 1)
+ if spell.o_amt and spell.o_amt > 0 then
+ tooltip:AddDoubleLine(L["Overheal"], format(hits_perc, Skada:FormatNumber(spell.o_amt), Skada:FormatPercent(spell.o_amt, spell.amount + spell.o_amt)), 1, 0.67, 0.67)
+ end
+
+ -- normal hits
+ if spell.n_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Normal Hits"], format(hits_perc, Skada:FormatNumber(spell.n_num), Skada:FormatPercent(spell.n_num, spell.count)))
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ end
+
+ -- critical hits
+ if spell.c_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Critical Hits"], format(hits_perc, Skada:FormatNumber(spell.c_num), Skada:FormatPercent(spell.c_num, spell.count)))
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetHealOnTarget(win.targetname)
+ local spells = (total and total > 0) and actor.healspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ local tar = spell.targets and spell.targets[win.targetname]
+ local amount = tar and (actor.enemy and tar or tar.amount)
+ if amount then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.heal
+ local spells = (total and total > 0) and actor.healspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = spell.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, total, actor = set:GetActorHealTargets(win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Healing"], L[win.class]) or L["Healing"]
+
+ local total = set and set:GetHeal(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.heal then
+ local hps, amount = actor:GetHPS(set, nil, not mode_cols.HPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, hps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local hps, amount = actor:GetHPS(set, false, not mode_cols.sHPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.sHPS and Skada:FormatNumber(hps)
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local hps, amount = set:GetHPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.HPS and Skada:FormatNumber(hps)
+ )
+ return amount, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_spell.metadata = {tooltip = mode_spell_tooltip}
+ mode_target.metadata = {showspots = true, click1 = mode_target_spell}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ tooltip = healing_tooltip,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Healing = true, HPS = true, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_nature_healingtouch]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ local flags_src = {src_is_interesting = true}
+ Skada:RegisterForCL(
+ spell_heal,
+ flags_src,
+ "SPELL_HEAL",
+ "SPELL_PERIODIC_HEAL"
+ )
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(heal)
+ end
+
+ function mode:SetComplete(set)
+ local total = (set.heal or 0) + (set.overheal or 0)
+ if total == 0 then return end
+
+ -- clean healspells table!
+ for _, actor in pairs(set.actors) do
+ local amount = (actor.heal or 0) + (actor.overheal or 0)
+ if (not amount and actor.healspells) or amount == 0 then
+ actor.heal, actor.overheal = nil, nil
+ actor.healspells = del(actor.healspells, true)
+ end
+ end
+ end
+end)
+
+---------------------------------------------------------------------------
+-- Overhealing Module
+
+Skada:RegisterModule("Overhealing", function(L)
+ local mode = Skada:NewModule("Overhealing")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function fmt_valuetext(d, columns, total, dps, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ columns.Overhealing and Skada:FormatNumber(d.value),
+ columns[subview and "sHPS" or "HPS"] and Skada:FormatNumber(dps),
+ columns[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetOverhealOnTarget(win.targetname)
+
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+ local spells = actor.healspells
+
+ for spellid, spell in pairs(spells) do
+ local tar = spell.targets and spell.targets[win.targetname]
+ if tar and tar.o_amt and tar.o_amt > 0 then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = tar.o_amt
+ fmt_valuetext(d, mode.metadata.columns, tar.amount + d.value, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetOverheal()
+ local spells = (total and total > 0) and actor.healspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ if spell.o_amt and spell.o_amt > 0 then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = spell.o_amt
+ fmt_valuetext(d, mode_cols, spell.amount + d.value, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.overheal
+ local targets = (total and total > 0) and actor:GetOverhealTargets(set)
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ fmt_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Overhealing"], L[win.class]) or L["Overhealing"]
+
+ local total = set and set:GetOverheal(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.overheal then
+ local ohps, overheal = actor:GetOHPS(set, nil, not mode_cols.HPS)
+ if overheal > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.overheal
+ fmt_valuetext(d, mode_cols, actor.heal + d.value, ohps, win.metadata)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local ohps, overheal = actor:GetOHPS(set, false, not mode_cols.sHPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Overhealing and Skada:FormatNumber(overheal),
+ mode_cols.sHPS and Skada:FormatNumber(ohps)
+ )
+ return overheal, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local ohps, overheal = set:GetOHPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Overhealing and Skada:FormatNumber(overheal),
+ mode_cols.HPS and Skada:FormatNumber(ohps)
+ )
+ return overheal, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_target.metadata = {click1 = mode_target_spell}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Overhealing = true, HPS = true, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_holybolt]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Healing")
+
+---------------------------------------------------------------------------
+-- Total Healing Module
+
+Skada:RegisterModule("Total Healing", function(L)
+ local mode = Skada:NewModule("Total Healing")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_target_spell = mode_target:NewModule("Spell List")
+ tooltip_school = tooltip_school or Skada.tooltip_school
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function mode_spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local spell = actor and actor.healspells and actor.healspells[id]
+ if not spell then return end
+
+ tooltip:AddLine(uformat("%s - %s", classfmt(win.actorclass, win.actorname), label))
+ tooltip_school(tooltip, id)
+
+ local total = spell.amount + (spell.o_amt or 0)
+ tooltip:AddDoubleLine(L["Total"], Skada:FormatNumber(total), 1, 1, 1)
+ if spell.amount > 0 then
+ tooltip:AddDoubleLine(L["Healing"], format(hits_perc, Skada:FormatNumber(spell.amount), Skada:FormatPercent(spell.amount, total)), 0.67, 1, 0.67)
+ end
+ if spell.o_amt and spell.o_amt > 0 then
+ tooltip:AddDoubleLine(L["Overheal"], format(hits_perc, Skada:FormatNumber(spell.o_amt), Skada:FormatPercent(spell.o_amt, total)), 1, 0.67, 0.67)
+ end
+
+ if not spell.count or spell.count == 0 then return end
+
+ tooltip:AddLine(" ")
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ -- hits and average
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.amount / spell.count), 1, 1, 1)
+
+ -- normal hits
+ if spell.n_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Normal Hits"], format(hits_perc, Skada:FormatNumber(spell.n_num), Skada:FormatPercent(spell.n_num, spell.count)))
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ end
+
+ -- critical hits
+ if spell.c_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Critical Hits"], format(hits_perc, Skada:FormatNumber(spell.c_num), Skada:FormatPercent(spell.c_num, spell.count)))
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ end
+ end
+
+ function mode_target_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(class, label))
+ end
+
+ function mode_target_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.actorclass, win.actorname), classfmt(win.targetclass, win.targetname))
+ if not set or not win.targetname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetTotalHealOnTarget(win.targetname)
+ local spells = (total and total > 0) and actor.healspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ local tar = spell.targets and spell.targets[win.targetname]
+ if tar then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = actor.enemy and tar or (tar.amount + (tar.o_amt or 0))
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = format(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not win.actorname then return end
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetTotalHeal()
+ local spells = (total and total > 0) and actor.healspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ local amount = spell.amount + (spell.o_amt or 0)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = format(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+
+ local actor = set and set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor:GetTotalHeal()
+ local targets = (total and total > 0) and actor:GetTotalHealTargets(set)
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Total Healing"], L[win.class]) or L["Total Healing"]
+
+ local total = set and set:GetTotalHeal(win.class)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and (actor.heal or actor.overheal) then
+ local hps, amount = actor:GetTHPS(set, nil, not mode_cols.HPS)
+ if amount > 0 then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = amount
+ format_valuetext(d, mode_cols, total, hps, win.metadata)
+ win:color(d, set, actor.enemy)
+ end
+ end
+ end
+ end
+
+ function mode_spell:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor then return end
+
+ local ops, amount = actor:GetTHPS(set, false, not mode_cols.sHPS)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.sHPS and Skada:FormatNumber(ops)
+ )
+ return amount, valuetext
+ end
+ mode_target.GetSetSummary = mode_spell.GetSetSummary
+
+ function mode:GetSetSummary(set, win)
+ local ops, amount = set:GetTHPS(win and win.class)
+ local valuetext = Skada:FormatValueCols(
+ mode_cols.Healing and Skada:FormatNumber(amount),
+ mode_cols.HPS and Skada:FormatNumber(ops)
+ )
+ return amount, valuetext
+ end
+
+ function mode:OnEnable()
+ mode_target.metadata = {showspots = true, click1 = mode_target_spell}
+ mode_spell.metadata = {tooltip = mode_spell_tooltip}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ click2 = mode_target,
+ columns = {Healing = true, HPS = true, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_holy_flashheal]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+ mode_target.nototal = true
+
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end, "Healing")
+
+---------------------------------------------------------------------------
+-- Healing Taken Module
+
+Skada:RegisterModule("Healing Taken", function(L, P)
+ local mode = Skada:NewModule("Healing Taken")
+ local mode_source = mode:NewModule("Source List")
+ local mode_source_spell = mode_source:NewModule("Spell List")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_spell_source = mode_source:NewModule("Source List")
+ local new, clear = Private.newTable, Private.clearTable
+ local C, classfmt = Skada.cacheTable2, Skada.classcolors.format
+ local mode_cols = nil
+
+ local get_set_healed_actors = nil
+ local get_actor_heal_sources = nil
+ local get_actor_healed_spells = nil
+ local get_actor_heal_spell_sources = nil
+
+ function mode_source:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's sources"], classfmt(class, label))
+ end
+
+ function mode_source:Update(win, set)
+ win.title = format(L["%s's sources"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local sources, total, actor = get_actor_heal_sources(set, win.actorname, win.actorid)
+ if not actor or not sources or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(C) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["Spells on %s"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = format(L["Spells on %s"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local spells, total, actor = get_actor_healed_spells(set, win.actorname, win.actorid)
+ if not actor or not spells or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell)
+ d.value = spell.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode_source_spell:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = uformat(L["%s's spells on %s"], classfmt(class, label), classfmt(win.actorclass, win.actorname))
+ end
+
+ function mode_source_spell:Update(win, set)
+ win.title = uformat(L["%s's spells on %s"], classfmt(win.targetclass, win.targetname), classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.targetname, win.targetid)
+ if not actor then return end
+
+ local total = actor and actor:GetAbsorbHealOnTarget(win.actorname)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ local spells = actor.absorbspells -- absorb spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ local amt = spell.targets and spell.targets[win.actorname]
+ if amt then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, spell)
+ d.value = amt
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+
+ if actor.healspells then
+ for spellid, spell in pairs(actor.healspells) do
+ local tar = spell.targets and spell.targets[win.actorname]
+ if tar then
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = actor.enemy and tar or tar.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+ end
+ end
+
+ function mode_spell_source:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = uformat(L["%s's <%s> sources"], classfmt(win.actorclass, win.actorname), label)
+ end
+
+ function mode_spell_source:Update(win, set)
+ win.title = uformat(L["%s's <%s> sources"], classfmt(win.actorclass, win.actorname), win.spellname)
+ if not set or not win.actorname or not win.spellid then return end
+
+ local sources, total, actor = get_actor_heal_spell_sources(set, win.actorname, win.actorid, win.spellid)
+ if not actor or not sources or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actortime = mode_cols.sHPS and actor:GetTime(set)
+
+ for sourcename, source in pairs(sources) do
+ nr = nr + 1
+
+ local d = win:actor(nr, source, source.enemy, sourcename)
+ d.value = source.amount
+ format_valuetext(d, mode_cols, total, actortime and (d.value / actortime), win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Healing Taken"], L[win.class]) or L["Healing Taken"]
+
+ local total = set and set:GetAbsorbHeal()
+ local actors = (total and total > 0) and get_set_healed_actors(set)
+
+ if not actors then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local settime = set:GetTime()
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set) then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.amount
+ format_valuetext(d, mode_cols, total, d.value / (actor.time or settime), win.metadata)
+ end
+ end
+ end
+
+ function mode:OnEnable()
+ mode_spell_source.metadata = {showspots = true}
+ mode_source.metadata = {showspots = true, click1 = mode_source_spell}
+ mode_spell.metadata = {click1 = mode_spell_source}
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_source,
+ click2 = mode_spell,
+ columns = {Healing = true, HPS = true, Percent = true, sHPS = false, sPercent = true},
+ icon = [[Interface\ICONS\spell_nature_resistnature]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:AddMode(self, "Absorbs and Healing")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_set_healed_actors = function(self, tbl)
+ local total = (self.heal or 0) + (self.absorb or 0)
+ if self.arena then
+ total = total + (self.eheal or 0) + (self.eabsorb or 0)
+ end
+ if total == 0 then return end
+
+ tbl = clear(tbl or C)
+
+ local actors = self.actors
+ for _, actor in pairs(actors) do
+ local spells = (not actor.enemy or self.arena) and actor.absorbspells -- absorb spells
+ if spells then
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, amount in pairs(spell.targets) do
+ if amount > 0 then
+ local t = tbl[name]
+ if not t then
+ t = new()
+ t.amount = amount
+ tbl[name] = t
+ else
+ t.amount = t.amount + amount
+ end
+
+ self:_fill_actor_table(t, name, true)
+ end
+ end
+ end
+ end
+ end
+
+ spells = (not actor.enemy or self.arena) and actor.healspells -- heal spells
+ if spells then
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for name, target in pairs(spell.targets) do
+ if target.amount > 0 then
+ local t = tbl[name]
+ if not t then
+ t = new()
+ t.amount = target.amount
+ tbl[name] = t
+ else
+ t.amount = t.amount + target.amount
+ end
+
+ self:_fill_actor_table(t, name, true)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ return tbl, total
+ end
+
+ get_actor_heal_sources = function(self, name, id, tbl)
+ local sources = self.actors
+ local actor = sources and self:GetActor(name, id)
+ if not actor then return end
+
+ tbl = clear(tbl or C)
+ local total = 0
+
+ for sourcename, source in pairs(sources) do
+ local spells = (not source.enemy or self.arena) and source.absorbspells -- absorb spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[name]
+ if amount and amount > 0 then
+ total = total + amount
+
+ local t = tbl[sourcename]
+ if not t then
+ t = new()
+ t.id = source.id
+ t.class = source.class
+ t.role = source.role
+ t.spec = source.spec
+ t.enemy = source.enemy
+ t.amount = amount
+ tbl[sourcename] = t
+ else
+ t.amount = t.amount + amount
+ end
+ end
+ end
+ end
+
+ spells = (not source.enemy or self.arena) and source.healspells -- heal spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[name] and spell.targets[name].amount
+ if amount and amount > 0 then
+ total = total + amount
+
+ local t = tbl[sourcename]
+ if not t then
+ t = new()
+ t.id = source.id
+ t.class = source.class
+ t.role = source.role
+ t.spec = source.spec
+ t.enemy = source.enemy
+ t.amount = amount
+ tbl[sourcename] = t
+ else
+ t.amount = t.amount + amount
+ end
+ end
+ end
+ end
+ end
+
+ return tbl, total, actor
+ end
+
+ get_actor_healed_spells = function(self, name, id, tbl)
+ local sources = self.actors
+ local actor = sources and self:GetActor(name, id)
+ if not actor then return end
+
+ tbl = clear(tbl or C)
+ local total = 0
+
+ for _, source in pairs(sources) do
+ local spells = (not actor.enemy or self.arena) and source.absorbspells -- absorb spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[name]
+ if amount and amount > 0 then
+ total = total + amount
+
+ local t = tbl[spellid]
+ if not t then
+ t = new()
+ t.amount = amount
+ tbl[spellid] = t
+ else
+ t.amount = t.amount + amount
+ end
+ end
+ end
+ end
+
+ spells = (not source.enemy or self.arena) and source.healspells -- heal spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ local amount = spell.targets and spell.targets[name] and spell.targets[name].amount
+ if amount and amount > 0 then
+ total = total + amount
+
+ local t = tbl[spellid]
+ if not t then
+ t = new()
+ t.amount = amount
+ tbl[spellid] = t
+ else
+ t.amount = t.amount + amount
+ end
+ end
+ end
+ end
+ end
+
+ return tbl, total, actor
+ end
+
+ get_actor_heal_spell_sources = function(self, name, id, spellid)
+ local sources = spellid and self.actors
+ local actor = sources and self:GetActor(name, id)
+ if not actor then return end
+
+ tbl = clear(tbl or C)
+ local total = 0
+
+ for sourcename, source in pairs(sources) do
+ local spells = (not source.enemy or self.arena) and source.absorbspells -- absorb spells
+ if spells then
+ for sid, spell in pairs(spells) do
+ local amount = (sid == spellid) and spell.targets and spell.targets[name]
+ if amount and amount > 0 then
+ total = total + amount
+
+ local t = tbl[sourcename]
+ if not t then
+ t = new()
+ t.id = source.id
+ t.class = source.class
+ t.role = source.role
+ t.spec = source.spec
+ t.enemy = source.enemy
+ t.amount = amount
+ tbl[sourcename] = t
+ else
+ t.amount = t.amount + amount
+ end
+ end
+ end
+ end
+
+ spells = (not source.enemy or self.arena) and source.healspells -- heal spells
+ if spells then
+ for sid, spell in pairs(spells) do
+ local amount = (sid == spellid) and spell.targets and spell.targets[name] and spell.targets[name].amount
+ if amount and amount > 0 then
+ total = total + amount
+
+ local t = tbl[sourcename]
+ if not t then
+ t = new()
+ t.id = source.id
+ t.class = source.class
+ t.role = source.role
+ t.spec = source.spec
+ t.enemy = source.enemy
+ t.amount = amount
+ tbl[sourcename] = t
+ else
+ t.amount = t.amount + amount
+ end
+ end
+ end
+ end
+ end
+
+ return tbl, total, actor
+ end
+end, "Absorbs", "Healing")
diff --git a/Skada/Modules/Healthstone.lua b/Skada/Modules/Healthstone.lua
new file mode 100644
index 0000000..ec53065
--- /dev/null
+++ b/Skada/Modules/Healthstone.lua
@@ -0,0 +1,83 @@
+local _, Skada = ...
+Skada:RegisterModule("Healthstones", function(L)
+ local mode = Skada:NewModule("Healthstones")
+ local stonespell = 6262
+ local stonename = GetSpellInfo(stonespell)
+
+ local format = string.format
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, metadata)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols.Percent and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function log_healthstone(set, actorname, actorid, actorflags)
+ local actor = Skada:GetActor(set, actorname, actorid, actorflags)
+ if actor then
+ actor.healthstone = (actor.healthstone or 0) + 1
+ set.healthstone = (set.healthstone or 0) + 1
+ end
+ end
+
+ local function stone_used(t)
+ if (t.spellid and t.spellid == stonespell) or (t.spellname and t.spellname == stonename) then
+ Skada:DispatchSets(log_healthstone, t.srcName, t.srcGUID, t.srcFlags)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Healthstones"], L[win.class]) or L["Healthstones"]
+
+ local total = set and set:GetTotal(win.class, nil, "healthstone")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.healthstone then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.healthstone
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ return set:GetTotal(win and win.class, nil, "healthstone") or 0
+ end
+
+ function mode:OnEnable()
+ stonename = stonename or GetSpellInfo(47874)
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ columns = {Count = true, Percent = false},
+ icon = [[Interface\ICONS\inv_stone_04]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:RegisterForCL(stone_used, {src_is_interesting_nopets = true}, "SPELL_CAST_SUCCESS")
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end)
diff --git a/Skada/Modules/Interrupts.lua b/Skada/Modules/Interrupts.lua
new file mode 100644
index 0000000..38da465
--- /dev/null
+++ b/Skada/Modules/Interrupts.lua
@@ -0,0 +1,319 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Interrupts", function(L, P, _, C, M, O)
+ local mode = Skada:NewModule("Interrupts")
+ local mode_extraspell = mode:NewModule("Spell List")
+ local mode_target = mode:NewModule("Target List")
+ local mode_spell = mode:NewModule("Interrupt Spells")
+ local ignored_spells = Skada.ignored_spells.interrupt -- Edit Skada\Core\Tables.lua
+ local get_actor_interrupted_spells = nil
+ local get_actor_interrupt_targets = nil
+
+ -- cache frequently used globals
+ local pairs, format, uformat = pairs, string.format, Private.uformat
+ local new, clear = Private.newTable, Private.clearTable
+ local SpellLink = Private.SpellLink or GetSpellLink
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local data = {}
+ local function log_interrupt(set)
+ local actor = Skada:GetActor(set, data.actorname, data.actorid, data.actorflags)
+ if not actor then return end
+
+ -- increment actor's and set's interrupts count
+ actor.interrupt = (actor.interrupt or 0) + 1
+ set.interrupt = (set.interrupt or 0) + 1
+
+ -- to save up memory, we only record the rest to the current set.
+ if (set == Skada.total and not P.totalidc) or not data.spellid then return end
+
+ local spell = actor.interruptspells and actor.interruptspells[data.spellid]
+ if not spell then
+ actor.interruptspells = actor.interruptspells or {}
+ actor.interruptspells[data.spellid] = {count = 1}
+ spell = actor.interruptspells[data.spellid]
+ else
+ spell.count = spell.count + 1
+ end
+
+ -- record interrupted spell
+ if data.extraspellid then
+ spell.spells = spell.spells or {}
+ spell.spells[data.extraspellid] = (spell.spells[data.extraspellid] or 0) + 1
+ end
+
+ -- record the target
+ if data.dstName then
+ spell.targets = spell.targets or {}
+ spell.targets[data.dstName] = (spell.targets[data.dstName] or 0) + 1
+ end
+ end
+
+ local function spell_interrupt(t)
+ local spellid = t.spellid or 6603
+ local spellname = t.spellname or L["Melee"]
+
+ -- invalid/ignored spell?
+ if ignored_spells[spellid] or (t.extraspellid and ignored_spells[t.extraspellid]) then return end
+
+ data.actorid = t.srcGUID
+ data.actorname = t.srcName
+ data.actorflags = t.srcFlags
+ data.dstName = Skada:FixPetsName(t.dstGUID, t.dstName, t.dstFlags)
+
+ data.spellid = t.spellstring
+ data.extraspellid = t.extrastring
+
+ Skada:FixPets(data)
+ Skada:DispatchSets(log_interrupt)
+
+ if not M.interruptannounce or t.srcGUID ~= Skada.userGUID then return end
+
+ local spelllink = t.extraspellname or data.dstName
+ if P.reportlinks then
+ spelllink = SpellLink(t.extraspellid or t.extraspellname) or spelllink
+ end
+ Skada:SendChat(format(L["%s interrupted!"], spelllink), M.interruptchannel or "SAY", "preset")
+ end
+
+ function mode_extraspell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's interrupted spells"], classfmt(class, label))
+ end
+
+ function mode_extraspell:Update(win, set)
+ win.title = uformat(L["%s's interrupted spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local spells, total, actor = get_actor_interrupted_spells(set, win.actorname, win.actorid)
+ if not spells or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, count in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, total, actor = get_actor_interrupt_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = (actor and not actor.enemy) and actor.interrupt
+ local spells = (total and total > 0) and actor.interruptspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Interrupts"], L[win.class]) or L["Interrupts"]
+
+ local total = set and set:GetTotal(win.class, nil, "interrupt")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.interrupt then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.interrupt
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ return set:GetTotal(win and win.class, nil, "interrupt") or 0
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_extraspell,
+ click2 = mode_target,
+ click3 = mode_spell,
+ columns = {Count = true, Percent = true, sPercent = true},
+ icon = [[Interface\ICONS\ability_kick]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_extraspell.nototal = true
+ mode_target.nototal = true
+ mode_spell.nototal = true
+
+ Skada:RegisterForCL(spell_interrupt, {src_is_interesting = true}, "SPELL_INTERRUPT")
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.interrupt and set.interrupt > 0 then
+ tooltip:AddDoubleLine(L["Interrupts"], set.interrupt, 1, 1, 1)
+ end
+ end
+
+ function mode:OnInitialize()
+ M.interruptchannel = M.interruptchannel or "SAY"
+
+ O.modules.args.interrupts = {
+ type = "group",
+ name = self.localeName,
+ desc = format(L["Options for %s."], self.localeName),
+ args = {
+ header = {
+ type = "description",
+ name = self.localeName,
+ fontSize = "large",
+ image = [[Interface\ICONS\ability_kick]],
+ imageWidth = 18,
+ imageHeight = 18,
+ imageCoords = Skada.cropTable,
+ width = "full",
+ order = 0
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ interruptannounce = {
+ type = "toggle",
+ name = format(L["Announce %s"], self.localeName),
+ order = 10,
+ width = "double"
+ },
+ interruptchannel = {
+ type = "select",
+ name = L["Channel"],
+ values = {AUTO = L["Instance"], SAY = L["Say"], YELL = L["Yell"], SELF = L["Self"]},
+ order = 20,
+ width = "double"
+ }
+ }
+ }
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actor_interrupted_spells = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local total = actor and actor.interrupt
+ local spells = total and actor.interruptspells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ if spell.spells then
+ for spellid, count in pairs(spell.spells) do
+ tbl[spellid] = (tbl[spellid] or 0) + count
+ end
+ end
+ end
+ return tbl, total, actor
+ end
+
+ get_actor_interrupt_targets = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local total = actor and actor.interrupt
+ local spells = total and actor.interruptspells
+ if not spells then return end
+
+ tbl = clear(tbl or C)
+ for _, spell in pairs(spells) do
+ if spell.targets then
+ for targetname, count in pairs(spell.targets) do
+ local t = tbl[targetname]
+ if not t then
+ t = new()
+ t.count = count
+ tbl[targetname] = t
+ else
+ t.count = t.count + count
+ end
+ self:_fill_actor_table(t, targetname)
+ end
+ end
+ end
+ return tbl, total, actor
+ end
+end)
diff --git a/Skada/Modules/KillingBlows.lua b/Skada/Modules/KillingBlows.lua
new file mode 100644
index 0000000..77cd9ce
--- /dev/null
+++ b/Skada/Modules/KillingBlows.lua
@@ -0,0 +1,361 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Killing Blows", function(L, P, _, C, M, O)
+ local mode = Skada:NewModule("Killing Blows")
+ local mode_target = mode:NewModule("Target List")
+ local mode_source = mode_target:NewModule("Source List")
+ local get_actor_killing_blows = nil
+ local get_target_killing_blows = nil
+ local mode_cols = nil
+
+ local KILLING_BLOWS = _G.KILLING_BLOWS or mode.localeName
+ local next, tconcat = next, table.concat
+ local SpellLink, uformat = Private.SpellLink or GetSpellLink, Private.uformat
+ local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+ local classfmt = Skada.classcolors.format
+ local announce_fmt = format("%s: %%s > %%s <%%s> %%s", KILLING_BLOWS)
+ local last_damager = {}
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function log_kill(set, data)
+ local actor = Skada:GetActor(set, data.actorname, data.actorid, data.actorflags)
+ if not actor then return end
+
+ set.kill = (set.kill or 0) + 1
+ actor.kill = (actor.kill or 0) + 1
+
+ local dstName = (set ~= Skada.total or P.totalidc) and data.dstName
+ if not dstName then return end
+
+ actor.kills = actor.kills or {}
+ actor.kills[dstName] = (actor.kills[dstName] or 0) + 1
+ end
+
+ local function spell_damage(t)
+ if not t.dstGUID or (M.killpvponly and not t:DestIsPlayer()) then return end
+
+ local data = last_damager[t.dstGUID] or new()
+ last_damager[t.dstGUID] = data
+
+ data.actorid = t.srcGUID
+ data.actorname = t.srcName
+ data.actorflags = t.srcFlags
+ data.dstName = t.dstName
+
+ -- announcing? collect data...
+ if M.killannounce then
+ data.spellname = t.spellname
+ data.amount = t.amount
+ data.overkill = t.overkill
+ data.absorbed = t.absorbed
+ data.blocked = t.blocked
+ data.resisted = t.resisted
+ end
+
+ Skada:FixPets(data)
+ end
+
+ local function unit_died(t)
+ local data = t.dstGUID and last_damager[t.dstGUID]
+ if not data then return end
+
+ Skada:DispatchSets(log_kill, data)
+
+ if M.killannounce and t:DestIsBoss() then
+ local output = format(
+ announce_fmt,
+ data.actorname,
+ data.dstName,
+ data.spellname or L["Unknown"],
+ data.amount and Skada:FormatNumber(0 - data.amount, 1) or "??"
+ )
+
+ if data.overkill or data.resisted or data.blocked or data.absorbed then
+ local extra = new()
+
+ if data.overkill then
+ extra[#extra + 1] = format("O:%s", Skada:FormatNumber(data.overkill, 1))
+ end
+ if data.resisted then
+ extra[#extra + 1] = format("R:%s", Skada:FormatNumber(data.resisted, 1))
+ end
+ if data.blocked then
+ extra[#extra + 1] = format("B:%s", Skada:FormatNumber(data.blocked, 1))
+ end
+ if data.absorbed then
+ extra[#extra + 1] = format("A:%s", Skada:FormatNumber(data.absorbed, 1))
+ end
+
+ if next(extra) then
+ output = format("%s [%s]", output, tconcat(extra, " - "))
+ end
+
+ extra = del(extra)
+ end
+
+ Skada:SendChat(output, M.killchannel or "SAY", "preset")
+ end
+
+ -- not needed anymore?
+ last_damager[t.dstGUID] = del(last_damager[t.dstGUID])
+ end
+
+ function mode_source:Enter(win, id, label, class)
+ win.targetid, win.targetname, win.targetclass = id, label, class
+ win.title = format("%s - %s", classfmt(class, label), KILLING_BLOWS)
+ end
+
+ function mode_source:Update(win, set)
+ win.title = uformat("%s - %s", classfmt(win.targetclass, win.targetname), KILLING_BLOWS)
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ if not win.targetname then return end
+
+ local total, actors = get_target_killing_blows(set, win.targetname, win.class)
+ if not total or not actors then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for actorname, actor in pairs(actors) do
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format("%s - %s", classfmt(class, label), KILLING_BLOWS)
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat("%s - %s", classfmt(win.actorclass, win.actorname), KILLING_BLOWS)
+ if not set or not win.actorname then return end
+
+ local total, targets = get_actor_killing_blows(set, win.actorname, win.actorid)
+ if not total or not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Killing Blows"], L[win.class]) or L["Killing Blows"]
+
+ local total = set and set:GetTotal(win.class, nil, "kill")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.kill then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.kill
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode_source:GetSetSummary(set, win)
+ local actors = win and win.targetname and set and set.kill and set.actors
+ if not actors then return end
+
+ local value = 0
+ for _, actor in pairs(actors) do
+ if not actor.enemy and actor.kills and actor.kills[win.targetname] and (not win.class or actor.class == win.class) then
+ value = value + actor.kills[win.targetname]
+ end
+ end
+ return value, Skada:FormatNumber(value)
+ end
+
+ function mode_target:GetSetSummary(set, win)
+ local actor = set and win and set:GetActor(win.actorname, win.actorid)
+ if not actor or not actor.kill then return end
+ return actor.kill, Skada:FormatNumber(actor.kill)
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ local value = set:GetTotal(win and win.class, nil, "kill") or 0
+ return value, Skada:FormatNumber(value)
+ end
+
+ function mode:SetComplete()
+ clear(last_damager)
+ end
+
+ function mode:OnEnable()
+ mode_source.metadata = {showspots = true, ordersort = true, filterclass = true}
+ mode_target.metadata = {click1 = mode_source}
+
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_target,
+ columns = {Count = true, Percent = true, sPercent = false},
+ icon = [[Interface\ICONS\ability_creature_cursed_02]]
+ }
+
+ mode_source.nototal = true
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ spell_damage,
+ {src_is_interesting = true, dst_is_not_interesting = true},
+ "DAMAGE_SHIELD",
+ "DAMAGE_SPLIT",
+ "RANGE_DAMAGE",
+ "SPELL_BUILDING_DAMAGE",
+ "SPELL_DAMAGE",
+ "SPELL_PERIODIC_DAMAGE",
+ "SWING_DAMAGE"
+ )
+
+ Skada:RegisterForCL(
+ unit_died,
+ {dst_is_not_interesting = true},
+ "UNIT_DIED",
+ "UNIT_DESTROYED",
+ "UNIT_DISSIPATES"
+ )
+
+ mode_cols = self.metadata.columns
+ Skada:AddMode(self, "Damage Done")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ function mode:OnInitialize()
+ M.killchannel = M.killchannel or "SAY"
+
+ O.modules.args.killbow = {
+ type = "group",
+ name = self.localeName,
+ desc = format(L["Options for %s."], self.localeName),
+ args = {
+ header = {
+ type = "description",
+ name = self.localeName,
+ fontSize = "large",
+ image = [[Interface\ICONS\ability_creature_cursed_02]],
+ imageWidth = 18,
+ imageHeight = 18,
+ imageCoords = Skada.cropTable,
+ width = "full",
+ order = 0
+ },
+ empty_1 = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ killpvponly = {
+ type = "toggle",
+ name = L["Only PvP Kills"],
+ desc = L["When enabled, only kills against enemy players count."],
+ descStyle = "inline",
+ width = "full",
+ order = 2
+ },
+ killannounce = {
+ type = "toggle",
+ name = format(L["Announce %s"], KILLING_BLOWS),
+ desc = L["Announce killing blows after combat ends. Only works for boss fights."],
+ descStyle = "inline",
+ width = "full",
+ order = 3
+ },
+ killchannel = {
+ type = "select",
+ name = L["Channel"],
+ values = {AUTO = L["Instance"], SAY = L["Say"], YELL = L["Yell"], SELF = L["Self"]},
+ order = 4,
+ width = "full"
+ },
+ }
+ }
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actor_killing_blows = function(self, actorname, actorid, tbl)
+ local actor = self:GetActor(actorname, actorid)
+ local total = actor and actor.kills and actor.kill
+ if not total or total == 0 then return end
+
+ tbl = clear(tbl or C)
+ for name, count in pairs(actor.kills) do
+ local t = tbl[name]
+ if not t then
+ t = new()
+ t.count = 0
+ tbl[name] = t
+ end
+ t.count = t.count + count
+ self:_fill_actor_table(t, name)
+ end
+ return total, tbl
+ end
+
+ get_target_killing_blows = function(self, name, class, tbl)
+ local actors = self.kill and name and self.actors
+ if not actors then return end
+
+ tbl = clear(tbl or C)
+ local total = 0
+ for actorname, actor in pairs(actors) do
+ local count = not actor.enemy and (not class or actor.class == class) and actor.kills and actor.kills[name]
+ if count then
+ local t = tbl[actorname] or new()
+ t.id = actor.id
+ t.class = actor.class
+ t.role = actor.role
+ t.spec = actor.spec
+ t.count = count
+ tbl[actorname] = t
+
+ total = total + count
+ end
+ end
+ return total, tbl
+ end
+end)
diff --git a/Skada/Modules/Load.xml b/Skada/Modules/Load.xml
new file mode 100644
index 0000000..ee5d4ca
--- /dev/null
+++ b/Skada/Modules/Load.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Skada/Modules/MySpells.lua b/Skada/Modules/MySpells.lua
new file mode 100644
index 0000000..11fefb4
--- /dev/null
+++ b/Skada/Modules/MySpells.lua
@@ -0,0 +1,152 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("My Spells", function(L, P)
+ local mode = Skada:NewModule("My Spells")
+
+ local pairs, format = pairs, string.format
+ local userGUID, userName = Skada.userGUID, Skada.userName
+ local tooltip_school = Skada.tooltip_school
+ local PercentToRGB = Private.PercentToRGB
+ local hits_perc = "%s (\124cffffffff%s\124r)"
+
+ local function format_valuetext(d, metadata)
+ d.valuetext = Skada:FormatNumber(d.value)
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function spell_tooltip(win, id, label, tooltip)
+ local set = win:GetSelectedSet()
+ local actor = set and set:GetActor(userName, userGUID)
+ if not actor then return end
+
+ local spell, damage = nil, nil
+ if actor.damagespells and actor.damagespells[id] then
+ spell, damage = actor.damagespells[id], true
+ elseif actor.absorbspells and actor.absorbspells[id] then
+ spell = actor.absorbspells[id]
+ elseif actor.healspells and actor.healspells[id] then
+ spell = actor.healspells[id]
+ end
+
+ if not spell then return end
+
+ tooltip:AddLine(format("%s - %s", userName, label))
+ tooltip_school(tooltip, id)
+
+ local cast = actor.GetSpellCast and actor:GetSpellCast(id)
+ if cast then
+ tooltip:AddDoubleLine(L["Casts"], cast, nil, nil, nil, 1, 1, 1)
+ end
+
+ if not spell.count or spell.count == 0 then return end
+
+ -- count stats
+ tooltip:AddDoubleLine(L["Hits"], spell.count, 1, 1, 1)
+ local amount = damage and P.absdamage and spell.total or spell.amount
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(amount / spell.count), 1, 1, 1)
+
+ local uptime = actor.auras and actor.auras[id] and actor.auras[id].uptime
+ if uptime and uptime > 0 then
+ uptime = 100 * (uptime / actor:GetTime(set))
+ tooltip:AddDoubleLine(L["Uptime"], Skada:FormatPercent(uptime), 1, 1, 1, PercentToRGB(uptime))
+ end
+
+ -- overheal/overkill
+ if spell.o_amt and spell.o_amt > 0 then
+ local overamount = format(hits_perc, Skada:FormatNumber(spell.o_amt), Skada:FormatPercent(spell.o_amt, spell.amount + spell.o_amt))
+ tooltip:AddDoubleLine(damage and L["Overkill"] or L["Overheal"], overamount, 1, 0.67, 0.67)
+ end
+
+ -- normal hits
+ if spell.n_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Normal Hits"], format(hits_perc, Skada:FormatNumber(spell.n_num), Skada:FormatPercent(spell.n_num, spell.count)))
+ if spell.n_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.n_min), 1, 1, 1)
+ end
+ if spell.n_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.n_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.n_amt / spell.n_num), 1, 1, 1)
+ end
+
+ -- critical hits
+ if spell.c_num then
+ tooltip:AddLine(" ")
+ tooltip:AddDoubleLine(L["Critical Hits"], format(hits_perc, Skada:FormatNumber(spell.c_num), Skada:FormatPercent(spell.c_num, spell.count)))
+ if spell.c_min then
+ tooltip:AddDoubleLine(L["Minimum"], Skada:FormatNumber(spell.c_min), 1, 1, 1)
+ end
+ if spell.c_max then
+ tooltip:AddDoubleLine(L["Maximum"], Skada:FormatNumber(spell.c_max), 1, 1, 1)
+ end
+ tooltip:AddDoubleLine(L["Average"], Skada:FormatNumber(spell.c_amt / spell.c_num), 1, 1, 1)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = L["My Spells"]
+
+ local player = set and set:GetActor(userName, userGUID)
+ if not player then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+
+ local spells = player.damagespells -- damage spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = P.absdamage and spell.total or spell.amount
+ format_valuetext(d, win.metadata)
+ end
+ end
+
+ spells = player.healspells -- heal spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, true)
+ d.value = spell.amount
+ format_valuetext(d, win.metadata)
+ end
+ end
+
+ spells = player.absorbspells -- absorb spells
+ if spells then
+ for spellid, spell in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = spell.amount
+ format_valuetext(d, win.metadata)
+ end
+ end
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ tooltip = spell_tooltip,
+ icon = [[Interface\ICONS\spell_nature_lightning]]
+ }
+
+ userGUID = userGUID or Skada.userGUID
+ userName = userName or Skada.userName
+
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+end)
diff --git a/Skada/Modules/Nickname.lua b/Skada/Modules/Nickname.lua
new file mode 100644
index 0000000..40ee93b
--- /dev/null
+++ b/Skada/Modules/Nickname.lua
@@ -0,0 +1,601 @@
+local _, Skada = ...
+Skada:RegisterModule("Nickname", function(L, P, G, _, _, O)
+ local mode = Skada:NewModule("Nickname")
+ local CONST_COMM_MOD = "Nickname"
+
+ local time, wipe = time, wipe
+ local strlower, format = string.lower, string.format
+ local check_nickname, cached_nickname
+
+ do
+ local type, strlen = type, strlenutf8 or string.len
+ local strfind, strmatch = string.find, string.match
+ local strupper, strgsub = string.upper, string.gsub
+
+ local function str_trim(str)
+ local from = strmatch(str, "^%s*()")
+ return from > #str and "" or strmatch(str, ".*%S", from)
+ end
+
+ local function title_case(first, rest)
+ return format("%s%s", strupper(first), strlower(rest))
+ end
+
+ local have_repeated = false
+ local count_spaces = 0
+
+ local blacklist = {
+ "abort",
+ "abuse",
+ "anal",
+ "arse",
+ "ass",
+ "azz",
+ "ball",
+ "bang",
+ "basst",
+ "bastard",
+ "beastal",
+ "beat",
+ "bestial",
+ "biat",
+ "bigass",
+ "bitc",
+ "blow",
+ "boner",
+ "boob",
+ "booty",
+ "breast",
+ "bugg",
+ "bum",
+ "bung",
+ "butt",
+ "byatch",
+ "camel",
+ "cawk",
+ "chesticle",
+ "clit",
+ "clog",
+ "clunge",
+ "cnts",
+ "cntz",
+ "cock",
+ "coitus",
+ "cok",
+ "commie",
+ "cooch",
+ "coon",
+ "cooter",
+ "copul",
+ "crack",
+ "crap",
+ "crotch",
+ "cum",
+ "cunil",
+ "cunni",
+ "cunt",
+ "dammit",
+ "damn",
+ "darkie",
+ "darky",
+ "dick",
+ "dike",
+ "dild",
+ "dipshit",
+ "dipstick",
+ "dixied",
+ "doggie",
+ "doggy",
+ "dooch",
+ "douch",
+ "dragqueen",
+ "dragqween",
+ "dumass",
+ "dumb",
+ "ejacul",
+ "excrement",
+ "facist",
+ "fag",
+ "faig",
+ "fark",
+ "fart",
+ "fatass",
+ "felatio",
+ "felch",
+ "fellatio",
+ "feltch",
+ "fister",
+ "flamer",
+ "flasher",
+ "fornicate",
+ "fucck",
+ "fuck",
+ "fuk",
+ "fukin",
+ "fukk",
+ "fuuck",
+ "gay",
+ "godammit",
+ "goddammit",
+ "goddamn",
+ "goddamned",
+ "goddamnes",
+ "goddamnit",
+ "gringo",
+ "hells",
+ "herpes",
+ "hindoo",
+ "hitler",
+ "hobo",
+ "hoe",
+ "hole",
+ "homo",
+ "hookers",
+ "hoor",
+ "hore",
+ "horne",
+ "horni",
+ "horny",
+ "hunk",
+ "hymen",
+ "idiot",
+ "incest",
+ "insest",
+ "jackass",
+ "jackoff",
+ "jackshit",
+ "jag",
+ "jerk",
+ "jihad",
+ "kidd",
+ "kinky",
+ "kooch",
+ "kootch",
+ "krap",
+ "kunilingus",
+ "kunnilingus",
+ "kunt",
+ "labia",
+ "lactate",
+ "lesb",
+ "lezb",
+ "lickm",
+ "lmfao",
+ "lube",
+ "masochist",
+ "massterbait",
+ "masstrbait",
+ "masstrbate",
+ "mastabate",
+ "mastabater",
+ "masterbaiter",
+ "masterbate",
+ "masterbates",
+ "mastrabator",
+ "masturbate",
+ "masturbating",
+ "milf",
+ "mofo",
+ "molest",
+ "moron",
+ "nastt",
+ "nasty",
+ "nazi",
+ "necro",
+ "negro",
+ "nigaboo",
+ "nigga",
+ "nigge",
+ "niggl",
+ "niggo",
+ "niggu",
+ "niglet",
+ "nigr",
+ "nigur",
+ "niig",
+ "nippl",
+ "nlgg",
+ "nonce",
+ "nook",
+ "nudg",
+ "nut",
+ "orgas",
+ "orgi",
+ "orgy",
+ "peedo",
+ "peeenus",
+ "peenus",
+ "peinus",
+ "penas",
+ "penile",
+ "penus",
+ "penuus",
+ "perv",
+ "phuck",
+ "phuk",
+ "phuq",
+ "pimp",
+ "piss",
+ "plumper",
+ "poon",
+ "poop",
+ "porn",
+ "pric",
+ "prik",
+ "pube",
+ "puke",
+ "punan",
+ "punta",
+ "puss",
+ "pusy",
+ "puuke",
+ "queef",
+ "queer",
+ "qweer",
+ "qweir",
+ "rape",
+ "rapist",
+ "recktum",
+ "rectum",
+ "redneck",
+ "ruski",
+ "russki",
+ "sadist",
+ "sadom",
+ "sandm",
+ "schlong",
+ "screw",
+ "scrotum",
+ "scum",
+ "seaman",
+ "semen",
+ "sex",
+ "shag",
+ "shat",
+ "shhit",
+ "shit",
+ "shiz",
+ "shyt",
+ "sissy",
+ "skeet",
+ "skirt",
+ "skum",
+ "slop",
+ "slut",
+ "smeg",
+ "snot",
+ "sodom",
+ "sperm",
+ "stabb",
+ "stiff",
+ "suck",
+ "tampon",
+ "tard",
+ "testic",
+ "threes",
+ "tits",
+ "titti",
+ "titty",
+ "torture",
+ "trots",
+ "trouser",
+ "tunnel",
+ "turd",
+ "twat",
+ "urin",
+ "uteru",
+ "vagi",
+ "vomit",
+ "vullv",
+ "vulva",
+ "wank",
+ "whitey",
+ "whoor",
+ "whore",
+ "wife",
+ "wog",
+ "ziga",
+ "zipp",
+ "name",
+ L["Name"],
+ "nickname",
+ L["Nickname"]
+ }
+
+ local function check_repeated(char)
+ if char == " " then
+ have_repeated = true
+ elseif strlen(char) > 2 then
+ have_repeated = true
+ elseif char == " " then
+ count_spaces = count_spaces + 1
+ end
+ end
+
+ function check_nickname(name)
+ if type(name) ~= "string" then
+ return false, L["Nickname isn't a valid string."]
+ end
+
+ name = str_trim(name)
+
+ local len = strlen(name)
+ if len == 0 then
+ return true, nil
+ elseif len > 12 then
+ return false, L["Your nickname is too long, max of 12 characters is allowed."]
+ end
+
+ local notallow = strfind(name, "[^a-zA-Z�������%s]")
+ if notallow then
+ return false, L["Only letters and two spaces are allowed."]
+ end
+
+ for _, word in pairs(blacklist) do
+ if strfind(strlower(name), word) then
+ return false, L["Your nickname contains a forbidden word."]
+ end
+ end
+
+ have_repeated = false
+ count_spaces = 0
+ strgsub(strgsub(strgsub(name, ".", "\0%0%0"), "(.)%z%1", "%1"), "%z.([^%z]+)", check_repeated)
+ if count_spaces > 2 then
+ have_repeated = true
+ end
+ if have_repeated then
+ return false, L["You can't use the same letter three times consecutively, two spaces consecutively or more then two spaces."]
+ end
+
+ return true, strgsub(name, "(%a)([%w_']*)", title_case)
+ end
+ end
+
+ function mode:OnEvent(event)
+ if self.sendCooldown > time() then
+ self.nicknameTimer = self.nicknameTimer or Skada.ScheduleTimer(self, "SendNickname", 30)
+ else
+ self:SendNickname()
+ end
+ end
+
+ function mode:SendNickname(nocooldown)
+ self:SetCacheTable()
+
+ if not nocooldown then
+ self.sendCooldown = time() + 29
+ end
+
+ if self.nicknameTimer then
+ Skada.CancelTimer(self, "SendNickname", true)
+ self.nicknameTimer = nil
+ end
+
+ Skada:SendComm(nil, nil, CONST_COMM_MOD, Skada.userGUID, G.nickname)
+ end
+
+ local function remove_nickname(guid)
+ if mode.db.cache[guid] then
+ mode.db.cache[guid] = nil
+ end
+ cached_nickname[guid] = false
+ end
+
+ function mode:OnCommNickname(sender, guid, nickname)
+ self:SetCacheTable()
+ if not P.ignorenicknames and sender and guid then
+ -- no nickname or removed?
+ if not nickname then
+ remove_nickname(guid)
+ return
+ end
+
+ local okey = nil
+ okey, nickname = check_nickname(nickname)
+ -- received an invalid nickname?
+ if not okey or not nickname or nickname == "" then
+ remove_nickname(guid)
+ return
+ end
+
+ -- so far so good? update...
+ self.db.cache[guid] = nickname -- only change if different
+ cached_nickname[guid] = nickname -- cache it and we're done!
+ end
+ end
+
+ function mode:OnInitialize()
+ P.namedisplay = P.namedisplay or 2
+
+ -- move nickname to global
+ if P.nickname then
+ G.nickname = G.nickname or P.nickname
+ P.nickname = nil
+ end
+
+ O.tweaks.args.advanced.args.nickname = {
+ type = "group",
+ name = self.localeName,
+ desc = format(L["Options for %s."], self.localeName),
+ order = 900,
+ get = function(i)
+ return P[i[#i]]
+ end,
+ set = function(i, val)
+ P[i[#i]] = val
+ Skada:ApplySettings()
+ end,
+ args = {
+ description = {
+ type = "description",
+ name = L["Nicknames are sent to group members and Skada can use them instead of your character name."],
+ fontSize = "medium",
+ width = "full",
+ order = 0
+ },
+ nickname = {
+ type = "input",
+ name = L["Nickname"],
+ desc = L["Set a nickname for you."],
+ order = 10,
+ get = function()
+ return G.nickname
+ end,
+ set = function(_, val)
+ local okey, nickname = check_nickname(val)
+ if okey == true then
+ G.nickname = nickname
+ cached_nickname[Skada.userGUID] = nickname or false
+ mode:SendNickname(true)
+ Skada:ApplySettings()
+ else
+ Skada:Print(nickname)
+ end
+ end
+ },
+ namedisplay = {
+ type = "select",
+ name = L["Name display"],
+ desc = L["Choose how names are shown on your bars."],
+ order = 20,
+ values = {
+ [1] = L["Name"],
+ [2] = L["Nickname"],
+ [3] = format("%s (%s)", L["Name"], L["Nickname"]),
+ [4] = format("%s (%s)", L["Nickname"], L["Name"])
+ }
+ },
+ ignorenicknames = {
+ type = "toggle",
+ name = L["Ignore Nicknames"],
+ desc = L["When enabled, nicknames set by Skada users are ignored."],
+ set = function(_, value)
+ P.ignorenicknames = value
+ mode:UpdateComms(nil, not P.syncoff)
+ Skada:ApplySettings()
+ end,
+ order = 30,
+ width = "full"
+ },
+ reset = {
+ type = "execute",
+ name = L["Clear Cache"],
+ order = 100,
+ width = "double",
+ confirm = function()
+ return L["Are you sure you want clear cached nicknames?"]
+ end,
+ func = function()
+ G.nicknames.reset = nil
+ G.nicknames.cache = wipe(G.nicknames.cache or {})
+ mode:SetCacheTable()
+ end,
+ disabled = function()
+ return (not G.nicknames or next(G.nicknames.cache) == nil)
+ end
+ }
+ }
+ }
+ end
+
+ function mode:UpdateComms(_, enable)
+ if enable and not P.ignorenicknames then
+ Skada.AddComm(self, CONST_COMM_MOD, "OnCommNickname")
+ Skada.RegisterMessage(self, "GROUP_ROSTER_UPDATE", "OnEvent")
+ Skada:Debug(format("%s Comms: \124cff00ff00%s\124r", self.localeName, L["ENABLED"]))
+ else
+ Skada.RemoveAllComms(self)
+ Skada.UnregisterAllMessages(self)
+ Skada:Debug(format("%s Comms: \124cffff0000%s\124r", self.localeName, L["DISABLED"]))
+ end
+ end
+
+ function mode:OnEnable()
+ self.sendCooldown = 0
+ self:SetCacheTable()
+
+ Skada.RegisterCallback(self, "Skada_UpdateCore", "Reset")
+ Skada.RegisterCallback(self, "Skada_UpdateComms", "UpdateComms")
+
+ self:UpdateComms(nil, not P.syncoff)
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllCallbacks(self)
+ Skada:UnregisterAllMessages(self)
+ Skada.RemoveAllComms(self)
+ end
+
+ -----------------------------------------------------------
+ -- Format name functions
+
+ do
+ -- modify this if you want to change the way nicknames are displayed
+ local nickname_fmt = {[1] = "%1$s", [2] = "%2$s", [3] = "%1$s (%2$s)", [4] = "%2$s (%1$s)"}
+
+ cached_nickname = setmetatable({}, {__mode = "kv", __index = function(t, guid)
+ if not mode.db then mode:SetCacheTable() end -- why wasn't it available yet?!
+
+ local nickname = false
+
+ -- ignoring nicknames and it's not me?
+ if P.ignorenicknames and guid ~= Skada.userGUID then
+ nickname = false
+ -- me?
+ elseif guid == Skada.userGUID then
+ nickname = G.nickname or false
+ -- well! we've got one!
+ elseif mode.db and mode.db.cache[guid] then
+ nickname = mode.db and mode.db.cache[guid] or false
+ end
+
+ -- cache it and move on!
+ t[guid] = nickname
+ return nickname
+ end})
+
+ Skada.oFormatName = Skada.FormatName
+ Skada.FormatName = function(self, name, guid)
+ -- missing guid or showing only names?
+ if not guid or P.namedisplay <= 1 then
+ return self:oFormatName(name)
+ end
+
+ -- cache table handles the worse part!
+ local nickname = cached_nickname[guid]
+ if nickname and nickname ~= name then
+ name = format(nickname_fmt[P.namedisplay], name, nickname)
+ end
+
+ -- leave the rest to the original func!
+ return self:oFormatName(name)
+ end
+ end
+
+ -----------------------------------------------------------
+ -- cache table functions
+
+ local function check_for_reset()
+ if not mode.db.reset or time() > mode.db.reset then
+ mode.db.reset = time() + (60 * 60 * 24 * 15)
+ mode.db.cache = wipe(mode.db.cache or {})
+ end
+ end
+
+ function mode:SetCacheTable()
+ if not self.db then
+ G.nicknames = G.nicknames or {cache = {}}
+ self.db = G.nicknames
+ end
+ check_for_reset()
+ end
+
+ function mode:Reset()
+ P.namedisplay = P.namedisplay or 2
+
+ G.nicknames = G.nicknames or {cache = {}}
+ G.nicknames.reset = time() + (60 * 60 * 24 * 15)
+ G.nicknames.cache = wipe(G.nicknames.cache or {})
+ self.db = G.nicknames
+ end
+end)
diff --git a/Skada/Modules/Parry.lua b/Skada/Modules/Parry.lua
new file mode 100644
index 0000000..a99077e
--- /dev/null
+++ b/Skada/Modules/Parry.lua
@@ -0,0 +1,199 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Parry-Haste", function(L, P, _, _, M, O)
+ local mode = Skada:NewModule("Parry-Haste")
+ local mode_target = mode:NewModule("Target List")
+ local pairs, format, uformat = pairs, string.format, Private.uformat
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local parrybosses = {
+ [10184] = true, -- Onyxia
+ [34797] = true, -- Icehowl
+ [34799] = true, -- Dreadscale
+ [35144] = true, -- Acidmaw
+ [36853] = true, -- Sindragosa
+ [36855] = true, -- Lady Deathwhisper
+ [39863] = true, -- Halion
+ -- UNCONFIRMED BOSSES - by shoggoth#9796
+ [15932] = true, -- Gluth
+ [15989] = true, -- Sapphiron
+ [15990] = true, -- Kel'Thuzad
+ [33271] = true, -- General Vezax
+ }
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function log_parry(set, actorname, actorid, actorflags, dstName)
+ local actor = Skada:GetActor(set, actorname, actorid, actorflags)
+ if not actor then return end
+
+ actor.parry = (actor.parry or 0) + 1
+ set.parry = (set.parry or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if (set == Skada.total and not P.totalidc) or not dstName then return end
+
+ actor.parrytargets = actor.parrytargets or {}
+ actor.parrytargets[dstName] = (actor.parrytargets[dstName] or 0) + 1
+
+ if M.parryannounce and set ~= Skada.total then
+ Skada:SendChat(format(L["%s parried %s (%s)"], dstName, actorname, actor.parrytargets[dstName] or 1), M.parrychannel, "preset")
+ end
+ end
+
+ local GetCreatureId = Skada.GetCreatureId
+ local function is_parry_boss(name, guid)
+ if parrybosses[name] or parrybosses[GetCreatureId(guid)] then
+ parrybosses[name] = parrybosses[name] or true -- cache it
+ return true
+ end
+ return false
+ end
+
+ local function spell_missed(t)
+ if t.misstype == "PARRY" and t.dstName and is_parry_boss(t.dstName, t.dstGUID) then
+ local actorid, actorname, actorflags = Skada:FixMyPets(t.srcGUID, t.srcName, t.srcFlags)
+ Skada:DispatchSets(log_parry, actorname, actorid, actorflags, t.dstName)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = (actor and not actor.enemy) and actor.parry
+ local targets = (total and total > 0) and actor.parrytargets
+
+ if not targets then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, count in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, targetname)
+ d.class = "BOSS" -- what else can it be?
+ d.value = count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Parry-Haste"], L[win.class]) or L["Parry-Haste"]
+
+ local total = set and set:GetTotal(win.class, nil, "parry")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.parry then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.parry
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ return set:GetTotal(win and win.class, nil, "parry") or 0
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_target,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\ability_parry]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(
+ spell_missed,
+ {src_is_interesting = true, dst_is_not_interesting = true},
+ "SPELL_MISSED",
+ "SWING_MISSED"
+ )
+
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ function mode:OnInitialize()
+ M.parrychannel = M.parrychannel or "AUTO"
+
+ O.modules.args.Parry = {
+ type = "group",
+ name = self.localeName,
+ desc = format(L["Options for %s."], self.localeName),
+ args = {
+ header = {
+ type = "description",
+ name = self.localeName,
+ fontSize = "large",
+ image = [[Interface\ICONS\ability_parry]],
+ imageWidth = 18,
+ imageHeight = 18,
+ imageCoords = Skada.cropTable,
+ width = "full",
+ order = 0
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ parryannounce = {
+ type = "toggle",
+ name = format(L["Announce %s"], self.localeName),
+ order = 10,
+ width = "double"
+ },
+ parrychannel = {
+ type = "select",
+ name = L["Channel"],
+ values = {AUTO = L["Instance"], SELF = L["Self"]},
+ order = 20,
+ width = "double"
+ }
+ }
+ }
+ end
+end)
diff --git a/Skada/Modules/Potions.lua b/Skada/Modules/Potions.lua
new file mode 100644
index 0000000..8de39c7
--- /dev/null
+++ b/Skada/Modules/Potions.lua
@@ -0,0 +1,460 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Potions", function(L, P, G, C, _, O)
+ local mode = Skada:NewModule("Potions")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_actor = mode_spell:NewModule("Target List")
+ local get_actors_by_potion = nil
+ local mode_cols = nil
+
+ local pairs, format, strsub, uformat = pairs, string.format, string.sub, Private.uformat
+ local GetItemInfo, classcolors, classfmt = GetItemInfo, Skada.classcolors, Skada.classcolors.format
+ local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+ local prepotionStr, potionStr = "\124c%s%s\124r %s", "\124T%s:14:14:0:0:64:64:4:60:4:60\124t"
+ local potion_ids, prepotion = {}, {}
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function log_potion(set, actorname, actorid, actorflags, potionid)
+ local actor = Skada:GetActor(set, actorname, actorid, actorflags)
+ if not actor then return end
+
+ -- record potion usage for actor and set
+ actor.potion = (actor.potion or 0) + 1
+ set.potion = (set.potion or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if set == Skada.total and not P.totalidc then return end
+
+ actor.potionspells = actor.potionspells or {}
+ actor.potionspells[potionid] = (actor.potionspells[potionid] or 0) + 1
+ end
+
+ local function potion_used(t)
+ if t.__temp or (t.spellid and potion_ids[t.spellid]) then
+ Skada:DispatchSets(log_potion, t.srcName, t.srcGUID, t.srcFlags, potion_ids[t.spellid])
+ end
+ end
+
+ do
+ local tconcat = table.concat
+ local UnitClass = UnitClass
+
+ -- listens to combat start
+ function mode:UnitBuff(_, args)
+ if args.owner or not args.auras then return end
+
+ local potions = nil
+ for _, aura in pairs(args.auras) do
+ if potion_ids[aura.id] then
+ local t = new()
+ t.srcGUID = args.dstGUID
+ t.srcName = args.dstName
+ t.srcFlags = args.dstFlags
+ t.spellid = aura.id
+ t.__temp = true
+ potion_used(t)
+ t = del(t)
+
+ potions = potions or new()
+ potions[#potions + 1] = format(potionStr, aura.icon)
+ end
+ end
+
+ if not potions then return end
+
+ local _, class = UnitClass(args.unit)
+ prepotion[#prepotion + 1] = format(prepotionStr, classcolors.str(class), args.dstName, tconcat(potions, " "))
+ potions = del(potions)
+ end
+
+ -- listens to combat end
+ function mode:CombatLeave()
+ if prepotion then
+ if P.prepotion and next(prepotion) ~= nil then
+ Skada:Printf(L["pre-potion: %s"], tconcat(prepotion, ", "))
+ end
+ clear(prepotion)
+ end
+ end
+ end
+
+ function mode_actor:Enter(win, id, label)
+ win.spellid, win.spellname = id, label
+ win.title = label
+ end
+
+ function mode_actor:Update(win, set)
+ win.title = win.spellname or L["Unknown"]
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ if not set or not win.spellname then return end
+
+ local total, actors = get_actors_by_potion(set, win.spellid, win.class)
+ if total == 0 or not actors then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for actorname, actor in pairs(actors) do
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's potions"], classfmt(class, label))
+ end
+
+ local function request_potion(potionid)
+ if potionid and potionid ~= nil and potionid ~= "" and potionid ~= 0 and strsub(potionid, 1, 1) ~= "s" then
+ GameTooltip:SetHyperlink(format("item:%s:0:0:0:0:0:0:0", potionid))
+ GameTooltip:Hide()
+ end
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's potions"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = Skada:FindActor(set, win.actorname, win.actorid, true)
+ local total = actor and actor.potion
+ local potions = (total and total > 0) and actor.potionspells
+
+ if not potions then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for potionid, count in pairs(potions) do
+ local potionname, potionlink, _, _, _, _, _, _, _, potionicon = GetItemInfo(potionid)
+ if not potionname then
+ request_potion(potionid)
+ end
+
+ if potionname then
+ nr = nr + 1
+ local d = win:nr(nr)
+
+ d.id = potionid
+ d.hyperlink = potionlink
+ d.label = potionname
+ d.icon = potionicon
+
+ d.value = count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Potions"], L[win.class]) or L["Potions"]
+
+ local total = set and set:GetTotal(win.class, nil, "potion")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.potion then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.potion
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ return set:GetTotal(win and win.class, nil, "potion") or 0
+ end
+
+ function mode:OnEnable()
+ mode_actor.metadata = {filterclass = true}
+ mode_spell.metadata = {click1 = mode_actor}
+ self.metadata = {
+ showspots = true,
+ ordersort = true,
+ filterclass = true,
+ click1 = mode_spell,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\inv_potion_31]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_spell.nototal = true
+
+ Skada:RegisterForCL(potion_used, {src_is_interesting_nopets = true}, "SPELL_CAST_SUCCESS")
+ Skada.RegisterCallback(self, "Skada_ApplySettings", "ApplySettings")
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllCallbacks(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:ApplySettings()
+ if P.prepotion then
+ Skada.RegisterCallback(self, "Skada_UnitBuffs", "UnitBuff")
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ else
+ Skada.UnregisterCallback(self, "Skada_UnitBuffs")
+ Skada.UnregisterAllMessages(self)
+ end
+ end
+
+ function mode:OnInitialize()
+ -- list of potion: [spellid] = potionid (string)
+
+ --[[ level NaN ]]--
+ potion_ids[439] = "118" -- Minor Healing Potion
+ potion_ids[6724] = "5816" -- Light of Elune
+ potion_ids[29236] = "3087" -- Mug of Shimmer Stout
+ potion_ids[47430] = "36770" -- Zort's Protective Elixir
+ potion_ids[50809] = "38351" -- Murliver Oil
+
+ --[[ level 03-17 ]]--
+ potion_ids[437] = "2455" -- Minor Mana Potion
+ potion_ids[438] = "3385" -- Lesser Mana Potion
+ potion_ids[440] = "4596" -- Discolored Healing Potion
+ potion_ids[441] = "929" -- Healing Potion
+ potion_ids[2370] = "2456" -- Minor Rejuvenation Potion
+ potion_ids[2379] = "2459" -- Swiftness Potion
+ potion_ids[2380] = "3384" -- Minor Magic Resistance Potion
+ potion_ids[6612] = "5631" -- Rage Potion
+ potion_ids[6612] = "858" -- Lesser Healing Potion
+ potion_ids[6614] = "5632" -- Cowardly Flight Potion
+ potion_ids[7242] = "6048" -- Shadow Protection Potion
+ potion_ids[7245] = "6051" -- Holy Protection Potion
+ potion_ids[7840] = "6372" -- Swim Speed Potion
+ potion_ids[26677] = "3386" -- Potion of Curing
+
+ --[[ level 20-28 ]]--
+ potion_ids[2023] = "3827" -- Mana Potion
+ potion_ids[2024] = "1710" -- Greater Healing Potion
+ potion_ids[3592] = "2633" -- Jungle Remedy
+ potion_ids[3680] = "3823" -- Lesser Invisibility Potion
+ potion_ids[6613] = "5633" -- Great Rage Potion
+ potion_ids[6615] = "5634" -- Free Action Potion
+ potion_ids[7233] = "6049" -- Fire Protection Potion
+ potion_ids[7239] = "6050" -- Frost Protection Potion
+ potion_ids[7254] = "6052" -- Nature Protection Potion
+
+ --[[ level 31-37 ]]--
+ potion_ids[4042] = "3928" -- Superior Healing Potion
+ potion_ids[4941] = "4623" -- Lesser Stoneshield Potion
+ potion_ids[11359] = "9030" -- Restorative Potion
+ potion_ids[11364] = "9036" -- Magic Resistance Potion
+ potion_ids[11387] = "9144" -- Wildvine Potion
+ potion_ids[11392] = "9172" -- Invisibility Potion
+ potion_ids[11903] = "6149" -- Greater Mana Potion
+ potion_ids[15822] = "12190" -- Dreamless Sleep Potion
+ potion_ids[21394] = "17349" -- Superior Healing Draught
+ potion_ids[21396] = "17352" -- Superior Mana Draught
+
+ --[[ level 41-49 ]]--
+ potion_ids[3169] = "3387" -- Limited Invulnerability Potion
+ potion_ids[17528] = "13442" -- Mighty Rage Potion
+ potion_ids[17530] = "13443" -- Superior Mana Potion
+ potion_ids[17540] = "13455" -- Greater Stoneshield Potion
+ potion_ids[17543] = "13457" -- Greater Fire Protection Potion
+ potion_ids[17544] = "13456" -- Greater Frost Protection Potion
+ potion_ids[17545] = "13460" -- Greater Holy Protection Potion
+ potion_ids[17546] = "13458" -- Greater Nature Protection Potion
+ potion_ids[17548] = "13459" -- Greater Shadow Protection Potion
+ potion_ids[17549] = "13461" -- Greater Arcane Protection Potion
+ potion_ids[17550] = "13462" -- Purification Potion
+ potion_ids[21393] = "17348" -- Major Healing Draught
+ potion_ids[21395] = "17351" -- Major Mana Draught
+ potion_ids[24364] = "20008" -- Living Action Potion
+
+ --[[ level 50-55 ]]--
+ potion_ids[17624] = "13506" -- Flask of Petrification
+ potion_ids[22729] = "18253" -- Major Rejuvenation Potion
+ potion_ids[24360] = "20002" -- Greater Dreamless Sleep Potion
+ potion_ids[28492] = "22826" -- Sneaking Potion
+ potion_ids[28548] = "22871" -- Shrouding Potion
+ potion_ids[41617] = "32903" -- Cenarion Mana Salve
+ potion_ids[41618] = "32902" -- Bottled Nethergon Energy
+ potion_ids[41619] = "32904" -- Cenarion Healing Salve
+ potion_ids[41620] = "32905" -- Bottled Nethergon Vapor
+ potion_ids[52697] = "39327" -- Noth's Special Brew
+ potion_ids[67486] = "33092" -- Healing Potion Injector
+ potion_ids[67487] = "33093" -- Mana Potion Injector
+
+ --[[ level 60-65 ]]--
+ potion_ids[17531] = "31840" -- Major Combat Mana Potion
+ potion_ids[17534] = "31838" -- Major Combat Healing Potion
+ potion_ids[28504] = "22836" -- Major Dreamless Sleep Potion
+ potion_ids[28506] = "22837" -- Heroic Potion
+ potion_ids[28507] = "22838" -- Haste Potion
+ potion_ids[28508] = "22839" -- Destruction Potion
+ potion_ids[28511] = "22841" -- Major Fire Protection Potion
+ potion_ids[28512] = "22842" -- Major Frost Protection Potion
+ potion_ids[28513] = "22844" -- Major Nature Protection Potion
+ potion_ids[28515] = "22849" -- Ironshield Potion
+ potion_ids[28517] = "22850" -- Super Rejuvenation Potion
+ potion_ids[28536] = "22845" -- Major Arcane Protection Potion
+ potion_ids[28537] = "22846" -- Major Shadow Protection Potion
+ potion_ids[28538] = "22847" -- Major Holy Protection Potion
+ potion_ids[38908] = "31676" -- Fel Regeneration Potion
+ potion_ids[45051] = "34440" -- Mad Alchemist's Potion
+
+ --[[ level 70 ]]--
+ potion_ids[28494] = "22828" -- Insane Strength Potion
+ potion_ids[28495] = "43569" -- Endless Healing Potion
+ potion_ids[28499] = "43570" -- Endless Mana Potion
+ potion_ids[38929] = "31677" -- Fel mana potion
+ potion_ids[41304] = "32783" -- Blue Ogre Brew
+ potion_ids[41306] = "32784" -- Red Ogre Brew
+ potion_ids[43185] = "33447" -- Healing Potion
+ potion_ids[43186] = "33448" -- Restore Mana
+ potion_ids[53750] = "40077" -- Crazy Alchemist's Potion
+ potion_ids[53753] = "40081" -- Nightmare Slumber
+ potion_ids[53761] = "40087" -- Powerful Rejuvenation Potion
+ potion_ids[53762] = "40093" -- Indestructible
+ potion_ids[53908] = "40211" -- Potion of Speed
+ potion_ids[53909] = "40212" -- Potion of Wild Magic
+ potion_ids[53910] = "40213" -- Arcane Protection
+ potion_ids[53911] = "40214" -- Fire Protection
+ potion_ids[53913] = "40215" -- Frost Protection
+ potion_ids[53914] = "40216" -- Nature Protection
+ potion_ids[53915] = "40217" -- Shadow Protection
+ potion_ids[61371] = "44728" -- Endless Rejuvenation Potion
+ potion_ids[67489] = "41166" -- Runic Healing Injector
+ potion_ids[67490] = "42545" -- Runic Mana Injector
+
+ --[[ Cataclysm ]]--
+ potion_ids[78992] = "57193" -- Mighty Rejuvenation Potion
+ potion_ids[78993] = "57194" -- Potion of Concentration
+ potion_ids[79475] = "58090" -- Earthen Potion
+ potion_ids[79476] = "58091" -- Volcanic Potion
+ potion_ids[79633] = "58145" -- Potion of the Tol'vir
+ potion_ids[79634] = "58146" -- Golemblood Potion
+
+ --[[ Mists of Pandaria ]]--
+ potion_ids[105697] = "76089" -- Virmen's Bite
+ potion_ids[105698] = "76090" -- Potion of the Mountains
+ potion_ids[105701] = "76092" -- Potion of Focus
+ potion_ids[105702] = "76093" -- Potion of the Jade Serpent
+ potion_ids[105704] = "76094" -- Alchemist's Rejuvenation
+ potion_ids[105706] = "76095" -- Potion of Mogu Power
+ potion_ids[105707] = "76096" -- Darkwater Potion
+ potion_ids[105708] = "76097" -- Master Healing Potion
+ potion_ids[105709] = "76098" -- Master Mana Potion
+ potion_ids[139493] = "93742" -- Healing Potion
+
+ --[[ Wardlords of Draenor ]]--
+ potion_ids[122451] = "118704" -- Commander's Draenic Invisibility Potion
+ potion_ids[156423] = "109217" -- Draenic Agility Potion
+ potion_ids[156426] = "109218" -- Draenic Intellect Potion
+ potion_ids[156428] = "109219" -- Draenic Strength Potion
+ potion_ids[156430] = "109220" -- Draenic Versatility Potion
+ potion_ids[156436] = "109222" -- Draenic Mana Potion
+ potion_ids[156438] = "117415" -- Smuggled Tonic
+ potion_ids[156445] = "109226" -- Draenic Rejuvenation Potion
+ potion_ids[170403] = "115498" -- Ashran Healing Tonic
+ potion_ids[172160] = "116925" -- Vintage Free Action Potion
+ potion_ids[173260] = "118006" -- Shieldtronic Shield
+ potion_ids[174018] = "118278" -- Pale Vision Potion
+ potion_ids[175790] = "116266" -- Draenic Swiftness Potion
+ potion_ids[175817] = "116276" -- Draenic Living Action Potion
+ potion_ids[175821] = "118704" -- Pure Rage Potion
+ potion_ids[175833] = "116268" -- Draenic Invisibility Potion
+ potion_ids[176107] = "118910" -- Brawler's Draenic Agility Potion
+ potion_ids[176108] = "118911" -- Brawler's Draenic Intellect Potion
+ potion_ids[176109] = "118915" -- Brawler's Bottomless Draenic Strength Potion
+ potion_ids[176114] = "118917" -- Brawler's Bottomless Healing Tonic
+ potion_ids[176151] = "118922" -- Oralius' Whispering Crystal
+ potion_ids[185490] = "124660" -- Darkmoon Healing Tonic
+ potion_ids[185491] = "124661" -- Gladiator's Healing Potion
+ potion_ids[185562] = "124671" -- Darkmoon Firewater
+ potion_ids[191212] = "128647" -- Fizzy Apple Cider
+
+ --[[ Legion ]]--
+ potion_ids[188016] = "136569" -- Aged/Ancient Health Potion
+ potion_ids[188017] = "127835" -- Ancient Mana Potion
+ potion_ids[188018] = "127836" -- Ancient Rejuvenation Potion
+ potion_ids[188027] = "127843" -- Potion of Deadly Grace
+ potion_ids[188028] = "127844" -- Potion of the Old War
+ potion_ids[188029] = "127845" -- Unbending Potion
+ potion_ids[188030] = "127846" -- Leytorrent Potion
+ potion_ids[193456] = "129192" -- Inquisitor's Menacing Eye
+ potion_ids[216802] = "138727" -- Potion of Defiance
+ potion_ids[216810] = "138729" -- Potion of Heightened Senses
+ potion_ids[223573] = "140347" -- Spirit Berries
+ potion_ids[223595] = "140351" -- Sunfruit
+ potion_ids[229206] = "142117" -- Potion of Prolonged Power
+ potion_ids[231784] = "143542" -- Crown Co. "Kure-Everything" Tonic
+ potion_ids[242551] = "147707" -- Repurposed Fel Focuser
+ potion_ids[251645] = "152615" -- Astral Healing Potion
+
+ -- don't edit below unless you know what you're doing.
+ if P.prepotion == nil then
+ P.prepotion = true
+ end
+
+ O.tweaks.args.general.args.prepotion = {
+ type = "toggle",
+ name = L["Pre-potion"],
+ desc = L["Prints pre-potion after the end of the combat."],
+ order = 0
+ }
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actors_by_potion = function(self, potionid, class, tbl)
+ local total = 0
+ if not self.actors or not self.potion or not potionid then
+ return total
+ end
+
+ tbl = clear(tbl or C)
+
+ local actors = self.actors
+ for aname, a in pairs(actors) do
+ if a.potionspells and a.potionspells[potionid] and (not class or class == a.class) then
+ total = total + a.potionspells[potionid]
+ tbl[aname] = new()
+ tbl[aname].id = a.id
+ tbl[aname].class = a.class
+ tbl[aname].role = a.role
+ tbl[aname].spec = a.spec
+ tbl[aname].enemy = a.enemy
+ tbl[aname].count = a.potionspells[potionid]
+ end
+ end
+
+ return total, tbl
+ end
+end)
diff --git a/Skada/Modules/Power.lua b/Skada/Modules/Power.lua
new file mode 100644
index 0000000..5ede265
--- /dev/null
+++ b/Skada/Modules/Power.lua
@@ -0,0 +1,216 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Resources", function(L, P)
+ local mode = Skada:NewModule("Resources")
+ mode.icon = [[Interface\ICONS\spell_holy_rapture]]
+
+ local setmetatable, pairs = setmetatable, pairs
+ local format, uformat = string.format, Private.uformat
+ local classfmt = Skada.classcolors.format
+ local mode_cols = nil
+
+ local SPELL_POWER_MANA = SPELL_POWER_MANA or 0
+ local SPELL_POWER_RAGE = SPELL_POWER_RAGE or 1
+ local SPELL_POWER_FOCUS = SPELL_POWER_FOCUS or 2
+ local SPELL_POWER_ENERGY = SPELL_POWER_ENERGY or 3
+ local SPELL_POWER_HAPPINESS = SPELL_POWER_HAPPINESS or 4
+ local SPELL_POWER_RUNIC_POWER = SPELL_POWER_RUNIC_POWER or 6
+
+ -- used to store total amounts for sets and actors
+ local gainTable = {
+ [SPELL_POWER_MANA] = "mana",
+ [SPELL_POWER_RAGE] = "rage",
+ [SPELL_POWER_FOCUS] = "energy",
+ [SPELL_POWER_ENERGY] = "energy",
+ [SPELL_POWER_HAPPINESS] = "energy",
+ [SPELL_POWER_RUNIC_POWER] = "runic"
+ }
+
+ -- users as keys to store spells and their amounts.
+ local spellTable = {
+ [SPELL_POWER_MANA] = "manaspells",
+ [SPELL_POWER_RAGE] = "ragespells",
+ [SPELL_POWER_FOCUS] = "energyspells",
+ [SPELL_POWER_ENERGY] = "energyspells",
+ [SPELL_POWER_HAPPINESS] = "energyspells",
+ [SPELL_POWER_RUNIC_POWER] = "runicspells"
+ }
+
+ local ignored_spells = Skada.ignored_spells.power -- Edit Skada\Core\Tables.lua
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Amount and Skada:FormatNumber(d.value),
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local gain = {}
+ local function log_gain(set)
+ local key = gain.type and gainTable[gain.type]
+ if not key then return end
+
+ local actor = Skada:GetActor(set, gain.actorname, gain.actorid, gain.actorflags)
+ if not actor then return end
+
+ actor[key] = (actor[key] or 0) + gain.amount
+ set[key] = (set[key] or 0) + gain.amount
+
+ -- saving this to total set may become a memory hog deluxe.
+ if (set == Skada.total and not P.totalidc) or not gain.spellid then return end
+
+ key = spellTable[gain.type]
+ actor[key] = actor[key] or {}
+ actor[key][gain.spellid] = (actor[key][gain.spellid] or 0) + gain.amount
+ end
+
+ local function spell_energize(t)
+ if t.spellid and not ignored_spells[t.spellid] then
+ gain.actorid = t.dstGUID
+ gain.actorname = t.dstName
+ gain.actorflags = t.dstFlags
+
+ gain.spellid = t.spellstring
+ gain.amount = t.amount
+ gain.type = t.powertype
+
+ Skada:FixPets(gain)
+ Skada:DispatchSets(log_gain)
+ end
+ end
+
+ -- a base module used to create our power modules.
+ local mode_base = {}
+ local mode_base_mt = {__index = mode_base}
+
+ -- a base actor module used to create power gained per actor modules.
+ local mode_actor = {}
+ local mode_actor_mt = {__index = mode_actor}
+
+ -- allows us to create a module for each power type.
+ function mode_base:Create(power, name)
+ if not power or not gainTable[power] then return end
+
+ local instance = Skada:NewModule(name)
+ setmetatable(instance, mode_base_mt)
+
+ local pmode = instance:NewModule("Spell List")
+ setmetatable(pmode, mode_actor_mt)
+
+ pmode.powerid = power
+ pmode.power = gainTable[power]
+ pmode.spells = spellTable[power]
+ instance.power = gainTable[power]
+ instance.metadata = {showspots = true, filterclass = true, click1 = pmode}
+
+ -- no total click.
+ pmode.nototal = true
+
+ return instance
+ end
+
+ -- this is the main module update function that shows the list
+ -- of actors depending on the selected power gain type.
+ function mode_base:Update(win, set)
+ win.title = self.localeName or self.moduleName or L["Unknown"]
+ if win.class then
+ win.title = format("%s (%s)", win.title, L[win.class])
+ end
+
+ local total = set and set:GetTotal(win.class, nil, self.power)
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor[self.power] then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor[self.power]
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ -- base function used to return sets summaries
+ function mode_base:GetSetSummary(set, win)
+ if not set then return end
+ local value = set:GetTotal(win and win.class, nil, self.power) or 0
+ return value, Skada:FormatNumber(value)
+ end
+
+ -- actor mods common Enter function.
+ function mode_actor:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = uformat(L["%s's spells"], classfmt(class, label))
+ end
+
+ -- actor mods main update function
+ function mode_actor:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ if not actor or actor.enemy then return end -- unavailable for enemies yet
+
+ local total = actor and self.power and actor[self.power]
+ local spells = (total and total > 0) and actor[self.spells]
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, amount in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid, false)
+ d.value = amount
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ -- we create the modules now
+ -- power gained: mana
+ local mode_mana = mode_base:Create(SPELL_POWER_MANA, "Mana Restored")
+ local mode_rage = mode_base:Create(SPELL_POWER_RAGE, "Rage Generated")
+ local mode_energy = mode_base:Create(SPELL_POWER_ENERGY, "Energy Generated")
+ local mode_runic = mode_base:Create(SPELL_POWER_RUNIC_POWER, "Runic Power Generated")
+
+ function mode:OnEnable()
+ self.metadata = {columns = {Amount = true, Percent = false, sPercent = true}}
+ mode_cols = self.metadata.columns
+ Skada:AddColumnOptions(self)
+
+ Skada:RegisterForCL(spell_energize, {src_is_interesting = true}, "SPELL_ENERGIZE", "SPELL_PERIODIC_ENERGIZE")
+
+ mode_mana.metadata.icon = [[Interface\ICONS\spell_frost_summonwaterelemental]]
+ mode_rage.metadata.icon = [[Interface\ICONS\spell_nature_shamanrage]]
+ mode_energy.metadata.icon = [[Interface\ICONS\spell_holy_circleofrenewal]]
+ mode_runic.metadata.icon = [[Interface\ICONS\inv_sword_62]]
+
+ Skada:AddMode(mode_mana, "Resources")
+ Skada:AddMode(mode_rage, "Resources")
+ Skada:AddMode(mode_energy, "Resources")
+ Skada:AddMode(mode_runic, "Resources")
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(mode_mana)
+ Skada:RemoveMode(mode_rage)
+ Skada:RemoveMode(mode_energy)
+ Skada:RemoveMode(mode_runic)
+ end
+end)
diff --git a/Skada/Modules/PvP.lua b/Skada/Modules/PvP.lua
new file mode 100644
index 0000000..76240b9
--- /dev/null
+++ b/Skada/Modules/PvP.lua
@@ -0,0 +1,314 @@
+local _, Skada = ...
+Skada:RegisterModule("Player vs. Player", "mod_pvp_desc", function(L, P, _, _, _, O)
+ local mode = Skada:NewModule("Player vs. Player")
+
+ local format, wipe, GetTime = string.format, wipe, GetTime
+ local UnitGUID, UnitClass, UnitBuff, UnitIsPlayer = UnitGUID, UnitClass, UnitBuff, UnitIsPlayer
+ local spellnames, UnitCastingInfo = Skada.spellnames, UnitCastingInfo
+ local group_units, group_pets = Skada.Units.group, Skada.Units.grouppet
+
+ local validclass = Skada.validclass
+ local specsCache, specsRoles = nil, nil
+ local spellsTable, aurasTable = nil, nil
+
+ local function build_spell_list()
+ if not specsRoles then
+ specsRoles = {
+ [105] = "HEALER", -- Druid: Restoration
+ [256] = "HEALER", -- Priest: Discipline
+ [257] = "HEALER", -- Priest: Holy
+ [264] = "HEALER", -- Shaman: Restoration
+ [65] = "HEALER", -- Paladin: Holy
+ [66] = "TANK", -- Paladin: Protection
+ [73] = "TANK" -- Warrior: Protection
+ }
+ end
+
+ if not aurasTable then
+ aurasTable = {
+ WARRIOR = {
+ [spellnames[50227]] = 73 -- Sword and Board
+ },
+ PALADIN = {
+ [spellnames[31801]] = 70 -- Seal of Vengeance
+ },
+ ROGUE = {
+ [spellnames[58427]] = 259, -- Overkill
+ [spellnames[36554]] = 261, -- Shadowstep
+ [spellnames[31223]] = 261 -- Master of Subtlety
+ },
+ PRIEST = {
+ [spellnames[47788]] = 257, -- Guardian Spirit
+ [spellnames[15473]] = 258, -- Shadowform
+ [spellnames[15286]] = 258 -- Vampiric Embrace
+ },
+ DEATHKNIGHT = {
+ [spellnames[49016]] = 250, -- Hysteria
+ [spellnames[55610]] = 251, -- Imp. Icy Talons
+ [spellnames[49222]] = 252 -- Bone Shield
+ },
+ MAGE = {
+ [spellnames[11426]] = 62, -- Ice Barrier
+ [spellnames[11129]] = 63, -- Combustion
+ },
+ WARLOCK = {
+ },
+ SHAMAN = {
+ [spellnames[51470]] = 262, -- Elemental Oath
+ [spellnames[974]] = 264 -- Earth Shield
+ },
+ HUNTER = {
+ [spellnames[20895]] = 253, -- Spirit Bond
+ [spellnames[19506]] = 254 -- Trueshot Aura
+ },
+ DRUID = {
+ [spellnames[24907]] = 102, -- Moonkin Aura
+ [spellnames[24932]] = 103, -- Leader of the Pack
+ [spellnames[33891]] = 105, -- Tree of Life
+ [spellnames[48438]] = 105 -- Wild Growth
+ }
+ }
+ end
+
+ if not spellsTable then
+ spellsTable = {
+ WARRIOR = {
+ [spellnames[12294]] = 71, -- Mortal Strike
+ [spellnames[46924]] = 71, -- Bladestorm
+ [spellnames[1680]] = 72, -- Whirlwind
+ [spellnames[23881]] = 72, -- Bloodthirst
+ },
+ PALADIN = {
+ [spellnames[20473]] = 65, -- Holy Shock
+ [spellnames[53563]] = 65, -- Beacon of Light
+ [spellnames[31935]] = 66, -- Avenger's Shield
+ [spellnames[35395]] = 70, -- Crusader Strike
+ [spellnames[53385]] = 70, -- Divine Storm
+ [spellnames[20066]] = 70 -- Repentance
+ },
+ ROGUE = {
+ [spellnames[1329]] = 259, -- Mutilate
+ [spellnames[51690]] = 260, -- Killing Spree
+ [spellnames[13877]] = 260, -- Blade Flurry
+ [spellnames[13750]] = 260, -- Adrenaline Rush
+ [spellnames[16511]] = 261, -- Hemorrhage
+ [spellnames[51713]] = 261 -- Shadow Dance
+ },
+ PRIEST = {
+ [spellnames[47540]] = 256, -- Penance
+ [spellnames[10060]] = 256, -- Power Infusion
+ [spellnames[33206]] = 256, -- Pain Suppression
+ [spellnames[34861]] = 257, -- Circle of Healing
+ [spellnames[15487]] = 258, -- Silence
+ [spellnames[34914]] = 258 -- Vampiric Touch
+ },
+ DEATHKNIGHT = {
+ [spellnames[45902]] = 250, -- Heart Strike
+ [spellnames[49143]] = 251, -- Frost Strike
+ [spellnames[49184]] = 251, -- Howling Blast
+ [spellnames[55090]] = 252 -- Scourge Strike
+ },
+ MAGE = {
+ [spellnames[44425]] = 62, -- Arcane Barrage
+ [spellnames[44457]] = 63, -- Living Bomb
+ [spellnames[31661]] = 63, -- Dragon's Breath
+ [spellnames[11113]] = 63, -- Blast Wave
+ [spellnames[44572]] = 64 -- Deep Freeze
+ },
+ WARLOCK = {
+ [spellnames[48181]] = 265, -- Haunt
+ [spellnames[30108]] = 265, -- Unstable Affliction
+ [spellnames[50769]] = 267, -- Chaos Bolt
+ [spellnames[30283]] = 267 -- Shadowfury
+ },
+ SHAMAN = {
+ [spellnames[51490]] = 262, -- Thunderstorm
+ [spellnames[16166]] = 262, -- Elemental Mastery
+ [spellnames[51533]] = 263, -- Feral Spirit
+ [spellnames[30823]] = 263, -- Shamanistic Rage
+ [spellnames[17364]] = 263, -- Stormstrike
+ [spellnames[61295]] = 264, -- Riptide
+ [spellnames[51886]] = 264 -- Cleanse Spirit
+ },
+ HUNTER = {
+ [spellnames[19577]] = 253, -- Intimidation
+ [spellnames[34490]] = 254, -- Silencing Shot
+ [spellnames[53209]] = 254, -- Chimera Shot
+ [spellnames[53301]] = 255, -- Explosive Shot
+ [spellnames[19386]] = 255 -- Wyvern Sting
+ },
+ DRUID = {
+ [spellnames[48505]] = 102, -- Starfall
+ [spellnames[33876]] = 103, -- Mangle (Cat)
+ [spellnames[33878]] = 104, -- Mangle (Bear)
+ [spellnames[18562]] = 105 -- Swiftmend
+ }
+ }
+ end
+ end
+
+ local function unit_guid_and_class(unit)
+ -- validate unit.
+ local guid = unit and not group_units[unit] and not group_pets[unit] and UnitIsPlayer(unit) and UnitGUID(unit)
+ if not guid or specsCache[guid] then return end -- invalid or already cached
+
+ -- validate class
+ local _, class = UnitClass(unit)
+ if not validclass[class] then return end
+
+ return guid, class
+ end
+
+ function mode:UNIT_AURA(units)
+ if not self.enabled then
+ Skada.UnregisterBucket(self, "UNIT_AURA")
+ return
+ end
+
+ for unit in pairs(units) do
+ local guid, class = unit_guid_and_class(unit)
+ if guid and class then
+ local i = 1
+ local name = UnitBuff(unit, i)
+ while name do
+ if aurasTable[class] and aurasTable[class][name] then
+ specsCache[guid] = aurasTable[class][name]
+ break -- found
+ end
+ i = i + 1
+ name = UnitBuff(unit, i)
+ end
+ end
+ end
+ end
+
+ function mode:UNIT_SPELLCAST_START(units)
+ if not self.enabled then
+ Skada.UnregisterBucket(self, "UNIT_SPELLCAST_START")
+ return
+ end
+
+ for unit in pairs(units) do
+ local guid, class = unit_guid_and_class(unit)
+ if guid and class then
+ local spell = UnitCastingInfo(unit)
+ if spell and spellsTable[class] and spellsTable[class][spell] then
+ specsCache[guid] = spellsTable[class][spell]
+ end
+ end
+ end
+ end
+
+ function mode:UNIT_SPELLCAST_SUCCEEDED(_, unit, spell)
+ if not self.enabled then
+ Skada.UnregisterEvent(self, "UNIT_SPELLCAST_SUCCEEDED")
+ return
+ end
+
+ local guid, class = unit_guid_and_class(unit)
+ if not guid or not spell then return end
+
+ if spellsTable[class] and spellsTable[class][spell] then
+ specsCache[guid] = spellsTable[class][spell]
+ end
+ end
+
+ function mode:CheckZone(_, current, previous)
+ self.enabled = current == "arena" or current == "pvp"
+
+ if current == previous then return end
+
+ specsCache = wipe(specsCache or {})
+
+ if self.enabled then
+ build_spell_list()
+ Skada.RegisterBucketEvent(self, "UNIT_AURA", 0.2)
+ Skada.RegisterBucketEvent(self, "UNIT_SPELLCAST_START", 0.2)
+ Skada.RegisterEvent(self, "UNIT_SPELLCAST_SUCCEEDED")
+ Skada.RegisterCallback(self, "Skada_GetEnemy", "GetEnemy")
+ else
+ Skada.UnregisterAllBuckets(self)
+ Skada.UnregisterEvent(self, "UNIT_SPELLCAST_SUCCEEDED")
+ Skada.UnregisterCallback(self, "Skada_GetEnemy")
+ end
+ end
+
+ function mode:GetEnemy(_, actor, set)
+ if not actor or actor.fake or not validclass[actor.class] then return end
+
+ actor.spec = actor.spec or specsCache[actor.id]
+
+ if actor.spec and (actor.role == nil or actor.role == "NONE") then
+ actor.role = specsRoles[actor.spec] or "DAMAGER"
+ end
+
+ actor.time = actor.time or 0
+ actor.last = actor.last or Skada._Time or GetTime()
+ end
+
+ function mode:OnEnable()
+ Skada.forPVP = true
+ specsCache = specsCache or {}
+ Skada.RegisterMessage(self, "ZONE_TYPE_CHANGED", "CheckZone")
+ Skada.RegisterMessage(self, "COMBAT_PVP_START", "CheckZone")
+ Skada.RegisterMessage(self, "COMBAT_PVP_END", "CheckZone")
+ end
+
+ function mode:OnDisable()
+ Skada.forPVP = nil
+ Skada.UnregisterAllBuckets(self)
+ Skada.UnregisterAllEvents(self)
+ Skada.UnregisterAllMessages(self)
+ Skada.UnregisterAllCallbacks(self)
+ end
+
+ ---------------------------------------------------------------------------
+
+ function mode:OnInitialize()
+ if P.modules.arena then
+ P.modules.arena = nil
+ end
+
+ -- add custom colors to tweaks
+ O.tweaks.args.advanced.args.colors.args.arean = {
+ type = "group",
+ name = L["Arena Teams"],
+ order = 40,
+ hidden = O.tweaks.args.advanced.args.colors.args.custom.disabled,
+ disabled = O.tweaks.args.advanced.args.colors.args.custom.disabled,
+ args = {
+ ARENA_GOLD = {
+ type = "color",
+ name = L["ARENA_GOLD"],
+ desc = format(L["Color for %s."], L["ARENA_GOLD"])
+ },
+ ARENA_GREEN = {
+ type = "color",
+ name = L["ARENA_GREEN"],
+ desc = format(L["Color for %s."], L["ARENA_GREEN"])
+ }
+ }
+ }
+ end
+
+ ---------------------------------------------------------------------------
+
+ -- arena custom colors
+ local classcolors = Skada.classcolors or {}
+ Skada.classcolors = classcolors
+
+ classcolors.ARENA_GOLD = {r = 1, g = 0.82, b = 0, colorStr = "ffffd100"}
+ classcolors.ARENA_GREEN = {r = 0.1, g = 1, b = 0.1, colorStr = "ff19ff19"}
+
+ -- purple color instead of green for color blind mode.
+ if GetCVar("colorblindMode") == "1" then
+ classcolors.ARENA_GREEN.r = 0.686
+ classcolors.ARENA_GREEN.g = 0.384
+ classcolors.ARENA_GREEN.b = 1
+ classcolors.ARENA_GREEN.colorStr = "ffae61ff"
+ end
+
+ -- localize arena team colors (just in case)
+ L["ARENA_GREEN"] = L["Green Team"]
+ L["ARENA_GOLD"] = L["Gold Team"]
+end)
diff --git a/Skada/Modules/Resurrects.lua b/Skada/Modules/Resurrects.lua
new file mode 100644
index 0000000..c7afb51
--- /dev/null
+++ b/Skada/Modules/Resurrects.lua
@@ -0,0 +1,147 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Resurrects", function(L, P, _, C)
+ local mode = Skada:NewModule("Resurrects")
+ local mode_target = mode:NewModule("Target List")
+
+ local pairs, format, uformat = pairs, string.format, Private.uformat
+ local new, clear = Private.newTable, Private.clearTable
+ local classfmt = Skada.classcolors.format
+ local ress_spells = Skada.ress_spells
+ local get_actor_ress_targets = nil
+ local mode_cols = nil
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local function log_resurrect(set, actorname, actorid, actorflags, dstName)
+ local actor = Skada:GetActor(set, actorname, actorid, actorflags)
+ if not actor then return end
+
+ actor.ress = (actor.ress or 0) + 1
+ set.ress = (set.ress or 0) + 1
+
+ -- saving this to total set may become a memory hog deluxe.
+ if (set == Skada.total and not P.totalidc) or not dstName then return end
+ actor.resstargets = actor.resstargets or {}
+ actor.resstargets[dstName] = (actor.resstargets[dstName] or 0) + 1
+ end
+
+ local function spell_resurrect(t)
+ if t.spellid and (t.event == "SPELL_RESURRECT" or ress_spells[t.spellid]) then
+ local dstName = (t.event == "SPELL_RESURRECT") and t.dstName or t.srcName
+ Skada:DispatchSets(log_resurrect, t.srcName, t.srcGUID, t.srcFlags, dstName)
+ end
+ end
+
+ function mode_target:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's targets"], classfmt(class, label))
+ end
+
+ function mode_target:Update(win, set)
+ win.title = uformat(L["%s's targets"], classfmt(win.actorclass, win.actorname))
+ if not set or not win.actorname then return end
+
+ local targets, total, actor = get_actor_ress_targets(set, win.actorname, win.actorid)
+ if not targets or not actor or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for targetname, target in pairs(targets) do
+ nr = nr + 1
+
+ local d = win:actor(nr, target, target.enemy, targetname)
+ d.value = target.count
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Resurrects"], L[win.class]) or L["Resurrects"]
+
+ local total = set and set:GetTotal(win.class, nil, "ress")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.ress then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.ress
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ if not set then return end
+ return set:GetTotal(win and win.class, nil, "ress") or 0
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ valuesort = true,
+ filterclass = true,
+ click1 = mode_target,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\spell_holy_resurrection]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ -- no total click.
+ mode_target.nototal = true
+
+ Skada:RegisterForCL(spell_resurrect, {src_is_not_interesting = true, dst_is_interesting_nopets = true}, "SPELL_RESURRECT")
+ Skada:RegisterForCL(spell_resurrect, {src_is_interesting = true, dst_is_not_interesting = true}, "SPELL_CAST_SUCCESS")
+
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada:RemoveMode(self)
+ end
+
+ function mode:AddToTooltip(set, tooltip)
+ if set.ress and set.ress > 0 then
+ tooltip:AddDoubleLine(L["Resurrects"], set.ress, 1, 1, 1)
+ end
+ end
+
+ ---------------------------------------------------------------------------
+
+ get_actor_ress_targets = function(self, name, id, tbl)
+ local actor = self:GetActor(name, id)
+ local total = actor and actor.ress
+ local targets = total and actor.resstargets
+ if not targets then return end
+
+ tbl = clear(tbl or C)
+ for targetname, count in pairs(targets) do
+ local t = new()
+ t.count = count
+ self:_fill_actor_table(t, targetname)
+ tbl[targetname] = t
+ end
+ return tbl, total, actor
+ end
+end)
diff --git a/Skada/Modules/Spellcast.lua b/Skada/Modules/Spellcast.lua
new file mode 100644
index 0000000..330d20d
--- /dev/null
+++ b/Skada/Modules/Spellcast.lua
@@ -0,0 +1,155 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Casts", function(L, P)
+ local mode = Skada:NewModule("Casts")
+ local mode_spell = mode:NewModule("Spell List")
+ local mode_cols = nil
+
+ local pairs, wipe = pairs, wipe
+ local format, uformat = string.format, Private.uformat
+ local classfmt = Skada.classcolors.format
+
+ local function format_valuetext(d, total, metadata, subview)
+ d.valuetext = Skada:FormatValueCols(
+ mode_cols.Count and d.value,
+ mode_cols[subview and "sPercent" or "Percent"] and Skada:FormatPercent(d.value, total)
+ )
+
+ if metadata and d.value > metadata.maxvalue then
+ metadata.maxvalue = d.value
+ end
+ end
+
+ local cast = {}
+ local function log_spellcast(set)
+ local actor = Skada:GetActor(set, cast.actorname, cast.actorid, cast.actorflags)
+ if not actor then return end
+
+ set.cast = (set.cast or 0) + 1
+ actor.cast = (actor.cast or 0) + 1
+
+ local spellid = (set ~= Skada.total or P.totalidc) and cast.spellid
+ if not spellid then return end
+
+ actor.castspells = actor.castspells or {}
+ actor.castspells[spellid] = (actor.castspells[spellid] or 0) + 1
+ end
+
+ local function spell_cast(t)
+ if not t.spellstring then return end
+
+ cast.actorid = t.srcGUID
+ cast.actorname = t.srcName
+ cast.actorflags = t.srcFlags
+ cast.spellid = t.spellstring
+
+ Skada:FixPets(cast)
+ Skada:DispatchSets(log_spellcast)
+ end
+
+ function mode_spell:Enter(win, id, label, class)
+ win.actorid, win.actorname, win.actorclass = id, label, class
+ win.title = format(L["%s's spells"], classfmt(class, label))
+ end
+
+ function mode_spell:Update(win, set)
+ win.title = uformat(L["%s's spells"], classfmt(win.actorclass, win.actorname))
+ if not win.actorname then return end
+
+ local actor = set:GetActor(win.actorname, win.actorid)
+ local total = actor and actor.cast
+ local spells = total and total > 0 and actor.castspells
+
+ if not spells then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for spellid, cast in pairs(spells) do
+ nr = nr + 1
+
+ local d = win:spell(nr, spellid)
+ d.value = cast
+ format_valuetext(d, total, win.metadata, true)
+ end
+ end
+
+ function mode:Update(win, set)
+ win.title = win.class and format("%s (%s)", L["Casts"], L[win.class]) or L["Casts"]
+
+ local total = set:GetTotal(win.class, nil, "cast")
+ if not total or total == 0 then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ local actors = set.actors
+ for actorname, actor in pairs(actors) do
+ if win:show_actor(actor, set, true) and actor.cast then
+ nr = nr + 1
+
+ local d = win:actor(nr, actor, actor.enemy, actorname)
+ d.value = actor.cast
+ format_valuetext(d, total, win.metadata)
+ end
+ end
+ end
+
+ function mode:GetSetSummary(set, win)
+ local value = set and set:GetTotal(win and win.class, nil, "cast")
+ return value, Skada:FormatNumber(value)
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ showspots = true,
+ filterclass = true,
+ click1 = mode_spell,
+ columns = {Count = true, Percent = false, sPercent = false},
+ icon = [[Interface\ICONS\spell_frost_frostbolt02]]
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada:RegisterForCL(spell_cast, {src_is_interesting = true}, "SPELL_CAST_SUCCESS")
+
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+ Skada:AddMode(self)
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ function mode:CombatLeave()
+ wipe(cast)
+ end
+
+ ---------------------------------------------------------------------------
+
+ local actorPrototype = Skada.actorPrototype
+ local spellnames = Skada.spellnames
+ local cast_string = "%s (\124cffffd100?\124r)"
+
+ function actorPrototype:GetSpellCast(spellid)
+ if spellid and self.castspells then
+ if self.castspells[spellid] then
+ return self.castspells[spellid]
+ end
+
+ local spellname = spellnames[spellid]
+ for spellstring, cast in pairs(self.castspells) do
+ local name = spellnames[spellstring]
+ if spellname == name then
+ return format(cast_string, cast)
+ end
+ end
+ end
+ return format(cast_string, "")
+ end
+end)
diff --git a/Skada/Modules/Threat.lua b/Skada/Modules/Threat.lua
new file mode 100644
index 0000000..a0eafe3
--- /dev/null
+++ b/Skada/Modules/Threat.lua
@@ -0,0 +1,638 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Threat", function(L, P, _, _, M, O)
+ local mode = Skada:NewModule("Threat")
+
+ local format, max, select = string.format, math.max, select
+ local UnitExists, UnitName = UnitExists, UnitName
+ local UnitDetailedThreatSituation, InCombatLockdown = UnitDetailedThreatSituation, InCombatLockdown
+ local GroupIterator, GetUnitRole, GetUnitSpec = Skada.GroupIterator, Skada.GetUnitRole, Skada.GetUnitSpec
+ local PlaySoundFile = PlaySoundFile
+ local new, del, clear = Private.newTable, Private.delTable, Private.clearTable
+ local mode_cols = nil
+
+ local aggro_icon = [[Interface\ICONS\ability_physical_taunt]]
+
+ do
+ local CheckInteractDistance, ItemRefTooltip = CheckInteractDistance, ItemRefTooltip
+ local GetItemInfo, IsItemInRange = GetItemInfo, IsItemInRange
+ local UnitGUID, UnitClass = UnitGUID, UnitClass
+ local UnitFullName, guidToClass = Private.UnitFullName, Private.guidToClass
+ local nr, max_threat, aggro_coef, my_percent = 0, 0, 1.1, nil
+ local last_warn, last_time = Skada._time, 0
+ local threat_table, we_should_warn = {}, false
+ local tank_threat, ruby_acorn, queried
+
+ -- bar colors
+ local aggro_color = RED_FONT_COLOR
+ local negative_color = GRAY_FONT_COLOR
+
+ local function add_to_threattable(unit, owner, target, win)
+ if unit == "AGGRO" then
+ if not mode.db.showAggroBar or not tank_threat or tank_threat == 0 then return end
+
+ nr = nr + 1
+ local d = win:nr(nr)
+
+ d.id = "AGGRO"
+ d.label = L["> Pull Aggro <"]
+ d.icon = aggro_icon
+ d.color = aggro_color
+ d.ignore = true
+ d.changed = nil
+ d.isTanking = nil
+
+ ruby_acorn = ruby_acorn or GetItemInfo(37727)
+ if ruby_acorn then
+ aggro_coef = (IsItemInRange(37727, target) == 1 and 1.1 or 1.3)
+ else
+ aggro_coef = (CheckInteractDistance(target, 3) and 1.1 or 1.3)
+ if not queried and not ItemRefTooltip:IsVisible() then
+ ItemRefTooltip:SetHyperlink("item:37727")
+ queried = true
+ end
+ end
+
+ d.threat = tank_threat * aggro_coef
+ d.value = max_threat * aggro_coef
+
+ return
+ end
+
+ -- ignore pets
+ if mode.db.ignorePets and owner then return end
+
+ local actorname = UnitFullName(unit, owner, true)
+ local actor = threat_table[actorname]
+
+ if not actor then
+ actor = new()
+ actor.unit = unit
+
+ local guid = UnitGUID(unit)
+ actor.id = guid
+ if owner ~= nil then
+ actor.class = "PET"
+ else
+ actor.class = guidToClass[guid] or select(2, UnitClass(unit))
+ actor.spec = GetUnitSpec(guid)
+ actor.role = GetUnitRole(guid)
+ end
+
+ -- cache the actor.
+ threat_table[actorname] = actor
+ end
+
+ if not actor or not actor.unit then return end
+
+ local isTanking, _, threatpct, _, threatvalue = UnitDetailedThreatSituation(actor.unit, target)
+ if threatvalue then
+ nr = nr + 1
+ local d = win:nr(nr)
+
+ d.id = actor.id or actorname
+ d.label = actorname
+ d.text = actor.id and Skada:FormatName(actorname, actor.id)
+
+ d.class = actor.class
+ d.role = actor.role
+ d.spec = actor.spec
+ d.isTanking = isTanking
+
+ if mode.db.rawvalue then
+ if threatvalue < 0 then
+ d.value = threatvalue + 410065408
+ d.threat = threatvalue + 410065408
+ d.color = negative_color
+ d.changed = true
+ else
+ d.value = threatvalue
+ d.threat = threatvalue
+ d.color = nil
+ d.changed = nil
+ end
+ elseif threatpct then
+ d.value = threatpct
+ d.threat = threatvalue
+ end
+
+ if d.value > max_threat then
+ max_threat = d.value
+ end
+
+ if isTanking then
+ tank_threat = d.threat
+ end
+ end
+ end
+
+ local function format_threatvalue(value)
+ if value == nil then
+ return "0"
+ elseif value >= 100000 then
+ return format("%2.1fk", value * 1e-05)
+ else
+ return format("%d", value * 0.01)
+ end
+ end
+
+ local function get_tps(threatvalue)
+ return Skada.current and format_threatvalue(threatvalue / Skada.current:GetTime()) or "0"
+ end
+
+ function mode:Update(win, set)
+ win.title = L["Threat"]
+
+ if not Skada.inCombat then return end -- not in combat
+ if not self.unitID or not UnitExists(self.unitID) then return end -- nothing targeted
+
+ self.unitName = self.unitName or UnitName(self.unitID)
+ win.title = self.unitName or win.title
+
+ -- reset stuff & check group
+ max_threat, nr = 0, 0
+ GroupIterator(add_to_threattable, self.unitID, win)
+ if max_threat > 0 and self.db.showAggroBar then
+ add_to_threattable("AGGRO", nil, self.unitID, win)
+ end
+
+ -- nothing was added.
+ if nr == 0 then return end
+
+ -- If we are going by raw threat we got the max threat from above; otherwise it's always 100.
+ max_threat = self.db.rawvalue and max_threat or 100
+
+ if win.metadata then
+ win.metadata.maxvalue = max_threat
+ end
+
+ we_should_warn = false -- reset warning state
+
+ -- We now have a a complete threat table.
+ -- Now we need to add valuetext.
+ for i = 1, #win.dataset do
+ local data = win.dataset[i]
+ if data and data.id == "AGGRO" then
+ if self.db.showAggroBar and tank_threat and tank_threat > 0 then
+ data.valuetext = Skada:FormatValueCols(
+ mode_cols.Threat and format_threatvalue(data.threat),
+ mode_cols.TPS and get_tps(data.threat),
+ mode_cols.Percent and Skada:FormatPercent(data.value, max(0.000001, max_threat))
+ )
+
+ if win.metadata then
+ win.metadata.maxvalue = self.db.rawvalue and data.threat or data.value
+ end
+ else
+ data.id = nil
+ end
+ elseif data and data.id then
+ if data.threat and data.threat > 0 then
+ -- Warn if this is ourselves and we are over the treshold.
+ local percent = 100 * data.value / max(0.000001, max_threat)
+ if data.id == Skada.userGUID then
+ my_percent = percent
+ if self.db.threshold and self.db.threshold < percent and (not data.isTanking or not self.db.notankwarnings) then
+ we_should_warn = (data.color == nil)
+ end
+ end
+
+ data.valuetext = Skada:FormatValueCols(
+ mode_cols.Threat and format_threatvalue(data.threat),
+ mode_cols.TPS and get_tps(data.threat),
+ mode_cols.Percent and Skada:FormatPercent(percent)
+ )
+ else
+ data.id = nil
+ end
+ end
+ end
+
+ -- Warn
+ last_time = Skada._time or time()
+ if we_should_warn and last_time - last_warn > (self.db.frequency or 2) then
+ self:Warn(self.db.sound, self.db.flash, self.db.shake, my_percent and format(L["%d%% Threat"], my_percent) or L["High Threat"])
+ last_warn = last_time
+ end
+ end
+
+ function mode:CombatLeave()
+ tank_threat = nil
+ clear(threat_table)
+ self.unitID, self.unitName = nil, nil
+ end
+ end
+
+ -- Shamelessly copied from Omen - thanks!
+ local function flasher_OnShow(self)
+ self.elapsed = 0
+ self:SetAlpha(0)
+ end
+
+ local function flasher_OnUpdate(self, elapsed)
+ elapsed = self.elapsed + elapsed
+ if elapsed < 2.6 then
+ local alpha = elapsed % 1.3
+ if alpha < 0.15 then
+ self:SetAlpha(alpha / 0.15)
+ elseif alpha < 0.9 then
+ self:SetAlpha(max(0, 1 - (alpha - 0.15) / 0.6))
+ else
+ self:SetAlpha(0)
+ end
+ else
+ self:Hide()
+ end
+ self.elapsed = elapsed
+ end
+
+ function mode:Flash()
+ if not self.FlashFrame then
+ local flasher = CreateFrame("Frame", "SkadaThreatFlashFrame")
+ flasher:SetToplevel(true)
+ flasher:SetFrameStrata("FULLSCREEN_DIALOG")
+ flasher:SetAllPoints(UIParent)
+ flasher:EnableMouse(false)
+ flasher:Hide()
+ flasher.texture = flasher:CreateTexture(nil, "BACKGROUND")
+ flasher.texture:SetTexture([[Interface\FullScreenTextures\LowHealth]])
+ flasher.texture:SetAllPoints(UIParent)
+ flasher.texture:SetBlendMode("ADD")
+ flasher:SetScript("OnShow", flasher_OnShow)
+ flasher:SetScript("OnUpdate", flasher_OnUpdate)
+ self.FlashFrame = flasher
+ end
+
+ self.FlashFrame:Show()
+ end
+
+ -- Shamelessly copied from Omen (which copied from BigWigs) - thanks!
+ local function shaker_OnShow(self)
+ -- Store old worldframe positions, we need them all, people have frame modifiers for it
+ if not self.originalPoints then
+ self.originalPoints = {}
+ for i = 1, WorldFrame:GetNumPoints() do
+ self.originalPoints[#self.originalPoints + 1] = {WorldFrame:GetPoint(i)}
+ end
+ end
+ self.elapsed = 0
+ end
+
+ local function shaker_OnUpdate(self, elapsed)
+ elapsed = self.elapsed + elapsed
+ local x, y = 0, 0 -- Resets to original position if we're supposed to stop.
+ if elapsed >= 0.8 then
+ self:Hide()
+ else
+ x, y = random(-8, 8), random(-8, 8)
+ end
+ if WorldFrame:IsProtected() and InCombatLockdown() then
+ if not self.fail then
+ self.fail = true
+ end
+ self:Hide()
+ else
+ WorldFrame:ClearAllPoints()
+ for i = 1, #self.originalPoints do
+ local v = self.originalPoints[i]
+ WorldFrame:SetPoint(v[1], v[2], v[3], v[4] + x, v[5] + y)
+ end
+ end
+ self.elapsed = elapsed
+ end
+
+ function mode:Shake()
+ local shaker = self.ShakerFrame
+ if not shaker then
+ shaker = CreateFrame("Frame", "SkadaThreatShaker", UIParent)
+ shaker:Hide()
+ shaker:SetScript("OnShow", shaker_OnShow)
+ shaker:SetScript("OnUpdate", shaker_OnUpdate)
+ self.ShakerFrame = shaker
+ end
+
+ shaker:Show()
+ end
+
+ -- prints warning messages
+ do
+ local CombatText_StandardScroll = CombatText_StandardScroll
+ local RaidNotice_AddMessage = RaidNotice_AddMessage
+ local UIErrorsFrame = UIErrorsFrame
+ local WrapTextInColorCode = Private.WrapTextInColorCode
+ local RGBPercToHex = Private.RGBPercToHex
+ local white = HIGHLIGHT_FONT_COLOR
+
+ local handlers = {
+ -- Default
+ [1] = function(text, r, g, b, font, size, outline, sticky)
+ if tostring(SHOW_COMBAT_TEXT) ~= "0" then
+ CombatText_AddMessage(text, CombatText_StandardScroll, r, g, b, sticky and "crit" or nil, false)
+ else
+ UIErrorsFrame:AddMessage(text, r, g, b, 1.0)
+ end
+ end,
+ -- Raid Warnings
+ [2] = function(text, r, g, b)
+ if r or g or b then
+ text = WrapTextInColorCode(text, RGBPercToHex(r or 0, g or 0, b or 0, true))
+ end
+ RaidNotice_AddMessage(RaidWarningFrame, text, white)
+ end,
+ -- UIError Frame
+ [3] = function(text, r, g, b)
+ UIErrorsFrame:AddMessage(text, r, g, b, 1.0)
+ end,
+ -- Chat Frame
+ [4] = function(text, r, g, b)
+ DEFAULT_CHAT_FRAME:AddMessage(text, r, g, b)
+ end
+ }
+
+ function mode:Pour(text, r, g, b, ...)
+ local func = handlers[self.db.output or 4]
+ func(text, r or 1, g or 1, b or 1, ...)
+ end
+ end
+
+ -- Shamelessly copied from Omen - thanks!
+ function mode:Warn(sound, flash, shake, message)
+ if sound then
+ PlaySoundFile(Skada:MediaFetch("sound", self.db.soundfile), "Master")
+ end
+ if flash then
+ self:Flash()
+ end
+ if shake then
+ self:Shake()
+ end
+ if self.db.message and message then
+ self:Pour(message, 1, 0, 0, nil, 24, "OUTLINE", true)
+ end
+ end
+
+ do
+ local opts = {
+ type = "group",
+ name = mode.localeName,
+ desc = format(L["Options for %s."], mode.localeName),
+ get = function(i)
+ return mode.db[i[#i]]
+ end,
+ set = function(i, val)
+ mode.db[i[#i]] = val
+ mode:ApplySettings()
+ end,
+ args = {
+ header = {
+ type = "description",
+ name = mode.localeName,
+ fontSize = "large",
+ image = aggro_icon,
+ imageWidth = 18,
+ imageHeight = 18,
+ imageCoords = Skada.cropTable,
+ width = "full",
+ order = 0
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 1
+ },
+ warning = {
+ type = "group",
+ name = L["Threat Warning"],
+ inline = true,
+ order = 10,
+ args = {
+ flash = {
+ type = "toggle",
+ name = L["Flash Screen"],
+ desc = L["This will cause the screen to flash as a threat warning."],
+ order = 10
+ },
+ shake = {
+ type = "toggle",
+ name = L["Shake Screen"],
+ desc = L["This will cause the screen to shake as a threat warning."],
+ order = 20
+ },
+ message = {
+ type = "toggle",
+ name = L["Warning Message"],
+ desc = L["Print a message to screen when you accumulate too much threat."],
+ order = 30
+ },
+ sound = {
+ type = "toggle",
+ name = L["Play sound"],
+ desc = L["This will play a sound as a threat warning."],
+ order = 40
+ },
+ output = {
+ type = "select",
+ name = L["Message Output"],
+ desc = L["Choose where warning messages should be displayed."],
+ order = 50,
+ width = "double",
+ values = {L["Default"], L["Raid Warning"], L["Blizzard Error Frame"], L["Chat Frame"]},
+ hidden = function()
+ return not mode.db.message
+ end,
+ disabled = function()
+ return not mode.db.message
+ end
+ },
+ soundfile = {
+ type = "select",
+ name = L["Threat sound"],
+ desc = L["opt_threat_soundfile_desc"],
+ order = 60,
+ width = "double",
+ dialogControl = "LSM30_Sound",
+ values = Skada:MediaList("sound"),
+ hidden = function()
+ return not mode.db.sound
+ end,
+ disabled = function()
+ return not mode.db.sound
+ end
+ },
+ frequency = {
+ type = "range",
+ name = L["Warning Frequency"],
+ order = 70,
+ min = 2,
+ max = 15,
+ step = 1
+ },
+ threshold = {
+ type = "range",
+ name = L["Threat Threshold"],
+ desc = L["opt_threat_threshold_desc"],
+ order = 80,
+ min = 60,
+ max = 130,
+ step = 1
+ }
+ }
+ },
+ rawvalue = {
+ type = "toggle",
+ name = L["Show raw threat"],
+ desc = L["opt_threat_rawvalue_desc"],
+ order = 20
+ },
+ focustarget = {
+ type = "toggle",
+ name = L["Use focus target"],
+ desc = L["opt_threat_focustarget_desc"],
+ order = 30
+ },
+ notankwarnings = {
+ type = "toggle",
+ name = L["Disable while tanking"],
+ desc = L["opt_threat_notankwarnings_desc"],
+ order = 40
+ },
+ ignorePets = {
+ type = "toggle",
+ name = L["Ignore Pets"],
+ desc = L["opt_threat_ignorepets_desc"],
+ order = 50
+ },
+ showAggroBar = {
+ type = "toggle",
+ name = L["Show Pull Aggro Bar"],
+ desc = L["opt_threat_showaggrobar_desc"],
+ order = 60
+ },
+ sep = {
+ type = "description",
+ name = " ",
+ width = "full",
+ order = 90
+ },
+ test = {
+ type = "execute",
+ name = L["Test Warnings"],
+ width = "double",
+ order = 100,
+ func = function()
+ mode:Warn(mode.db.sound, mode.db.flash, mode.db.shake, mode.db.message and L["Test Warnings"])
+ end
+ }
+ }
+ }
+
+ function mode:OnInitialize()
+ if not M.threat then
+ M.threat = {
+ sound = true,
+ flash = true,
+ output = 1,
+ frequency = 2,
+ threshold = 90,
+ soundfile = "Fel Nova",
+ notankwarnings = true,
+ ignorePets = true,
+ showAggroBar = true
+ }
+ else
+ M.threat.sinkOptions = nil -- old stuff
+ M.threat.output = M.threat.output or 1
+ end
+
+ self.db = M.threat
+ O.modules.args.threat = opts
+ end
+ end
+
+ do
+ local function add_threat_feed()
+ if Skada.current and UnitExists("target") then
+ local _, _, threatpct = UnitDetailedThreatSituation("player", "target")
+ return threatpct and Skada:FormatPercent(threatpct)
+ end
+ end
+
+ function mode:OnEnable()
+ self.metadata = {
+ wipestale = true,
+ columns = {Threat = true, TPS = false, Percent = true},
+ notitleset = true, -- ignore title set
+ icon = aggro_icon
+ }
+
+ mode_cols = self.metadata.columns
+
+ Skada.RegisterBucketEvent(self, "UNIT_THREAT_LIST_UPDATE", 0.1, "SetUnit")
+ Skada.RegisterBucketEvent(self, "UNIT_THREAT_SITUATION_UPDATE", 0.1, "SetUnit")
+ Skada.RegisterBucketEvent(self, "PLAYER_TARGET_CHANGED", 0.1, "SetUnit")
+
+ Skada.RegisterCallback(self, "Skada_ApplySettings", "ApplySettings")
+ Skada.RegisterMessage(self, "COMBAT_PLAYER_LEAVE", "CombatLeave")
+
+ Skada:AddFeed(L["Threat: Personal Threat"], add_threat_feed)
+ Skada:AddMode(self)
+ end
+ end
+
+ function mode:OnDisable()
+ Skada.UnregisterAllBuckets(self)
+ Skada.UnregisterAllCallbacks(self)
+ Skada.UnregisterAllMessages(self)
+
+ Skada:RemoveFeed(L["Threat: Personal Threat"])
+ Skada:RemoveMode(self)
+ end
+
+ function mode:ApplySettings()
+ self.db = self.db or M.threat
+ if self.db.focustarget then
+ Skada.RegisterEvent(self, "UNIT_TARGET")
+ else
+ Skada.UnregisterEvent(self, "UNIT_TARGET")
+ end
+ end
+
+ do
+ local UnitIsPlayer = UnitIsPlayer
+ local UnitCanAttack = UnitCanAttack
+ local UnitHealth = UnitHealth
+
+ local throttleFrame = CreateFrame("Frame")
+ local threatUnits = {"focus", "focustarget", "target", "targettarget"}
+
+ local function find_threat_unit()
+ mode.unitID, mode.unitName = nil, nil -- reset
+
+ local n = mode.db.focustarget and 1 or 3
+ for i = n, 4 do
+ local unit = threatUnits[i]
+ if UnitExists(unit) and not UnitIsPlayer(unit) and UnitCanAttack("player", unit) and UnitHealth(unit) > 0 then
+ mode.unitID = unit
+ mode.unitName = UnitName(unit)
+ break
+ end
+ end
+
+ throttleFrame:Hide()
+ end
+
+ throttleFrame:Hide()
+ throttleFrame:SetScript("OnUpdate", find_threat_unit)
+
+ function mode:SetUnit()
+ throttleFrame:Show()
+ end
+
+ function mode:UNIT_TARGET(_, unit)
+ if unit == "focus" and self.db.focustarget and self.unitID == "focustarget" then
+ throttleFrame:Show()
+ end
+ end
+ end
+end)
diff --git a/Skada/Modules/Tweaks.lua b/Skada/Modules/Tweaks.lua
new file mode 100644
index 0000000..506d2fb
--- /dev/null
+++ b/Skada/Modules/Tweaks.lua
@@ -0,0 +1,266 @@
+local _, Skada = ...
+local Private = Skada.Private
+Skada:RegisterModule("Tweaks", function(L, P, _, _, _, O)
+ local mode = Skada:NewModule("Tweaks", "AceHook-3.0")
+
+ local format = string.format
+ local GetSpellInfo = Private.SpellInfo or GetSpellInfo
+ local channel_events, fofrostmourne
+
+ ---------------------------------------------------------------------------
+ -- OnCombatEvent Hook
+
+ do
+ local Skada_OnCombatEvent = Skada.OnCombatEvent
+ function Skada:OnCombatEvent(args)
+ -- The Lich King fight & Fury of Frostmourne
+ if args.spellid == 72350 or args.spellname == fofrostmourne then
+ if self.current and not self.current.success then
+ self.current.success = true
+ self:SendMessage("COMBAT_BOSS_DEFEATED", self.current)
+
+ if self.tempsets then -- phases
+ for i = 1, #self.tempsets do
+ local set = self.tempsets[i]
+ if set and not set.success then
+ set.success = true
+ self:SendMessage("COMBAT_BOSS_DEFEATED", set)
+ end
+ end
+ end
+ end
+ -- ignore the spell
+ if P.fofrostmourne then return end
+ end
+
+ return Skada_OnCombatEvent(self, args)
+ end
+ end
+
+ ---------------------------------------------------------------------------
+ -- DPSLink filter
+
+ do
+ local find, gsub, split, tonumber = string.find, string.gsub, string.split, tonumber
+ local ShowUIPanel, GetTime = ShowUIPanel, GetTime
+ local ItemRefTooltip = ItemRefTooltip
+
+ local firstlines = {
+ -- Skada
+ "^Sh?kada report on (.+) for (.+), (.+) to (.+):$", -- enUS
+ "^Sh?kada: (.+) for (.+):$", -- enUS
+ "^Sh?kada: (.+) für (.+):$", -- deDE
+ "^Sh?kada: (.+) por (.+):$", -- esES/ptBR
+ "^Sh?kada: (.+) pour (.+):$", -- frFR
+ "^Sh?kada: (.+) для (.+):$", -- ruRU
+ "^Sh?kada:(.+)來自(.+):$", -- zhTW
+ "^Sh?kada报告(.+)的(.+), (.+)到(.+):$", -- zhCN
+ "^Sh?kada报告(.+)的(.+):$", -- zhCN
+ "^(.+) - (.+)의 Sh?kada 보고, (.+) ~ (.+):$", -- koKR
+ "^(.+)的報告來自(.+),從(.+)到(.+):$", -- zhTW
+ "^Отчёт Sh?kada: (.+), с (.+):$", -- ruRU
+ "^(.+) 의 Sh?kada 보고 (.+):$", -- koKR
+ "^Sh?kada: (.+) for (.+), (.+) - (.+):$", -- Better Skada support player details
+ -- TinyDPS
+ "^(.+) Done for (.+)$", -- TinyDPS enUS
+ "^(.+) für (.+)$", -- TinyDPS deDE
+ "데미지량 -(.+)$", -- TinyDPS koKR
+ "힐량 -(.+)$", -- TinyDPS koKR
+ "Урон:(.+)$", -- TinyDPS ruRU
+ "Исцеление:(.+)$", -- TinyDPS ruRU
+ -- Other damage meters.
+ "^Details!: (.+)$", -- Details!
+ "^Details! Report for (.+)$", -- Details!
+ "^Recount - (.+)$", -- Recount
+ "^# (.+) - (.+)$", -- Numeration
+ "alDamageMeter : (.+)$" -- alDamageMeter
+ }
+
+ local nextlines = {
+ "^(%d+)%. (.+)$", -- Recount, Details! and Skada
+ "^ (%d+). (.+)$", -- Skada (default)
+ "^[+-]?%d+..+$", -- Skada (deaths) (credits: @ridepad)
+ "^(.+)%s%s%s(.+)$", -- Additional Skada details
+ "^.*%%%)$", --Skada player details
+ "^[+-]%d+.%d", -- Numeration deathlog details
+ "^(%d+). (.+):(.+)(%d+)(.+)(%d+)%%(.+)%((%d+)%)$" -- TinyDPS
+ }
+
+ channel_events = {
+ "CHAT_MSG_CHANNEL",
+ "CHAT_MSG_GUILD",
+ "CHAT_MSG_OFFICER",
+ "CHAT_MSG_PARTY",
+ "CHAT_MSG_PARTY_LEADER",
+ "CHAT_MSG_RAID",
+ "CHAT_MSG_RAID_LEADER",
+ "CHAT_MSG_SAY",
+ "CHAT_MSG_WHISPER",
+ "CHAT_MSG_WHISPER_INFORM",
+ "CHAT_MSG_BN_WHISPER",
+ "CHAT_MSG_BN_WHISPER_INFORM",
+ "CHAT_MSG_YELL"
+ }
+
+ local meters = {}
+
+ local function filter_chat_line(event, source, msg, ...)
+ for i = 1, #firstlines do
+ local line = firstlines[i]
+ if line and msg:match(line) then
+ local newID = 0
+ local curtime = GetTime()
+ if find(msg, "\124cff(.+)\124r") then
+ msg = gsub(msg, "\124cff%w%w%w%w%w%w", "")
+ msg = gsub(msg, "\124r", "")
+ end
+ for j = 1, #meters do
+ local meter = meters[j]
+ local elapsed = meter and (curtime - meter.time) or 0
+ if meter and meter.src == source and meter.evt == event and elapsed < 1 then
+ newID = j
+ return true, true, format("\124HSKSP:%1$d\124h\124cffffff00[%2$s]\124r\124h", newID or 0, msg or "nil")
+ end
+ end
+ meters[#meters + 1] = {src = source, evt = event, time = curtime, data = {}, title = msg}
+ for j = 1, #meters do
+ local meter = meters[j]
+ if meter and meter.src == source and meter.evt == event and meter.time == curtime then
+ newID = j
+ end
+ end
+ return true, true, format("\124HSKSP:%1$d\124h\124cffffff00[%2$s]\124r\124h", newID or 0, msg or "nil")
+ end
+ end
+
+ for i = 1, #nextlines do
+ local line = nextlines[i]
+ if line and msg:match(line) then
+ local curtime = GetTime()
+ for j = 1, #meters do
+ local meter = meters[j]
+ local elapsed = meter and (curtime - meter.time) or 0
+ if meter and meter.src == source and meter.evt == event and elapsed < 1 then
+ local toInsert = true
+ for k = 1, #meter.data do
+ local b = meter.data[k]
+ if b and b == msg then
+ toInsert = false
+ end
+ end
+ if toInsert then
+ meter.data[#meter.data + 1] = msg
+ end
+ return true, false, nil
+ end
+ end
+ end
+ end
+
+ return false, false, nil
+ end
+
+ function Private.ParseChatEvent(_, event, msg, sender, ...)
+ local ismeter, isfirstline, message = filter_chat_line(event, sender, msg)
+ if ismeter and isfirstline then
+ return false, message, sender, ...
+ elseif ismeter then
+ return true
+ end
+ end
+
+ function mode:ParseLink(link, text, button, chatframe)
+ local linktype, id = split(":", link)
+ if linktype ~= "SKSP" then
+ return mode.hooks.SetItemRef(link, text, button, chatframe)
+ end
+
+ local meterid = tonumber(id)
+ ShowUIPanel(ItemRefTooltip)
+ if not ItemRefTooltip:IsShown() then
+ ItemRefTooltip:SetOwner(UIParent, "ANCHOR_PRESERVE")
+ end
+ ItemRefTooltip:ClearLines()
+ ItemRefTooltip:AddLine(meters[meterid].title)
+ ItemRefTooltip:AddLine(format(L["Reported by: %s"], meters[meterid].src))
+ ItemRefTooltip:AddLine(" ")
+ for i = 1, #meters[meterid].data do
+ local line = meters[meterid].data[i]
+ if line then
+ ItemRefTooltip:AddLine(line, 1, 1, 1)
+ end
+ end
+ ItemRefTooltip:Show()
+ end
+ end
+
+ ---------------------------------------------------------------------------
+
+ function mode:ApplySettings()
+ -- fury of frostmourne
+ fofrostmourne = fofrostmourne or GetSpellInfo(72350)
+
+ -- filter dps meters
+ if P.spamage then
+ if not self:IsHooked("SetItemRef") then
+ self:RawHook("SetItemRef", "ParseLink", true)
+ end
+ for i = 1, #channel_events do
+ ChatFrame_AddMessageEventFilter(channel_events[i], Private.ParseChatEvent)
+ end
+ elseif self:IsHooked("SetItemRef") then
+ self:Unhook("SetItemRef")
+ for i = 1, #channel_events do
+ ChatFrame_RemoveMessageEventFilter(channel_events[i], Private.ParseChatEvent)
+ end
+ end
+ end
+ mode.OnEnable = mode.ApplySettings
+
+ function mode:OnDisable()
+ self:UnhookAll()
+ Skada.UnregisterAllCallbacks(self)
+ Skada.UnregisterAllMessages(self)
+ end
+
+ function mode:OnInitialize()
+ local function set_value(i, val)
+ P[i[#i]] = val
+ mode:ApplySettings()
+ end
+
+ -- old unused data
+ if type(P.spamage) == "table" then
+ P.spamage = nil
+ end
+
+ -- Fury of Frostmourne
+ fofrostmourne = fofrostmourne or GetSpellInfo(72350)
+
+ local gen_opt = O.tweaks.args.general -- Tweaks > General
+ local adv_opt = O.tweaks.args.advanced -- Tweaks > Advanced
+
+ -- options.
+ gen_opt.args.moduleicons = {
+ type = "toggle",
+ name = L["Modes Icons"],
+ desc = L["Show modes icons on bars and menus."],
+ set = set_value,
+ order = 20
+ }
+ gen_opt.args.spamage = {
+ type = "toggle",
+ name = L["Filter DPS meters Spam"],
+ desc = L["opt_tweaks_spamage_desc"],
+ set = set_value,
+ order = 30
+ }
+ gen_opt.args.fofrostmourne = {
+ type = "toggle",
+ name = fofrostmourne,
+ desc = format(L["Enable this if you want to ignore \124cffffbb00%s\124r."], fofrostmourne),
+ set = set_value,
+ order = 40
+ }
+ end
+end)
diff --git a/Skada/Skada.toc b/Skada/Skada.toc
new file mode 100644
index 0000000..8ae4e7a
--- /dev/null
+++ b/Skada/Skada.toc
@@ -0,0 +1,28 @@
+## Interface: 80300
+## Title: Skada
+## Notes: Modular damage meter.
+## Notes-deDE: Ein Damage-Meter.
+## Notes-esES: Un medidor de daño.
+## Notes-esMX: Un medidor de daño.
+## Notes-frFR: Un damage meter.
+## Notes-koKR: 데미지 미터 모듈입니다.
+## Notes-ruRU: Измеритель урона.
+## Notes-zhCN: 模块化伤害统计。
+## Notes-zhTW: 模組化的傷害統計。
+## OptionalDeps: Ace3, LibSharedMedia-3.0, LibDBIcon-1.0, AceGUI-3.0-SharedMediaWidgets, LibBossIDs-1.0, LibFail-1.0
+## LoadOnDemand: 0
+## SavedVariables: SkadaDB
+## SavedVariablesPerCharacter: SkadaCharDB
+## DefaultState: enabled
+## Author: Kader (|cff808080bkader#5341|r)
+## Version: 1.8.86
+## X-Date: 2024-03-17 @ 00:39 |cff808080UTC|r
+## X-Credits: Zarnivoop
+## X-Curse-Project-ID: 623633
+## X-Category: Combat
+## X-License: MIT/X
+
+Libs\Load.xml
+Locales\Load.xml
+Core\Load.xml
+Modules\Load.xml
diff --git a/SkadaImprovement/Locales.lua b/SkadaImprovement/Locales.lua
new file mode 100644
index 0000000..0283c06
--- /dev/null
+++ b/SkadaImprovement/Locales.lua
@@ -0,0 +1,91 @@
+if not _G.Skada then return end
+
+local L = LibStub("AceLocale-3.0"):NewLocale("Skada", "enUS")
+if L then
+ L["Improvement"] = true
+ L["Improvement modes"] = true
+ L["Improvement comparison"] = true
+ L["Do you want to reset your improvement data?"] = true
+ L["%s's overall data"] = true
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "deDE")
+if L then
+ L["Improvement"] = "Verbesserung"
+ L["Improvement modes"] = "Verbesserungsmodi"
+ L["Improvement comparison"] = "Verbesserungsvergleich"
+ L["Do you want to reset your improvement data?"] = "Möchten Sie Ihre Verbesserungsdaten zurücksetzen?"
+ L["%s's overall data"] = "%s Gesamtdaten"
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "esES")
+if L then
+ L["Improvement"] = "Mejora"
+ L["Improvement modes"] = "Modos de mejora"
+ L["Improvement comparison"] = "Comparación de mejoras"
+ L["Do you want to reset your improvement data?"] = "¿Quieres restablecer tus datos de mejora?"
+ L["%s's overall data"] = "Datos generales de %s"
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "esMX")
+if L then
+ L["Improvement"] = "Mejora"
+ L["Improvement modes"] = "Modos de mejora"
+ L["Improvement comparison"] = "Comparación de mejoras"
+ L["Do you want to reset your improvement data?"] = "¿Quieres restablecer tus datos de mejora?"
+ L["%s's overall data"] = "Datos generales de %s"
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "frFR")
+if L then
+ L["Improvement"] = "Amélioration"
+ L["Improvement modes"] = "Modes d'amélioration"
+ L["Improvement comparison"] = "Comparaison des améliorations"
+ L["Do you want to reset your improvement data?"] = "Voulez-vous réinitialiser vos données d'améliorations?"
+ L["%s's overall data"] = "Données globales de %s"
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "koKR")
+if L then
+ -- L["Improvement"] = ""
+ -- L["Improvement modes"] = ""
+ -- L["Improvement comparison"] = ""
+ -- L["Do you want to reset your improvement data?"] = ""
+ -- L["%s's overall data"] = ""
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "ruRU")
+if L then
+ L["Improvement"] = "Улучшение"
+ L["Improvement modes"] = "Режимы улучшения"
+ L["Improvement comparison"] = "Сравнение улучшений"
+ L["Do you want to reset your improvement data?"] = "Вы хотите сбросить данные об улучшении?"
+ L["%s's overall data"] = "%s - Данные об улучшении"
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "zhCN")
+if L then
+ L["Improvement"] = "提升"
+ L["Improvement modes"] = "提升模式"
+ L["Improvement comparison"] = "提升比较"
+ L["Do you want to reset your improvement data?"] = "确定要重置你的提升数据?"
+ L["%s's overall data"] = "%s的总体数据"
+ return
+end
+
+L = LibStub("AceLocale-3.0"):NewLocale("Skada", "zhTW")
+if L then
+ -- L["Improvement"] = ""
+ -- L["Improvement modes"] = ""
+ -- L["Improvement comparison"] = ""
+ -- L["Do you want to reset your improvement data?"] = ""
+ -- L["%s's overall data"] = ""
+ return
+end
diff --git a/SkadaImprovement/SkadaImprovement.lua b/SkadaImprovement/SkadaImprovement.lua
new file mode 100644
index 0000000..dfde997
--- /dev/null
+++ b/SkadaImprovement/SkadaImprovement.lua
@@ -0,0 +1,320 @@
+local Skada = _G.Skada
+if not Skada then return end
+Skada:RegisterModule("Improvement", function(L)
+ local mod = Skada:NewModule("Improvement")
+ local mod_modes = mod:NewModule("Improvement modes")
+ local mod_comparison = mod:NewModule("Improvement comparison")
+
+ local pairs, date, tostring = pairs, date, tostring
+ local windows = Skada.windows
+ local userGUID = Skada.userGUID or UnitGUID("player")
+
+ local modes = {
+ "ActiveTime",
+ "Damage",
+ "DamageTaken",
+ "Deaths",
+ "Dispels",
+ "Healing",
+ "Interrupts",
+ "Overhealing"
+ }
+
+ local localized = {
+ ActiveTime = L["Active Time"],
+ Damage = L["Damage Done"],
+ DamageTaken = L["Damage Taken"],
+ Deaths = L["Deaths"],
+ Dispels = L["Dispels"],
+ Healing = L["Healing"],
+ Interrupts = L["Interrupts"],
+ Overhealing = L["Overhealing"]
+ }
+
+ local revlocalized = {
+ [L["Active Time"]] = "ActiveTime",
+ [L["Damage Done"]] = "Damage",
+ [L["Damage Taken"]] = "DamageTaken",
+ [L["Deaths"]] = "Deaths",
+ [L["Dispels"]] = "Dispels",
+ [L["Healing"]] = "Healing",
+ [L["Interrupts"]] = "Interrupts",
+ [L["Overhealing"]] = "Overhealing"
+ }
+
+ local updaters = {}
+
+ updaters.ActiveTime = function(set, actor)
+ return Skada:GetActiveTime(set, actor, true)
+ end
+
+ updaters.Damage = function(set, actor)
+ return actor.damage
+ end
+
+ updaters.DamageTaken = function(set, actor)
+ return actor.damaged
+ end
+
+ updaters.Deaths = function(set, actor)
+ return actor.deaths or actor.death
+ end
+
+ updaters.Healing = function(set, actor)
+ if actor.heal or actor.absorb then
+ return (actor.heal or 0) + (actor.absorb or 0)
+ end
+ end
+
+ updaters.Overhealing = function(set, actor)
+ return actor.overheal
+ end
+
+ updaters.Interrupts = function(set, actor)
+ return actor.interrupt
+ end
+
+ updaters.Dispels = function(set, actor)
+ return actor.dispel
+ end
+
+ local function find_boss_data(bossname)
+ if not bossname then
+ return
+ end
+ mod.db = mod.db or {}
+ for k, v in pairs(mod.db) do
+ if k == bossname then
+ return v
+ end
+ end
+
+ mod.db[bossname] = {count = 0, encounters = {}}
+ return find_boss_data(bossname)
+ end
+
+ local function find_encounter_data(boss, starttime)
+ for i = 1, #boss.encounters do
+ local encounter = boss.encounters[i]
+ if encounter and encounter.starttime == starttime then
+ return encounter
+ end
+ end
+
+ boss.encounters[#boss.encounters + 1] = {starttime = starttime, data = {}}
+ return find_encounter_data(boss, starttime)
+ end
+
+ function mod_comparison:Enter(win, id, label)
+ win.targetid, win.modename = id, revlocalized[label] or label
+ win.title = (win.targetname or L["Unknown"]) .. " - " .. label
+ end
+
+ function mod_comparison:Update(win, set)
+ win.title = (win.targetname or L["Unknown"]) .. " - " .. (localized[win.modename] or win.modename)
+ local boss = win.modename and win.targetname and find_boss_data(win.targetname)
+
+ if not boss or not boss.encounters then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for i = 1, #boss.encounters do
+ local encounter = boss.encounters[i]
+ local value = encounter and encounter.data and encounter.data[win.modename]
+ if value and value > 0 then
+ nr = nr + 1
+
+ local d = win:nr(nr)
+ d.id = i
+ d.label = date("%x %X", encounter.starttime)
+ d.value = value
+ if win.modename == "ActiveTime" then
+ d.valuetext = Skada:FormatTime(d.value)
+ elseif win.modename == "Deaths" or win.modename == "Interrupts" then
+ d.valuetext = tostring(d.value)
+ else
+ d.valuetext = Skada:FormatValueCols(
+ Skada:FormatNumber(d.value),
+ Skada:FormatNumber((d.value) / max(1, encounter.data.ActiveTime or 0))
+ )
+ end
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+ end
+
+ function mod_modes:Enter(win, id, label)
+ win.targetid, win.targetname = id, label
+ win.title = L["%s's overall data"]:format(label)
+ end
+
+ function mod_modes:Update(win, set)
+ win.title = L["%s's overall data"]:format(win.targetname or L["Unknown"])
+ local boss = win.targetname and find_boss_data(win.targetname)
+
+ if not boss then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 1
+ end
+
+ local nr = 0
+ for i = 1, #modes do
+ local mode = modes[i]
+ local value = 0
+ for j = 1, #boss.encounters do
+ value = value + (boss.encounters[j].data[mode] or 0)
+ end
+ if value > 0 then
+ nr = nr + 1
+
+ local d = win:nr(nr)
+ d.id = i
+ d.label = localized[mode] or mode
+ d.value = value
+
+ if mode == "ActiveTime" then
+ d.valuetext = Skada:FormatTime(d.value)
+ elseif mode == "Deaths" or mode == "Interrupts" then
+ d.valuetext = tostring(d.value)
+ else
+ d.valuetext = Skada:FormatNumber(d.value)
+ end
+ end
+ end
+ end
+
+ function mod:Update(win, set)
+ win.title = L["Improvement"]
+ if not self.db then
+ return
+ elseif win.metadata then
+ win.metadata.maxvalue = 0
+ end
+
+ local nr = 0
+ for name, data in pairs(self.db) do
+ nr = nr + 1
+
+ local d = win:nr(nr)
+ d.id = name
+ d.label = name
+ d.class = "BOSS"
+ d.value = data.count
+ d.valuetext = tostring(data.count)
+
+ if win.metadata and d.value > win.metadata.maxvalue then
+ win.metadata.maxvalue = d.value
+ end
+ end
+ end
+
+ function mod:OnInitialize()
+ if self.db then return end
+
+ SkadaImprovementDB = SkadaImprovementDB or {}
+ self.db = SkadaImprovementDB
+ end
+
+ function mod:BossDefeated(_, set)
+ if not set or set.type ~= "raid" or not set.success then return end
+
+ local boss = find_boss_data(set.mobname)
+ if not boss then return end
+
+ local encounter = find_encounter_data(boss, set.starttime)
+ if not encounter then return end
+
+ local actors = set.actors
+ for _, actor in pairs(actors) do
+ if actor.id == userGUID then
+ for j = 1, #modes do
+ local mode = modes[j]
+ if mode and updaters[mode] then
+ encounter.data[mode] = updaters[mode](set, actor)
+ elseif mode then
+ encounter.data[mode] = actor[mode:lower()]
+ end
+ end
+ -- increment boss count and stop
+ boss.count = boss.count + 1
+ if boss.count ~= #boss.encounters then
+ boss.count = #boss.encounters
+ end
+ break
+ end
+ end
+ end
+
+ function mod:OnEnable()
+ userGUID = userGUID or Skada.userGUID or UnitGUID("player")
+ self:OnInitialize()
+
+ mod_comparison.metadata = {notitleset = true}
+ mod_modes.metadata = {click1 = mod_comparison, notitleset = true}
+ self.metadata = {
+ click1 = mod_modes,
+ notitleset = true, -- ignore title set
+ icon = [[Interface\ICONS\ability_warrior_intensifyrage]]
+ }
+
+ Skada.RegisterMessage(self, "COMBAT_BOSS_DEFEATED", "BossDefeated")
+ Skada:AddMode(self)
+ end
+
+ function mod:OnDisable()
+ Skada.UnregisterAllMessages(self)
+ Skada:RemoveMode(self)
+ end
+
+ local function ask_for_reset()
+ if not StaticPopupDialogs["SkadaResetImprovementDialog"] then
+ StaticPopupDialogs["SkadaResetImprovementDialog"] = {
+ text = L["Do you want to reset your improvement data?"],
+ button1 = L["Accept"],
+ button2 = L["Cancel"],
+ timeout = 30,
+ whileDead = 0,
+ hideOnEscape = 1,
+ OnAccept = function()
+ mod:Reset()
+ end
+ }
+ end
+ StaticPopup_Show("SkadaResetImprovementDialog")
+ end
+
+ function mod:Reset()
+ Skada:Wipe()
+ SkadaImprovementDB = wipe(SkadaImprovementDB or {})
+ self.db = SkadaImprovementDB
+ self:OnInitialize()
+
+ for i = 1, #windows do
+ local win = windows[i]
+ local mode = (win and win.db) and win.db.mode or nil
+ if mode == "Improvement" or mode == "Improvement modes" or mode == "Improvement comparison" then
+ win:DisplayMode(mod)
+ end
+ end
+
+ Skada:UpdateDisplay(true)
+ Skada:Print(L["All data has been reset."])
+ end
+
+ local Default_ShowPopup = Skada.ShowPopup
+ function Skada:ShowPopup(win, force)
+ if win and win.db and win.db.mode == "Improvement" then
+ ask_for_reset()
+ return
+ end
+
+ return Default_ShowPopup(Skada, win, force)
+ end
+end)
diff --git a/SkadaImprovement/SkadaImprovement.toc b/SkadaImprovement/SkadaImprovement.toc
new file mode 100644
index 0000000..f83d9d6
--- /dev/null
+++ b/SkadaImprovement/SkadaImprovement.toc
@@ -0,0 +1,26 @@
+## Interface: 80300
+## Title: Skada: |cff7fff7fImprovement|r
+## Title-deDE: Skada: |cff7fff7fVerbesserung|r
+## Title-esES: Skada: |cff7fff7fMejora|r
+## Title-esMX: Skada: |cff7fff7fMejora|r
+## Title-frFR: Skada: |cff7fff7fAmélioration|r
+## Title-koKR: Skada: |cff7fff7f개선|r
+## Title-ruRU: Skada: |cff7fff7fУлучшение|r
+## Title-zhCN: Skada: |cff7fff7f提升|r
+## Title-zhTW: Skada: |cff7fff7f改進|r
+## Notes: Saves your character boss fights data to track your improvement.
+## Notes-deDE: Speichert die Kampfdaten Ihres Charakterboss, um Ihren Fortschritt zu verfolgen.
+## Notes-esES: Guarda los datos de las peleas del jefe de tu personaje para seguir tu progreso.
+## Notes-esMX: Guarda los datos de las peleas del jefe de tu personaje para seguir tu progreso.
+## Notes-frFR: Sauvgarde les données des combats de boss de votre personnage pour suivre vos progrès.
+## Notes-koKR: 캐릭터 보스 전투 데이터를 저장하여 개선 사항을 추적합니다.
+## Notes-ruRU: Сохраняет данные о боях с боссом вашего персонажа, чтобы отслеживать ваш прогресс.
+## Notes-zhCN: 保存您的角色首领战斗数据以跟踪您的进度。
+## Notes-zhTW: 保存您的角色首領戰斗數據以跟踪您的進度。
+## Dependencies: Skada
+## SavedVariablesPerCharacter: SkadaImprovementDB
+## DefaultState: disabled
+## Author: Kader (|cff808080bkader#5341|r)
+
+Locales.lua
+SkadaImprovement.lua
diff --git a/SkadaStorage/SkadaStorage.lua b/SkadaStorage/SkadaStorage.lua
new file mode 100644
index 0000000..40eca63
--- /dev/null
+++ b/SkadaStorage/SkadaStorage.lua
@@ -0,0 +1,28 @@
+local Skada = _G.Skada
+if not Skada then return end
+
+local AddOnName = ...
+local L = LibStub("AceLocale-3.0"):GetLocale("Skada")
+
+local function SetupStorage(self)
+ self.sets = self.sets or _G.SkadaStorageDB
+end
+
+local function CheckMemory(self)
+ if not self.profile.memorycheck then return end
+ UpdateAddOnMemoryUsage()
+ local memory = GetAddOnMemoryUsage(AddOnName)
+ if memory > (self.maxmeme * 1024) then
+ self:Notify(L["Memory usage is high. You may want to reset Skada, and enable one of the automatic reset options."], L["Memory Check"], nil, "emergency")
+ end
+end
+
+local LoadFrame = CreateFrame("Frame")
+LoadFrame:RegisterEvent("ADDON_LOADED")
+LoadFrame:SetScript("OnEvent", function(_, event, name)
+ if name == AddOnName then
+ SkadaStorageDB = SkadaStorageDB or {}
+ Skada.SetupStorage = SetupStorage
+ Skada.CheckMemory = CheckMemory
+ end
+end)
diff --git a/SkadaStorage/SkadaStorage.toc b/SkadaStorage/SkadaStorage.toc
new file mode 100644
index 0000000..e9d6e36
--- /dev/null
+++ b/SkadaStorage/SkadaStorage.toc
@@ -0,0 +1,25 @@
+## Interface: 80300
+## Title: Skada: |cff7fff7fStorage|r
+## Title-deDE: Skada: |cff7fff7fLagerung|r
+## Title-esES: Skada: |cff7fff7fAlmacenamiento|r
+## Title-esMX: Skada: |cff7fff7fAlmacenamiento|r
+## Title-frFR: Skada: |cff7fff7fStockage|r
+## Title-koKR: Skada: |cff7fff7f스토리지|r
+## Title-ruRU: Skada: |cff7fff7fХранение|r
+## Title-zhCN: Skada: |cff7fff7f存储|r
+## Title-zhTW: Skada: |cff7fff7f存儲|r
+## Notes: Stores Skada segments.
+## Notes-deDE: Speichert Skada-Segmente.
+## Notes-esES: Tiandas segmentos de Skada.
+## Notes-esMX: Tiandas segmentos de Skada.
+## Notes-frFR: Stocke les segments Skada.
+## Notes-koKR: Skada 세그먼트를 저장합니다.
+## Notes-ruRU: Хранилище сегментов Skada.
+## Notes-zhCN: 存储 Skada 段。
+## Notes-zhTW: 存儲 Skada 段。
+## Dependencies: Skada
+## SavedVariablesPerCharacter: SkadaStorageDB
+## DefaultState: disabled
+## Author: Kader (|cff808080bkader#5341|r)
+
+SkadaStorage.lua