1
0
mirror of https://github.com/brues-code/TwitchEmotes.git synced 2026-09-21 23:26:57 +00:00

31 Commits

Author SHA1 Message Date
Brues 3f1e198e4e Add DisGonBGud 2026-09-16 19:36:22 -05:00
Brues 87147d61ac Add DIESOFCRINGE 2026-09-16 19:33:40 -05:00
Brues 110d8c3002 add YouTried 2026-09-16 19:32:09 -05:00
Brues 9cd7911c73 add SpeedLaugh 2026-09-16 19:30:53 -05:00
Brues 0f20f91466 Add TheVoices
https://betterttv.com/emotes/63e4728a7b3e63779e666353
2026-09-16 19:27:15 -05:00
Brues b466f0b2a5 Add Tssk 2026-09-16 19:24:51 -05:00
Brues 0470d5bbc6 Fix animated frame budget for non-square emote cells
main() capped resample() at the square-cell frame budget (128 across 4
columns) regardless of cell shape, but layout() forces a wide/tall cell
to a single column, whose real budget is only 32. A long animation in
a non-square cell would blow past MAX_TEXTURE and die instead of
resampling down to a fitting framerate.
2026-09-16 13:31:20 -05:00
Brues 3fe9ed86b8 Mirror releases to the Gitea instance, by hand
A Gitea pull mirror replicates commits and tags only, so the mirror's Releases
page shows bare tags with nothing to download. ClassicAPI's mirror-release
workflow pushes the notes and attachments over through Gitea's API; this is
that workflow pointed at brues/TwitchEmotes.

Manual only: workflow_call is dropped, so a release does not trigger it and
nothing else calls it. Run it from the Actions UI with a tag, or with the tag
blank to backfill every release.

Needs its own MIRROR_TOKEN secret on this repo before the first run.
2026-09-14 14:19:20 -05:00
Brues 6348b85740 Draw the stats window with art 1.12 actually ships
Neither texture it asked for exists on this client, and ClassicAPI ships no
art of its own. UI-DialogBox-Background-Dark is a later addition -- 1.12 has
only the un-suffixed UI-DialogBox-Background -- and ItemSocketingFrame is TBC,
so the featured emotes' border was cropped out of a sheet whose folder isn't
there at all.

UI-Quickslot2 is the obvious stand-in for that border, but its hole is ~55% of
the texture, so a 70px emote needs a 128px ring and runs into the title above
and the caption below. It is a small backdrop frame instead, styled like the
autocomplete popup, which keeps the 86/70 sizing. The emote moves onto that
frame to draw above the backdrop; topSentTex/topSeenTex keep their names, so
the animator still finds them.
2026-09-14 14:05:29 -05:00
Brues bea278e730 Add a README 2026-09-14 13:58:06 -05:00
Brues ce8038ed03 Pack animation sheets as tall strips
ClassicAPI's texture dimension gate lifts the two limits the sheet layout was
built around. A sheet skinnier than 16:1 drawing nothing was never a client
rule -- VanillaHelpers grew the texture recycle pool to 6x6 but left the index
stride at 5, so a 32x1024 strip collided with a 64x32 bucket and was handed
back the wrong texture. And power-of-two is no longer required, since the gate
grows the decode scratch to fit.

So a run wraps into columns only when it outgrows the scratch at 32 frames, and
a sheet is sized to its frames exactly: 20 frames is a 32x640 strip rather than
64x1024. The 128 frame budget is unchanged, and older sheets still play -- the
animator reads the column count off the sheet.
2026-09-14 13:58:06 -05:00
Brues a9297cc58b Set changelog-title 2026-09-08 17:30:48 -05:00
Brues 83c1c1f0a7 Add Maaaaan
A single frame - the CDN serves it as a PNG - so a plain 32x32 texture with
no crop spec and no animation metadata.
2026-09-04 03:17:37 -05:00
Brues 34a0a2d5c9 Add DONOTCUM, :Awkward: and catKISS
DONOTCUM is 46 frames at 25fps, catKISS 60 at 17fps, both keeping their
source duration. :Awkward: is 76 frames at 10fps - a 7.6s loop, by far the
longest here, but that is the rate its zero-delay frames play at in a
browser. It takes the token form because Awkward is an ordinary word.
2026-09-04 03:14:31 -05:00
Brues 8d73824e9a Treat a zero GIF delay as 100ms
A GIF frame delay under 20ms means "as fast as possible", and browsers clamp
it to 100ms - the speed the emote actually plays at where people see it.
Summed literally, :Awkward: reported 76 frames lasting 0.1s and collapsed to
a single still. Any emote authored that way would have silently become a
static image.
2026-09-04 03:14:21 -05:00
Brues 0515d796af Add lebronJAM; rebuild RIPBOZO at its real speed
lebronJAM is 121 frames at 13fps, resampled down from 232 source frames over
9.28s - the first emote to hit the 128-frame ceiling for length rather than
speed. The loop keeps its duration.

RIPBOZO was 28 frames at 13fps, a 2.15s loop, against a source of 81 frames
over 5.06s: a third of the frames playing 2.4x too fast. Rebuilt from that
source as 86 frames at 17fps, so it runs at its real speed with every source
frame kept. Its sheet grows from 64x512 to 128x1024 to hold them.
2026-09-04 02:48:45 -05:00
Brues 6d43915fd9 Animate COGGERS; add PepePls, AlienPls, omgBruh, AINTNOWAY, :Cinema:
COGGERS replaces its static art with the animated original: 36 frames at
30fps, a 1.20s loop. Its source is 60 frames at 50fps, so resampling to the
animator's ceiling keeps the duration and drops what could not be shown.

New: PepePls (21 frames, 14fps), AlienPls (128 at 20fps - the tool's frame
ceiling exactly), omgBruh (60 at 10fps), AINTNOWAY (122 of 200 source frames
at 20fps), and :Cinema:, a still.

:Cinema: takes the token form because Cinema is an ordinary English word and
would fire mid-sentence. Its texture stays Cinema.tga, the way :copium:
points at needcopium.tga.
2026-09-04 02:44:43 -05:00
Brues a0082b9f35 Fit wide emotes to their own aspect
A source wider than it is tall was squeezed into a square 32x32 cell, so it
rendered as a letterboxed sliver in a 28x28 box. The frame cell now follows
the source - 32 tall, as wide as its aspect wants - and the payload carries
a matching display size. Cinema (298x112) goes from a 32x12 strip with
transparent bands to an 85x32 cell filling a 28x74 box.

Notes on the payload: it reads HEIGHT first then width, per ParseIcon in
ClassicAPI's InlineTexture.cpp. A square still frame keeps its bare :28:28
with no crop; anything else needs one to pick its cell out of the texture.
Non-square cells stay single-column, since the animator derives its column
count as imageWidth / frameWidth, which only holds when the cell tiles the
texture width exactly. layout() also checks the 16:1 limit both ways now - a
very wide sheet can bust it as easily as a tall one.

--file decouples the texture basename from the trigger word, so a :token:
emote is possible at all: ':Cinema:.tga' is not a legal filename.
2026-09-04 02:44:33 -05:00
Brues f5e1ab506a Add ricardoFlick and popCat
ricardoFlick keeps all 127 source frames at 25fps in a 128x1024 sheet, four
columns wide - the tool's 128-frame ceiling, and at 512KB the largest
texture here. popCat is two frames at 10fps in 32x64.

popCat duplicates the existing CatPop, which is the same emote under a
transposed name with its frames in the opposite order. Both kept, since
popCat is the spelling people type.
2026-09-04 02:27:12 -05:00
Brues d8143801fd Add HyperMpreg
Single frame, so a plain 32x32 texture with no crop spec and no animation
metadata. Listed in the Custom pack.
2026-09-04 02:25:03 -05:00
Brues 96fb7091fc Add peepoTalk
16 frames at 10fps in a 32x512 sheet, a 1.6s loop matching the source with
no frames dropped. Listed in the peepo pack alongside its siblings.
2026-09-04 02:22:45 -05:00
Brues fc6e9f125b Animate peepoClap
Replaces the static art with the animated original: two frames at 10fps in
a 32x64 sheet, matching the source's 0.2s loop. The trigger word and menu
listing are unchanged, so only the texture spec and a metadata row move.
2026-09-04 02:18:18 -05:00
Brues 311359dcc8 Repack sheets the client is too skinny to sample; add blobDance
A texture skinnier than 16:1 draws nothing at all. Confirmed in-game with
one crop shape across two sheets: ratJAM (32x512) renders, modCheck
(32x1024) is blank. The earlier 2048 repack fixed those sheets by accident
- two columns took them from 64:1 to 16:1, not by getting under the 1024
cap as its commit message claimed.

Twenty-seven sheets were still at 32:1 and had never rendered: modCheck,
meow, BOOBA, rooRave, Aware, Thinkge, alert and the rest. All repacked to
64x512, same frames in the same order, with their crops and metadata
updated. Verified across all 112 animated sheets: none over 1024 or
skinnier than 16:1, declared sizes match the files, frame counts fit their
grids, and every repacked frame still matches what its sheet held at that
index.

add_emote.py learns the same limit, and resamples the source timeline at a
constant rate instead of expanding holds into repeats: a hold repeats, a
source faster than the ~30fps ticker drops frames, and the loop keeps its
duration either way. blobDance is 50fps at source, so the old code stretched
its 0.74s loop to 1.23s.

Also drops the atoi note from BuildFrameString - ParseField uses atof and
tolerates decimals, so that was never the failure it described.
2026-09-04 01:17:26 -05:00
Brues 4173e827eb Warn instead of loading when ClassicAPI is missing
The addon needs the ClassicAPI DLL - without it the inline |T markup the
emotes are built from renders as literal text, title included. Move the
real load order into TwitchEmotes_ClassicAPI.toc, which the DLL picks up
in preference, and leave the base TOC loading nothing but CAPI_Warning.lua:
a popup and a chat line pointing at the latest release, with the download
URL in a preselected edit box. Its title drops the inline-texture markup
for the same reason.

Also list CreateFrame among the globals in .luarc.json.
2026-09-03 16:05:02 -05:00
Brues 94777ecbc4 Add an emote installer, animate Nerdge
tools/add_emote.py downloads a BetterTTV emote, converts it to a texture
the 1.12 client decodes, and registers it in defaultpack, emoticons, the
animation table and the minimap pack list.

Two client limits shape the conversion. Textures cap at 1024px per side,
so anything longer than 32 frames packs row-major across several 32px
columns. And the animator plays one constant rate while a GIF holds
individual frames for different lengths, so uneven delays expand into
repeated frames at the integer rate that reproduces the source timing with
the fewest frames - a faster rate always matches the duration more exactly
but pays for it in texture size.

Nerdge is the first emote through it, replacing the static art with the
animated original: 17 source frames over 3.12s become 36 frames at 11fps
(3.27s) in a 64x1024 sheet, keeping its hold, push, hold shape.

.pkgmeta is tracked now so the release packager honours its ignore list
and leaves tools out of the zip.
2026-09-03 16:00:41 -05:00
Brues fe2cac7168 Correct the payload form in the animator's header
The crop args became left:right:top:bottom when frames gained columns; the
comment still described the single-column 0:frameW form.
2026-09-03 16:00:10 -05:00
Brues 5cce48bc0b use brues-code/packager@vCAPI 2026-09-03 14:59:33 -05:00
Brues 879ab2918c Slow catJAM to its source speed, emit integer texcoords
The source emote is 158 frames at 25fps, a 6.32s loop; this sheet holds 60
of those frames but kept a framerate of 15, running the loop in 4.0s.

A fractional rate would have matched it exactly, but the engine splits the
|T payload on ':' and atoi's each field, so a coordinate carrying a decimal
point truncates and crops the wrong rect - the emote renders as the whole
sheet squeezed into its box. The animator now formats the payload with %d
so the frame math can never leak a float into it, and the rate stays a
whole number: 10fps, a 6.0s loop.
2026-09-03 14:54:07 -05:00
Brues c08c89ebb9 Repack over-tall emote sheets into a 2-column grid
The client caps a texture at 1024px in either dimension - nothing in its
own art exceeds it - and squeezes anything larger on load, so every 32px
crop of a 32x2048 sheet landed between frames and the emote rendered as a
stretched smear scrolling vertically. catJAM, pedro, goinginsane, HUHH,
Kiss and Awoken are now 64x1024, the same frames laid out row-major
across two columns.

The animator derives the column count from imageWidth / frameWidth, so
single-column sheets produce the same crop they did before. Fixed the
frame-0 crops in the autocomplete popup and the stats screen, which
hardcoded the full texture width.

Also: HACKERMANS is a single 32x32 frame on disk but was declared as 11
frames of 32x512, which rendered it as the same kind of sliver; it is now
a static icon. Dropped the shadowed duplicate RIPBOZO metadata entry.
2026-09-03 14:14:27 -05:00
Brues 2e87a84450 Added luarc and pkgmeta 2026-09-03 09:29:56 -05:00
Brues f2daf6847e Keep emote dropdown menus on screen
ToggleDropDownMenu tests only the bottom and right edges, flips a list
once and never re-measures, so a flipped page overflows the top instead,
and its off-right test compares list coordinates against pixel widths so
submenus flip leftward past the left edge. Clamp our own lists back
inside the screen after it positions them.
2026-09-03 09:29:07 -05:00
71 changed files with 866 additions and 122 deletions
+180
View File
@@ -0,0 +1,180 @@
name: Mirror release
# Copy a GitHub release — its notes and the files attached to it — across to
# the Gitea mirror at https://octowow.st/git/brues/TwitchEmotes.
#
# A Gitea pull mirror replicates commits and tags only. Releases are database
# records with their own attachments, so they never cross: the mirror's
# Releases page shows bare tags with nothing to download. This workflow pushes
# them over through Gitea's API.
#
# ONE-TIME SETUP: on the mirror, go to Settings -> Applications -> Generate New
# Token, tick `repository` write, and copy the token. On GitHub, add it under
# Settings -> Secrets and variables -> Actions as `MIRROR_TOKEN`. The token
# needs push rights on brues/TwitchEmotes.
#
# Manual only — nothing calls it, and a release does not trigger it. Run it from
# the Actions UI with a `tag` to mirror one release, or with `tag` left blank to
# backfill every release that exists on GitHub.
on:
workflow_dispatch:
inputs:
tag:
description: 'Release tag to mirror (e.g. v2.0.0). Blank = every release.'
required: false
default: ''
permissions:
contents: read
jobs:
mirror:
runs-on: ubuntu-latest
steps:
# No checkout: the release files come from the GitHub release itself, so
# this reads the same bytes a user downloads rather than a rebuild.
- name: Push release to the mirror
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
MIRROR_TOKEN: ${{ secrets.MIRROR_TOKEN }}
TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [ -z "${MIRROR_TOKEN:-}" ]; then
echo "::error::MIRROR_TOKEN is not set - see the setup note at the top of .github/workflows/mirror-release.yml"
exit 1
fi
API=https://octowow.st/git/api/v1
MIRROR=brues/TwitchEmotes
RESP=$(mktemp)
# Sends one API call. Prints the HTTP status; leaves the body in $RESP.
req() {
local method=$1 path=$2
shift 2
curl -sS -m 600 -o "$RESP" -w '%{http_code}' -X "$method" \
-H "Authorization: token $MIRROR_TOKEN" \
-H 'Accept: application/json' \
"$API/$path" "$@"
}
fail() {
echo "::error::$1"
echo "the mirror replied: $(head -c 2000 "$RESP")"
exit 1
}
# A release must hang off a tag that is already on the mirror. If the
# tag is missing the mirror has not pulled yet, so ask it to and wait.
# Attaching to a tag the mirror does not have would let its next sync
# turn our release back into a draft.
ensure_tag() {
local tag=$1 i
if [ "$(req GET "repos/$MIRROR/tags/$tag")" = 200 ]; then
return 0
fi
echo " tag $tag is not on the mirror yet - asking it to sync"
req POST "repos/$MIRROR/mirror-sync" > /dev/null || true
for i in $(seq 1 30); do
sleep 10
if [ "$(req GET "repos/$MIRROR/tags/$tag")" = 200 ]; then
echo " tag $tag arrived after $(( i * 10 ))s"
return 0
fi
done
fail "tag $tag never reached the mirror. Sync it, then run this workflow again."
}
mirror_one() {
local tag=$1 work code id f name size have_id have_size enc
work=$(mktemp -d)
echo "=== $tag ==="
gh release view "$tag" --json tagName,name,body,isDraft,isPrerelease > "$work/gh.json"
if [ "$(jq -r .isDraft "$work/gh.json")" = true ]; then
echo " still a draft on GitHub - skipped"
return 0
fi
ensure_tag "$tag"
jq '{tag_name: .tagName,
name: (.name // .tagName),
body: (.body // ""),
draft: false,
prerelease: .isPrerelease}' "$work/gh.json" > "$work/release.json"
# Gitea's tag sync leaves a bare tag record behind. Patching it
# promotes that record to a real release instead of colliding.
code=$(req GET "repos/$MIRROR/releases/tags/$tag")
if [ "$code" = 200 ]; then
id=$(jq -r .id "$RESP")
code=$(req PATCH "repos/$MIRROR/releases/$id" \
-H 'Content-Type: application/json' --data-binary @"$work/release.json")
if [ "$code" != 200 ]; then
fail "could not update release $tag on the mirror (HTTP $code)"
fi
echo " updated release #$id"
else
code=$(req POST "repos/$MIRROR/releases" \
-H 'Content-Type: application/json' --data-binary @"$work/release.json")
if [ "$code" != 201 ]; then
fail "could not create release $tag on the mirror (HTTP $code)"
fi
id=$(jq -r .id "$RESP")
echo " created release #$id"
fi
mkdir -p "$work/assets"
# Exits non-zero when the release carries no files, which is fine.
gh release download "$tag" --dir "$work/assets" --clobber || true
code=$(req GET "repos/$MIRROR/releases/$id/assets")
if [ "$code" != 200 ]; then
fail "could not list the mirror's attachments for $tag (HTTP $code)"
fi
cp "$RESP" "$work/have.json"
for f in "$work"/assets/*; do
[ -f "$f" ] || continue
name=$(basename "$f")
size=$(stat -c %s "$f")
have_id=$(jq -r --arg n "$name" 'map(select(.name == $n)) | .[0].id // ""' "$work/have.json")
have_size=$(jq -r --arg n "$name" 'map(select(.name == $n)) | .[0].size // ""' "$work/have.json")
# Same name and same size: already mirrored. A size mismatch means
# a re-cut release, so replace it - Gitea would otherwise keep both
# and serve the stale one from the older link.
if [ -n "$have_id" ] && [ "$have_size" = "$size" ]; then
echo " $name is already there"
continue
fi
if [ -n "$have_id" ]; then
req DELETE "repos/$MIRROR/releases/$id/assets/$have_id" > /dev/null
fi
enc=$(jq -rn --arg n "$name" '$n | @uri')
code=$(req POST "repos/$MIRROR/releases/$id/assets?name=$enc" -F "attachment=@$f")
if [ "$code" != 201 ]; then
fail "could not upload $name (HTTP $code)"
fi
echo " uploaded $name ($size bytes)"
done
}
if [ -n "${TAG:-}" ]; then
mirror_one "$TAG"
else
echo "no tag given - backfilling every release on GitHub"
gh release list --limit 200 --json tagName --jq '.[].tagName' > /tmp/tags.txt
# fd 3 keeps gh and curl from eating the tag list off stdin.
while read -r t <&3; do
if [ -n "$t" ]; then
mirror_one "$t"
fi
done 3< /tmp/tags.txt
fi
+1 -1
View File
@@ -18,6 +18,6 @@ jobs:
fetch-depth: 0
- name: Package and release to GitHub
uses: BigWigsMods/packager@v2
uses: brues-code/packager@vCAPI
env:
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
+23
View File
@@ -0,0 +1,23 @@
{
"runtime": {
"version": "Lua 5.1"
},
"diagnostics": {
"disable": ["deprecated"],
"globals": [
"this",
"event",
"arg",
"arg1",
"arg2",
"arg3",
"arg4",
"arg5",
"arg6",
"arg7",
"arg8",
"arg9",
"CreateFrame"
]
}
}
+6
View File
@@ -0,0 +1,6 @@
package-as: TwitchEmotes
changelog-title: TwitchEmotes
ignore:
- .luarc.json
- tools
+38
View File
@@ -0,0 +1,38 @@
local CLASSIC_API_WEBSITE = "https://github.com/brues-code/ClassicAPI"
local CLASSIC_API_LATEST_URL = CLASSIC_API_WEBSITE .. "/releases/latest"
local headline = "TwitchEmotes has been disabled."
local detail = "The ClassicAPI DLL isn't loaded. Download the latest release from: "
local function ShowRequiredPopup()
StaticPopupDialogs["TWITCH_CLASSICAPI_REQUIRED"] = {
text = headline .. "\n\n" .. detail,
button1 = OKAY,
hasEditBox = 1,
editBoxWidth = 280,
timeout = 0,
whileDead = 1,
hideOnEscape = 1,
preferredIndex = 3,
OnShow = function()
local editBox = getglobal(this:GetName().."EditBox")
if editBox then
editBox:SetText(CLASSIC_API_LATEST_URL)
editBox:HighlightText()
editBox:SetFocus()
end
end,
}
StaticPopup_Show("TWITCH_CLASSICAPI_REQUIRED")
DEFAULT_CHAT_FRAME:AddMessage(
headline .. " " .. detail .. CLASSIC_API_LATEST_URL,
1, 0.3, 0.3
)
end
local loginFrame = CreateFrame("Frame")
loginFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
loginFrame:SetScript("OnEvent", function()
loginFrame:UnregisterEvent("PLAYER_ENTERING_WORLD")
ShowRequiredPopup()
end)
+132 -71
View File
@@ -2320,7 +2320,7 @@ defaultpack={
["SMUGGERS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\SMUGGERS.tga:28:28",
["EVILSMILERS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\EVILSMILERS.tga:28:28",
["WEIRDERS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\WEIRDERS.tga:28:28",
["COGGERS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\COGGERS.tga:28:28",
["COGGERS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\COGGERS.tga:28:28:0:0:64:1024:0:32:0:32",
["monkaStop"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monkaStop.tga:28:28",
["FeelsLoveMan"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsLoveMan.tga:28:28:0:0:32:512:0:32:0:32",
["PepeDent"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeDent.tga:28:28",
@@ -3629,9 +3629,9 @@ defaultpack={
["LockStone"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\LockStone.tga:28:28",
["KomodoHype"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\KomodoHype.tga:28:28",
["HiveDiver"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HiveDiver.tga:28:28",
["catJAM"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\catJAM.tga:28:28:0:0:32:2048:0:32:0:32",
["catJAM"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\catJAM.tga:28:28:0:0:64:1024:0:32:0:32",
["ratJAM"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ratJAM.tga:28:28:0:0:32:512:0:32:0:32",
["modCheck"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\modCheck.tga:28:28:0:0:32:1024:0:32:0:32",
["modCheck"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\modCheck.tga:28:28:0:0:64:512:0:32:0:32",
["CatMad"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\CatMad.tga:28:28",
["freddyW"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\freddyW.tga:28:28",
["freddyLUL"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\freddyLUL.tga:28:28",
@@ -3656,7 +3656,7 @@ defaultpack={
["channWeen"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\channWeen.tga:28:28",
["Lole"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Lole.tga:28:28",
["GasmChamp"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\GasmChamp.tga:28:28",
["DonoWall"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DonoWall.tga:28:28:0:0:32:1024:0:32:0:32",
["DonoWall"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DonoWall.tga:28:28:0:0:64:512:0:32:0:32",
["sameEnergy"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\sameEnergy.tga:28:28",
["intjdreaming"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\intjdreaming.tga:28:28",
["intjXD1"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\intjXD1.tga:28:28",
@@ -3704,13 +3704,13 @@ defaultpack={
["OMEGAKEKMAN"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\OMEGAKEKMAN.tga:28:28",
["ThumbsUp"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ThumbsUp.tga:28:28",
[":Clueless:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\clueless.tga:28:28",
[":Awoken:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Awoken.tga:28:28:0:0:32:2048:0:32:0:32",
[":Awoken:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Awoken.tga:28:28:0:0:64:1024:0:32:0:32",
["yeshoney"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\yeshoney.tga:28:28",
["goinginsane"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\goinginsane.tga:28:28:0:0:32:2048:0:32:0:32",
["goinginsane"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\goinginsane.tga:28:28:0:0:64:1024:0:32:0:32",
["AbdulPls"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\AbdulPls.tga:28:28:0:0:32:512:0:32:0:32",
["PunkChamp"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\PunkChamp.tga:28:28",
["batBrah"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\batBrah.tga:28:28",
[":Aware:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Aware.tga:28:28:0:0:32:1024:0:32:0:32",
[":Aware:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Aware.tga:28:28:0:0:64:512:0:32:0:32",
[":Concerned:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Concerned.tga:28:28",
["HmmTodayIWill"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HmmTodayIWill.tga:28:28",
["NoBitches"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\NoBitches.tga:28:28",
@@ -3725,8 +3725,8 @@ defaultpack={
["Catablepon"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Catablepon.tga:28:28",
["HUH"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HUH.tga:28:28",
["jewdai"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\jewdai.tga:28:28",
["YodaSip"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YodaSip.tga:28:28:0:0:32:1024:0:32:0:32",
["billyReady"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\billyReady.tga:28:28:0:0:32:1024:0:32:0:32",
["YodaSip"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YodaSip.tga:28:28:0:0:64:512:0:32:0:32",
["billyReady"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\billyReady.tga:28:28:0:0:64:512:0:32:0:32",
[":soy:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\soy.tga:28:28:0:0:32:128:0:32:0:32",
["ICANT"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ICANT.tga:28:28",
["megaflushed"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\megaflushed.tga:28:28",
@@ -3734,34 +3734,34 @@ defaultpack={
["Sussy"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Sussy.tga:28:28:0:0:32:256:0:32:0:32",
["worryFat"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\worryFat.tga:28:28",
["WrathChest"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\WrathChest.tga:28:28",
["MoneySniff"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\MoneySniff.tga:28:28:0:0:32:1024:0:32:0:32",
["GAMING"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\GAMING.tga:28:28:0:0:32:1024:0:32:0:32",
["RAGEY"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RAGEY.tga:28:28:0:0:32:1024:0:32:0:32",
["MoneySniff"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\MoneySniff.tga:28:28:0:0:64:512:0:32:0:32",
["GAMING"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\GAMING.tga:28:28:0:0:64:512:0:32:0:32",
["RAGEY"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RAGEY.tga:28:28:0:0:64:512:0:32:0:32",
["hehecat"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\hehecat.tga:28:28",
["TeaTime"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\TeaTime.tga:28:28:0:0:32:1024:0:32:0:32",
["TeaTime"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\TeaTime.tga:28:28:0:0:64:512:0:32:0:32",
[":WM:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\WM.tga:28:28",
[":noted:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\noted.tga:28:28:0:0:32:1024:0:32:0:32",
[":noted:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\noted.tga:28:28:0:0:64:512:0:32:0:32",
["YOGGERS"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YOGGERS.tga:28:28",
["HYPERYOGGERS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HYPERYOGGERS.tga:28:28:0:0:32:64:0:32:0:32",
[":xdd:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\xdd.tga:28:28",
[":meow:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\meow.tga:28:28:0:0:32:1024:0:32:0:32",
["HUHH"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HUHH.tga:28:28:0:0:32:2048:0:32:0:32",
["RIPBOZO"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RIPBOZO.tga:28:28:0:0:32:1024:0:32:0:32",
[":meow:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\meow.tga:28:28:0:0:64:512:0:32:0:32",
["HUHH"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HUHH.tga:28:28:0:0:64:1024:0:32:0:32",
["RIPBOZO"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RIPBOZO.tga:28:28:0:0:128:1024:0:32:0:32",
["evilcat"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\evilcat.tga:28:28",
["bufeY"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\bufeY.tga:28:28",
["deanWink"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\deanWink.tga:28:28:0:0:32:512:0:32:0:32",
["DocLeave"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocLeave.tga:28:28:0:0:32:1024:0:32:0:32",
["DocArrive"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocArrive.tga:28:28:0:0:32:1024:0:32:0:32",
["DocLeave"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocLeave.tga:28:28:0:0:64:512:0:32:0:32",
["DocArrive"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocArrive.tga:28:28:0:0:64:512:0:32:0:32",
[":alarm:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\alarm.tga:28:28",
["angrybear"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\angrybear.tga:28:28",
["docmeat"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\docmeat.tga:28:28:0:0:32:512:0:32:0:32",
["politeCatWTF"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\politeCatWTF.tga:28:28",
["SNIFFA"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\SNIFFA.tga:28:28:0:0:32:1024:0:32:0:32",
[":kissing:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kiss.tga:28:28:0:0:32:2048:0:32:0:32",
["SNIFFA"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\SNIFFA.tga:28:28:0:0:64:512:0:32:0:32",
[":kissing:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kiss.tga:28:28:0:0:64:1024:0:32:0:32",
["bidenBlast"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\bidenBlast.tga:28:28",
[":om:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\om.tga:28:28:0:0:32:128:0:32:0:32",
[":Classic:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Classic.tga:28:28:0:0:32:1024:0:32:0:32",
[":yo:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\yo.tga:28:28:0:0:32:1024:0:32:0:32",
[":Classic:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Classic.tga:28:28:0:0:64:512:0:32:0:32",
[":yo:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\yo.tga:28:28:0:0:64:512:0:32:0:32",
["bange"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\bange.tga:28:28",
[":kms:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\kms.tga:28:28",
["headBang"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\headBang.tga:28:28:0:0:32:256:0:32:0:32",
@@ -3774,14 +3774,14 @@ defaultpack={
["Kekflap"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kekflap.tga:28:28:0:0:32:64:0:32:0:32",
["businesscat"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\businesscat.tga:28:28",
["LETHIMCOOK"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\LETHIMCOOK.tga:28:28",
["ChipiChipi"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ChipiChipi.tga:28:28:0:0:32:1024:0:32:0:32",
["ChipiChipi"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ChipiChipi.tga:28:28:0:0:64:512:0:32:0:32",
[":horror:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\horror.tga:28:28",
["MikeSmug"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\MikeSmug.tga:28:28",
["BedgeMorgan"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\BedgeMorgan.tga:28:28",
[":alert:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\alert.tga:28:28:0:0:32:1024:0:32:0:32",
[":alert:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\alert.tga:28:28:0:0:64:512:0:32:0:32",
[":groove:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\groove.tga:28:28",
["LETSGOOO"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\LETSGOOO.tga:28:28:0:0:32:512:0:32:0:32",
["pedro"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\pedro.tga:28:28:0:0:32:2048:0:32:0:32",
["pedro"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\pedro.tga:28:28:0:0:64:1024:0:32:0:32",
[":pls:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\pls.tga:28:28",
["Cluegi"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Cluegi.tga:28:28",
["intjCaught"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\intjCaught.tga:28:56",
@@ -3903,7 +3903,7 @@ defaultpack={
["monakW"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monakW.tga:LARGE",
["monakGun"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monakGun.tga:28:28",
["monakMultiple"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Monaks1.tga:28:28",
["HACKERMANS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\HACKERMANS.tga:28:28:0:0:32:512:0:32:0:32",
["HACKERMANS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\HACKERMANS.tga:28:28",
["peepoFR1"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoFR1.tga:28:28",
["peepoFR2"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoFR2.tga:28:28",
["PepeSmug"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeSmug.tga:28:28",
@@ -3976,7 +3976,7 @@ defaultpack={
["PepePuke"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepePuke.tga:28:28",
["PepegaHammer"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepegaHammer.tga:28:28",
["Sadga"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Sadga.tga:28:28",
["BOOBA"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\BOOBA.tga:28:28:0:0:32:1024:0:32:0:32",
["BOOBA"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\BOOBA.tga:28:28:0:0:64:512:0:32:0:32",
["COCKA"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\COCKA.tga:28:28:0:0:32:256:0:32:0:32",
["FUTA"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FUTA.tga:28:28:0:0:32:512:0:32:0:32",
["BOOFA"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\BOOFA.tga:28:28",
@@ -3997,7 +3997,7 @@ defaultpack={
["Bedge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Bedge.tga:28:28",
["PAUSERS"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PAUSERS.tga:28:28",
["WICKED"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\WICKED.tga:28:28:0:0:32:128:0:32:0:32",
["peepoClap"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoClap.tga:28:28",
["peepoClap"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoClap.tga:28:28:0:0:32:64:0:32:0:32",
["COPIUM"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\COPIUM.tga:28:28",
[":copium:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\needcopium.tga:28:28",
["Copege"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Copege.tga:28:28",
@@ -4021,7 +4021,7 @@ defaultpack={
["soupchamp"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\soupchamp.tga:28:28",
["Starege"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Starege.tga:28:28",
["Hmmmge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Hmmmge.tga:28:28",
["lovehug"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\lovehug.tga:28:28:0:0:32:1024:0:32:0:32",
["lovehug"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\lovehug.tga:28:28:0:0:64:512:0:32:0:32",
["Madgee"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Madgee.tga:28:28",
["Clownge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Clownge.tga:28:28",
["ehWTF"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\ehWTF.tga:28:28",
@@ -4039,7 +4039,7 @@ defaultpack={
["peepoJail"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoJail.tga:28:28",
["peepoNotes"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoNotes.tga:28:28",
["Awakge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Awakge.tga:28:28",
["Nerdge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Nerdge.tga:28:28",
["Nerdge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Nerdge.tga:28:28:0:0:64:1024:0:32:0:32",
[":shy:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\shy.tga:28:28:0:0:32:64:0:32:0:32",
["peepoSmash"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoSmash.tga:28:28:0:0:32:256:0:32:0:32",
["peepoBye"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoBye.tga:28:28",
@@ -4063,7 +4063,7 @@ defaultpack={
["FeelsLateMan"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsLateMan.tga:28:28:0:0:32:512:0:32:0:32",
["CROGGERS"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\CROGGERS.tga:28:28",
["DinkDonk"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\DinkDonk.tga:28:28:0:0:32:64:0:32:0:32",
["Thinkge"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Thinkge.tga:28:28:0:0:32:1024:0:32:0:32",
["Thinkge"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Thinkge.tga:28:28:0:0:64:512:0:32:0:32",
[":fml:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\fml.tga:28:28",
["binocs"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\binocs.tga:28:28",
["PepePlan"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepePlan.tga:28:28",
@@ -4089,7 +4089,7 @@ defaultpack={
["Readge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Readge.tga:28:28",
["peepoChop"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoChop.tga:28:28:0:0:32:256:0:32:0:32",
["monkaSteer"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monkaSteer.tga:28:28:0:0:32:512:0:32:0:32",
["ppHop"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\ppHop.tga:28:28:0:0:32:1024:0:32:0:32",
["ppHop"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\ppHop.tga:28:28:0:0:64:512:0:32:0:32",
["FeelsWeakMan"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsWeakMan.tga:28:28:0:0:32:512:0:32:0:32",
["PepegaCredit"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepegaCredit.tga:28:28:0:0:32:512:0:32:0:32",
["PepeNOOO"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeNOOO.tga:28:28:0:0:32:256:0:32:0:32",
@@ -4104,7 +4104,7 @@ defaultpack={
["sadgers"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\sadgers.tga:28:28",
["gladgers"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\gladgers.tga:28:28",
["Voidge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Voidge.tga:28:28",
["peepoGhost"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoGhost.tga:28:28:0:0:32:1024:0:32:0:32",
["peepoGhost"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoGhost.tga:28:28:0:0:64:512:0:32:0:32",
["Smoge"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Smoge.tga:28:28",
["NeedCopium"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\NeedCopiumPepe.tga:28:28",
["Bedges"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Bedges.tga:28:28",
@@ -4192,7 +4192,7 @@ defaultpack={
["PogOff"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\PogOff.tga:28:28",
["Pausey"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\Pausey.tga:28:28",
["RowSalt"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\RowSalt.tga:56:56",
["PogTasty"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\PogTasty.tga:28:28:0:0:32:1024:0:32:0:32",
["PogTasty"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\PogTasty.tga:28:28:0:0:64:512:0:32:0:32",
["TriTasty"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\TriTasty.tga:28:28",
[":twoofakind:"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\Maya.tga:28:28",
["RowFish"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\RowFish.tga:28:28",
@@ -4230,7 +4230,7 @@ defaultpack={
["rooC"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooC.tga:28:28",
["rooComfy"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooComfy.tga:28:28",
["rooMadSlam"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooMadSlam.tga:28:28:0:0:32:512:0:32:0:32",
["rooRave"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooRave.tga:28:28:0:0:32:1024:0:32:0:32",
["rooRave"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooRave.tga:28:28:0:0:64:512:0:32:0:32",
["drxCozy"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Drainerx\\drxCozy.tga:28:28",
["drxLUL"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Drainerx\\drxLUL.tga:28:28",
["drxHappy"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\Drainerx\\drxHappy.tga:28:28",
@@ -4255,6 +4255,27 @@ defaultpack={
["typegYIP"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\typeg\\typegYIP.tga:28:28",
["typegChill"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\typeg\\typegChill.tga:28:28",
["typegBricked"] = "Interface\\AddOns\\TwitchEmotes\\Emotes\\typeg\\typegBricked.tga:28:28",
["blobDance"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\blobDance.tga:28:28:0:0:64:512:0:32:0:32",
["peepoTalk"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoTalk.tga:28:28:0:0:32:512:0:32:0:32",
["HyperMpreg"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HyperMpreg.tga:28:28",
["ricardoFlick"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ricardoFlick.tga:28:28:0:0:128:1024:0:32:0:32",
["popCat"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\popCat.tga:28:28:0:0:32:64:0:32:0:32",
["PepePls"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepePls.tga:28:28:0:0:64:512:0:32:0:32",
["AlienPls"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\AlienPls.tga:28:28:0:0:128:1024:0:32:0:32",
["omgBruh"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\omgBruh.tga:28:28:0:0:64:1024:0:32:0:32",
["AINTNOWAY"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\AINTNOWAY.tga:28:28:0:0:128:1024:0:32:0:32",
[":Cinema:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Cinema.tga:28:74:0:0:128:32:0:85:0:32",
["lebronJAM"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\lebronJAM.tga:28:28:0:0:128:1024:0:32:0:32",
["DONOTCUM"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DONOTCUM.tga:28:28:0:0:64:1024:0:32:0:32",
[":Awkward:"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Awkward.tga:28:28:0:0:128:1024:0:32:0:32",
["catKISS"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\catKISS.tga:28:28:0:0:64:1024:0:32:0:32",
["Maaaaan"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Maaaaan.tga:28:28",
["Tssk"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Tssk.tga:28:28:0:0:32:416:0:32:0:32",
["TheVoices"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\TheVoices.tga:28:28:0:0:128:1024:0:32:0:32",
["SpeedLaugh"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\SpeedLaugh.tga:28:32:0:0:36:928:0:36:0:32",
["YouTried"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YouTried.tga:28:28:0:0:32:576:0:32:0:32",
["DIESOFCRINGE"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DIESOFCRINGE.tga:28:28:0:0:128:896:0:32:0:32",
["DisGonBGud"]="Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DisGonBGud.tga:28:28:0:0:128:1024:0:32:0:32",
};
emoticons={
@@ -8920,14 +8941,35 @@ defaultpack={
["typegChill"] = "typegChill",
["typegBricked"] = "typegBricked",
[":twoofakind:"]=":twoofakind:",
["blobDance"]="blobDance",
["peepoTalk"]="peepoTalk",
["HyperMpreg"]="HyperMpreg",
["ricardoFlick"]="ricardoFlick",
["popCat"]="popCat",
["PepePls"]="PepePls",
["AlienPls"]="AlienPls",
["omgBruh"]="omgBruh",
["AINTNOWAY"]="AINTNOWAY",
[":Cinema:"]=":Cinema:",
["lebronJAM"]="lebronJAM",
["DONOTCUM"]="DONOTCUM",
[":Awkward:"]=":Awkward:",
["catKISS"]="catKISS",
["Maaaaan"]="Maaaaan",
["Tssk"]="Tssk",
["TheVoices"]="TheVoices",
["SpeedLaugh"]="SpeedLaugh",
["YouTried"]="YouTried",
["DIESOFCRINGE"]="DIESOFCRINGE",
["DisGonBGud"]="DisGonBGud",
};
TwitchEmotes_animation_metadata = {
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Clap.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 6},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\modCheck.tga"] = {["nFrames"] = 28, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 9},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\goinginsane.tga"] = {["nFrames"] = 47, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=2048, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\catJAM.tga"] = {["nFrames"] = 60, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=2048, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\modCheck.tga"] = {["nFrames"] = 28, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 9},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\goinginsane.tga"] = {["nFrames"] = 47, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\catJAM.tga"] = {["nFrames"] = 60, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ratJAM.tga"] = {["nFrames"] = 16, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\BTTV+FFZ\\haHAA.tga"] = {["nFrames"] = 14, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 34},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeMeltdown.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 34},
@@ -8936,9 +8978,9 @@ TwitchEmotes_animation_metadata = {
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\worryPopcorn.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 26},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\worryExcite.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 26},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\AbdulPls.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 24},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\lovehug.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\lovehug.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monkaX.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 11},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\BOOBA.tga"] = {["nFrames"] = 27, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 16},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\BOOBA.tga"] = {["nFrames"] = 27, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 16},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\MadgeRightNow.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\shy.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 4},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\DinkDonk.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 20},
@@ -8949,7 +8991,7 @@ TwitchEmotes_animation_metadata = {
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FUTA.tga"] = {["nFrames"] = 12, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\NODDERS.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\NOPERS.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DonoWall.tga"] = {["nFrames"] = 24, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 8},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DonoWall.tga"] = {["nFrames"] = 24, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 8},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\WICKEDSTEER.tga"] = {["nFrames"] = 15, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 16},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\WICKED.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 16},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\ClownHypers.tga"] = {["nFrames"] = 6, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 6},
@@ -8957,7 +8999,7 @@ TwitchEmotes_animation_metadata = {
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\CatDance.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsLoveMan.tga"] = {["nFrames"] = 12, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooMadSlam.tga"] = {["nFrames"] = 11, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooRave.tga"] = {["nFrames"] = 25, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 24},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\AdmiralBahroo\\rooRave.tga"] = {["nFrames"] = 25, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 24},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\worryStick.tga"] = {["nFrames"] = 12, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeJAM.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoSmash.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 12},
@@ -8965,72 +9007,91 @@ TwitchEmotes_animation_metadata = {
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Chatting.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoGiggle.tga"] = {["nFrames"] = 6, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsRainMan.tga"] = {["nFrames"] = 14, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoPat.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoPat.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoEhm.tga"] = {["nFrames"] = 6, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 1},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monkaInsane.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 60},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsLateMan.tga"] = {["nFrames"] = 16, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 8},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\SadCatWave.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Aware.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Aware.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsNzoth.tga"] = {["nFrames"] = 9, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Thinkge.tga"] = {["nFrames"] = 28, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Thinkge.tga"] = {["nFrames"] = 28, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsIllidanMan.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 18},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\BTTV+FFZ\\gachiBASS.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\BTTV+FFZ\\pokiBASS.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 30},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YodaSip.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\billyReady.tga"] = {["nFrames"] = 18, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YodaSip.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\billyReady.tga"] = {["nFrames"] = 18, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\soy.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Sussy.tga"] = {["nFrames"] = 5, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoChop.tga"] = {["nFrames"] = 5, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\monkaSteer.tga"] = {["nFrames"] = 13, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\ppHop.tga"] = {["nFrames"] = 19, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\ppHop.tga"] = {["nFrames"] = 19, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsWeakMan.tga"] = {["nFrames"] = 15, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepegaCredit.tga"] = {["nFrames"] = 15, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 16},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\MoneySniff.tga"] = {["nFrames"] = 25, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\GAMING.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\MoneySniff.tga"] = {["nFrames"] = 25, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\GAMING.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeNOOO.tga"] = {["nFrames"] = 7, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepeSith.tga"] = {["nFrames"] = 12, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\POGGIES.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RAGEY.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\TeaTime.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\PogTasty.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 13},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\noted.tga"] = {["nFrames"] = 30, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RAGEY.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\TeaTime.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\GuildEmotes\\PogTasty.tga"] = {["nFrames"] = 31, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 13},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\noted.tga"] = {["nFrames"] = 30, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\HYPEROMEGAPOGGERSCRAZY.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\meow.tga"] = {["nFrames"] = 24, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 11},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HUHH.tga"] = {["nFrames"] = 47, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=2048, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RIPBOZO.tga"] = {["nFrames"] = 28, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RIPBOZO.tga"] = {["nFrames"] = 28, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 13},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\meow.tga"] = {["nFrames"] = 24, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 11},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HUHH.tga"] = {["nFrames"] = 47, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoStrong.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 14},["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoHorse.tga"] = {["nFrames"] = 13, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoPolice.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\HYPERYOGGERS.tga"] = {["nFrames"] = 2,["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\deanWink.tga"] = {["nFrames"] = 14, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoGhost.tga"] = {["nFrames"] = 25, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocLeave.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocArrive.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoGhost.tga"] = {["nFrames"] = 25, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocLeave.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DocArrive.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\MadgeClap.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\FeelsQueueMan.tga"] = {["nFrames"] = 11, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 8},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\docmeat.tga"] = {["nFrames"] = 16, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\YEPPERS.tga"] = {["nFrames"] = 12, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\SNIFFA.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kiss.tga"] = {["nFrames"] = 38, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=2048, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\SNIFFA.tga"] = {["nFrames"] = 20, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kiss.tga"] = {["nFrames"] = 38, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\om.tga"] = {["nFrames"] = 4, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Classic.tga"] = {["nFrames"] = 26, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Classic.tga"] = {["nFrames"] = 26, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\binocsSpin.tga"] = {["nFrames"] = 5, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\yo.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\yo.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoShake.tga"] = {["nFrames"] = 5, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\headBang.tga"] = {["nFrames"] = 6, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\BLUBBERS.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Plotge.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 18},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\shadowChatting.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Jammies.tga"] = {["nFrames"] = 7, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\HACKERMANS.tga"] = {["nFrames"] = 11, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoComfy.tga"] = {["nFrames"] = 6, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\SALAMI.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\typeg\\typegLoad.tga"] = {["nFrames"] = 8, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=256, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\typeg\\typegPaul.tga"] = {["nFrames"] = 10, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},["Interface\\AddOns\\TwitchEmotes\\Emotes\\typeg\\hyperjoy.tga"] = {["nFrames"] = 9, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kekflap.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 15},["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Awoken.tga"] = {["nFrames"] = 38, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=2048, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ChipiChipi.tga"] = {["nFrames"] = 24, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\alert.tga"] = {["nFrames"] = 17, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=1024, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Kekflap.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 15},["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Awoken.tga"] = {["nFrames"] = 38, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ChipiChipi.tga"] = {["nFrames"] = 24, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\alert.tga"] = {["nFrames"] = 17, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 40},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\LETSGOOO.tga"] = {["nFrames"] = 11, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\pedro.tga"] = {["nFrames"] = 48, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=2048, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\pedro.tga"] = {["nFrames"] = 48, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepofeet.tga"] = {["nFrames"] = 3, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=128, ["framerate"] = 15},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\Nerdge.tga"] = {["nFrames"] = 37, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 12},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\blobDance.tga"] = {["nFrames"] = 22, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 30},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoClap.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\peepoTalk.tga"] = {["nFrames"] = 16, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=512, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\ricardoFlick.tga"] = {["nFrames"] = 128, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\popCat.tga"] = {["nFrames"] = 2, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=64, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\COGGERS.tga"] = {["nFrames"] = 36, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 30},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Pepes\\PepePls.tga"] = {["nFrames"] = 21, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=512, ["framerate"] = 14},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\AlienPls.tga"] = {["nFrames"] = 128, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\omgBruh.tga"] = {["nFrames"] = 60, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\AINTNOWAY.tga"] = {["nFrames"] = 122, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 20},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\lebronJAM.tga"] = {["nFrames"] = 121, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 13},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\RIPBOZO.tga"] = {["nFrames"] = 86, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 17},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DONOTCUM.tga"] = {["nFrames"] = 46, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 25},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Awkward.tga"] = {["nFrames"] = 76, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\catKISS.tga"] = {["nFrames"] = 60, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=64, ["imageHeight"]=1024, ["framerate"] = 17},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\Tssk.tga"] = {["nFrames"] = 13, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=416, ["framerate"] = 30},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\TheVoices.tga"] = {["nFrames"] = 127, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 21},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\SpeedLaugh.tga"] = {["nFrames"] = 29, ["frameWidth"] = 36, ["frameHeight"] = 32, ["imageWidth"]=36, ["imageHeight"]=928, ["framerate"] = 6},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\YouTried.tga"] = {["nFrames"] = 18, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=32, ["imageHeight"]=576, ["framerate"] = 10},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DIESOFCRINGE.tga"] = {["nFrames"] = 111, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=896, ["framerate"] = 30},
["Interface\\AddOns\\TwitchEmotes\\Emotes\\Custom\\DisGonBGud.tga"] = {["nFrames"] = 125, ["frameWidth"] = 32, ["frameHeight"] = 32, ["imageWidth"]=128, ["imageHeight"]=1024, ["framerate"] = 25},
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 512 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

After

Width:  |  Height:  |  Size: 128 KiB

+42
View File
@@ -0,0 +1,42 @@
[![ClassicAPI](https://img.shields.io/badge/ClassicAPI%20>=%20v1.14.0-Required-purple.svg)](https://github.com/brues-code/ClassicAPI)
# TwitchEmotes
Twitch, BetterTTV, FrankerFaceZ and Discord emotes in World of Warcraft 1.12.1.
Type `Kappa`, `PepeLaugh` or `:skull:` in chat and it comes out as the emote — for you and for
everyone else running the addon. Over 4,000 codes across 28 packs, 122 of them animated, rendered
inline in chat, chat bubbles and mail.
Originally written for retail by **Ren**; backported to vanilla by **Brues**.
## Features
- **Emotes everywhere** — say, yell, guild, officer, whisper, party, raid, battleground, channels
and in-game mail. Each channel can be toggled on its own.
- **Animated emotes** at ~30fps, in chat, in the picker, and over chat bubbles.
- **Autocomplete** — type `:` plus two characters for a ranked popup (prefix, then substring, then
fuzzy). Tab cycles the suggestions, space or a click accepts one.
- **Emote picker** on the minimap button, grouped by pack. Mark the packs you use as favourites and
hide the rest.
- **Clickable emotes** — hover an emote in chat to see its code, shift-click to put it in your
edit box.
- **Usage statistics** — how often you have sent and seen each emote (shift-click the minimap
button).
Minimap button: click for the picker, shift-click for statistics, right-click for options.
## Requirements
[ClassicAPI](https://github.com/brues-code/ClassicAPI) is required. The 1.12 client cannot draw
cropped inline textures on its own, which is what animated emotes and sprite sheets need. Without
the DLL loaded the addon disables itself and points you at the download.
## Adding an emote
`tools/add_emote.py` takes a BetterTTV emote, converts it to a texture the 1.12 client can decode,
and registers it:
```
python tools/add_emote.py https://betterttv.com/emotes/<id> PepeCool
```
+46 -3
View File
@@ -71,7 +71,7 @@ Emoticons_Settings={
[1]= {"Asmongold","asmon1","asmon2","asmon3","asmon4","asmonBoi","asmonC","asmonCD","asmonD","asmonDad","asmonDaze","asmonDegen","asmonE","asmonE1","asmonE2","asmonE3","asmonE4","asmonFiend","asmonG","asmonGASM","asmonGet","asmonHide","asmonL","asmonLFR","asmonLong1","asmonLong2","asmonLong3","asmonLong4","asmonLove","asmonM","asmonOcean","asmonOrc","asmonP","asmonPower","asmonPray","asmonPrime","asmonR","asmonREE","asmonSad","asmonStare","asmonTar","asmonTiger","asmonUH","asmonW","asmonWHAT","asmonWHATR","asmonWOW"},
[2]= {"Preachlfw","pgeBan","pgeBen","pgeBrian","pgeCheese","pgeChick","pgeClub","pgeCrisp","pgeDrama","pgeEdge","pgeEmma","pgeFish","pgeGhost","pgeHmm","pgeNem","pgeNoob","pgeOhno","pgeOhno2","pgePog","pgePug","pgeRay","pgeScience","pgeShame","pgeSherry"},
[3]= {"BTTV+FFZ","4Head","ANELE","AngelThump","BabyRage","BBona","BibleThump","BlessRNG","BloodTrail","bUrself","cmonBrother","cmonBrug","cmonBruh","ConcernDoge","ConcernFroge","D:","DansGame","DatSheffy","DD:","DogeWitIt","EleGiggle","eShrug","FacePalm","FailFish","FrankerZ","GabeN","gachiBASS","gachiGASM","gachiHYPER","GivePLZ","haHAA","HandsUp","HeyGuys","HotPokket","HYPERBRUG","HYPERLUL","HYPERTHONK","Jebaited","Kapp","Kappa","KappaPride","Keepo","KKomrade","Kreygasm","LUL","LULE","LULW","MegaLUL","MingLee","MingLUL","MrDestructoid","NickyQ","NotLike","NotLikeThis","o_O","OhMyDog","OpieOP","PagMan","PartyTime","pokiBASS","PotFriend","PowerUpL","PowerUpR","RCool","ResidentSleeper","RFrown","RGasp","RHeart","RMeh","RPatch","RSmile","RSmiling","RTired","RTongue","RWink","RWinkTongue","SeemsGood","smileC","smileW","SMOrc","Squid1","Squid2","Squid3","Squid4","SwiftRage","TakeNRG","Thonk","tooDank","TriHard","weSmart","WideHard","WinnerWinner","WTFF","Wut","WutFace","ZULOL","ZULUL"},
[4]= {"Custom","4Play","4WeirdBusiness",":alarm:",":alert:",":Aware:",":Awoken:",":blinking:",":Classic:",":Clueless:",":Concerned:",":cringe:",":doo:",":empty:",":ew:",":groove:",":hehe:",":hehesip:",":horror:",":jons:",":kissing:",":kms:",":mc:",":meow:",":misery:",":mo:",":noted:",":om:",":penguin:",":pls:",":queen:",":quest:",":sitch:",":soy:",":torment:",":waiting:",":WM:",":xdd:",":yo:","AbdulPls","AMAZIN","ANEBruh","angrybear","arnoldHalt","AYAYA","bange","batBrah","BedgeMorgan","bidenBlast","bign","billyReady","bjornoVV","bjornoVVona","BOGGED","bruggaroniNcheese","bufeY","businesscat","Catablepon","CatDance","catJAM","CatMad","CatPop","channMies","channWeen","ChipiChipi","chompy","chupBro","chupDerp","chupHappy","ciaciuu","ciaciuWorried","Clap","Cluegi","cmon","confuseddoggo","cptfriHE","CUNGUS","deanWink","Del","Depresstiny","DestiSenpaii","Disgustiny","DocArrive","DocLeave","docmeat","DogeKek","DonoWall","ednasly","Eggroll","endANELE","endBomb","endDawg","endFrench","endHarambe","endKyori","endNotLikeThis","endRP","endTrump","evilcat","fentL","FlipThis","FLOOSHED","flushdoggo","foxsus","freddyCREEP","freddyFINGER","freddyLUL","freddyW","FrogPog","fruitBug","GAMING","GasmChamp","GigaChad","GODSTINY","goinginsane","HappyMerchant","headBang","hehecat","HiveDiver","HmmStiny","HmmTodayIWill","HowSleeper","HUH","HUHH","HyperAngryMerchant","HYPERYOGGERS","ICANT","intjCaught","intjdreaming","intjGlad","intjIdk","intjMad","intjReallyMad","intjSad","intjSalute","intjShake","intjSmile","intjSus","intjWoa","intjXD1","intjXD2","jerryWhat","jewdai","jillzoMallet","jinL","Jons","Joy2","Kekflap","KEKok","KEKWait","KermitScream","KKonaS","Klappa","KomodoHype","Krug","LaurGasm","LeoHug","LeRuse","LETHIMCOOK","LETSGOOO","lockOmegatayys","LockStone","Lole","LOLW","marcithDerp","marcithMath","mastahFloor","megaflushed","MikeSmug","modCheck","MoneySniff","monkeyS","MooCowGold","MooCowW","moWait","MrStark","NeckBeard","NoAnime","NoBitches","NOBULLY","NoTears","OKKona","oldmorDim","OMEGAKEKMAN","OMEGALOL","OverRustle","PatrickMad","PatrickPray","pedro","peepoVW","PEPE","PogCena","PogT","poki1","poki2","pokiW","politeCatWTF","Popoga","PunkChamp","RAGEY","ratJAM","REE","RIPBOZO","sameEnergy","selyihHEY","SNIFFA","StareBruh","Stonks","SuicideThinking","sunglassesflushed","SURPRISE","susfox","Sussy","SWEATSTINY","TeaTime","ThisIsFine","ThumbsUp","totekatze","TrollDespair","TrollLaugh","VoHiYo","WeirdAYAYA","worryChocolate","worryCool","worryExcite","worryFat","worryHug","worryHugged","worryLove","worryPopcorn","worryStick","worryWave","WrathChest","yacubgasm","YEE","yeshoney","YodaSip","YOGGERS","YoshiBlush","ZOINKS"},
[4]= {"Custom","4Play","4WeirdBusiness",":alarm:",":alert:",":Aware:",":Awkward:",":Awoken:",":blinking:",":Cinema:",":Classic:",":Clueless:",":Concerned:",":cringe:",":doo:",":empty:",":ew:",":groove:",":hehe:",":hehesip:",":horror:",":jons:",":kissing:",":kms:",":mc:",":meow:",":misery:",":mo:",":noted:",":om:",":penguin:",":pls:",":queen:",":quest:",":sitch:",":soy:",":torment:",":waiting:",":WM:",":xdd:",":yo:","AbdulPls","AINTNOWAY","AlienPls","AMAZIN","ANEBruh","angrybear","arnoldHalt","AYAYA","bange","batBrah","BedgeMorgan","bidenBlast","bign","billyReady","bjornoVV","bjornoVVona","blobDance","BOGGED","bruggaroniNcheese","bufeY","businesscat","Catablepon","CatDance","catJAM","catKISS","CatMad","CatPop","channMies","channWeen","ChipiChipi","chompy","chupBro","chupDerp","chupHappy","ciaciuu","ciaciuWorried","Clap","Cluegi","cmon","confuseddoggo","cptfriHE","CUNGUS","deanWink","Del","Depresstiny","DestiSenpaii","DIESOFCRINGE","DisGonBGud","Disgustiny","DocArrive","DocLeave","docmeat","DogeKek","DONOTCUM","DonoWall","ednasly","Eggroll","endANELE","endBomb","endDawg","endFrench","endHarambe","endKyori","endNotLikeThis","endRP","endTrump","evilcat","fentL","FlipThis","FLOOSHED","flushdoggo","foxsus","freddyCREEP","freddyFINGER","freddyLUL","freddyW","FrogPog","fruitBug","GAMING","GasmChamp","GigaChad","GODSTINY","goinginsane","HappyMerchant","headBang","hehecat","HiveDiver","HmmStiny","HmmTodayIWill","HowSleeper","HUH","HUHH","HyperAngryMerchant","HyperMpreg","HYPERYOGGERS","ICANT","intjCaught","intjdreaming","intjGlad","intjIdk","intjMad","intjReallyMad","intjSad","intjSalute","intjShake","intjSmile","intjSus","intjWoa","intjXD1","intjXD2","jerryWhat","jewdai","jillzoMallet","jinL","Jons","Joy2","Kekflap","KEKok","KEKWait","KermitScream","KKonaS","Klappa","KomodoHype","Krug","LaurGasm","lebronJAM","LeoHug","LeRuse","LETHIMCOOK","LETSGOOO","lockOmegatayys","LockStone","Lole","LOLW","Maaaaan","marcithDerp","marcithMath","mastahFloor","megaflushed","MikeSmug","modCheck","MoneySniff","monkeyS","MooCowGold","MooCowW","moWait","MrStark","NeckBeard","NoAnime","NoBitches","NOBULLY","NoTears","OKKona","oldmorDim","OMEGAKEKMAN","OMEGALOL","omgBruh","OverRustle","PatrickMad","PatrickPray","pedro","peepoVW","PEPE","PogCena","PogT","poki1","poki2","pokiW","politeCatWTF","popCat","Popoga","PunkChamp","RAGEY","ratJAM","REE","ricardoFlick","RIPBOZO","sameEnergy","selyihHEY","SNIFFA","SpeedLaugh","StareBruh","Stonks","SuicideThinking","sunglassesflushed","SURPRISE","susfox","Sussy","SWEATSTINY","TeaTime","TheVoices","ThisIsFine","ThumbsUp","totekatze","TrollDespair","TrollLaugh","Tssk","VoHiYo","WeirdAYAYA","worryChocolate","worryCool","worryExcite","worryFat","worryHug","worryHugged","worryLove","worryPopcorn","worryStick","worryWave","WrathChest","yacubgasm","YEE","yeshoney","YodaSip","YOGGERS","YoshiBlush","YouTried","ZOINKS"},
[5]= {"Greekgodx","greekA","greekBrow","greekDiet","greekGirl","greekGordo","greekGweek","greekHard","greekHYPERP","greekJoy","greekKek","greekM","greekMlady","greekOi","greekP","greekPVC","greekSad","greekSheep","greekSleeper","greekSquad","greekT","greekThink","greekTilt","greekWC","greekWhy","greekWtf","greekYikes"},
[6]= {"nymn","nymn0","nymn1","nymn158","nymn2","nymn2x","nymn3","nymnA","nymnAww","nymnB","nymnBee","nymnBenis","nymnBiggus","nymnBridge","nymnC","nymnCaptain","nymnCC","nymnCD","nymnCozy","nymnCREB","nymnCringe","nymnCry","nymnDab","nymnDeer","nymnE","nymnElf","nymnEU","nymnEZ","nymnFEEDME","nymnFlag","nymnFlick","nymnFood","nymnG","nymnGasm","nymnGasp","nymnGnome","nymnGold","nymnGolden","nymnGun","nymnH","nymnHammer","nymnHmm","nymnHonk","nymnHydra","nymnJoy","nymnK","nymnKek","nymnKing","nymnKomrade","nymnL","nymnM","nymnNA","nymnNo","nymnNormie","nymnOkay","nymnP","nymnPains","nymnPog","nymnPuke","nymnR","nymnRaffle","nymnRupert","nymnS","nymnSad","nymnScuffed","nymnSleeper","nymnSmart","nymnSmol","nymnSmug","nymnSon","nymnSoy","nymnSpurdo","nymnStrong","nymnThink","nymnTransparent","nymnU","nymnV","nymnW","nymnWhy","nymnXD","nymnY","nymnZ"},
[7]= {"Drainerx","drxBrain","drxCozy","drxCri","drxCS","drxD","drxDict","drxED","drxED2","drxEyes","drxFE","drxFE1","drxFEED","drxGlad","drxGod","drxHappy","drxHey","drxKEK","drxLewd","drxLit","drxLUL","drxMad","drxmonkaEYES","drxPog","drxR","drxSad","drxSmart","drxSmile","drxSpace","drxSSJ","drxThink","drxW","drxWeird","drxWink"},
@@ -79,8 +79,8 @@ Emoticons_Settings={
[9]= {"Forsen","forsen1","forsen2","forsen3","forsen4","forsenAYAYA","forsenAYOYO","forsenBanned","forsenBee","forsenBlob","forsenBoys","forsenC","forsenCD","forsenChamp","forsenClown","forsenConnoisseur","forsenCool","forsenD","forsenDab","forsenDank","forsenDDK","forsenDED","forsenDespair","forsenDiglett","forsenE","forsenEcardo","forsenEmote","forsenEmote2","forsenFajita","forsenFeels","forsenFur","forsenG","forsenGa","forsenGASM","forsenGrill","forsenGun","forsenH","forsenHappy","forsenHead","forsenHobo","forsenHorsen","forsenIQ","forsenJoy","forsenK","forsenKek","forsenKnife","forsenKraken","forsenL","forsenLewd","forsenLicence","forsenLookingAtYou","forsenLooted","forsenLUL","forsenM","forsenMald","forsenMoney","forsenMonkey","forsenNam","forsenO","forsenODO","forsenOG","forsenOP","forsenP","forsenPepe","forsenPog","forsenPosture","forsenPosture1","forsenPosture2","forsenPuke","forsenPuke2","forsenPuke3","forsenPuke4","forsenPuke5","forsenR","forsenReally","forsenRedSonic","forsenRP","forsenS","forsenSambool","forsenScoots","forsenSheffy","forsenSith","forsenSkip","forsenSleeper","forsenSmile","forsenSS","forsenStein","forsenSwag","forsenT","forsenTILT","forsenTriggered","forsenW","forsenWC","forsenWeird","forsenWeird25","forsenWhat","forsenWhip","forsenWitch","forsenWTF","forsenWut","forsenX","forsenY","forsenYHD","PogChimp"},
[10]= {"AdmiralBahroo","rooAww","rooBlank","rooBless","rooBlind","rooBonk","rooBooli","rooBot","rooC","rooCarry","rooComfy","rooCookie","rooCop","rooCry","rooCult","rooD","rooDab","rooDerp","rooDevil","rooDisgust","rooDuck","rooEZ","rooGift","rooGun","rooHappy","rooLick","rooLick2","rooLove","rooMadSlam","rooMurica","rooNap","rooNom","rooPog","rooPs","rooRave","rooREE","rooScheme","rooScream","rooSellout","rooSleepy","rooSmush","rooThink","rooTHIVV","rooUwU","rooVV","rooW","rooWhine","rooWut"},
[11]= {"VR","02Dab","02Stare","02Yum",":HEH:","astrovrCry","astrovrHi","astrovrRee","CuteMelon","DrunkMelon","GaspMelon","HyperHappyMelon","HyperMelon","MelonGun","OwOMelon","radiantAYAYA","radiantBlush","radiantBomb","radiantBoop","radiantComfy","radiantCry","radiantCult","radiantCute","radiantEEEEE","radiantEvil","radiantGimme","radiantGun","radiantHmm","radiantISee","radiantJam","radiantKek","radiantLag","radiantLick","radiantLurk","radiantNom","radiantOmega","radiantOmegaOWO","radiantOwO","radiantPat","radiantPepega","radiantPog","radiantPout","radiantREE","radiantSalute","radiantScared","radiantShrug","radiantSip","radiantSmile","radiantSmug","radiantSnoze","radiantStare","radiantTOS","radiantWave","radiantWeird","RageMelon","ReeMelon","SadMelon","SweatMelon","tyrissBlush","tyrissBoop","tyrissComfy","tyrissDisappointed","tyrissGasp","tyrissGimme","tyrissGlare","tyrissHeadpat","tyrissHeart","tyrissHeartz","tyrissHi","tyrissHug","tyrissHyper","tyrissLul","tyrissLurk","tyrissPout","tyrissRee","tyrissRip","tyrissS","tyrissSad","tyrissSmug","tyrissSmugOwO","tyrissThink","tyrissVictory","ZevvyBlush"},
[12]= {"Pepe",":copium:",":done:",":drama:",":fml:",":fork:",":hmm:",":memes:",":need:",":shy:",":skip:",":think:",":whip:","Awakge","BadW","beanping","Bedge","Bedges","BedgeTogether","binocs","binocsSpin","BLUBBERS","Blushge","BOOBA","BOOFA","Boolin","Borpa","BorpaL","BorpaU","Catge","Chatting","Clownge","ClownHypers","COCKA","Copege","COPIUM","CringeW","CROGGERS","Cryge","CutePepe","DankHug","Deadge","DeadgeTogether","dejj","Despairge","DinkDonk","ehWTF","EVILSMILERS","EZ","FARTIUM","FatBod","FatDank","Fatge","FeelsAmazingMan","FeelsBetaMan","FeelsBlushMan","FeelsBoredMan","FeelsCoolMan","FeelsCopterMan","FeelsCringeMan","FeelsCryManW","FeelsCuteMan","FeelsDeadMan","FeelsDrunkMan","FeelsEvilMan","FeelsFatMan","FeelsGamerMan","FeelsGermanMan","FeelsGreekMan","FeelsIllidanMan","FeelsIncredibleMan","FeelsLateMan","FeelsLitMan","FeelsLoveManW","FeelsMyFingerMan","FeelsOakyMan","FeelsOldMan","FeelsPinkMan","FeelsQueueMan","FeelsRainSadge","FeelsRottenMan","FeelsSad","FeelsSorryMan","FeelsStrongMan","FeelsSuicideMan","FeelsTastyMan","FeelsTiredAF","FeelsWeakMan","FeelsWiredMan","fingi","FrogO","FUARK","FUTA","Gayge","GiggleHands","Gladge","gladgers","goodd","GoodW","HabibiPrayge","HACKERMANS","HappyJammies","Hmmge","Hmmmge","HYPEROMEGAPOGGERSCRAZY","HYPERS","imKEKWing","imOkayChamp","Jammies","JanCarlo","KEKGA","KEKWHands","KMS","LMAO","lookdown","lookup","lovehug","Lovge","LULERS","Madge","MadgeBackhand","MadgeClap","Madgee","MadgeNow","MadgeRightNow","majj","MALDD","maximumautism","meAutism","monakGun","monakHmm","monakMultiple","monakS","monakW","monkaCapture","monkaGasp","monkaGIGA","monkaHands","monkaInsane","monkaLaugh","monkaMEGA","monkaMultiple","monkaOh","monkaOMEGA","monkaPickle","monkaS","monkaShake","monkaShoot","monkaStab","monkaStare","monkaSteer","monkaSusp","monkaT","monkaThink","monkaTOS","monkaU","monkaVirus","monkaW","monkaWCB","monkaX","monkaYou","monkerS","NA","nanoMEGA","NeedCopium","Nerdge","noClown","NODDERS","NOOBA","NOP","NOPERS","Notsurege","Okayeg","Okayga","Okayge","OkaygeShrug","OkayLaugh","OkayW","oldpepe","OMEGAEZ","oniongang","PAUSERS","peep","PeepHand","peepo","peepo2","peepoAlliance","peepoBaba","peepoBlankey","peepoBritish","peepoBye","peepoCat","peepoChonk","peepoChop","peepoClap","peepoComfy","peepoDab","peepoEhm","peepoEvilSip","peepofeet","peepoFoil","peepoFR1","peepoFR2","peepoGhost","peepoGiggle","peepoGroovie","peepoHeart","peepoHehe","peepoHey","peepoHorse","peepoIsForMe","peepoJail","peepoJedi","peepoJorts","peepoJudge","peepoJuice","peepoLoser","peepoM","peepoMadder","peepoNotes","peepoPanda","peepoParty","peepoPlease","peepoPolice","peepoRiot","peepoSadLogize","peepoScam","peepoShake","peepoShy","peepoSimp","peepoSimping","peepoSith","peepoSleepo","peepoSmash","peepoSoup","peepoSPopcorn","peepoStonks","peepoStrong","peepoSure","peepoSweat","peepoTeeth","peepoTrash","peepoWhy","peepoWow","PepeAyy","PepeBald","PepeBlyat","PepeBruh","PepeCat","PepeCatGun","PepeCatHeart","PepeCoffee","PepeCoolStory","PepeCozy","PepeCry","PepeDisgust","PepeDribble","PepeFlushed","PepeFrench","PepeFU","PepeFuming","PepegaCredit","PepegaHammer","PepegaHands","PepeGang","PepegaSad","PepeHammer","PepeHands","PepeHard","PepeHeart","PepeHmm","PepeHug","PepeJAM","PepeKMS","PepeL","PepeLa","PepeLaffe","PepeLegs","PepeLoser","PepeM","PepeMods","PepeNOOO","PepeNotOK","PepeOK","PepeOuuuhh","PepePains","PepePants","PepePhone","PepePhoned","PepePlan","PepePoint","PepePoo","PepePopcorn","PepePuke","PepePyroblast","PepeReach","PepeRun","PepeScoots","PepeScout","PepeSith","PepeSlice","PepeSmile","PepeSmug","PepeStepBro","PepeStressed","PepeThumbsUp","pepeW","PepeWizard","PepeWot","PepeXD","pepoEZ","pepoGun","PepoHide","pepoS","PepoScience","PepoThink","PepperHands","Plotge","pogg","PoggersHype","POGGIES","PogO2","POOGERS","ppEZ","ppFootbol","ppHop","Prayge","RandomPepe","Ratge","Readge","Riotge","SadBlanket","Sadga","Sadge","sadgers","SadHug","SadLove","SadPepe","SAJ","sajj","SALAMI","salutt","shadowChatting","shrujj","Smadge","SMILERS","Smoge","SMUGGERS","SmugPepe","soupchamp","Starege","Stronge","SucksMan","Susge","Suske","Thinkge","TiredW","tomatogang","TroggHYPERS","UHM","Voidge","Weirdga","Weirdge","WeirdJAM","WeirdU","WeirdW","WICKED","WickedDrip","WICKEDSTEER","widepeepoHappy","widepeepoLove","widepeepoPride","widepeepoSad","widepeepoWeird","WideSadge","widestpeepoHappy","widestpeepoSad","Wipege","WOAW","Wokege","Wokegesus","YEP","Yepge","YEPPERS","yikers"},
[13]= {"peepo","peepaKiss","peepoAP","peepoBeer","peepoBlanket","peepoBlush","peepoBored","peepoCool","peepoCringe","peepoCute","peepoExit","peepoEZ","peepoFA","peepoFat","peepoFH","peepoFight","peepoFriends","peepoGlad","peepoGun","peepoHands","peepoHide","peepoHit","peepoHmm","peepoHug","peepoHugged","peepoKEKW","peepoKiss","peepoKnight","peepoLip","peepoLove","peepoMaybe","peepoNo","peepoNolegs","peepoNOO","peepoOK","peepoPants","peepoPat","peepoPee","peepoPeek","peepoPlot","peepoPoint","peepoPoo","peepoPride","peepoRain","peepoReallyHappy","peepoS","peepoSad","peepoSalute","peepoSenor","peepoShrug","peepoSick","peepoSip","peepoSmile","peepoStudy","peepoSuspect","peepoSuspicious","peepoTeddy","peepoThink","peepoTired","peepoUgh","peepoWave","peepoWoW","peepoWTF","peepoYes","pillowJammies"},
[12]= {"Pepe",":copium:",":done:",":drama:",":fml:",":fork:",":hmm:",":memes:",":need:",":shy:",":skip:",":think:",":whip:","Awakge","BadW","beanping","Bedge","Bedges","BedgeTogether","binocs","binocsSpin","BLUBBERS","Blushge","BOOBA","BOOFA","Boolin","Borpa","BorpaL","BorpaU","Catge","Chatting","Clownge","ClownHypers","COCKA","Copege","COPIUM","CringeW","CROGGERS","Cryge","CutePepe","DankHug","Deadge","DeadgeTogether","dejj","Despairge","DinkDonk","ehWTF","EVILSMILERS","EZ","FARTIUM","FatBod","FatDank","Fatge","FeelsAmazingMan","FeelsBetaMan","FeelsBlushMan","FeelsBoredMan","FeelsCoolMan","FeelsCopterMan","FeelsCringeMan","FeelsCryManW","FeelsCuteMan","FeelsDeadMan","FeelsDrunkMan","FeelsEvilMan","FeelsFatMan","FeelsGamerMan","FeelsGermanMan","FeelsGreekMan","FeelsIllidanMan","FeelsIncredibleMan","FeelsLateMan","FeelsLitMan","FeelsLoveManW","FeelsMyFingerMan","FeelsOakyMan","FeelsOldMan","FeelsPinkMan","FeelsQueueMan","FeelsRainSadge","FeelsRottenMan","FeelsSad","FeelsSorryMan","FeelsStrongMan","FeelsSuicideMan","FeelsTastyMan","FeelsTiredAF","FeelsWeakMan","FeelsWiredMan","fingi","FrogO","FUARK","FUTA","Gayge","GiggleHands","Gladge","gladgers","goodd","GoodW","HabibiPrayge","HACKERMANS","HappyJammies","Hmmge","Hmmmge","HYPEROMEGAPOGGERSCRAZY","HYPERS","imKEKWing","imOkayChamp","Jammies","JanCarlo","KEKGA","KEKWHands","KMS","LMAO","lookdown","lookup","lovehug","Lovge","LULERS","Madge","MadgeBackhand","MadgeClap","Madgee","MadgeNow","MadgeRightNow","majj","MALDD","maximumautism","meAutism","monakGun","monakHmm","monakMultiple","monakS","monakW","monkaCapture","monkaGasp","monkaGIGA","monkaHands","monkaInsane","monkaLaugh","monkaMEGA","monkaMultiple","monkaOh","monkaOMEGA","monkaPickle","monkaS","monkaShake","monkaShoot","monkaStab","monkaStare","monkaSteer","monkaSusp","monkaT","monkaThink","monkaTOS","monkaU","monkaVirus","monkaW","monkaWCB","monkaX","monkaYou","monkerS","NA","nanoMEGA","NeedCopium","Nerdge","noClown","NODDERS","NOOBA","NOP","NOPERS","Notsurege","Okayeg","Okayga","Okayge","OkaygeShrug","OkayLaugh","OkayW","oldpepe","OMEGAEZ","oniongang","PAUSERS","peep","PeepHand","peepo","peepo2","peepoAlliance","peepoBaba","peepoBlankey","peepoBritish","peepoBye","peepoCat","peepoChonk","peepoChop","peepoClap","peepoComfy","peepoDab","peepoEhm","peepoEvilSip","peepofeet","peepoFoil","peepoFR1","peepoFR2","peepoGhost","peepoGiggle","peepoGroovie","peepoHeart","peepoHehe","peepoHey","peepoHorse","peepoIsForMe","peepoJail","peepoJedi","peepoJorts","peepoJudge","peepoJuice","peepoLoser","peepoM","peepoMadder","peepoNotes","peepoPanda","peepoParty","peepoPlease","peepoPolice","peepoRiot","peepoSadLogize","peepoScam","peepoShake","peepoShy","peepoSimp","peepoSimping","peepoSith","peepoSleepo","peepoSmash","peepoSoup","peepoSPopcorn","peepoStonks","peepoStrong","peepoSure","peepoSweat","peepoTeeth","peepoTrash","peepoWhy","peepoWow","PepeAyy","PepeBald","PepeBlyat","PepeBruh","PepeCat","PepeCatGun","PepeCatHeart","PepeCoffee","PepeCoolStory","PepeCozy","PepeCry","PepeDisgust","PepeDribble","PepeFlushed","PepeFrench","PepeFU","PepeFuming","PepegaCredit","PepegaHammer","PepegaHands","PepeGang","PepegaSad","PepeHammer","PepeHands","PepeHard","PepeHeart","PepeHmm","PepeHug","PepeJAM","PepeKMS","PepeL","PepeLa","PepeLaffe","PepeLegs","PepeLoser","PepeM","PepeMods","PepeNOOO","PepeNotOK","PepeOK","PepeOuuuhh","PepePains","PepePants","PepePhone","PepePhoned","PepePlan","PepePls","PepePoint","PepePoo","PepePopcorn","PepePuke","PepePyroblast","PepeReach","PepeRun","PepeScoots","PepeScout","PepeSith","PepeSlice","PepeSmile","PepeSmug","PepeStepBro","PepeStressed","PepeThumbsUp","pepeW","PepeWizard","PepeWot","PepeXD","pepoEZ","pepoGun","PepoHide","pepoS","PepoScience","PepoThink","PepperHands","Plotge","pogg","PoggersHype","POGGIES","PogO2","POOGERS","ppEZ","ppFootbol","ppHop","Prayge","RandomPepe","Ratge","Readge","Riotge","SadBlanket","Sadga","Sadge","sadgers","SadHug","SadLove","SadPepe","SAJ","sajj","SALAMI","salutt","shadowChatting","shrujj","Smadge","SMILERS","Smoge","SMUGGERS","SmugPepe","soupchamp","Starege","Stronge","SucksMan","Susge","Suske","Thinkge","TiredW","tomatogang","TroggHYPERS","UHM","Voidge","Weirdga","Weirdge","WeirdJAM","WeirdU","WeirdW","WICKED","WickedDrip","WICKEDSTEER","widepeepoHappy","widepeepoLove","widepeepoPride","widepeepoSad","widepeepoWeird","WideSadge","widestpeepoHappy","widestpeepoSad","Wipege","WOAW","Wokege","Wokegesus","YEP","Yepge","YEPPERS","yikers"},
[13]= {"peepo","peepaKiss","peepoAP","peepoBeer","peepoBlanket","peepoBlush","peepoBored","peepoCool","peepoCringe","peepoCute","peepoExit","peepoEZ","peepoFA","peepoFat","peepoFH","peepoFight","peepoFriends","peepoGlad","peepoGun","peepoHands","peepoHide","peepoHit","peepoHmm","peepoHug","peepoHugged","peepoKEKW","peepoKiss","peepoKnight","peepoLip","peepoLove","peepoMaybe","peepoNo","peepoNolegs","peepoNOO","peepoOK","peepoPants","peepoPat","peepoPee","peepoPeek","peepoPlot","peepoPoint","peepoPoo","peepoPride","peepoRain","peepoReallyHappy","peepoS","peepoSad","peepoSalute","peepoSenor","peepoShrug","peepoSick","peepoSip","peepoSmile","peepoStudy","peepoSuspect","peepoSuspicious","peepoTalk","peepoTeddy","peepoThink","peepoTired","peepoUgh","peepoWave","peepoWoW","peepoWTF","peepoYes","pillowJammies"},
[14]= {"Suze4Mumes Life","ANELELUL","angery","beamB","beamBrah","beenocs","bricky","bubby","CaptainSuze","ClownBall","ClownPain","coffeeS","EZGiggle","FeelsCozyMan","FeelsDankMan","FeelsShadowMan","GAmer","JanCarlo2","miffs","mumes","PauseChamp","peep420","peepKing","peepoCheer","peepoChef","peepoChrist","peepoCozy","peepoCrown","peepoCry","peepoDK","peepoEZSip","peepoH","peepOK","peepoKing","peepoKnife","peepoKnifeNANI","peepoMad","peepoStab","peepoSuze","peepoWeirdCrown","PepeBed","PepeChill","PepeClown","PepeCool","PepeCop","PepeGiggle","PepeGod","PepeHacker","PepeKing","PepeKingLove","PepeRuski","PepeScience","PepeSmurf","PepeSoldier","PepeSpartan","PepeStudy","PepeSurgeon","PepeSuspect","PepeWave","PepeWheels","PogChampius","PogO","potter","SadHonk","SchubertSmile","spit1","spit2","suze4animals","suze4food","suze4know","suze4study","suzeOK","TheBoys","WeirdChampius"},
[15]= {"Ren Custom","0Head","1Head","2Head","3Head","3Lass","4HEader","4Mansion","4Shrug","4Weird","5Hard","5Head",":fluff2:",":fluff:","AMAZINGA","BaconEffect","BlackKnight","Boomer","BroKiss","cmoN","cmonEyes","CrazyChamp","DisappointChamp","DKKona","FLOPPERS","HYPERDANSGAMEW","KEKL","KEKSad","KEKW","KEKWeird","kkOna","KKonaW","LULChamp","LULWW","MaldChamp","MaN","NaM","noxSorry","OhISee","OkayChamp","OldChamp","PATHETIC","PikaWOW","pOg","Pogey","PogeyU","Poghurt","PogWarts","SadChamp","SillyChamp","StareChamp","TriEasy","TriGold","TriHardo","TriHardS","TriKool","TriPeek","VaN","WeirdBruh","WeirdChamp","WhiteKnight","WutChamp"},
[16]= {"Chromie","CavemanBob","CcKekThas","CcMile","Dedge","GusFring"},
@@ -501,6 +501,49 @@ end
local EmoticonChatFrameDropDown = CreateFrame("Frame", "EmoticonChatFrameDropDown", UIParent, "UIDropDownMenuTemplate")
UIDropDownMenu_Initialize(EmoticonChatFrameDropDown, Emoticons_LoadChatFrameDropdown, "MENU", 1)
-- ToggleDropDownMenu only tests whether a list runs off the bottom or the
-- right of the screen, flips its anchor once and never re-measures, so a list
-- flipped upwards overflows the top instead (a 40-row emote page opened from a
-- submenu halfway down the screen), and its off-screen-X test compares the
-- list's own coordinates against pixel widths, flipping submenus left even
-- when that pushes them past the left edge. Nudge our own lists back inside
-- the screen after it has positioned them; the emote pages are at most
-- 40 * UIDROPDOWNMENU_BUTTON_HEIGHT + borders tall, so they always fit.
local function Emoticons_ClampDropDownList(level)
local list = _G["DropDownList"..level];
if (not list or not list:IsShown()) then return end
local scale = list:GetEffectiveScale();
local uiScale = UIParent:GetEffectiveScale();
local left, right = list:GetLeft(), list:GetRight();
local bottom, top = list:GetBottom(), list:GetTop();
if (not left or not bottom) then return end
-- Everything below is in screen pixels, since the list carries a scale of
-- its own (ToggleDropDownMenu sets it from the uiscale cvar).
left, right, bottom, top = left * scale, right * scale, bottom * scale, top * scale;
local screenWidth = GetScreenWidth() * uiScale;
local screenHeight = GetScreenHeight() * uiScale;
local dx, dy = 0, 0;
if (right > screenWidth) then dx = screenWidth - right end
if (left + dx < 0) then dx = -left end -- a list wider than the screen keeps its left edge
if (top > screenHeight) then dy = screenHeight - top end
if (bottom + dy < 0) then dy = -bottom end
if (dx == 0 and dy == 0) then return end
-- UIParent's BOTTOMLEFT is screen pixel (0,0); SetPoint offsets are in the
-- units of the frame being moved, so scale the corrected position back down.
list:ClearAllPoints();
list:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", (left + dx) / scale, (top + dy) / scale);
end
local Emoticons_Orig_ToggleDropDownMenu = ToggleDropDownMenu;
function ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset)
Emoticons_Orig_ToggleDropDownMenu(level, value, dropDownFrame, anchorName, xOffset, yOffset);
-- Submenus are opened by the list buttons themselves with no dropDownFrame,
-- so identify ours by the menu ToggleDropDownMenu just recorded as open.
if (UIDROPDOWNMENU_OPEN_MENU == "EmoticonChatFrameDropDown") then
Emoticons_ClampDropDownList(level or 1);
end
end
do
local pending, seen = {}, {}
for _, group in ipairs(dropdown_options) do
+4 -25
View File
@@ -1,29 +1,8 @@
## Interface: 11200
## Title: |TInterface\Addons\TwitchEmotes\Emotes\Pepes\EZ:0|t|cff6441a5Twitch|r |cffffffffEmotes|r|TInterface\Addons\TwitchEmotes\Emotes\Pepes\EZ:0|t
## IconTexture: Interface\AddOns\TwitchEmotes\Emotes\1337.tga
## Notes: Adds popular Twitch & Discord emotes to your chat. Developed by Ren - 1.12.1 backport by Brues
## Author: Ren
## Title: TwitchEmotes (MISSING CLASSICAPI)
## Notes: If you're seeing this, ClassicAPI has failed to load.
## Author: Brues
## Version: @project-version@
## SavedVariables: Emoticons_Settings, Emoticons_Eyecandy, TwitchEmoteStatistics
## OptionalDeps: LibStub
## LoadSavedVariablesFirst: 1
# Libraries (Ace3v — the 1.12.1 fork of Ace3)
Libs\LibStub\LibStub.lua
Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
Libs\AceCore-3.0\AceCore-3.0.xml
Libs\AceHook-3.0\AceHook-3.0.xml
Libs\libdatabroker-1-1\LibDataBroker-1.1.lua
Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
Libs\AceConsole-3.0\AceConsole-3.0.xml
Libs\AceGUI-3.0\AceGUI-3.0.xml
Libs\AceGUI-3.0\widgets\widgets.xml
Libs\AceConfig-3.0\AceConfig-3.0.xml
Emotes.lua
TwitchEmotes.lua
TwitchEmotesAutoComplete.lua
TwitchEmotesStats.lua
TwitchEmotesAnimator.lua
CAPI_Warning.lua
+27 -12
View File
@@ -1,8 +1,8 @@
-- Animated emotes are vertical sprite sheets; TwitchEmotes_animation_metadata
-- Animated emotes are sprite sheets; TwitchEmotes_animation_metadata
-- (Emotes.lua) maps each sheet's texture path to its frame layout. ClassicAPI's
-- inline-texture renderer supports the extended
-- |Tpath:w:h:0:0:imgW:imgH:0:frameW:top:bottom|t form (sprite-sheet crop), so we
-- animate by re-SetText-ing each visible FontString ~30fps with the current
-- |Tpath:w:h:0:0:imgW:imgH:left:right:top:bottom|t form (sprite-sheet crop), so
-- we animate by re-SetText-ing each visible FontString ~30fps with the current
-- frame's crop. On 1.12 a ScrollingMessageFrame's visible lines are real
-- CSimpleFontStrings exposed as the ChatFrame's FontString regions, so they can
-- be rewritten in place — the same way the retail TwitchEmotesAnimator does it.
@@ -21,18 +21,33 @@ local function GetCurrentFrameNum(animdata)
return math.floor((TWITCHEMOTES_T * animdata.framerate) % animdata.nFrames)
end
-- Crop a Texture (not inline text) to its animdata's current frame.
local function CropToCurrentFrame(tex, animdata)
local top = GetCurrentFrameNum(animdata) * animdata.frameHeight / animdata.imageHeight
tex:SetTexCoord(0, 1, top, top + animdata.frameHeight / animdata.imageHeight)
-- Frames run row-major across however many columns the sheet is wide, since a
-- run longer than 32 frames outgrows the 1024px decode scratch as one strip.
-- Older sheets are packed more densely than that: before ClassicAPI's texture
-- dimension gate a sheet skinnier than 16:1 drew nothing, so runs wrapped at 16
-- frames. Deriving the column count from the sheet handles either.
local function GetFrameRect(animdata, framenum)
local cols = math.floor(animdata.imageWidth / animdata.frameWidth)
if cols < 1 then cols = 1 end
local left = (framenum % cols) * animdata.frameWidth
local top = math.floor(framenum / cols) * animdata.frameHeight
return left, left + animdata.frameWidth, top, top + animdata.frameHeight
end
-- Crop a Texture (not inline text) to its animdata's current frame.
local function CropToCurrentFrame(tex, animdata)
local left, right, top, bottom = GetFrameRect(animdata, GetCurrentFrameNum(animdata))
tex:SetTexCoord(left / animdata.imageWidth, right / animdata.imageWidth,
top / animdata.imageHeight, bottom / animdata.imageHeight)
end
-- The crop bounds are texel offsets, so emit them as integers rather than
-- letting a float from the frame maths stringify into the payload.
local function BuildFrameString(imagepath, animdata, framenum, w, h)
local top = framenum * animdata.frameHeight
local bottom = top + animdata.frameHeight
return "|T" .. imagepath .. ":" .. w .. ":" .. h .. ":0:0:" ..
animdata.imageWidth .. ":" .. animdata.imageHeight .. ":0:" ..
animdata.frameWidth .. ":" .. top .. ":" .. bottom .. "|t"
local left, right, top, bottom = GetFrameRect(animdata, framenum)
return ("|T%s:%d:%d:0:0:%d:%d:%d:%d:%d:%d|t"):format(imagepath, w, h,
animdata.imageWidth, animdata.imageHeight,
left, right, top, bottom)
end
-- escape the pattern-magic chars that can appear in an emote escape (paths use
+2 -1
View File
@@ -158,7 +158,8 @@ local function showPopup(eb, results)
-- animated emote sheets crop to a frame; the animator advances it
b.animdata = TwitchEmotes_animation_metadata and TwitchEmotes_animation_metadata[tex]
if b.animdata then
b.ico:SetTexCoord(0, 1, 0, b.animdata.frameHeight / b.animdata.imageHeight)
b.ico:SetTexCoord(0, b.animdata.frameWidth / b.animdata.imageWidth,
0, b.animdata.frameHeight / b.animdata.imageHeight)
else
b.ico:SetTexCoord(0, 1, 0, 1)
end
+18 -9
View File
@@ -49,8 +49,13 @@ local WIN_H = 516
local FALLBACK_TEX = "Interface\\AddOns\\TwitchEmotes\\Emotes\\1337.tga"
local BORDER_TEX = "Interface\\ItemSocketingFrame\\UI-EngineeringSockets"
local BORDER = { left = 0.015625, right = 0.6875, top = 0.41210938, bottom = 0.49609375 }
-- Same panel styling as the autocomplete popup.
local FEATURED_BACKDROP = {
bgFile = "Interface\\Buttons\\WHITE8X8",
edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
tile = true, tileSize = 8, edgeSize = 8,
insets = { left = 3, right = 3, top = 3, bottom = 3 },
}
local sentKeys = {}
local seenKeys = {}
@@ -84,7 +89,8 @@ local function setTopEmote(tex, emote)
-- store animdata so the animator can crop frames; frame 0 as the base
tex.animdata = tga and TwitchEmotes_animation_metadata and TwitchEmotes_animation_metadata[tga]
if tex.animdata then
tex:SetTexCoord(0, 1, 0, tex.animdata.frameHeight / tex.animdata.imageHeight)
tex:SetTexCoord(0, tex.animdata.frameWidth / tex.animdata.imageWidth,
0, tex.animdata.frameHeight / tex.animdata.imageHeight)
else
tex:SetTexCoord(0, 1, 0, 1)
end
@@ -183,15 +189,18 @@ local function makeFeatured(f, label, centerX)
title:SetPoint("CENTER", f, "TOPLEFT", centerX, -52)
title:SetText(label)
local border = f:CreateTexture(nil, "ARTWORK")
border:SetTexture(BORDER_TEX)
-- a frame rather than a texture, so the emote can sit on its OVERLAY layer
-- above the backdrop
local border = CreateFrame("Frame", nil, f)
border:SetSize(86, 86)
border:SetTexCoord(BORDER.left, BORDER.right, BORDER.top, BORDER.bottom)
border:SetPoint("CENTER", f, "TOPLEFT", centerX, -108)
border:SetBackdrop(FEATURED_BACKDROP)
border:SetBackdropColor(0.05, 0.05, 0.05, 0.95)
border:SetBackdropBorderColor(1, 1, 1, 1)
local tex = f:CreateTexture(nil, "OVERLAY")
local tex = border:CreateTexture(nil, "OVERLAY")
tex:SetSize(70, 70)
tex:SetPoint("CENTER", f, "TOPLEFT", centerX, -108)
tex:SetPoint("CENTER", border, "CENTER", 0, 0)
local cap = f:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
cap:SetPoint("CENTER", f, "TOPLEFT", centerX, -160)
@@ -211,7 +220,7 @@ local function buildWindow()
f:SetScript("OnDragStop", f.StopMovingOrSizing)
f:SetFrameStrata("HIGH")
f:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true, tileSize = 32, edgeSize = 32,
insets = { left = 11, right = 12, top = 12, bottom = 11 },
+28
View File
@@ -0,0 +1,28 @@
## Interface: 11200
## Title: |TInterface\Addons\TwitchEmotes\Emotes\Pepes\EZ:0|t|cff6441a5Twitch|r |cffffffffEmotes|r|TInterface\Addons\TwitchEmotes\Emotes\Pepes\EZ:0|t
## Notes: Adds popular Twitch & Discord emotes to your chat. Developed by Ren - 1.12.1 backport by Brues
## Author: Ren
## Version: @project-version@
## SavedVariables: Emoticons_Settings, Emoticons_Eyecandy, TwitchEmoteStatistics
## OptionalDeps: LibStub
## LoadSavedVariablesFirst: 1
# Libraries (Ace3v — the 1.12.1 fork of Ace3)
Libs\LibStub\LibStub.lua
Libs\CallbackHandler-1.0\CallbackHandler-1.0.lua
Libs\AceCore-3.0\AceCore-3.0.xml
Libs\AceHook-3.0\AceHook-3.0.xml
Libs\libdatabroker-1-1\LibDataBroker-1.1.lua
Libs\LibDBIcon-1.0\LibDBIcon-1.0.lua
Libs\AceConsole-3.0\AceConsole-3.0.xml
Libs\AceGUI-3.0\AceGUI-3.0.xml
Libs\AceGUI-3.0\widgets\widgets.xml
Libs\AceConfig-3.0\AceConfig-3.0.xml
Emotes.lua
TwitchEmotes.lua
TwitchEmotesAutoComplete.lua
TwitchEmotesStats.lua
TwitchEmotesAnimator.lua
+319
View File
@@ -0,0 +1,319 @@
#!/usr/bin/env python3
"""Add a BetterTTV emote to the addon.
python tools/add_emote.py https://betterttv.com/emotes/<id> PepeCool
python tools/add_emote.py <id> PepeCool --dir Pepes --pack Pepe
Downloads the emote, converts it to a texture the 1.12 client can decode, and
registers it in Emotes.lua (and in the minimap dropdown's pack list).
Two constraints drive the conversion:
* A sheet may not exceed 1024px per side, so an animation longer than 32
frames is packed row-major across several 32px columns rather than one
over-tall strip. TwitchEmotesAnimator derives the column count from
imageWidth / frameWidth.
* The animator plays frames at one constant rate off a ~30fps ticker, but a
GIF holds each frame for as long as it likes. The source timeline is
resampled at a constant rate instead: a long hold repeats, and a source
faster than the ticker (or too long for the frame budget) drops frames.
The loop keeps its original duration either way.
"""
import argparse
import bisect
import os
import re
import struct
import sys
import urllib.request
from PIL import Image, ImageSequence
CDN = 'https://cdn.betterttv.net/emote/%s/%s'
FRAME = 32 # cell height in the sheet; a wide emote's cell is wider
DISPLAY = 28 # rendered height in a chat line
MAX_TEXTURE = 1024 # side of the decode scratch, per side
MAX_COLS = 4 # 4 * 32 = 128px wide, 128 frames at most
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def emote_id(arg):
m = re.search(r'([0-9a-f]{24})', arg)
if not m:
sys.exit('not a BetterTTV emote id or URL: %s' % arg)
return m.group(1)
def download(eid):
last = None
for size in ('3x', '2x', '1x'):
try:
with urllib.request.urlopen(CDN % (eid, size), timeout=30) as r:
return r.read()
except Exception as exc: # noqa: BLE001 - try the next size
last = exc
sys.exit('could not download emote %s: %s' % (eid, last))
def cell_size(source):
"""Frame cell for a source image: 32 tall, as wide as its aspect wants.
A wide emote squeezed into a square cell renders as a letterboxed sliver
with transparent bands, so the cell follows the source instead and the
escape carries a matching display size.
"""
w, h = source
width = max(1, int(round(FRAME * w / float(h))))
if abs(width - FRAME) <= 1:
width = FRAME # square enough; keep the common path
return width, FRAME
def load_frames(blob):
"""Frames at the source's cell size, plus each frame's duration in ms."""
from io import BytesIO
im = Image.open(BytesIO(blob))
cw, ch = cell_size(im.size)
frames, durations = [], []
for page in ImageSequence.Iterator(im):
rgba = page.convert('RGBA')
fitted = Image.new('RGBA', (cw, ch), (0, 0, 0, 0))
scaled = rgba.copy()
scaled.thumbnail((cw, ch), Image.LANCZOS)
fitted.paste(scaled, ((cw - scaled.width) // 2, (ch - scaled.height) // 2))
frames.append(fitted)
durations.append(page.info.get('duration') or 0)
# A GIF delay under 20ms means "as fast as possible"; browsers clamp it to
# 100ms, so that is the speed the emote actually plays at where people see
# it. Taken literally, a sheet of zero-delay frames looks like a 0-second
# animation and collapses to one frame.
durations = [d if d >= 20 else 100 for d in durations]
return frames, durations, (cw, ch)
TICKER_FPS = 30 # TwitchEmotesAnimator advances frames on a ~30fps ticker
def resample(durations, budget):
"""Sample the source timeline at a constant rate the animator can play.
Returns (fps, indices): which source frame to show on each tick. Sampling
handles both directions - a frame held longer than a tick repeats, and a
source faster than the ticker (or too long for the frame budget) drops
frames. Either way the loop keeps the source's duration, which matters more
than showing every frame: nothing above the ticker rate can be displayed
anyway.
"""
total = sum(durations)
if not total:
sys.exit('animation has no frame delays to time it by')
shortest = min(d for d in durations if d > 0)
fps = min(TICKER_FPS, max(1, int(round(1000.0 / shortest))))
while fps > 1 and int(round(total * fps / 1000.0)) > budget:
fps -= 1
count = max(1, int(round(total * fps / 1000.0)))
if count > budget:
sys.exit('animation does not fit in %d frames' % budget)
ends, acc = [], 0
for d in durations:
acc += d
ends.append(acc)
indices = []
for tick in range(count):
at = (tick + 0.5) * total / count # middle of the tick
indices.append(min(bisect.bisect_left(ends, at), len(durations) - 1))
return fps, indices
def max_frames(cell):
"""Most frames `layout` can pack for this cell shape within MAX_TEXTURE.
A non-square cell stays single-column (see `layout`), so its budget is
shallower than a square cell's, which can spread across MAX_COLS.
"""
cw, ch = cell
cols = MAX_COLS if cw == FRAME else 1
return cols * (MAX_TEXTURE // ch)
def layout(count, cell):
"""Column count and texture size for `count` frames.
ClassicAPI's dimension gate lifts 1.12's power-of-two rule and grows the
decode scratch to fit, so the sheet is sized to its frames exactly. One
limit is left - the scratch's own side, 1024 - which a run longer than 32
frames outgrows, so it wraps into further 32px columns.
(A sheet skinnier than 16:1 used to draw nothing, which forced columns much
sooner. That was never a client rule: VanillaHelpers grew the texture
recycle pool to 6x6 but left the index stride at 5, so a 32x1024 strip
collided with a 64x32 bucket and got handed back the wrong texture. The gate
rewrites both index sites to stride 6.)
A non-square cell stays single-column: the animator derives its column count
as imageWidth / frameWidth, which only holds when the cell tiles the texture
width exactly.
"""
cw, ch = cell
for cols in ((1,) if cw != FRAME else (1, 2, 4)):
width = cols * cw
rows = -(-count // cols)
height = rows * ch
if max(width, height) <= MAX_TEXTURE:
return cols, width, height
sys.exit('%d frames of %dx%d do not fit a sheet within %dpx'
% (count, cw, ch, MAX_TEXTURE))
def write_tga(im, path):
"""Uncompressed 32-bit BGRA, top-down origin - what the client decodes."""
w, h = im.size
r, g, b, a = im.split()
header = struct.pack('<BBBHHBHHHHBB', 0, 0, 2, 0, 0, 0, 0, 0, w, h, 32, 0x28)
os.makedirs(os.path.dirname(path), exist_ok=True)
with open(path, 'wb') as f:
f.write(header)
f.write(Image.merge('RGBA', (b, g, r, a)).tobytes())
def build_sheet(frames, indices, cell):
cw, ch = cell
expanded = [frames[i] for i in indices]
cols, width, height = layout(len(expanded), cell)
sheet = Image.new('RGBA', (width, height), (0, 0, 0, 0))
for i, frame in enumerate(expanded):
sheet.paste(frame, ((i % cols) * cw, (i // cols) * ch))
return sheet, len(expanded), cols, width, height
def insert_before(text, anchor, line):
at = text.rindex(anchor)
return text[:at] + line + '\n' + text[at:]
def register(name, basename, texdir, pack, cell, tex, sheet_info, replace=False):
"""Add the emote to defaultpack, emoticons, the animation table and the menu."""
path = 'Interface\\\\AddOns\\\\TwitchEmotes\\\\Emotes\\\\%s\\\\%s.tga' % (texdir, basename)
emotes_lua = os.path.join(ROOT, 'Emotes.lua')
src = open(emotes_lua, encoding='utf-8').read()
known = '["%s"]=' % name in src or '["%s"] =' % name in src
if known and not replace:
sys.exit('%s is already registered in Emotes.lua (pass --replace to '
'update it in place)' % name)
# The payload reads HEIGHT first, then width (ParseIcon in ClassicAPI's
# InlineTexture.cpp), so a wide emote is ':28:<wider>'. A square still frame
# needs no crop; anything else does, to pick its cell out of the texture.
cw, ch = cell
display = '%d:%d' % (DISPLAY, int(round(DISPLAY * cw / float(ch))))
if sheet_info or cell != (FRAME, FRAME):
spec = '%s:%s:0:0:%d:%d:0:%d:0:%d' % (path, display, tex[0], tex[1], cw, ch)
else:
spec = '%s:%s' % (path, display)
if known:
# Only the texture spec changes; the emoticons entry and the menu
# already name this emote. Match the defaultpack row by its value, so
# the emoticons row (name -> name) is left alone.
src, hits = re.subn(r'(\["%s"\]\s*=\s*")Interface\\\\AddOns[^"]*(")'
% re.escape(name), lambda m: m.group(1) + spec + m.group(2),
src, count=1)
if hits != 1:
sys.exit('could not find the defaultpack row for %s' % name)
else:
# defaultpack (name -> texture) and emoticons (typed token -> name) are
# two separate tables; Emoticons_Deformat walks emoticons and indexes
# defaultpack with the same key, so both need the name.
src = insert_before(src, '\n };\n emoticons={',
'\t["%s"]="%s",' % (name, spec))
src = insert_before(src, '\n };\n\nTwitchEmotes_animation_metadata',
'\t["%s"]="%s",' % (name, name))
# A sheet needs an animation entry; a static texture must not have one.
src = re.sub(r'\t\["%s"\] = \{\["nFrames"\][^\n]*\n' % re.escape(path), '', src)
if sheet_info:
nframes, fps = sheet_info
entry = ('\t["%s"] = {["nFrames"] = %d, ["frameWidth"] = %d, '
'["frameHeight"] = %d, ["imageWidth"]=%d, ["imageHeight"]=%d, '
'["framerate"] = %d},' %
(path, nframes, cw, ch, tex[0], tex[1], fps))
src = src.rstrip('\n')
assert src.endswith('}'), 'unexpected end of Emotes.lua'
src = src[:-1] + entry + '\n}\n'
open(emotes_lua, 'w', encoding='utf-8', newline='').write(src)
if known:
return
# dropdown_options in TwitchEmotes.lua drives the minimap menu; keep each
# pack sorted, since the submenu pages are labelled by their first and last
# entry.
main_lua = os.path.join(ROOT, 'TwitchEmotes.lua')
main = open(main_lua, encoding='utf-8').read()
pat = re.compile(r'(\[\d+\]=\s*\{"%s"(.*?)\},\n)' % re.escape(pack))
m = pat.search(main)
if not m:
sys.exit('no dropdown pack named %r in TwitchEmotes.lua' % pack)
names = re.findall(r'"([^"]*)"', m.group(1))
if name in names[1:]:
sys.exit('%s is already in the %s menu' % (name, pack))
body = sorted(names[1:] + [name], key=lambda s: s.lower())
# the match starts at '[' so the line's existing indent is already in place
line = '[%s]= {%s},\n' % (
re.match(r'\[(\d+)\]', m.group(1)).group(1),
','.join('"%s"' % n for n in [names[0]] + body))
main = main[:m.start(1)] + line + main[m.end(1):]
open(main_lua, 'w', encoding='utf-8', newline='').write(main)
def main():
ap = argparse.ArgumentParser(description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter)
ap.add_argument('emote', help='BetterTTV emote id or URL')
ap.add_argument('name', help='chat trigger word, e.g. PepeCool')
ap.add_argument('--file', help='texture basename, when the trigger word is not a '
'legal filename (:Cinema: -> --file Cinema)')
ap.add_argument('--dir', default='Custom', help='folder under Emotes/ (default: Custom)')
ap.add_argument('--pack', default='Custom', help='minimap menu pack (default: Custom)')
ap.add_argument('--replace', action='store_true',
help='update an emote that is already registered')
ap.add_argument('--dry-run', action='store_true', help='report only, write nothing')
args = ap.parse_args()
if not re.match(r'^[%:\w]+$', args.name):
sys.exit('name must be a plain word or :token: - got %r' % args.name)
basename = args.file or args.name
if not re.match(r'^\w+$', basename):
sys.exit('%r is not a legal filename; pass --file' % basename)
frames, durations, cell = load_frames(download(emote_id(args.emote)))
tga = os.path.join(ROOT, 'Emotes', args.dir, basename + '.tga')
shape = '%dx%d cell' % cell if cell != (FRAME, FRAME) else 'square'
if len(frames) == 1:
cols, tw, th = layout(1, cell)
sheet = Image.new('RGBA', (tw, th), (0, 0, 0, 0))
sheet.paste(frames[0], (0, 0))
info = None
print('%s: static, %s in a %dx%d texture' % (args.name, shape, tw, th))
else:
fps, indices = resample(durations, max_frames(cell))
sheet, nframes, cols, tw, th = build_sheet(frames, indices, cell)
info = (nframes, fps)
print('%s: %d source frames (%.2fs) -> %d frames at %dfps (%.2fs, '
'%d of the source frames kept), %s, %dx%d sheet in %d column(s)' %
(args.name, len(frames), sum(durations) / 1000.0, nframes, fps,
nframes / float(fps), len(set(indices)), shape, tw, th, cols))
if args.dry_run:
print('dry run: would write %s' % os.path.relpath(tga, ROOT))
return
write_tga(sheet, tga)
register(args.name, basename, args.dir, args.pack, cell, (tw, th), info, args.replace)
print('wrote %s and %s' % (os.path.relpath(tga, ROOT),
'updated its registration' if args.replace
else 'registered it in the %s pack' % args.pack))
if __name__ == '__main__':
main()