Four more modules into Nim: members, glyphs, emoji, store
Not deleted from `common/` — CLAUDE.md is explicit that the ClojureDart
original stays as the web's implementation until there is a wasm build, and
deleting one would take the web target with it. This is the port, not a
removal.
`members` brought a model change with it. `Room.users` was a list of names and
is now nick → mode prefix, because the panel sorts ops first and a MODE has to
find one person among many. With it: 353 accumulating into a pending list and
366 promoting it — replacing the list on each 353 empties the panel and refills
it a name at a time — and MODE, which is the fiddly one. A mode that takes an
argument without naming a member still eats one, so `+ko secret alice` ops
alice rather than putting the op on whoever `secret` matched. There is a test
for exactly that.
`emoji` is generated, not typed. `tools/emoji2nim.py` reads the Clojure and
emits the Nim — 1,884 entries, matching row for row — because the catalogue is
Unicode's own list and a second hand-maintained copy is how two languages
start disagreeing about what can be drawn. `just test emoji` regenerates it.
`glyphs` splits a line into words and pictures on top of that. Longest match
first, because 👨 is the head of 👨👩👧 and taking the man would leave his
family as three more glyphs and two tofu joiners; and a skin tone is stripped
for the lookup and kept for the drawing, since the catalogue leaves toned
variants out and the pack has them.
`store` is JSON rather than EDN. The Clojure writes through the `frq.io` seam
because ClojureDart had no portable filesystem; Nim has one, so the seam is
gone — and nothing but this reads these files, so a format with a parser in the
standard library is one less thing to get wrong. Every read treats a file that
will not parse as absent: a stale credential is not worth an error at startup,
and a room with a broken marker would count its whole history unread. The
session file is created and then restricted, because there is no atomic
create-with-mode here and the alternative is a token written world-readable and
never narrowed.
Three of my own tests were wrong before the code was: `completeNick("bo", …)`
at position 0 really is the start of a line, so `bob: ` is right and `bob ` was
my expectation rather than the rule.
258 Nim tests, 20 Dart, 21 layout, no warnings, and the window still reaches
#test with 114 lines and no layout errors.
Remaining Clojure logic with no Nim yet: msgsig and crypto (ed25519, which
needs a dependency or an implementation — the core has no dependencies outside
Nim's stdlib today), profile, and replies.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>3975b4b parent: 4dfc719 modified
justfile +1 -0 | @@ -107,6 +107,7 @@ test suite="all" *args: | ||
| 107 | 107 | all) just test common && just test nim && just test dart \ |
| 108 | 108 | && just test layout ;; |
| 109 | 109 | common) exec python3 tools/check-common.py common ;; |
| 110 | + emoji) exec python3 tools/emoji2nim.py ;; | |
| 110 | 111 | layout) just _nim-lib |
| 111 | 112 | just _flutter layout test ;; |
| 112 | 113 | nim) just _nim-test "$@" ;; |
| @@ -107,6 +107,7 @@ test suite="all" *args: | |||
| 107 | all) just test common && just test nim && just test dart \ | 107 | all) just test common && just test nim && just test dart \ |
| 108 | && just test layout ;; | 108 | && just test layout ;; |
| 109 | common) exec python3 tools/check-common.py common ;; | 109 | common) exec python3 tools/check-common.py common ;; |
| 110 | + emoji) exec python3 tools/emoji2nim.py ;; | ||
| 110 | layout) just _nim-lib | 111 | layout) just _nim-lib |
| 111 | just _flutter layout test ;; | 112 | just _flutter layout test ;; |
| 112 | nim) just _nim-test "$@" ;; | 113 | nim) just _nim-test "$@" ;; |
added
nim/src/frq/emoji.nim +1920 -0 | new file mode 100644 | ||
| @@ -0,0 +1,1920 @@ | ||
| 1 | +## Every emoji this client can draw, with the name to search it by. | |
| 2 | +## | |
| 3 | +## GENERATED by tools/emoji2nim.py from common/frq/emoji.cljc. Do not edit: | |
| 4 | +## the catalogue is Unicode's own `emoji-test.txt` (15.1), filtered to what | |
| 5 | +## the Twemoji pack has a picture for, and a second hand-maintained copy is | |
| 6 | +## how the two languages start disagreeing about what can be drawn. | |
| 7 | +## | |
| 8 | +## Skin-tone variants are left out — they multiply the list by five and say | |
| 9 | +## nothing a reaction needs to say. `glyphs` strips a tone before looking a | |
| 10 | +## glyph up here, and keeps it for the drawing. | |
| 11 | + | |
| 12 | +type | |
| 13 | + Emoji* = object | |
| 14 | + glyph*, name*, group*: string | |
| 15 | + | |
| 16 | +const | |
| 17 | + popular* = [ | |
| 18 | + "👍", "❤️", "😂", "🎉", "👀", "🔥", "🙏", "😍", "😭", "😮", "👏", "💯", "✅", "🤔", "😅", "🚀" | |
| 19 | + ] | |
| 20 | + ## What a reaction usually is. The picker opens on these, because the | |
| 21 | + ## whole point of reacting is that it costs less than typing. | |
| 22 | + | |
| 23 | + groups* = [ | |
| 24 | + "Smileys & Emotion", | |
| 25 | + "People & Body", | |
| 26 | + "Animals & Nature", | |
| 27 | + "Food & Drink", | |
| 28 | + "Travel & Places", | |
| 29 | + "Activities", | |
| 30 | + "Objects", | |
| 31 | + "Symbols", | |
| 32 | + "Flags" | |
| 33 | + ] | |
| 34 | + | |
| 35 | + catalog*: array[1884, Emoji] = [ | |
| 36 | + Emoji(glyph: "😀", name: "grinning face", group: "Smileys & Emotion"), | |
| 37 | + Emoji(glyph: "😃", name: "grinning face with big eyes", group: "Smileys & Emotion"), | |
| 38 | + Emoji(glyph: "😄", name: "grinning face with smiling eyes", group: "Smileys & Emotion"), | |
| 39 | + Emoji(glyph: "😁", name: "beaming face with smiling eyes", group: "Smileys & Emotion"), | |
| 40 | + Emoji(glyph: "😆", name: "grinning squinting face", group: "Smileys & Emotion"), | |
| 41 | + Emoji(glyph: "😅", name: "grinning face with sweat", group: "Smileys & Emotion"), | |
| 42 | + Emoji(glyph: "🤣", name: "rolling on the floor laughing", group: "Smileys & Emotion"), | |
| 43 | + Emoji(glyph: "😂", name: "face with tears of joy", group: "Smileys & Emotion"), | |
| 44 | + Emoji(glyph: "🙂", name: "slightly smiling face", group: "Smileys & Emotion"), | |
| 45 | + Emoji(glyph: "🙃", name: "upside-down face", group: "Smileys & Emotion"), | |
| 46 | + Emoji(glyph: "🫠", name: "melting face", group: "Smileys & Emotion"), | |
| 47 | + Emoji(glyph: "😉", name: "winking face", group: "Smileys & Emotion"), | |
| 48 | + Emoji(glyph: "😊", name: "smiling face with smiling eyes", group: "Smileys & Emotion"), | |
| 49 | + Emoji(glyph: "😇", name: "smiling face with halo", group: "Smileys & Emotion"), | |
| 50 | + Emoji(glyph: "🥰", name: "smiling face with hearts", group: "Smileys & Emotion"), | |
| 51 | + Emoji(glyph: "😍", name: "smiling face with heart-eyes", group: "Smileys & Emotion"), | |
| 52 | + Emoji(glyph: "🤩", name: "star-struck", group: "Smileys & Emotion"), | |
| 53 | + Emoji(glyph: "😘", name: "face blowing a kiss", group: "Smileys & Emotion"), | |
| 54 | + Emoji(glyph: "😗", name: "kissing face", group: "Smileys & Emotion"), | |
| 55 | + Emoji(glyph: "☺️", name: "smiling face", group: "Smileys & Emotion"), | |
| 56 | + Emoji(glyph: "😚", name: "kissing face with closed eyes", group: "Smileys & Emotion"), | |
| 57 | + Emoji(glyph: "😙", name: "kissing face with smiling eyes", group: "Smileys & Emotion"), | |
| 58 | + Emoji(glyph: "🥲", name: "smiling face with tear", group: "Smileys & Emotion"), | |
| 59 | + Emoji(glyph: "😋", name: "face savoring food", group: "Smileys & Emotion"), | |
| 60 | + Emoji(glyph: "😛", name: "face with tongue", group: "Smileys & Emotion"), | |
| 61 | + Emoji(glyph: "😜", name: "winking face with tongue", group: "Smileys & Emotion"), | |
| 62 | + Emoji(glyph: "🤪", name: "zany face", group: "Smileys & Emotion"), | |
| 63 | + Emoji(glyph: "😝", name: "squinting face with tongue", group: "Smileys & Emotion"), | |
| 64 | + Emoji(glyph: "🤑", name: "money-mouth face", group: "Smileys & Emotion"), | |
| 65 | + Emoji(glyph: "🤗", name: "smiling face with open hands", group: "Smileys & Emotion"), | |
| 66 | + Emoji(glyph: "🤭", name: "face with hand over mouth", group: "Smileys & Emotion"), | |
| 67 | + Emoji(glyph: "🫢", name: "face with open eyes and hand over mouth", group: "Smileys & Emotion"), | |
| 68 | + Emoji(glyph: "🫣", name: "face with peeking eye", group: "Smileys & Emotion"), | |
| 69 | + Emoji(glyph: "🤫", name: "shushing face", group: "Smileys & Emotion"), | |
| 70 | + Emoji(glyph: "🤔", name: "thinking face", group: "Smileys & Emotion"), | |
| 71 | + Emoji(glyph: "🫡", name: "saluting face", group: "Smileys & Emotion"), | |
| 72 | + Emoji(glyph: "🤐", name: "zipper-mouth face", group: "Smileys & Emotion"), | |
| 73 | + Emoji(glyph: "🤨", name: "face with raised eyebrow", group: "Smileys & Emotion"), | |
| 74 | + Emoji(glyph: "😐", name: "neutral face", group: "Smileys & Emotion"), | |
| 75 | + Emoji(glyph: "😑", name: "expressionless face", group: "Smileys & Emotion"), | |
| 76 | + Emoji(glyph: "😶", name: "face without mouth", group: "Smileys & Emotion"), | |
| 77 | + Emoji(glyph: "🫥", name: "dotted line face", group: "Smileys & Emotion"), | |
| 78 | + Emoji(glyph: "😶🌫️", name: "face in clouds", group: "Smileys & Emotion"), | |
| 79 | + Emoji(glyph: "😏", name: "smirking face", group: "Smileys & Emotion"), | |
| 80 | + Emoji(glyph: "😒", name: "unamused face", group: "Smileys & Emotion"), | |
| 81 | + Emoji(glyph: "🙄", name: "face with rolling eyes", group: "Smileys & Emotion"), | |
| 82 | + Emoji(glyph: "😬", name: "grimacing face", group: "Smileys & Emotion"), | |
| 83 | + Emoji(glyph: "😮💨", name: "face exhaling", group: "Smileys & Emotion"), | |
| 84 | + Emoji(glyph: "🤥", name: "lying face", group: "Smileys & Emotion"), | |
| 85 | + Emoji(glyph: "🫨", name: "shaking face", group: "Smileys & Emotion"), | |
| 86 | + Emoji(glyph: "🙂↔️", name: "head shaking horizontally", group: "Smileys & Emotion"), | |
| 87 | + Emoji(glyph: "🙂↕️", name: "head shaking vertically", group: "Smileys & Emotion"), | |
| 88 | + Emoji(glyph: "😌", name: "relieved face", group: "Smileys & Emotion"), | |
| 89 | + Emoji(glyph: "😔", name: "pensive face", group: "Smileys & Emotion"), | |
| 90 | + Emoji(glyph: "😪", name: "sleepy face", group: "Smileys & Emotion"), | |
| 91 | + Emoji(glyph: "🤤", name: "drooling face", group: "Smileys & Emotion"), | |
| 92 | + Emoji(glyph: "😴", name: "sleeping face", group: "Smileys & Emotion"), | |
| 93 | + Emoji(glyph: "😷", name: "face with medical mask", group: "Smileys & Emotion"), | |
| 94 | + Emoji(glyph: "🤒", name: "face with thermometer", group: "Smileys & Emotion"), | |
| 95 | + Emoji(glyph: "🤕", name: "face with head-bandage", group: "Smileys & Emotion"), | |
| 96 | + Emoji(glyph: "🤢", name: "nauseated face", group: "Smileys & Emotion"), | |
| 97 | + Emoji(glyph: "🤮", name: "face vomiting", group: "Smileys & Emotion"), | |
| 98 | + Emoji(glyph: "🤧", name: "sneezing face", group: "Smileys & Emotion"), | |
| 99 | + Emoji(glyph: "🥵", name: "hot face", group: "Smileys & Emotion"), | |
| 100 | + Emoji(glyph: "🥶", name: "cold face", group: "Smileys & Emotion"), | |
| 101 | + Emoji(glyph: "🥴", name: "woozy face", group: "Smileys & Emotion"), | |
| 102 | + Emoji(glyph: "😵", name: "face with crossed-out eyes", group: "Smileys & Emotion"), | |
| 103 | + Emoji(glyph: "😵💫", name: "face with spiral eyes", group: "Smileys & Emotion"), | |
| 104 | + Emoji(glyph: "🤯", name: "exploding head", group: "Smileys & Emotion"), | |
| 105 | + Emoji(glyph: "🤠", name: "cowboy hat face", group: "Smileys & Emotion"), | |
| 106 | + Emoji(glyph: "🥳", name: "partying face", group: "Smileys & Emotion"), | |
| 107 | + Emoji(glyph: "🥸", name: "disguised face", group: "Smileys & Emotion"), | |
| 108 | + Emoji(glyph: "😎", name: "smiling face with sunglasses", group: "Smileys & Emotion"), | |
| 109 | + Emoji(glyph: "🤓", name: "nerd face", group: "Smileys & Emotion"), | |
| 110 | + Emoji(glyph: "🧐", name: "face with monocle", group: "Smileys & Emotion"), | |
| 111 | + Emoji(glyph: "😕", name: "confused face", group: "Smileys & Emotion"), | |
| 112 | + Emoji(glyph: "🫤", name: "face with diagonal mouth", group: "Smileys & Emotion"), | |
| 113 | + Emoji(glyph: "😟", name: "worried face", group: "Smileys & Emotion"), | |
| 114 | + Emoji(glyph: "🙁", name: "slightly frowning face", group: "Smileys & Emotion"), | |
| 115 | + Emoji(glyph: "☹️", name: "frowning face", group: "Smileys & Emotion"), | |
| 116 | + Emoji(glyph: "😮", name: "face with open mouth", group: "Smileys & Emotion"), | |
| 117 | + Emoji(glyph: "😯", name: "hushed face", group: "Smileys & Emotion"), | |
| 118 | + Emoji(glyph: "😲", name: "astonished face", group: "Smileys & Emotion"), | |
| 119 | + Emoji(glyph: "😳", name: "flushed face", group: "Smileys & Emotion"), | |
| 120 | + Emoji(glyph: "🥺", name: "pleading face", group: "Smileys & Emotion"), | |
| 121 | + Emoji(glyph: "🥹", name: "face holding back tears", group: "Smileys & Emotion"), | |
| 122 | + Emoji(glyph: "😦", name: "frowning face with open mouth", group: "Smileys & Emotion"), | |
| 123 | + Emoji(glyph: "😧", name: "anguished face", group: "Smileys & Emotion"), | |
| 124 | + Emoji(glyph: "😨", name: "fearful face", group: "Smileys & Emotion"), | |
| 125 | + Emoji(glyph: "😰", name: "anxious face with sweat", group: "Smileys & Emotion"), | |
| 126 | + Emoji(glyph: "😥", name: "sad but relieved face", group: "Smileys & Emotion"), | |
| 127 | + Emoji(glyph: "😢", name: "crying face", group: "Smileys & Emotion"), | |
| 128 | + Emoji(glyph: "😭", name: "loudly crying face", group: "Smileys & Emotion"), | |
| 129 | + Emoji(glyph: "😱", name: "face screaming in fear", group: "Smileys & Emotion"), | |
| 130 | + Emoji(glyph: "😖", name: "confounded face", group: "Smileys & Emotion"), | |
| 131 | + Emoji(glyph: "😣", name: "persevering face", group: "Smileys & Emotion"), | |
| 132 | + Emoji(glyph: "😞", name: "disappointed face", group: "Smileys & Emotion"), | |
| 133 | + Emoji(glyph: "😓", name: "downcast face with sweat", group: "Smileys & Emotion"), | |
| 134 | + Emoji(glyph: "😩", name: "weary face", group: "Smileys & Emotion"), | |
| 135 | + Emoji(glyph: "😫", name: "tired face", group: "Smileys & Emotion"), | |
| 136 | + Emoji(glyph: "🥱", name: "yawning face", group: "Smileys & Emotion"), | |
| 137 | + Emoji(glyph: "😤", name: "face with steam from nose", group: "Smileys & Emotion"), | |
| 138 | + Emoji(glyph: "😡", name: "enraged face", group: "Smileys & Emotion"), | |
| 139 | + Emoji(glyph: "😠", name: "angry face", group: "Smileys & Emotion"), | |
| 140 | + Emoji(glyph: "🤬", name: "face with symbols on mouth", group: "Smileys & Emotion"), | |
| 141 | + Emoji(glyph: "😈", name: "smiling face with horns", group: "Smileys & Emotion"), | |
| 142 | + Emoji(glyph: "👿", name: "angry face with horns", group: "Smileys & Emotion"), | |
| 143 | + Emoji(glyph: "💀", name: "skull", group: "Smileys & Emotion"), | |
| 144 | + Emoji(glyph: "☠️", name: "skull and crossbones", group: "Smileys & Emotion"), | |
| 145 | + Emoji(glyph: "💩", name: "pile of poo", group: "Smileys & Emotion"), | |
| 146 | + Emoji(glyph: "🤡", name: "clown face", group: "Smileys & Emotion"), | |
| 147 | + Emoji(glyph: "👹", name: "ogre", group: "Smileys & Emotion"), | |
| 148 | + Emoji(glyph: "👺", name: "goblin", group: "Smileys & Emotion"), | |
| 149 | + Emoji(glyph: "👻", name: "ghost", group: "Smileys & Emotion"), | |
| 150 | + Emoji(glyph: "👽", name: "alien", group: "Smileys & Emotion"), | |
| 151 | + Emoji(glyph: "👾", name: "alien monster", group: "Smileys & Emotion"), | |
| 152 | + Emoji(glyph: "🤖", name: "robot", group: "Smileys & Emotion"), | |
| 153 | + Emoji(glyph: "😺", name: "grinning cat", group: "Smileys & Emotion"), | |
| 154 | + Emoji(glyph: "😸", name: "grinning cat with smiling eyes", group: "Smileys & Emotion"), | |
| 155 | + Emoji(glyph: "😹", name: "cat with tears of joy", group: "Smileys & Emotion"), | |
| 156 | + Emoji(glyph: "😻", name: "smiling cat with heart-eyes", group: "Smileys & Emotion"), | |
| 157 | + Emoji(glyph: "😼", name: "cat with wry smile", group: "Smileys & Emotion"), | |
| 158 | + Emoji(glyph: "😽", name: "kissing cat", group: "Smileys & Emotion"), | |
| 159 | + Emoji(glyph: "🙀", name: "weary cat", group: "Smileys & Emotion"), | |
| 160 | + Emoji(glyph: "😿", name: "crying cat", group: "Smileys & Emotion"), | |
| 161 | + Emoji(glyph: "😾", name: "pouting cat", group: "Smileys & Emotion"), | |
| 162 | + Emoji(glyph: "🙈", name: "see-no-evil monkey", group: "Smileys & Emotion"), | |
| 163 | + Emoji(glyph: "🙉", name: "hear-no-evil monkey", group: "Smileys & Emotion"), | |
| 164 | + Emoji(glyph: "🙊", name: "speak-no-evil monkey", group: "Smileys & Emotion"), | |
| 165 | + Emoji(glyph: "💌", name: "love letter", group: "Smileys & Emotion"), | |
| 166 | + Emoji(glyph: "💘", name: "heart with arrow", group: "Smileys & Emotion"), | |
| 167 | + Emoji(glyph: "💝", name: "heart with ribbon", group: "Smileys & Emotion"), | |
| 168 | + Emoji(glyph: "💖", name: "sparkling heart", group: "Smileys & Emotion"), | |
| 169 | + Emoji(glyph: "💗", name: "growing heart", group: "Smileys & Emotion"), | |
| 170 | + Emoji(glyph: "💓", name: "beating heart", group: "Smileys & Emotion"), | |
| 171 | + Emoji(glyph: "💞", name: "revolving hearts", group: "Smileys & Emotion"), | |
| 172 | + Emoji(glyph: "💕", name: "two hearts", group: "Smileys & Emotion"), | |
| 173 | + Emoji(glyph: "💟", name: "heart decoration", group: "Smileys & Emotion"), | |
| 174 | + Emoji(glyph: "❣️", name: "heart exclamation", group: "Smileys & Emotion"), | |
| 175 | + Emoji(glyph: "💔", name: "broken heart", group: "Smileys & Emotion"), | |
| 176 | + Emoji(glyph: "❤️🔥", name: "heart on fire", group: "Smileys & Emotion"), | |
| 177 | + Emoji(glyph: "❤️🩹", name: "mending heart", group: "Smileys & Emotion"), | |
| 178 | + Emoji(glyph: "❤️", name: "red heart", group: "Smileys & Emotion"), | |
| 179 | + Emoji(glyph: "🩷", name: "pink heart", group: "Smileys & Emotion"), | |
| 180 | + Emoji(glyph: "🧡", name: "orange heart", group: "Smileys & Emotion"), | |
| 181 | + Emoji(glyph: "💛", name: "yellow heart", group: "Smileys & Emotion"), | |
| 182 | + Emoji(glyph: "💚", name: "green heart", group: "Smileys & Emotion"), | |
| 183 | + Emoji(glyph: "💙", name: "blue heart", group: "Smileys & Emotion"), | |
| 184 | + Emoji(glyph: "🩵", name: "light blue heart", group: "Smileys & Emotion"), | |
| 185 | + Emoji(glyph: "💜", name: "purple heart", group: "Smileys & Emotion"), | |
| 186 | + Emoji(glyph: "🤎", name: "brown heart", group: "Smileys & Emotion"), | |
| 187 | + Emoji(glyph: "🖤", name: "black heart", group: "Smileys & Emotion"), | |
| 188 | + Emoji(glyph: "🩶", name: "grey heart", group: "Smileys & Emotion"), | |
| 189 | + Emoji(glyph: "🤍", name: "white heart", group: "Smileys & Emotion"), | |
| 190 | + Emoji(glyph: "💋", name: "kiss mark", group: "Smileys & Emotion"), | |
| 191 | + Emoji(glyph: "💯", name: "hundred points", group: "Smileys & Emotion"), | |
| 192 | + Emoji(glyph: "💢", name: "anger symbol", group: "Smileys & Emotion"), | |
| 193 | + Emoji(glyph: "💥", name: "collision", group: "Smileys & Emotion"), | |
| 194 | + Emoji(glyph: "💫", name: "dizzy", group: "Smileys & Emotion"), | |
| 195 | + Emoji(glyph: "💦", name: "sweat droplets", group: "Smileys & Emotion"), | |
| 196 | + Emoji(glyph: "💨", name: "dashing away", group: "Smileys & Emotion"), | |
| 197 | + Emoji(glyph: "🕳️", name: "hole", group: "Smileys & Emotion"), | |
| 198 | + Emoji(glyph: "💬", name: "speech balloon", group: "Smileys & Emotion"), | |
| 199 | + Emoji(glyph: "👁️🗨️", name: "eye in speech bubble", group: "Smileys & Emotion"), | |
| 200 | + Emoji(glyph: "🗨️", name: "left speech bubble", group: "Smileys & Emotion"), | |
| 201 | + Emoji(glyph: "🗯️", name: "right anger bubble", group: "Smileys & Emotion"), | |
| 202 | + Emoji(glyph: "💭", name: "thought balloon", group: "Smileys & Emotion"), | |
| 203 | + Emoji(glyph: "💤", name: "ZZZ", group: "Smileys & Emotion"), | |
| 204 | + Emoji(glyph: "👋", name: "waving hand", group: "People & Body"), | |
| 205 | + Emoji(glyph: "🤚", name: "raised back of hand", group: "People & Body"), | |
| 206 | + Emoji(glyph: "🖐️", name: "hand with fingers splayed", group: "People & Body"), | |
| 207 | + Emoji(glyph: "✋", name: "raised hand", group: "People & Body"), | |
| 208 | + Emoji(glyph: "🖖", name: "vulcan salute", group: "People & Body"), | |
| 209 | + Emoji(glyph: "🫱", name: "rightwards hand", group: "People & Body"), | |
| 210 | + Emoji(glyph: "🫲", name: "leftwards hand", group: "People & Body"), | |
| 211 | + Emoji(glyph: "🫳", name: "palm down hand", group: "People & Body"), | |
| 212 | + Emoji(glyph: "🫴", name: "palm up hand", group: "People & Body"), | |
| 213 | + Emoji(glyph: "🫷", name: "leftwards pushing hand", group: "People & Body"), | |
| 214 | + Emoji(glyph: "🫸", name: "rightwards pushing hand", group: "People & Body"), | |
| 215 | + Emoji(glyph: "👌", name: "OK hand", group: "People & Body"), | |
| 216 | + Emoji(glyph: "🤌", name: "pinched fingers", group: "People & Body"), | |
| 217 | + Emoji(glyph: "🤏", name: "pinching hand", group: "People & Body"), | |
| 218 | + Emoji(glyph: "✌️", name: "victory hand", group: "People & Body"), | |
| 219 | + Emoji(glyph: "🤞", name: "crossed fingers", group: "People & Body"), | |
| 220 | + Emoji(glyph: "🫰", name: "hand with index finger and thumb crossed", group: "People & Body"), | |
| 221 | + Emoji(glyph: "🤟", name: "love-you gesture", group: "People & Body"), | |
| 222 | + Emoji(glyph: "🤘", name: "sign of the horns", group: "People & Body"), | |
| 223 | + Emoji(glyph: "🤙", name: "call me hand", group: "People & Body"), | |
| 224 | + Emoji(glyph: "👈", name: "backhand index pointing left", group: "People & Body"), | |
| 225 | + Emoji(glyph: "👉", name: "backhand index pointing right", group: "People & Body"), | |
| 226 | + Emoji(glyph: "👆", name: "backhand index pointing up", group: "People & Body"), | |
| 227 | + Emoji(glyph: "🖕", name: "middle finger", group: "People & Body"), | |
| 228 | + Emoji(glyph: "👇", name: "backhand index pointing down", group: "People & Body"), | |
| 229 | + Emoji(glyph: "☝️", name: "index pointing up", group: "People & Body"), | |
| 230 | + Emoji(glyph: "🫵", name: "index pointing at the viewer", group: "People & Body"), | |
| 231 | + Emoji(glyph: "👍", name: "thumbs up", group: "People & Body"), | |
| 232 | + Emoji(glyph: "👎", name: "thumbs down", group: "People & Body"), | |
| 233 | + Emoji(glyph: "✊", name: "raised fist", group: "People & Body"), | |
| 234 | + Emoji(glyph: "👊", name: "oncoming fist", group: "People & Body"), | |
| 235 | + Emoji(glyph: "🤛", name: "left-facing fist", group: "People & Body"), | |
| 236 | + Emoji(glyph: "🤜", name: "right-facing fist", group: "People & Body"), | |
| 237 | + Emoji(glyph: "👏", name: "clapping hands", group: "People & Body"), | |
| 238 | + Emoji(glyph: "🙌", name: "raising hands", group: "People & Body"), | |
| 239 | + Emoji(glyph: "🫶", name: "heart hands", group: "People & Body"), | |
| 240 | + Emoji(glyph: "👐", name: "open hands", group: "People & Body"), | |
| 241 | + Emoji(glyph: "🤲", name: "palms up together", group: "People & Body"), | |
| 242 | + Emoji(glyph: "🤝", name: "handshake", group: "People & Body"), | |
| 243 | + Emoji(glyph: "🙏", name: "folded hands", group: "People & Body"), | |
| 244 | + Emoji(glyph: "✍️", name: "writing hand", group: "People & Body"), | |
| 245 | + Emoji(glyph: "💅", name: "nail polish", group: "People & Body"), | |
| 246 | + Emoji(glyph: "🤳", name: "selfie", group: "People & Body"), | |
| 247 | + Emoji(glyph: "💪", name: "flexed biceps", group: "People & Body"), | |
| 248 | + Emoji(glyph: "🦾", name: "mechanical arm", group: "People & Body"), | |
| 249 | + Emoji(glyph: "🦿", name: "mechanical leg", group: "People & Body"), | |
| 250 | + Emoji(glyph: "🦵", name: "leg", group: "People & Body"), | |
| 251 | + Emoji(glyph: "🦶", name: "foot", group: "People & Body"), | |
| 252 | + Emoji(glyph: "👂", name: "ear", group: "People & Body"), | |
| 253 | + Emoji(glyph: "🦻", name: "ear with hearing aid", group: "People & Body"), | |
| 254 | + Emoji(glyph: "👃", name: "nose", group: "People & Body"), | |
| 255 | + Emoji(glyph: "🧠", name: "brain", group: "People & Body"), | |
| 256 | + Emoji(glyph: "🫀", name: "anatomical heart", group: "People & Body"), | |
| 257 | + Emoji(glyph: "🫁", name: "lungs", group: "People & Body"), | |
| 258 | + Emoji(glyph: "🦷", name: "tooth", group: "People & Body"), | |
| 259 | + Emoji(glyph: "🦴", name: "bone", group: "People & Body"), | |
| 260 | + Emoji(glyph: "👀", name: "eyes", group: "People & Body"), | |
| 261 | + Emoji(glyph: "👁️", name: "eye", group: "People & Body"), | |
| 262 | + Emoji(glyph: "👅", name: "tongue", group: "People & Body"), | |
| 263 | + Emoji(glyph: "👄", name: "mouth", group: "People & Body"), | |
| 264 | + Emoji(glyph: "🫦", name: "biting lip", group: "People & Body"), | |
| 265 | + Emoji(glyph: "👶", name: "baby", group: "People & Body"), | |
| 266 | + Emoji(glyph: "🧒", name: "child", group: "People & Body"), | |
| 267 | + Emoji(glyph: "👦", name: "boy", group: "People & Body"), | |
| 268 | + Emoji(glyph: "👧", name: "girl", group: "People & Body"), | |
| 269 | + Emoji(glyph: "🧑", name: "person", group: "People & Body"), | |
| 270 | + Emoji(glyph: "👱", name: "person: blond hair", group: "People & Body"), | |
| 271 | + Emoji(glyph: "👨", name: "man", group: "People & Body"), | |
| 272 | + Emoji(glyph: "🧔", name: "person: beard", group: "People & Body"), | |
| 273 | + Emoji(glyph: "🧔♂️", name: "man: beard", group: "People & Body"), | |
| 274 | + Emoji(glyph: "🧔♀️", name: "woman: beard", group: "People & Body"), | |
| 275 | + Emoji(glyph: "👨🦰", name: "man: red hair", group: "People & Body"), | |
| 276 | + Emoji(glyph: "👨🦱", name: "man: curly hair", group: "People & Body"), | |
| 277 | + Emoji(glyph: "👨🦳", name: "man: white hair", group: "People & Body"), | |
| 278 | + Emoji(glyph: "👨🦲", name: "man: bald", group: "People & Body"), | |
| 279 | + Emoji(glyph: "👩", name: "woman", group: "People & Body"), | |
| 280 | + Emoji(glyph: "👩🦰", name: "woman: red hair", group: "People & Body"), | |
| 281 | + Emoji(glyph: "🧑🦰", name: "person: red hair", group: "People & Body"), | |
| 282 | + Emoji(glyph: "👩🦱", name: "woman: curly hair", group: "People & Body"), | |
| 283 | + Emoji(glyph: "🧑🦱", name: "person: curly hair", group: "People & Body"), | |
| 284 | + Emoji(glyph: "👩🦳", name: "woman: white hair", group: "People & Body"), | |
| 285 | + Emoji(glyph: "🧑🦳", name: "person: white hair", group: "People & Body"), | |
| 286 | + Emoji(glyph: "👩🦲", name: "woman: bald", group: "People & Body"), | |
| 287 | + Emoji(glyph: "🧑🦲", name: "person: bald", group: "People & Body"), | |
| 288 | + Emoji(glyph: "👱♀️", name: "woman: blond hair", group: "People & Body"), | |
| 289 | + Emoji(glyph: "👱♂️", name: "man: blond hair", group: "People & Body"), | |
| 290 | + Emoji(glyph: "🧓", name: "older person", group: "People & Body"), | |
| 291 | + Emoji(glyph: "👴", name: "old man", group: "People & Body"), | |
| 292 | + Emoji(glyph: "👵", name: "old woman", group: "People & Body"), | |
| 293 | + Emoji(glyph: "🙍", name: "person frowning", group: "People & Body"), | |
| 294 | + Emoji(glyph: "🙍♂️", name: "man frowning", group: "People & Body"), | |
| 295 | + Emoji(glyph: "🙍♀️", name: "woman frowning", group: "People & Body"), | |
| 296 | + Emoji(glyph: "🙎", name: "person pouting", group: "People & Body"), | |
| 297 | + Emoji(glyph: "🙎♂️", name: "man pouting", group: "People & Body"), | |
| 298 | + Emoji(glyph: "🙎♀️", name: "woman pouting", group: "People & Body"), | |
| 299 | + Emoji(glyph: "🙅", name: "person gesturing NO", group: "People & Body"), | |
| 300 | + Emoji(glyph: "🙅♂️", name: "man gesturing NO", group: "People & Body"), | |
| 301 | + Emoji(glyph: "🙅♀️", name: "woman gesturing NO", group: "People & Body"), | |
| 302 | + Emoji(glyph: "🙆", name: "person gesturing OK", group: "People & Body"), | |
| 303 | + Emoji(glyph: "🙆♂️", name: "man gesturing OK", group: "People & Body"), | |
| 304 | + Emoji(glyph: "🙆♀️", name: "woman gesturing OK", group: "People & Body"), | |
| 305 | + Emoji(glyph: "💁", name: "person tipping hand", group: "People & Body"), | |
| 306 | + Emoji(glyph: "💁♂️", name: "man tipping hand", group: "People & Body"), | |
| 307 | + Emoji(glyph: "💁♀️", name: "woman tipping hand", group: "People & Body"), | |
| 308 | + Emoji(glyph: "🙋", name: "person raising hand", group: "People & Body"), | |
| 309 | + Emoji(glyph: "🙋♂️", name: "man raising hand", group: "People & Body"), | |
| 310 | + Emoji(glyph: "🙋♀️", name: "woman raising hand", group: "People & Body"), | |
| 311 | + Emoji(glyph: "🧏", name: "deaf person", group: "People & Body"), | |
| 312 | + Emoji(glyph: "🧏♂️", name: "deaf man", group: "People & Body"), | |
| 313 | + Emoji(glyph: "🧏♀️", name: "deaf woman", group: "People & Body"), | |
| 314 | + Emoji(glyph: "🙇", name: "person bowing", group: "People & Body"), | |
| 315 | + Emoji(glyph: "🙇♂️", name: "man bowing", group: "People & Body"), | |
| 316 | + Emoji(glyph: "🙇♀️", name: "woman bowing", group: "People & Body"), | |
| 317 | + Emoji(glyph: "🤦", name: "person facepalming", group: "People & Body"), | |
| 318 | + Emoji(glyph: "🤦♂️", name: "man facepalming", group: "People & Body"), | |
| 319 | + Emoji(glyph: "🤦♀️", name: "woman facepalming", group: "People & Body"), | |
| 320 | + Emoji(glyph: "🤷", name: "person shrugging", group: "People & Body"), | |
| 321 | + Emoji(glyph: "🤷♂️", name: "man shrugging", group: "People & Body"), | |
| 322 | + Emoji(glyph: "🤷♀️", name: "woman shrugging", group: "People & Body"), | |
| 323 | + Emoji(glyph: "🧑⚕️", name: "health worker", group: "People & Body"), | |
| 324 | + Emoji(glyph: "👨⚕️", name: "man health worker", group: "People & Body"), | |
| 325 | + Emoji(glyph: "👩⚕️", name: "woman health worker", group: "People & Body"), | |
| 326 | + Emoji(glyph: "🧑🎓", name: "student", group: "People & Body"), | |
| 327 | + Emoji(glyph: "👨🎓", name: "man student", group: "People & Body"), | |
| 328 | + Emoji(glyph: "👩🎓", name: "woman student", group: "People & Body"), | |
| 329 | + Emoji(glyph: "🧑🏫", name: "teacher", group: "People & Body"), | |
| 330 | + Emoji(glyph: "👨🏫", name: "man teacher", group: "People & Body"), | |
| 331 | + Emoji(glyph: "👩🏫", name: "woman teacher", group: "People & Body"), | |
| 332 | + Emoji(glyph: "🧑⚖️", name: "judge", group: "People & Body"), | |
| 333 | + Emoji(glyph: "👨⚖️", name: "man judge", group: "People & Body"), | |
| 334 | + Emoji(glyph: "👩⚖️", name: "woman judge", group: "People & Body"), | |
| 335 | + Emoji(glyph: "🧑🌾", name: "farmer", group: "People & Body"), | |
| 336 | + Emoji(glyph: "👨🌾", name: "man farmer", group: "People & Body"), | |
| 337 | + Emoji(glyph: "👩🌾", name: "woman farmer", group: "People & Body"), | |
| 338 | + Emoji(glyph: "🧑🍳", name: "cook", group: "People & Body"), | |
| 339 | + Emoji(glyph: "👨🍳", name: "man cook", group: "People & Body"), | |
| 340 | + Emoji(glyph: "👩🍳", name: "woman cook", group: "People & Body"), | |
| 341 | + Emoji(glyph: "🧑🔧", name: "mechanic", group: "People & Body"), | |
| 342 | + Emoji(glyph: "👨🔧", name: "man mechanic", group: "People & Body"), | |
| 343 | + Emoji(glyph: "👩🔧", name: "woman mechanic", group: "People & Body"), | |
| 344 | + Emoji(glyph: "🧑🏭", name: "factory worker", group: "People & Body"), | |
| 345 | + Emoji(glyph: "👨🏭", name: "man factory worker", group: "People & Body"), | |
| 346 | + Emoji(glyph: "👩🏭", name: "woman factory worker", group: "People & Body"), | |
| 347 | + Emoji(glyph: "🧑💼", name: "office worker", group: "People & Body"), | |
| 348 | + Emoji(glyph: "👨💼", name: "man office worker", group: "People & Body"), | |
| 349 | + Emoji(glyph: "👩💼", name: "woman office worker", group: "People & Body"), | |
| 350 | + Emoji(glyph: "🧑🔬", name: "scientist", group: "People & Body"), | |
| 351 | + Emoji(glyph: "👨🔬", name: "man scientist", group: "People & Body"), | |
| 352 | + Emoji(glyph: "👩🔬", name: "woman scientist", group: "People & Body"), | |
| 353 | + Emoji(glyph: "🧑💻", name: "technologist", group: "People & Body"), | |
| 354 | + Emoji(glyph: "👨💻", name: "man technologist", group: "People & Body"), | |
| 355 | + Emoji(glyph: "👩💻", name: "woman technologist", group: "People & Body"), | |
| 356 | + Emoji(glyph: "🧑🎤", name: "singer", group: "People & Body"), | |
| 357 | + Emoji(glyph: "👨🎤", name: "man singer", group: "People & Body"), | |
| 358 | + Emoji(glyph: "👩🎤", name: "woman singer", group: "People & Body"), | |
| 359 | + Emoji(glyph: "🧑🎨", name: "artist", group: "People & Body"), | |
| 360 | + Emoji(glyph: "👨🎨", name: "man artist", group: "People & Body"), | |
| 361 | + Emoji(glyph: "👩🎨", name: "woman artist", group: "People & Body"), | |
| 362 | + Emoji(glyph: "🧑✈️", name: "pilot", group: "People & Body"), | |
| 363 | + Emoji(glyph: "👨✈️", name: "man pilot", group: "People & Body"), | |
| 364 | + Emoji(glyph: "👩✈️", name: "woman pilot", group: "People & Body"), | |
| 365 | + Emoji(glyph: "🧑🚀", name: "astronaut", group: "People & Body"), | |
| 366 | + Emoji(glyph: "👨🚀", name: "man astronaut", group: "People & Body"), | |
| 367 | + Emoji(glyph: "👩🚀", name: "woman astronaut", group: "People & Body"), | |
| 368 | + Emoji(glyph: "🧑🚒", name: "firefighter", group: "People & Body"), | |
| 369 | + Emoji(glyph: "👨🚒", name: "man firefighter", group: "People & Body"), | |
| 370 | + Emoji(glyph: "👩🚒", name: "woman firefighter", group: "People & Body"), | |
| 371 | + Emoji(glyph: "👮", name: "police officer", group: "People & Body"), | |
| 372 | + Emoji(glyph: "👮♂️", name: "man police officer", group: "People & Body"), | |
| 373 | + Emoji(glyph: "👮♀️", name: "woman police officer", group: "People & Body"), | |
| 374 | + Emoji(glyph: "🕵️", name: "detective", group: "People & Body"), | |
| 375 | + Emoji(glyph: "🕵️♂️", name: "man detective", group: "People & Body"), | |
| 376 | + Emoji(glyph: "🕵️♀️", name: "woman detective", group: "People & Body"), | |
| 377 | + Emoji(glyph: "💂", name: "guard", group: "People & Body"), | |
| 378 | + Emoji(glyph: "💂♂️", name: "man guard", group: "People & Body"), | |
| 379 | + Emoji(glyph: "💂♀️", name: "woman guard", group: "People & Body"), | |
| 380 | + Emoji(glyph: "🥷", name: "ninja", group: "People & Body"), | |
| 381 | + Emoji(glyph: "👷", name: "construction worker", group: "People & Body"), | |
| 382 | + Emoji(glyph: "👷♂️", name: "man construction worker", group: "People & Body"), | |
| 383 | + Emoji(glyph: "👷♀️", name: "woman construction worker", group: "People & Body"), | |
| 384 | + Emoji(glyph: "🫅", name: "person with crown", group: "People & Body"), | |
| 385 | + Emoji(glyph: "🤴", name: "prince", group: "People & Body"), | |
| 386 | + Emoji(glyph: "👸", name: "princess", group: "People & Body"), | |
| 387 | + Emoji(glyph: "👳", name: "person wearing turban", group: "People & Body"), | |
| 388 | + Emoji(glyph: "👳♂️", name: "man wearing turban", group: "People & Body"), | |
| 389 | + Emoji(glyph: "👳♀️", name: "woman wearing turban", group: "People & Body"), | |
| 390 | + Emoji(glyph: "👲", name: "person with skullcap", group: "People & Body"), | |
| 391 | + Emoji(glyph: "🧕", name: "woman with headscarf", group: "People & Body"), | |
| 392 | + Emoji(glyph: "🤵", name: "person in tuxedo", group: "People & Body"), | |
| 393 | + Emoji(glyph: "🤵♂️", name: "man in tuxedo", group: "People & Body"), | |
| 394 | + Emoji(glyph: "🤵♀️", name: "woman in tuxedo", group: "People & Body"), | |
| 395 | + Emoji(glyph: "👰", name: "person with veil", group: "People & Body"), | |
| 396 | + Emoji(glyph: "👰♂️", name: "man with veil", group: "People & Body"), | |
| 397 | + Emoji(glyph: "👰♀️", name: "woman with veil", group: "People & Body"), | |
| 398 | + Emoji(glyph: "🤰", name: "pregnant woman", group: "People & Body"), | |
| 399 | + Emoji(glyph: "🫃", name: "pregnant man", group: "People & Body"), | |
| 400 | + Emoji(glyph: "🫄", name: "pregnant person", group: "People & Body"), | |
| 401 | + Emoji(glyph: "🤱", name: "breast-feeding", group: "People & Body"), | |
| 402 | + Emoji(glyph: "👩🍼", name: "woman feeding baby", group: "People & Body"), | |
| 403 | + Emoji(glyph: "👨🍼", name: "man feeding baby", group: "People & Body"), | |
| 404 | + Emoji(glyph: "🧑🍼", name: "person feeding baby", group: "People & Body"), | |
| 405 | + Emoji(glyph: "👼", name: "baby angel", group: "People & Body"), | |
| 406 | + Emoji(glyph: "🎅", name: "Santa Claus", group: "People & Body"), | |
| 407 | + Emoji(glyph: "🤶", name: "Mrs. Claus", group: "People & Body"), | |
| 408 | + Emoji(glyph: "🧑🎄", name: "mx claus", group: "People & Body"), | |
| 409 | + Emoji(glyph: "🦸", name: "superhero", group: "People & Body"), | |
| 410 | + Emoji(glyph: "🦸♂️", name: "man superhero", group: "People & Body"), | |
| 411 | + Emoji(glyph: "🦸♀️", name: "woman superhero", group: "People & Body"), | |
| 412 | + Emoji(glyph: "🦹", name: "supervillain", group: "People & Body"), | |
| 413 | + Emoji(glyph: "🦹♂️", name: "man supervillain", group: "People & Body"), | |
| 414 | + Emoji(glyph: "🦹♀️", name: "woman supervillain", group: "People & Body"), | |
| 415 | + Emoji(glyph: "🧙", name: "mage", group: "People & Body"), | |
| 416 | + Emoji(glyph: "🧙♂️", name: "man mage", group: "People & Body"), | |
| 417 | + Emoji(glyph: "🧙♀️", name: "woman mage", group: "People & Body"), | |
| 418 | + Emoji(glyph: "🧚", name: "fairy", group: "People & Body"), | |
| 419 | + Emoji(glyph: "🧚♂️", name: "man fairy", group: "People & Body"), | |
| 420 | + Emoji(glyph: "🧚♀️", name: "woman fairy", group: "People & Body"), | |
| 421 | + Emoji(glyph: "🧛", name: "vampire", group: "People & Body"), | |
| 422 | + Emoji(glyph: "🧛♂️", name: "man vampire", group: "People & Body"), | |
| 423 | + Emoji(glyph: "🧛♀️", name: "woman vampire", group: "People & Body"), | |
| 424 | + Emoji(glyph: "🧜", name: "merperson", group: "People & Body"), | |
| 425 | + Emoji(glyph: "🧜♂️", name: "merman", group: "People & Body"), | |
| 426 | + Emoji(glyph: "🧜♀️", name: "mermaid", group: "People & Body"), | |
| 427 | + Emoji(glyph: "🧝", name: "elf", group: "People & Body"), | |
| 428 | + Emoji(glyph: "🧝♂️", name: "man elf", group: "People & Body"), | |
| 429 | + Emoji(glyph: "🧝♀️", name: "woman elf", group: "People & Body"), | |
| 430 | + Emoji(glyph: "🧞", name: "genie", group: "People & Body"), | |
| 431 | + Emoji(glyph: "🧞♂️", name: "man genie", group: "People & Body"), | |
| 432 | + Emoji(glyph: "🧞♀️", name: "woman genie", group: "People & Body"), | |
| 433 | + Emoji(glyph: "🧟", name: "zombie", group: "People & Body"), | |
| 434 | + Emoji(glyph: "🧟♂️", name: "man zombie", group: "People & Body"), | |
| 435 | + Emoji(glyph: "🧟♀️", name: "woman zombie", group: "People & Body"), | |
| 436 | + Emoji(glyph: "🧌", name: "troll", group: "People & Body"), | |
| 437 | + Emoji(glyph: "💆", name: "person getting massage", group: "People & Body"), | |
| 438 | + Emoji(glyph: "💆♂️", name: "man getting massage", group: "People & Body"), | |
| 439 | + Emoji(glyph: "💆♀️", name: "woman getting massage", group: "People & Body"), | |
| 440 | + Emoji(glyph: "💇", name: "person getting haircut", group: "People & Body"), | |
| 441 | + Emoji(glyph: "💇♂️", name: "man getting haircut", group: "People & Body"), | |
| 442 | + Emoji(glyph: "💇♀️", name: "woman getting haircut", group: "People & Body"), | |
| 443 | + Emoji(glyph: "🚶", name: "person walking", group: "People & Body"), | |
| 444 | + Emoji(glyph: "🚶♂️", name: "man walking", group: "People & Body"), | |
| 445 | + Emoji(glyph: "🚶♀️", name: "woman walking", group: "People & Body"), | |
| 446 | + Emoji(glyph: "🚶➡️", name: "person walking facing right", group: "People & Body"), | |
| 447 | + Emoji(glyph: "🚶♀️➡️", name: "woman walking facing right", group: "People & Body"), | |
| 448 | + Emoji(glyph: "🚶♂️➡️", name: "man walking facing right", group: "People & Body"), | |
| 449 | + Emoji(glyph: "🧍", name: "person standing", group: "People & Body"), | |
| 450 | + Emoji(glyph: "🧍♂️", name: "man standing", group: "People & Body"), | |
| 451 | + Emoji(glyph: "🧍♀️", name: "woman standing", group: "People & Body"), | |
| 452 | + Emoji(glyph: "🧎", name: "person kneeling", group: "People & Body"), | |
| 453 | + Emoji(glyph: "🧎♂️", name: "man kneeling", group: "People & Body"), | |
| 454 | + Emoji(glyph: "🧎♀️", name: "woman kneeling", group: "People & Body"), | |
| 455 | + Emoji(glyph: "🧎➡️", name: "person kneeling facing right", group: "People & Body"), | |
| 456 | + Emoji(glyph: "🧎♀️➡️", name: "woman kneeling facing right", group: "People & Body"), | |
| 457 | + Emoji(glyph: "🧎♂️➡️", name: "man kneeling facing right", group: "People & Body"), | |
| 458 | + Emoji(glyph: "🧑🦯", name: "person with white cane", group: "People & Body"), | |
| 459 | + Emoji(glyph: "🧑🦯➡️", name: "person with white cane facing right", group: "People & Body"), | |
| 460 | + Emoji(glyph: "👨🦯", name: "man with white cane", group: "People & Body"), | |
| 461 | + Emoji(glyph: "👨🦯➡️", name: "man with white cane facing right", group: "People & Body"), | |
| 462 | + Emoji(glyph: "👩🦯", name: "woman with white cane", group: "People & Body"), | |
| 463 | + Emoji(glyph: "👩🦯➡️", name: "woman with white cane facing right", group: "People & Body"), | |
| 464 | + Emoji(glyph: "🧑🦼", name: "person in motorized wheelchair", group: "People & Body"), | |
| 465 | + Emoji(glyph: "🧑🦼➡️", name: "person in motorized wheelchair facing right", group: "People & Body"), | |
| 466 | + Emoji(glyph: "👨🦼", name: "man in motorized wheelchair", group: "People & Body"), | |
| 467 | + Emoji(glyph: "👨🦼➡️", name: "man in motorized wheelchair facing right", group: "People & Body"), | |
| 468 | + Emoji(glyph: "👩🦼", name: "woman in motorized wheelchair", group: "People & Body"), | |
| 469 | + Emoji(glyph: "👩🦼➡️", name: "woman in motorized wheelchair facing right", group: "People & Body"), | |
| 470 | + Emoji(glyph: "🧑🦽", name: "person in manual wheelchair", group: "People & Body"), | |
| 471 | + Emoji(glyph: "🧑🦽➡️", name: "person in manual wheelchair facing right", group: "People & Body"), | |
| 472 | + Emoji(glyph: "👨🦽", name: "man in manual wheelchair", group: "People & Body"), | |
| 473 | + Emoji(glyph: "👨🦽➡️", name: "man in manual wheelchair facing right", group: "People & Body"), | |
| 474 | + Emoji(glyph: "👩🦽", name: "woman in manual wheelchair", group: "People & Body"), | |
| 475 | + Emoji(glyph: "👩🦽➡️", name: "woman in manual wheelchair facing right", group: "People & Body"), | |
| 476 | + Emoji(glyph: "🏃", name: "person running", group: "People & Body"), | |
| 477 | + Emoji(glyph: "🏃♂️", name: "man running", group: "People & Body"), | |
| 478 | + Emoji(glyph: "🏃♀️", name: "woman running", group: "People & Body"), | |
| 479 | + Emoji(glyph: "🏃➡️", name: "person running facing right", group: "People & Body"), | |
| 480 | + Emoji(glyph: "🏃♀️➡️", name: "woman running facing right", group: "People & Body"), | |
| 481 | + Emoji(glyph: "🏃♂️➡️", name: "man running facing right", group: "People & Body"), | |
| 482 | + Emoji(glyph: "💃", name: "woman dancing", group: "People & Body"), | |
| 483 | + Emoji(glyph: "🕺", name: "man dancing", group: "People & Body"), | |
| 484 | + Emoji(glyph: "🕴️", name: "person in suit levitating", group: "People & Body"), | |
| 485 | + Emoji(glyph: "👯", name: "people with bunny ears", group: "People & Body"), | |
| 486 | + Emoji(glyph: "👯♂️", name: "men with bunny ears", group: "People & Body"), | |
| 487 | + Emoji(glyph: "👯♀️", name: "women with bunny ears", group: "People & Body"), | |
| 488 | + Emoji(glyph: "🧖", name: "person in steamy room", group: "People & Body"), | |
| 489 | + Emoji(glyph: "🧖♂️", name: "man in steamy room", group: "People & Body"), | |
| 490 | + Emoji(glyph: "🧖♀️", name: "woman in steamy room", group: "People & Body"), | |
| 491 | + Emoji(glyph: "🧗", name: "person climbing", group: "People & Body"), | |
| 492 | + Emoji(glyph: "🧗♂️", name: "man climbing", group: "People & Body"), | |
| 493 | + Emoji(glyph: "🧗♀️", name: "woman climbing", group: "People & Body"), | |
| 494 | + Emoji(glyph: "🤺", name: "person fencing", group: "People & Body"), | |
| 495 | + Emoji(glyph: "🏇", name: "horse racing", group: "People & Body"), | |
| 496 | + Emoji(glyph: "⛷️", name: "skier", group: "People & Body"), | |
| 497 | + Emoji(glyph: "🏂", name: "snowboarder", group: "People & Body"), | |
| 498 | + Emoji(glyph: "🏌️", name: "person golfing", group: "People & Body"), | |
| 499 | + Emoji(glyph: "🏌️♂️", name: "man golfing", group: "People & Body"), | |
| 500 | + Emoji(glyph: "🏌️♀️", name: "woman golfing", group: "People & Body"), | |
| 501 | + Emoji(glyph: "🏄", name: "person surfing", group: "People & Body"), | |
| 502 | + Emoji(glyph: "🏄♂️", name: "man surfing", group: "People & Body"), | |
| 503 | + Emoji(glyph: "🏄♀️", name: "woman surfing", group: "People & Body"), | |
| 504 | + Emoji(glyph: "🚣", name: "person rowing boat", group: "People & Body"), | |
| 505 | + Emoji(glyph: "🚣♂️", name: "man rowing boat", group: "People & Body"), | |
| 506 | + Emoji(glyph: "🚣♀️", name: "woman rowing boat", group: "People & Body"), | |
| 507 | + Emoji(glyph: "🏊", name: "person swimming", group: "People & Body"), | |
| 508 | + Emoji(glyph: "🏊♂️", name: "man swimming", group: "People & Body"), | |
| 509 | + Emoji(glyph: "🏊♀️", name: "woman swimming", group: "People & Body"), | |
| 510 | + Emoji(glyph: "⛹️", name: "person bouncing ball", group: "People & Body"), | |
| 511 | + Emoji(glyph: "⛹️♂️", name: "man bouncing ball", group: "People & Body"), | |
| 512 | + Emoji(glyph: "⛹️♀️", name: "woman bouncing ball", group: "People & Body"), | |
| 513 | + Emoji(glyph: "🏋️", name: "person lifting weights", group: "People & Body"), | |
| 514 | + Emoji(glyph: "🏋️♂️", name: "man lifting weights", group: "People & Body"), | |
| 515 | + Emoji(glyph: "🏋️♀️", name: "woman lifting weights", group: "People & Body"), | |
| 516 | + Emoji(glyph: "🚴", name: "person biking", group: "People & Body"), | |
| 517 | + Emoji(glyph: "🚴♂️", name: "man biking", group: "People & Body"), | |
| 518 | + Emoji(glyph: "🚴♀️", name: "woman biking", group: "People & Body"), | |
| 519 | + Emoji(glyph: "🚵", name: "person mountain biking", group: "People & Body"), | |
| 520 | + Emoji(glyph: "🚵♂️", name: "man mountain biking", group: "People & Body"), | |
| 521 | + Emoji(glyph: "🚵♀️", name: "woman mountain biking", group: "People & Body"), | |
| 522 | + Emoji(glyph: "🤸", name: "person cartwheeling", group: "People & Body"), | |
| 523 | + Emoji(glyph: "🤸♂️", name: "man cartwheeling", group: "People & Body"), | |
| 524 | + Emoji(glyph: "🤸♀️", name: "woman cartwheeling", group: "People & Body"), | |
| 525 | + Emoji(glyph: "🤼", name: "people wrestling", group: "People & Body"), | |
| 526 | + Emoji(glyph: "🤼♂️", name: "men wrestling", group: "People & Body"), | |
| 527 | + Emoji(glyph: "🤼♀️", name: "women wrestling", group: "People & Body"), | |
| 528 | + Emoji(glyph: "🤽", name: "person playing water polo", group: "People & Body"), | |
| 529 | + Emoji(glyph: "🤽♂️", name: "man playing water polo", group: "People & Body"), | |
| 530 | + Emoji(glyph: "🤽♀️", name: "woman playing water polo", group: "People & Body"), | |
| 531 | + Emoji(glyph: "🤾", name: "person playing handball", group: "People & Body"), | |
| 532 | + Emoji(glyph: "🤾♂️", name: "man playing handball", group: "People & Body"), | |
| 533 | + Emoji(glyph: "🤾♀️", name: "woman playing handball", group: "People & Body"), | |
| 534 | + Emoji(glyph: "🤹", name: "person juggling", group: "People & Body"), | |
| 535 | + Emoji(glyph: "🤹♂️", name: "man juggling", group: "People & Body"), | |
| 536 | + Emoji(glyph: "🤹♀️", name: "woman juggling", group: "People & Body"), | |
| 537 | + Emoji(glyph: "🧘", name: "person in lotus position", group: "People & Body"), | |
| 538 | + Emoji(glyph: "🧘♂️", name: "man in lotus position", group: "People & Body"), | |
| 539 | + Emoji(glyph: "🧘♀️", name: "woman in lotus position", group: "People & Body"), | |
| 540 | + Emoji(glyph: "🛀", name: "person taking bath", group: "People & Body"), | |
| 541 | + Emoji(glyph: "🛌", name: "person in bed", group: "People & Body"), | |
| 542 | + Emoji(glyph: "🧑🤝🧑", name: "people holding hands", group: "People & Body"), | |
| 543 | + Emoji(glyph: "👭", name: "women holding hands", group: "People & Body"), | |
| 544 | + Emoji(glyph: "👫", name: "woman and man holding hands", group: "People & Body"), | |
| 545 | + Emoji(glyph: "👬", name: "men holding hands", group: "People & Body"), | |
| 546 | + Emoji(glyph: "💏", name: "kiss", group: "People & Body"), | |
| 547 | + Emoji(glyph: "👩❤️💋👨", name: "kiss: woman, man", group: "People & Body"), | |
| 548 | + Emoji(glyph: "👨❤️💋👨", name: "kiss: man, man", group: "People & Body"), | |
| 549 | + Emoji(glyph: "👩❤️💋👩", name: "kiss: woman, woman", group: "People & Body"), | |
| 550 | + Emoji(glyph: "💑", name: "couple with heart", group: "People & Body"), | |
| 551 | + Emoji(glyph: "👩❤️👨", name: "couple with heart: woman, man", group: "People & Body"), | |
| 552 | + Emoji(glyph: "👨❤️👨", name: "couple with heart: man, man", group: "People & Body"), | |
| 553 | + Emoji(glyph: "👩❤️👩", name: "couple with heart: woman, woman", group: "People & Body"), | |
| 554 | + Emoji(glyph: "👨👩👦", name: "family: man, woman, boy", group: "People & Body"), | |
| 555 | + Emoji(glyph: "👨👩👧", name: "family: man, woman, girl", group: "People & Body"), | |
| 556 | + Emoji(glyph: "👨👩👧👦", name: "family: man, woman, girl, boy", group: "People & Body"), | |
| 557 | + Emoji(glyph: "👨👩👦👦", name: "family: man, woman, boy, boy", group: "People & Body"), | |
| 558 | + Emoji(glyph: "👨👩👧👧", name: "family: man, woman, girl, girl", group: "People & Body"), | |
| 559 | + Emoji(glyph: "👨👨👦", name: "family: man, man, boy", group: "People & Body"), | |
| 560 | + Emoji(glyph: "👨👨👧", name: "family: man, man, girl", group: "People & Body"), | |
| 561 | + Emoji(glyph: "👨👨👧👦", name: "family: man, man, girl, boy", group: "People & Body"), | |
| 562 | + Emoji(glyph: "👨👨👦👦", name: "family: man, man, boy, boy", group: "People & Body"), | |
| 563 | + Emoji(glyph: "👨👨👧👧", name: "family: man, man, girl, girl", group: "People & Body"), | |
| 564 | + Emoji(glyph: "👩👩👦", name: "family: woman, woman, boy", group: "People & Body"), | |
| 565 | + Emoji(glyph: "👩👩👧", name: "family: woman, woman, girl", group: "People & Body"), | |
| 566 | + Emoji(glyph: "👩👩👧👦", name: "family: woman, woman, girl, boy", group: "People & Body"), | |
| 567 | + Emoji(glyph: "👩👩👦👦", name: "family: woman, woman, boy, boy", group: "People & Body"), | |
| 568 | + Emoji(glyph: "👩👩👧👧", name: "family: woman, woman, girl, girl", group: "People & Body"), | |
| 569 | + Emoji(glyph: "👨👦", name: "family: man, boy", group: "People & Body"), | |
| 570 | + Emoji(glyph: "👨👦👦", name: "family: man, boy, boy", group: "People & Body"), | |
| 571 | + Emoji(glyph: "👨👧", name: "family: man, girl", group: "People & Body"), | |
| 572 | + Emoji(glyph: "👨👧👦", name: "family: man, girl, boy", group: "People & Body"), | |
| 573 | + Emoji(glyph: "👨👧👧", name: "family: man, girl, girl", group: "People & Body"), | |
| 574 | + Emoji(glyph: "👩👦", name: "family: woman, boy", group: "People & Body"), | |
| 575 | + Emoji(glyph: "👩👦👦", name: "family: woman, boy, boy", group: "People & Body"), | |
| 576 | + Emoji(glyph: "👩👧", name: "family: woman, girl", group: "People & Body"), | |
| 577 | + Emoji(glyph: "👩👧👦", name: "family: woman, girl, boy", group: "People & Body"), | |
| 578 | + Emoji(glyph: "👩👧👧", name: "family: woman, girl, girl", group: "People & Body"), | |
| 579 | + Emoji(glyph: "🗣️", name: "speaking head", group: "People & Body"), | |
| 580 | + Emoji(glyph: "👤", name: "bust in silhouette", group: "People & Body"), | |
| 581 | + Emoji(glyph: "👥", name: "busts in silhouette", group: "People & Body"), | |
| 582 | + Emoji(glyph: "🫂", name: "people hugging", group: "People & Body"), | |
| 583 | + Emoji(glyph: "👪", name: "family", group: "People & Body"), | |
| 584 | + Emoji(glyph: "🧑🧑🧒", name: "family: adult, adult, child", group: "People & Body"), | |
| 585 | + Emoji(glyph: "🧑🧑🧒🧒", name: "family: adult, adult, child, child", group: "People & Body"), | |
| 586 | + Emoji(glyph: "🧑🧒", name: "family: adult, child", group: "People & Body"), | |
| 587 | + Emoji(glyph: "🧑🧒🧒", name: "family: adult, child, child", group: "People & Body"), | |
| 588 | + Emoji(glyph: "👣", name: "footprints", group: "People & Body"), | |
| 589 | + Emoji(glyph: "🐵", name: "monkey face", group: "Animals & Nature"), | |
| 590 | + Emoji(glyph: "🐒", name: "monkey", group: "Animals & Nature"), | |
| 591 | + Emoji(glyph: "🦍", name: "gorilla", group: "Animals & Nature"), | |
| 592 | + Emoji(glyph: "🦧", name: "orangutan", group: "Animals & Nature"), | |
| 593 | + Emoji(glyph: "🐶", name: "dog face", group: "Animals & Nature"), | |
| 594 | + Emoji(glyph: "🐕", name: "dog", group: "Animals & Nature"), | |
| 595 | + Emoji(glyph: "🦮", name: "guide dog", group: "Animals & Nature"), | |
| 596 | + Emoji(glyph: "🐕🦺", name: "service dog", group: "Animals & Nature"), | |
| 597 | + Emoji(glyph: "🐩", name: "poodle", group: "Animals & Nature"), | |
| 598 | + Emoji(glyph: "🐺", name: "wolf", group: "Animals & Nature"), | |
| 599 | + Emoji(glyph: "🦊", name: "fox", group: "Animals & Nature"), | |
| 600 | + Emoji(glyph: "🦝", name: "raccoon", group: "Animals & Nature"), | |
| 601 | + Emoji(glyph: "🐱", name: "cat face", group: "Animals & Nature"), | |
| 602 | + Emoji(glyph: "🐈", name: "cat", group: "Animals & Nature"), | |
| 603 | + Emoji(glyph: "🐈⬛", name: "black cat", group: "Animals & Nature"), | |
| 604 | + Emoji(glyph: "🦁", name: "lion", group: "Animals & Nature"), | |
| 605 | + Emoji(glyph: "🐯", name: "tiger face", group: "Animals & Nature"), | |
| 606 | + Emoji(glyph: "🐅", name: "tiger", group: "Animals & Nature"), | |
| 607 | + Emoji(glyph: "🐆", name: "leopard", group: "Animals & Nature"), | |
| 608 | + Emoji(glyph: "🐴", name: "horse face", group: "Animals & Nature"), | |
| 609 | + Emoji(glyph: "🫎", name: "moose", group: "Animals & Nature"), | |
| 610 | + Emoji(glyph: "🫏", name: "donkey", group: "Animals & Nature"), | |
| 611 | + Emoji(glyph: "🐎", name: "horse", group: "Animals & Nature"), | |
| 612 | + Emoji(glyph: "🦄", name: "unicorn", group: "Animals & Nature"), | |
| 613 | + Emoji(glyph: "🦓", name: "zebra", group: "Animals & Nature"), | |
| 614 | + Emoji(glyph: "🦌", name: "deer", group: "Animals & Nature"), | |
| 615 | + Emoji(glyph: "🦬", name: "bison", group: "Animals & Nature"), | |
| 616 | + Emoji(glyph: "🐮", name: "cow face", group: "Animals & Nature"), | |
| 617 | + Emoji(glyph: "🐂", name: "ox", group: "Animals & Nature"), | |
| 618 | + Emoji(glyph: "🐃", name: "water buffalo", group: "Animals & Nature"), | |
| 619 | + Emoji(glyph: "🐄", name: "cow", group: "Animals & Nature"), | |
| 620 | + Emoji(glyph: "🐷", name: "pig face", group: "Animals & Nature"), | |
| 621 | + Emoji(glyph: "🐖", name: "pig", group: "Animals & Nature"), | |
| 622 | + Emoji(glyph: "🐗", name: "boar", group: "Animals & Nature"), | |
| 623 | + Emoji(glyph: "🐽", name: "pig nose", group: "Animals & Nature"), | |
| 624 | + Emoji(glyph: "🐏", name: "ram", group: "Animals & Nature"), | |
| 625 | + Emoji(glyph: "🐑", name: "ewe", group: "Animals & Nature"), | |
| 626 | + Emoji(glyph: "🐐", name: "goat", group: "Animals & Nature"), | |
| 627 | + Emoji(glyph: "🐪", name: "camel", group: "Animals & Nature"), | |
| 628 | + Emoji(glyph: "🐫", name: "two-hump camel", group: "Animals & Nature"), | |
| 629 | + Emoji(glyph: "🦙", name: "llama", group: "Animals & Nature"), | |
| 630 | + Emoji(glyph: "🦒", name: "giraffe", group: "Animals & Nature"), | |
| 631 | + Emoji(glyph: "🐘", name: "elephant", group: "Animals & Nature"), | |
| 632 | + Emoji(glyph: "🦣", name: "mammoth", group: "Animals & Nature"), | |
| 633 | + Emoji(glyph: "🦏", name: "rhinoceros", group: "Animals & Nature"), | |
| 634 | + Emoji(glyph: "🦛", name: "hippopotamus", group: "Animals & Nature"), | |
| 635 | + Emoji(glyph: "🐭", name: "mouse face", group: "Animals & Nature"), | |
| 636 | + Emoji(glyph: "🐁", name: "mouse", group: "Animals & Nature"), | |
| 637 | + Emoji(glyph: "🐀", name: "rat", group: "Animals & Nature"), | |
| 638 | + Emoji(glyph: "🐹", name: "hamster", group: "Animals & Nature"), | |
| 639 | + Emoji(glyph: "🐰", name: "rabbit face", group: "Animals & Nature"), | |
| 640 | + Emoji(glyph: "🐇", name: "rabbit", group: "Animals & Nature"), | |
| 641 | + Emoji(glyph: "🐿️", name: "chipmunk", group: "Animals & Nature"), | |
| 642 | + Emoji(glyph: "🦫", name: "beaver", group: "Animals & Nature"), | |
| 643 | + Emoji(glyph: "🦔", name: "hedgehog", group: "Animals & Nature"), | |
| 644 | + Emoji(glyph: "🦇", name: "bat", group: "Animals & Nature"), | |
| 645 | + Emoji(glyph: "🐻", name: "bear", group: "Animals & Nature"), | |
| 646 | + Emoji(glyph: "🐻❄️", name: "polar bear", group: "Animals & Nature"), | |
| 647 | + Emoji(glyph: "🐨", name: "koala", group: "Animals & Nature"), | |
| 648 | + Emoji(glyph: "🐼", name: "panda", group: "Animals & Nature"), | |
| 649 | + Emoji(glyph: "🦥", name: "sloth", group: "Animals & Nature"), | |
| 650 | + Emoji(glyph: "🦦", name: "otter", group: "Animals & Nature"), | |
| 651 | + Emoji(glyph: "🦨", name: "skunk", group: "Animals & Nature"), | |
| 652 | + Emoji(glyph: "🦘", name: "kangaroo", group: "Animals & Nature"), | |
| 653 | + Emoji(glyph: "🦡", name: "badger", group: "Animals & Nature"), | |
| 654 | + Emoji(glyph: "🐾", name: "paw prints", group: "Animals & Nature"), | |
| 655 | + Emoji(glyph: "🦃", name: "turkey", group: "Animals & Nature"), | |
| 656 | + Emoji(glyph: "🐔", name: "chicken", group: "Animals & Nature"), | |
| 657 | + Emoji(glyph: "🐓", name: "rooster", group: "Animals & Nature"), | |
| 658 | + Emoji(glyph: "🐣", name: "hatching chick", group: "Animals & Nature"), | |
| 659 | + Emoji(glyph: "🐤", name: "baby chick", group: "Animals & Nature"), | |
| 660 | + Emoji(glyph: "🐥", name: "front-facing baby chick", group: "Animals & Nature"), | |
| 661 | + Emoji(glyph: "🐦", name: "bird", group: "Animals & Nature"), | |
| 662 | + Emoji(glyph: "🐧", name: "penguin", group: "Animals & Nature"), | |
| 663 | + Emoji(glyph: "🕊️", name: "dove", group: "Animals & Nature"), | |
| 664 | + Emoji(glyph: "🦅", name: "eagle", group: "Animals & Nature"), | |
| 665 | + Emoji(glyph: "🦆", name: "duck", group: "Animals & Nature"), | |
| 666 | + Emoji(glyph: "🦢", name: "swan", group: "Animals & Nature"), | |
| 667 | + Emoji(glyph: "🦉", name: "owl", group: "Animals & Nature"), | |
| 668 | + Emoji(glyph: "🦤", name: "dodo", group: "Animals & Nature"), | |
| 669 | + Emoji(glyph: "🪶", name: "feather", group: "Animals & Nature"), | |
| 670 | + Emoji(glyph: "🦩", name: "flamingo", group: "Animals & Nature"), | |
| 671 | + Emoji(glyph: "🦚", name: "peacock", group: "Animals & Nature"), | |
| 672 | + Emoji(glyph: "🦜", name: "parrot", group: "Animals & Nature"), | |
| 673 | + Emoji(glyph: "🪽", name: "wing", group: "Animals & Nature"), | |
| 674 | + Emoji(glyph: "🐦⬛", name: "black bird", group: "Animals & Nature"), | |
| 675 | + Emoji(glyph: "🪿", name: "goose", group: "Animals & Nature"), | |
| 676 | + Emoji(glyph: "🐦🔥", name: "phoenix", group: "Animals & Nature"), | |
| 677 | + Emoji(glyph: "🐸", name: "frog", group: "Animals & Nature"), | |
| 678 | + Emoji(glyph: "🐊", name: "crocodile", group: "Animals & Nature"), | |
| 679 | + Emoji(glyph: "🐢", name: "turtle", group: "Animals & Nature"), | |
| 680 | + Emoji(glyph: "🦎", name: "lizard", group: "Animals & Nature"), | |
| 681 | + Emoji(glyph: "🐍", name: "snake", group: "Animals & Nature"), | |
| 682 | + Emoji(glyph: "🐲", name: "dragon face", group: "Animals & Nature"), | |
| 683 | + Emoji(glyph: "🐉", name: "dragon", group: "Animals & Nature"), | |
| 684 | + Emoji(glyph: "🦕", name: "sauropod", group: "Animals & Nature"), | |
| 685 | + Emoji(glyph: "🦖", name: "T-Rex", group: "Animals & Nature"), | |
| 686 | + Emoji(glyph: "🐳", name: "spouting whale", group: "Animals & Nature"), | |
| 687 | + Emoji(glyph: "🐋", name: "whale", group: "Animals & Nature"), | |
| 688 | + Emoji(glyph: "🐬", name: "dolphin", group: "Animals & Nature"), | |
| 689 | + Emoji(glyph: "🦭", name: "seal", group: "Animals & Nature"), | |
| 690 | + Emoji(glyph: "🐟", name: "fish", group: "Animals & Nature"), | |
| 691 | + Emoji(glyph: "🐠", name: "tropical fish", group: "Animals & Nature"), | |
| 692 | + Emoji(glyph: "🐡", name: "blowfish", group: "Animals & Nature"), | |
| 693 | + Emoji(glyph: "🦈", name: "shark", group: "Animals & Nature"), | |
| 694 | + Emoji(glyph: "🐙", name: "octopus", group: "Animals & Nature"), | |
| 695 | + Emoji(glyph: "🐚", name: "spiral shell", group: "Animals & Nature"), | |
| 696 | + Emoji(glyph: "🪸", name: "coral", group: "Animals & Nature"), | |
| 697 | + Emoji(glyph: "🪼", name: "jellyfish", group: "Animals & Nature"), | |
| 698 | + Emoji(glyph: "🐌", name: "snail", group: "Animals & Nature"), | |
| 699 | + Emoji(glyph: "🦋", name: "butterfly", group: "Animals & Nature"), | |
| 700 | + Emoji(glyph: "🐛", name: "bug", group: "Animals & Nature"), | |
| 701 | + Emoji(glyph: "🐜", name: "ant", group: "Animals & Nature"), | |
| 702 | + Emoji(glyph: "🐝", name: "honeybee", group: "Animals & Nature"), | |
| 703 | + Emoji(glyph: "🪲", name: "beetle", group: "Animals & Nature"), | |
| 704 | + Emoji(glyph: "🐞", name: "lady beetle", group: "Animals & Nature"), | |
| 705 | + Emoji(glyph: "🦗", name: "cricket", group: "Animals & Nature"), | |
| 706 | + Emoji(glyph: "🪳", name: "cockroach", group: "Animals & Nature"), | |
| 707 | + Emoji(glyph: "🕷️", name: "spider", group: "Animals & Nature"), | |
| 708 | + Emoji(glyph: "🕸️", name: "spider web", group: "Animals & Nature"), | |
| 709 | + Emoji(glyph: "🦂", name: "scorpion", group: "Animals & Nature"), | |
| 710 | + Emoji(glyph: "🦟", name: "mosquito", group: "Animals & Nature"), | |
| 711 | + Emoji(glyph: "🪰", name: "fly", group: "Animals & Nature"), | |
| 712 | + Emoji(glyph: "🪱", name: "worm", group: "Animals & Nature"), | |
| 713 | + Emoji(glyph: "🦠", name: "microbe", group: "Animals & Nature"), | |
| 714 | + Emoji(glyph: "💐", name: "bouquet", group: "Animals & Nature"), | |
| 715 | + Emoji(glyph: "🌸", name: "cherry blossom", group: "Animals & Nature"), | |
| 716 | + Emoji(glyph: "💮", name: "white flower", group: "Animals & Nature"), | |
| 717 | + Emoji(glyph: "🪷", name: "lotus", group: "Animals & Nature"), | |
| 718 | + Emoji(glyph: "🏵️", name: "rosette", group: "Animals & Nature"), | |
| 719 | + Emoji(glyph: "🌹", name: "rose", group: "Animals & Nature"), | |
| 720 | + Emoji(glyph: "🥀", name: "wilted flower", group: "Animals & Nature"), | |
| 721 | + Emoji(glyph: "🌺", name: "hibiscus", group: "Animals & Nature"), | |
| 722 | + Emoji(glyph: "🌻", name: "sunflower", group: "Animals & Nature"), | |
| 723 | + Emoji(glyph: "🌼", name: "blossom", group: "Animals & Nature"), | |
| 724 | + Emoji(glyph: "🌷", name: "tulip", group: "Animals & Nature"), | |
| 725 | + Emoji(glyph: "🪻", name: "hyacinth", group: "Animals & Nature"), | |
| 726 | + Emoji(glyph: "🌱", name: "seedling", group: "Animals & Nature"), | |
| 727 | + Emoji(glyph: "🪴", name: "potted plant", group: "Animals & Nature"), | |
| 728 | + Emoji(glyph: "🌲", name: "evergreen tree", group: "Animals & Nature"), | |
| 729 | + Emoji(glyph: "🌳", name: "deciduous tree", group: "Animals & Nature"), | |
| 730 | + Emoji(glyph: "🌴", name: "palm tree", group: "Animals & Nature"), | |
| 731 | + Emoji(glyph: "🌵", name: "cactus", group: "Animals & Nature"), | |
| 732 | + Emoji(glyph: "🌾", name: "sheaf of rice", group: "Animals & Nature"), | |
| 733 | + Emoji(glyph: "🌿", name: "herb", group: "Animals & Nature"), | |
| 734 | + Emoji(glyph: "☘️", name: "shamrock", group: "Animals & Nature"), | |
| 735 | + Emoji(glyph: "🍀", name: "four leaf clover", group: "Animals & Nature"), | |
| 736 | + Emoji(glyph: "🍁", name: "maple leaf", group: "Animals & Nature"), | |
| 737 | + Emoji(glyph: "🍂", name: "fallen leaf", group: "Animals & Nature"), | |
| 738 | + Emoji(glyph: "🍃", name: "leaf fluttering in wind", group: "Animals & Nature"), | |
| 739 | + Emoji(glyph: "🪹", name: "empty nest", group: "Animals & Nature"), | |
| 740 | + Emoji(glyph: "🪺", name: "nest with eggs", group: "Animals & Nature"), | |
| 741 | + Emoji(glyph: "🍄", name: "mushroom", group: "Animals & Nature"), | |
| 742 | + Emoji(glyph: "🍇", name: "grapes", group: "Food & Drink"), | |
| 743 | + Emoji(glyph: "🍈", name: "melon", group: "Food & Drink"), | |
| 744 | + Emoji(glyph: "🍉", name: "watermelon", group: "Food & Drink"), | |
| 745 | + Emoji(glyph: "🍊", name: "tangerine", group: "Food & Drink"), | |
| 746 | + Emoji(glyph: "🍋", name: "lemon", group: "Food & Drink"), | |
| 747 | + Emoji(glyph: "🍋🟩", name: "lime", group: "Food & Drink"), | |
| 748 | + Emoji(glyph: "🍌", name: "banana", group: "Food & Drink"), | |
| 749 | + Emoji(glyph: "🍍", name: "pineapple", group: "Food & Drink"), | |
| 750 | + Emoji(glyph: "🥭", name: "mango", group: "Food & Drink"), | |
| 751 | + Emoji(glyph: "🍎", name: "red apple", group: "Food & Drink"), | |
| 752 | + Emoji(glyph: "🍏", name: "green apple", group: "Food & Drink"), | |
| 753 | + Emoji(glyph: "🍐", name: "pear", group: "Food & Drink"), | |
| 754 | + Emoji(glyph: "🍑", name: "peach", group: "Food & Drink"), | |
| 755 | + Emoji(glyph: "🍒", name: "cherries", group: "Food & Drink"), | |
| 756 | + Emoji(glyph: "🍓", name: "strawberry", group: "Food & Drink"), | |
| 757 | + Emoji(glyph: "🫐", name: "blueberries", group: "Food & Drink"), | |
| 758 | + Emoji(glyph: "🥝", name: "kiwi fruit", group: "Food & Drink"), | |
| 759 | + Emoji(glyph: "🍅", name: "tomato", group: "Food & Drink"), | |
| 760 | + Emoji(glyph: "🫒", name: "olive", group: "Food & Drink"), | |
| 761 | + Emoji(glyph: "🥥", name: "coconut", group: "Food & Drink"), | |
| 762 | + Emoji(glyph: "🥑", name: "avocado", group: "Food & Drink"), | |
| 763 | + Emoji(glyph: "🍆", name: "eggplant", group: "Food & Drink"), | |
| 764 | + Emoji(glyph: "🥔", name: "potato", group: "Food & Drink"), | |
| 765 | + Emoji(glyph: "🥕", name: "carrot", group: "Food & Drink"), | |
| 766 | + Emoji(glyph: "🌽", name: "ear of corn", group: "Food & Drink"), | |
| 767 | + Emoji(glyph: "🌶️", name: "hot pepper", group: "Food & Drink"), | |
| 768 | + Emoji(glyph: "🫑", name: "bell pepper", group: "Food & Drink"), | |
| 769 | + Emoji(glyph: "🥒", name: "cucumber", group: "Food & Drink"), | |
| 770 | + Emoji(glyph: "🥬", name: "leafy green", group: "Food & Drink"), | |
| 771 | + Emoji(glyph: "🥦", name: "broccoli", group: "Food & Drink"), | |
| 772 | + Emoji(glyph: "🧄", name: "garlic", group: "Food & Drink"), | |
| 773 | + Emoji(glyph: "🧅", name: "onion", group: "Food & Drink"), | |
| 774 | + Emoji(glyph: "🥜", name: "peanuts", group: "Food & Drink"), | |
| 775 | + Emoji(glyph: "🫘", name: "beans", group: "Food & Drink"), | |
| 776 | + Emoji(glyph: "🌰", name: "chestnut", group: "Food & Drink"), | |
| 777 | + Emoji(glyph: "🫚", name: "ginger root", group: "Food & Drink"), | |
| 778 | + Emoji(glyph: "🫛", name: "pea pod", group: "Food & Drink"), | |
| 779 | + Emoji(glyph: "🍄🟫", name: "brown mushroom", group: "Food & Drink"), | |
| 780 | + Emoji(glyph: "🍞", name: "bread", group: "Food & Drink"), | |
| 781 | + Emoji(glyph: "🥐", name: "croissant", group: "Food & Drink"), | |
| 782 | + Emoji(glyph: "🥖", name: "baguette bread", group: "Food & Drink"), | |
| 783 | + Emoji(glyph: "🫓", name: "flatbread", group: "Food & Drink"), | |
| 784 | + Emoji(glyph: "🥨", name: "pretzel", group: "Food & Drink"), | |
| 785 | + Emoji(glyph: "🥯", name: "bagel", group: "Food & Drink"), | |
| 786 | + Emoji(glyph: "🥞", name: "pancakes", group: "Food & Drink"), | |
| 787 | + Emoji(glyph: "🧇", name: "waffle", group: "Food & Drink"), | |
| 788 | + Emoji(glyph: "🧀", name: "cheese wedge", group: "Food & Drink"), | |
| 789 | + Emoji(glyph: "🍖", name: "meat on bone", group: "Food & Drink"), | |
| 790 | + Emoji(glyph: "🍗", name: "poultry leg", group: "Food & Drink"), | |
| 791 | + Emoji(glyph: "🥩", name: "cut of meat", group: "Food & Drink"), | |
| 792 | + Emoji(glyph: "🥓", name: "bacon", group: "Food & Drink"), | |
| 793 | + Emoji(glyph: "🍔", name: "hamburger", group: "Food & Drink"), | |
| 794 | + Emoji(glyph: "🍟", name: "french fries", group: "Food & Drink"), | |
| 795 | + Emoji(glyph: "🍕", name: "pizza", group: "Food & Drink"), | |
| 796 | + Emoji(glyph: "🌭", name: "hot dog", group: "Food & Drink"), | |
| 797 | + Emoji(glyph: "🥪", name: "sandwich", group: "Food & Drink"), | |
| 798 | + Emoji(glyph: "🌮", name: "taco", group: "Food & Drink"), | |
| 799 | + Emoji(glyph: "🌯", name: "burrito", group: "Food & Drink"), | |
| 800 | + Emoji(glyph: "🫔", name: "tamale", group: "Food & Drink"), | |
| 801 | + Emoji(glyph: "🥙", name: "stuffed flatbread", group: "Food & Drink"), | |
| 802 | + Emoji(glyph: "🧆", name: "falafel", group: "Food & Drink"), | |
| 803 | + Emoji(glyph: "🥚", name: "egg", group: "Food & Drink"), | |
| 804 | + Emoji(glyph: "🍳", name: "cooking", group: "Food & Drink"), | |
| 805 | + Emoji(glyph: "🥘", name: "shallow pan of food", group: "Food & Drink"), | |
| 806 | + Emoji(glyph: "🍲", name: "pot of food", group: "Food & Drink"), | |
| 807 | + Emoji(glyph: "🫕", name: "fondue", group: "Food & Drink"), | |
| 808 | + Emoji(glyph: "🥣", name: "bowl with spoon", group: "Food & Drink"), | |
| 809 | + Emoji(glyph: "🥗", name: "green salad", group: "Food & Drink"), | |
| 810 | + Emoji(glyph: "🍿", name: "popcorn", group: "Food & Drink"), | |
| 811 | + Emoji(glyph: "🧈", name: "butter", group: "Food & Drink"), | |
| 812 | + Emoji(glyph: "🧂", name: "salt", group: "Food & Drink"), | |
| 813 | + Emoji(glyph: "🥫", name: "canned food", group: "Food & Drink"), | |
| 814 | + Emoji(glyph: "🍱", name: "bento box", group: "Food & Drink"), | |
| 815 | + Emoji(glyph: "🍘", name: "rice cracker", group: "Food & Drink"), | |
| 816 | + Emoji(glyph: "🍙", name: "rice ball", group: "Food & Drink"), | |
| 817 | + Emoji(glyph: "🍚", name: "cooked rice", group: "Food & Drink"), | |
| 818 | + Emoji(glyph: "🍛", name: "curry rice", group: "Food & Drink"), | |
| 819 | + Emoji(glyph: "🍜", name: "steaming bowl", group: "Food & Drink"), | |
| 820 | + Emoji(glyph: "🍝", name: "spaghetti", group: "Food & Drink"), | |
| 821 | + Emoji(glyph: "🍠", name: "roasted sweet potato", group: "Food & Drink"), | |
| 822 | + Emoji(glyph: "🍢", name: "oden", group: "Food & Drink"), | |
| 823 | + Emoji(glyph: "🍣", name: "sushi", group: "Food & Drink"), | |
| 824 | + Emoji(glyph: "🍤", name: "fried shrimp", group: "Food & Drink"), | |
| 825 | + Emoji(glyph: "🍥", name: "fish cake with swirl", group: "Food & Drink"), | |
| 826 | + Emoji(glyph: "🥮", name: "moon cake", group: "Food & Drink"), | |
| 827 | + Emoji(glyph: "🍡", name: "dango", group: "Food & Drink"), | |
| 828 | + Emoji(glyph: "🥟", name: "dumpling", group: "Food & Drink"), | |
| 829 | + Emoji(glyph: "🥠", name: "fortune cookie", group: "Food & Drink"), | |
| 830 | + Emoji(glyph: "🥡", name: "takeout box", group: "Food & Drink"), | |
| 831 | + Emoji(glyph: "🦀", name: "crab", group: "Food & Drink"), | |
| 832 | + Emoji(glyph: "🦞", name: "lobster", group: "Food & Drink"), | |
| 833 | + Emoji(glyph: "🦐", name: "shrimp", group: "Food & Drink"), | |
| 834 | + Emoji(glyph: "🦑", name: "squid", group: "Food & Drink"), | |
| 835 | + Emoji(glyph: "🦪", name: "oyster", group: "Food & Drink"), | |
| 836 | + Emoji(glyph: "🍦", name: "soft ice cream", group: "Food & Drink"), | |
| 837 | + Emoji(glyph: "🍧", name: "shaved ice", group: "Food & Drink"), | |
| 838 | + Emoji(glyph: "🍨", name: "ice cream", group: "Food & Drink"), | |
| 839 | + Emoji(glyph: "🍩", name: "doughnut", group: "Food & Drink"), | |
| 840 | + Emoji(glyph: "🍪", name: "cookie", group: "Food & Drink"), | |
| 841 | + Emoji(glyph: "🎂", name: "birthday cake", group: "Food & Drink"), | |
| 842 | + Emoji(glyph: "🍰", name: "shortcake", group: "Food & Drink"), | |
| 843 | + Emoji(glyph: "🧁", name: "cupcake", group: "Food & Drink"), | |
| 844 | + Emoji(glyph: "🥧", name: "pie", group: "Food & Drink"), | |
| 845 | + Emoji(glyph: "🍫", name: "chocolate bar", group: "Food & Drink"), | |
| 846 | + Emoji(glyph: "🍬", name: "candy", group: "Food & Drink"), | |
| 847 | + Emoji(glyph: "🍭", name: "lollipop", group: "Food & Drink"), | |
| 848 | + Emoji(glyph: "🍮", name: "custard", group: "Food & Drink"), | |
| 849 | + Emoji(glyph: "🍯", name: "honey pot", group: "Food & Drink"), | |
| 850 | + Emoji(glyph: "🍼", name: "baby bottle", group: "Food & Drink"), | |
| 851 | + Emoji(glyph: "🥛", name: "glass of milk", group: "Food & Drink"), | |
| 852 | + Emoji(glyph: "☕", name: "hot beverage", group: "Food & Drink"), | |
| 853 | + Emoji(glyph: "🫖", name: "teapot", group: "Food & Drink"), | |
| 854 | + Emoji(glyph: "🍵", name: "teacup without handle", group: "Food & Drink"), | |
| 855 | + Emoji(glyph: "🍶", name: "sake", group: "Food & Drink"), | |
| 856 | + Emoji(glyph: "🍾", name: "bottle with popping cork", group: "Food & Drink"), | |
| 857 | + Emoji(glyph: "🍷", name: "wine glass", group: "Food & Drink"), | |
| 858 | + Emoji(glyph: "🍸", name: "cocktail glass", group: "Food & Drink"), | |
| 859 | + Emoji(glyph: "🍹", name: "tropical drink", group: "Food & Drink"), | |
| 860 | + Emoji(glyph: "🍺", name: "beer mug", group: "Food & Drink"), | |
| 861 | + Emoji(glyph: "🍻", name: "clinking beer mugs", group: "Food & Drink"), | |
| 862 | + Emoji(glyph: "🥂", name: "clinking glasses", group: "Food & Drink"), | |
| 863 | + Emoji(glyph: "🥃", name: "tumbler glass", group: "Food & Drink"), | |
| 864 | + Emoji(glyph: "🫗", name: "pouring liquid", group: "Food & Drink"), | |
| 865 | + Emoji(glyph: "🥤", name: "cup with straw", group: "Food & Drink"), | |
| 866 | + Emoji(glyph: "🧋", name: "bubble tea", group: "Food & Drink"), | |
| 867 | + Emoji(glyph: "🧃", name: "beverage box", group: "Food & Drink"), | |
| 868 | + Emoji(glyph: "🧉", name: "mate", group: "Food & Drink"), | |
| 869 | + Emoji(glyph: "🧊", name: "ice", group: "Food & Drink"), | |
| 870 | + Emoji(glyph: "🥢", name: "chopsticks", group: "Food & Drink"), | |
| 871 | + Emoji(glyph: "🍽️", name: "fork and knife with plate", group: "Food & Drink"), | |
| 872 | + Emoji(glyph: "🍴", name: "fork and knife", group: "Food & Drink"), | |
| 873 | + Emoji(glyph: "🥄", name: "spoon", group: "Food & Drink"), | |
| 874 | + Emoji(glyph: "🔪", name: "kitchen knife", group: "Food & Drink"), | |
| 875 | + Emoji(glyph: "🫙", name: "jar", group: "Food & Drink"), | |
| 876 | + Emoji(glyph: "🏺", name: "amphora", group: "Food & Drink"), | |
| 877 | + Emoji(glyph: "🌍", name: "globe showing Europe-Africa", group: "Travel & Places"), | |
| 878 | + Emoji(glyph: "🌎", name: "globe showing Americas", group: "Travel & Places"), | |
| 879 | + Emoji(glyph: "🌏", name: "globe showing Asia-Australia", group: "Travel & Places"), | |
| 880 | + Emoji(glyph: "🌐", name: "globe with meridians", group: "Travel & Places"), | |
| 881 | + Emoji(glyph: "🗺️", name: "world map", group: "Travel & Places"), | |
| 882 | + Emoji(glyph: "🗾", name: "map of Japan", group: "Travel & Places"), | |
| 883 | + Emoji(glyph: "🧭", name: "compass", group: "Travel & Places"), | |
| 884 | + Emoji(glyph: "🏔️", name: "snow-capped mountain", group: "Travel & Places"), | |
| 885 | + Emoji(glyph: "⛰️", name: "mountain", group: "Travel & Places"), | |
| 886 | + Emoji(glyph: "🌋", name: "volcano", group: "Travel & Places"), | |
| 887 | + Emoji(glyph: "🗻", name: "mount fuji", group: "Travel & Places"), | |
| 888 | + Emoji(glyph: "🏕️", name: "camping", group: "Travel & Places"), | |
| 889 | + Emoji(glyph: "🏖️", name: "beach with umbrella", group: "Travel & Places"), | |
| 890 | + Emoji(glyph: "🏜️", name: "desert", group: "Travel & Places"), | |
| 891 | + Emoji(glyph: "🏝️", name: "desert island", group: "Travel & Places"), | |
| 892 | + Emoji(glyph: "🏞️", name: "national park", group: "Travel & Places"), | |
| 893 | + Emoji(glyph: "🏟️", name: "stadium", group: "Travel & Places"), | |
| 894 | + Emoji(glyph: "🏛️", name: "classical building", group: "Travel & Places"), | |
| 895 | + Emoji(glyph: "🏗️", name: "building construction", group: "Travel & Places"), | |
| 896 | + Emoji(glyph: "🧱", name: "brick", group: "Travel & Places"), | |
| 897 | + Emoji(glyph: "🪨", name: "rock", group: "Travel & Places"), | |
| 898 | + Emoji(glyph: "🪵", name: "wood", group: "Travel & Places"), | |
| 899 | + Emoji(glyph: "🛖", name: "hut", group: "Travel & Places"), | |
| 900 | + Emoji(glyph: "🏘️", name: "houses", group: "Travel & Places"), | |
| 901 | + Emoji(glyph: "🏚️", name: "derelict house", group: "Travel & Places"), | |
| 902 | + Emoji(glyph: "🏠", name: "house", group: "Travel & Places"), | |
| 903 | + Emoji(glyph: "🏡", name: "house with garden", group: "Travel & Places"), | |
| 904 | + Emoji(glyph: "🏢", name: "office building", group: "Travel & Places"), | |
| 905 | + Emoji(glyph: "🏣", name: "Japanese post office", group: "Travel & Places"), | |
| 906 | + Emoji(glyph: "🏤", name: "post office", group: "Travel & Places"), | |
| 907 | + Emoji(glyph: "🏥", name: "hospital", group: "Travel & Places"), | |
| 908 | + Emoji(glyph: "🏦", name: "bank", group: "Travel & Places"), | |
| 909 | + Emoji(glyph: "🏨", name: "hotel", group: "Travel & Places"), | |
| 910 | + Emoji(glyph: "🏩", name: "love hotel", group: "Travel & Places"), | |
| 911 | + Emoji(glyph: "🏪", name: "convenience store", group: "Travel & Places"), | |
| 912 | + Emoji(glyph: "🏫", name: "school", group: "Travel & Places"), | |
| 913 | + Emoji(glyph: "🏬", name: "department store", group: "Travel & Places"), | |
| 914 | + Emoji(glyph: "🏭", name: "factory", group: "Travel & Places"), | |
| 915 | + Emoji(glyph: "🏯", name: "Japanese castle", group: "Travel & Places"), | |
| 916 | + Emoji(glyph: "🏰", name: "castle", group: "Travel & Places"), | |
| 917 | + Emoji(glyph: "💒", name: "wedding", group: "Travel & Places"), | |
| 918 | + Emoji(glyph: "🗼", name: "Tokyo tower", group: "Travel & Places"), | |
| 919 | + Emoji(glyph: "🗽", name: "Statue of Liberty", group: "Travel & Places"), | |
| 920 | + Emoji(glyph: "⛪", name: "church", group: "Travel & Places"), | |
| 921 | + Emoji(glyph: "🕌", name: "mosque", group: "Travel & Places"), | |
| 922 | + Emoji(glyph: "🛕", name: "hindu temple", group: "Travel & Places"), | |
| 923 | + Emoji(glyph: "🕍", name: "synagogue", group: "Travel & Places"), | |
| 924 | + Emoji(glyph: "⛩️", name: "shinto shrine", group: "Travel & Places"), | |
| 925 | + Emoji(glyph: "🕋", name: "kaaba", group: "Travel & Places"), | |
| 926 | + Emoji(glyph: "⛲", name: "fountain", group: "Travel & Places"), | |
| 927 | + Emoji(glyph: "⛺", name: "tent", group: "Travel & Places"), | |
| 928 | + Emoji(glyph: "🌁", name: "foggy", group: "Travel & Places"), | |
| 929 | + Emoji(glyph: "🌃", name: "night with stars", group: "Travel & Places"), | |
| 930 | + Emoji(glyph: "🏙️", name: "cityscape", group: "Travel & Places"), | |
| 931 | + Emoji(glyph: "🌄", name: "sunrise over mountains", group: "Travel & Places"), | |
| 932 | + Emoji(glyph: "🌅", name: "sunrise", group: "Travel & Places"), | |
| 933 | + Emoji(glyph: "🌆", name: "cityscape at dusk", group: "Travel & Places"), | |
| 934 | + Emoji(glyph: "🌇", name: "sunset", group: "Travel & Places"), | |
| 935 | + Emoji(glyph: "🌉", name: "bridge at night", group: "Travel & Places"), | |
| 936 | + Emoji(glyph: "♨️", name: "hot springs", group: "Travel & Places"), | |
| 937 | + Emoji(glyph: "🎠", name: "carousel horse", group: "Travel & Places"), | |
| 938 | + Emoji(glyph: "🛝", name: "playground slide", group: "Travel & Places"), | |
| 939 | + Emoji(glyph: "🎡", name: "ferris wheel", group: "Travel & Places"), | |
| 940 | + Emoji(glyph: "🎢", name: "roller coaster", group: "Travel & Places"), | |
| 941 | + Emoji(glyph: "💈", name: "barber pole", group: "Travel & Places"), | |
| 942 | + Emoji(glyph: "🎪", name: "circus tent", group: "Travel & Places"), | |
| 943 | + Emoji(glyph: "🚂", name: "locomotive", group: "Travel & Places"), | |
| 944 | + Emoji(glyph: "🚃", name: "railway car", group: "Travel & Places"), | |
| 945 | + Emoji(glyph: "🚄", name: "high-speed train", group: "Travel & Places"), | |
| 946 | + Emoji(glyph: "🚅", name: "bullet train", group: "Travel & Places"), | |
| 947 | + Emoji(glyph: "🚆", name: "train", group: "Travel & Places"), | |
| 948 | + Emoji(glyph: "🚇", name: "metro", group: "Travel & Places"), | |
| 949 | + Emoji(glyph: "🚈", name: "light rail", group: "Travel & Places"), | |
| 950 | + Emoji(glyph: "🚉", name: "station", group: "Travel & Places"), | |
| 951 | + Emoji(glyph: "🚊", name: "tram", group: "Travel & Places"), | |
| 952 | + Emoji(glyph: "🚝", name: "monorail", group: "Travel & Places"), | |
| 953 | + Emoji(glyph: "🚞", name: "mountain railway", group: "Travel & Places"), | |
| 954 | + Emoji(glyph: "🚋", name: "tram car", group: "Travel & Places"), | |
| 955 | + Emoji(glyph: "🚌", name: "bus", group: "Travel & Places"), | |
| 956 | + Emoji(glyph: "🚍", name: "oncoming bus", group: "Travel & Places"), | |
| 957 | + Emoji(glyph: "🚎", name: "trolleybus", group: "Travel & Places"), | |
| 958 | + Emoji(glyph: "🚐", name: "minibus", group: "Travel & Places"), | |
| 959 | + Emoji(glyph: "🚑", name: "ambulance", group: "Travel & Places"), | |
| 960 | + Emoji(glyph: "🚒", name: "fire engine", group: "Travel & Places"), | |
| 961 | + Emoji(glyph: "🚓", name: "police car", group: "Travel & Places"), | |
| 962 | + Emoji(glyph: "🚔", name: "oncoming police car", group: "Travel & Places"), | |
| 963 | + Emoji(glyph: "🚕", name: "taxi", group: "Travel & Places"), | |
| 964 | + Emoji(glyph: "🚖", name: "oncoming taxi", group: "Travel & Places"), | |
| 965 | + Emoji(glyph: "🚗", name: "automobile", group: "Travel & Places"), | |
| 966 | + Emoji(glyph: "🚘", name: "oncoming automobile", group: "Travel & Places"), | |
| 967 | + Emoji(glyph: "🚙", name: "sport utility vehicle", group: "Travel & Places"), | |
| 968 | + Emoji(glyph: "🛻", name: "pickup truck", group: "Travel & Places"), | |
| 969 | + Emoji(glyph: "🚚", name: "delivery truck", group: "Travel & Places"), | |
| 970 | + Emoji(glyph: "🚛", name: "articulated lorry", group: "Travel & Places"), | |
| 971 | + Emoji(glyph: "🚜", name: "tractor", group: "Travel & Places"), | |
| 972 | + Emoji(glyph: "🏎️", name: "racing car", group: "Travel & Places"), | |
| 973 | + Emoji(glyph: "🏍️", name: "motorcycle", group: "Travel & Places"), | |
| 974 | + Emoji(glyph: "🛵", name: "motor scooter", group: "Travel & Places"), | |
| 975 | + Emoji(glyph: "🦽", name: "manual wheelchair", group: "Travel & Places"), | |
| 976 | + Emoji(glyph: "🦼", name: "motorized wheelchair", group: "Travel & Places"), | |
| 977 | + Emoji(glyph: "🛺", name: "auto rickshaw", group: "Travel & Places"), | |
| 978 | + Emoji(glyph: "🚲", name: "bicycle", group: "Travel & Places"), | |
| 979 | + Emoji(glyph: "🛴", name: "kick scooter", group: "Travel & Places"), | |
| 980 | + Emoji(glyph: "🛹", name: "skateboard", group: "Travel & Places"), | |
| 981 | + Emoji(glyph: "🛼", name: "roller skate", group: "Travel & Places"), | |
| 982 | + Emoji(glyph: "🚏", name: "bus stop", group: "Travel & Places"), | |
| 983 | + Emoji(glyph: "🛣️", name: "motorway", group: "Travel & Places"), | |
| 984 | + Emoji(glyph: "🛤️", name: "railway track", group: "Travel & Places"), | |
| 985 | + Emoji(glyph: "🛢️", name: "oil drum", group: "Travel & Places"), | |
| 986 | + Emoji(glyph: "⛽", name: "fuel pump", group: "Travel & Places"), | |
| 987 | + Emoji(glyph: "🛞", name: "wheel", group: "Travel & Places"), | |
| 988 | + Emoji(glyph: "🚨", name: "police car light", group: "Travel & Places"), | |
| 989 | + Emoji(glyph: "🚥", name: "horizontal traffic light", group: "Travel & Places"), | |
| 990 | + Emoji(glyph: "🚦", name: "vertical traffic light", group: "Travel & Places"), | |
| 991 | + Emoji(glyph: "🛑", name: "stop sign", group: "Travel & Places"), | |
| 992 | + Emoji(glyph: "🚧", name: "construction", group: "Travel & Places"), | |
| 993 | + Emoji(glyph: "⚓", name: "anchor", group: "Travel & Places"), | |
| 994 | + Emoji(glyph: "🛟", name: "ring buoy", group: "Travel & Places"), | |
| 995 | + Emoji(glyph: "⛵", name: "sailboat", group: "Travel & Places"), | |
| 996 | + Emoji(glyph: "🛶", name: "canoe", group: "Travel & Places"), | |
| 997 | + Emoji(glyph: "🚤", name: "speedboat", group: "Travel & Places"), | |
| 998 | + Emoji(glyph: "🛳️", name: "passenger ship", group: "Travel & Places"), | |
| 999 | + Emoji(glyph: "⛴️", name: "ferry", group: "Travel & Places"), | |
| 1000 | + Emoji(glyph: "🛥️", name: "motor boat", group: "Travel & Places"), | |
| 1001 | + Emoji(glyph: "🚢", name: "ship", group: "Travel & Places"), | |
| 1002 | + Emoji(glyph: "✈️", name: "airplane", group: "Travel & Places"), | |
| 1003 | + Emoji(glyph: "🛩️", name: "small airplane", group: "Travel & Places"), | |
| 1004 | + Emoji(glyph: "🛫", name: "airplane departure", group: "Travel & Places"), | |
| 1005 | + Emoji(glyph: "🛬", name: "airplane arrival", group: "Travel & Places"), | |
| 1006 | + Emoji(glyph: "🪂", name: "parachute", group: "Travel & Places"), | |
| 1007 | + Emoji(glyph: "💺", name: "seat", group: "Travel & Places"), | |
| 1008 | + Emoji(glyph: "🚁", name: "helicopter", group: "Travel & Places"), | |
| 1009 | + Emoji(glyph: "🚟", name: "suspension railway", group: "Travel & Places"), | |
| 1010 | + Emoji(glyph: "🚠", name: "mountain cableway", group: "Travel & Places"), | |
| 1011 | + Emoji(glyph: "🚡", name: "aerial tramway", group: "Travel & Places"), | |
| 1012 | + Emoji(glyph: "🛰️", name: "satellite", group: "Travel & Places"), | |
| 1013 | + Emoji(glyph: "🚀", name: "rocket", group: "Travel & Places"), | |
| 1014 | + Emoji(glyph: "🛸", name: "flying saucer", group: "Travel & Places"), | |
| 1015 | + Emoji(glyph: "🛎️", name: "bellhop bell", group: "Travel & Places"), | |
| 1016 | + Emoji(glyph: "🧳", name: "luggage", group: "Travel & Places"), | |
| 1017 | + Emoji(glyph: "⌛", name: "hourglass done", group: "Travel & Places"), | |
| 1018 | + Emoji(glyph: "⏳", name: "hourglass not done", group: "Travel & Places"), | |
| 1019 | + Emoji(glyph: "⌚", name: "watch", group: "Travel & Places"), | |
| 1020 | + Emoji(glyph: "⏰", name: "alarm clock", group: "Travel & Places"), | |
| 1021 | + Emoji(glyph: "⏱️", name: "stopwatch", group: "Travel & Places"), | |
| 1022 | + Emoji(glyph: "⏲️", name: "timer clock", group: "Travel & Places"), | |
| 1023 | + Emoji(glyph: "🕰️", name: "mantelpiece clock", group: "Travel & Places"), | |
| 1024 | + Emoji(glyph: "🕛", name: "twelve o’clock", group: "Travel & Places"), | |
| 1025 | + Emoji(glyph: "🕧", name: "twelve-thirty", group: "Travel & Places"), | |
| 1026 | + Emoji(glyph: "🕐", name: "one o’clock", group: "Travel & Places"), | |
| 1027 | + Emoji(glyph: "🕜", name: "one-thirty", group: "Travel & Places"), | |
| 1028 | + Emoji(glyph: "🕑", name: "two o’clock", group: "Travel & Places"), | |
| 1029 | + Emoji(glyph: "🕝", name: "two-thirty", group: "Travel & Places"), | |
| 1030 | + Emoji(glyph: "🕒", name: "three o’clock", group: "Travel & Places"), | |
| 1031 | + Emoji(glyph: "🕞", name: "three-thirty", group: "Travel & Places"), | |
| 1032 | + Emoji(glyph: "🕓", name: "four o’clock", group: "Travel & Places"), | |
| 1033 | + Emoji(glyph: "🕟", name: "four-thirty", group: "Travel & Places"), | |
| 1034 | + Emoji(glyph: "🕔", name: "five o’clock", group: "Travel & Places"), | |
| 1035 | + Emoji(glyph: "🕠", name: "five-thirty", group: "Travel & Places"), | |
| 1036 | + Emoji(glyph: "🕕", name: "six o’clock", group: "Travel & Places"), | |
| 1037 | + Emoji(glyph: "🕡", name: "six-thirty", group: "Travel & Places"), | |
| 1038 | + Emoji(glyph: "🕖", name: "seven o’clock", group: "Travel & Places"), | |
| 1039 | + Emoji(glyph: "🕢", name: "seven-thirty", group: "Travel & Places"), | |
| 1040 | + Emoji(glyph: "🕗", name: "eight o’clock", group: "Travel & Places"), | |
| 1041 | + Emoji(glyph: "🕣", name: "eight-thirty", group: "Travel & Places"), | |
| 1042 | + Emoji(glyph: "🕘", name: "nine o’clock", group: "Travel & Places"), | |
| 1043 | + Emoji(glyph: "🕤", name: "nine-thirty", group: "Travel & Places"), | |
| 1044 | + Emoji(glyph: "🕙", name: "ten o’clock", group: "Travel & Places"), | |
| 1045 | + Emoji(glyph: "🕥", name: "ten-thirty", group: "Travel & Places"), | |
| 1046 | + Emoji(glyph: "🕚", name: "eleven o’clock", group: "Travel & Places"), | |
| 1047 | + Emoji(glyph: "🕦", name: "eleven-thirty", group: "Travel & Places"), | |
| 1048 | + Emoji(glyph: "🌑", name: "new moon", group: "Travel & Places"), | |
| 1049 | + Emoji(glyph: "🌒", name: "waxing crescent moon", group: "Travel & Places"), | |
| 1050 | + Emoji(glyph: "🌓", name: "first quarter moon", group: "Travel & Places"), | |
| 1051 | + Emoji(glyph: "🌔", name: "waxing gibbous moon", group: "Travel & Places"), | |
| 1052 | + Emoji(glyph: "🌕", name: "full moon", group: "Travel & Places"), | |
| 1053 | + Emoji(glyph: "🌖", name: "waning gibbous moon", group: "Travel & Places"), | |
| 1054 | + Emoji(glyph: "🌗", name: "last quarter moon", group: "Travel & Places"), | |
| 1055 | + Emoji(glyph: "🌘", name: "waning crescent moon", group: "Travel & Places"), | |
| 1056 | + Emoji(glyph: "🌙", name: "crescent moon", group: "Travel & Places"), | |
| 1057 | + Emoji(glyph: "🌚", name: "new moon face", group: "Travel & Places"), | |
| 1058 | + Emoji(glyph: "🌛", name: "first quarter moon face", group: "Travel & Places"), | |
| 1059 | + Emoji(glyph: "🌜", name: "last quarter moon face", group: "Travel & Places"), | |
| 1060 | + Emoji(glyph: "🌡️", name: "thermometer", group: "Travel & Places"), | |
| 1061 | + Emoji(glyph: "☀️", name: "sun", group: "Travel & Places"), | |
| 1062 | + Emoji(glyph: "🌝", name: "full moon face", group: "Travel & Places"), | |
| 1063 | + Emoji(glyph: "🌞", name: "sun with face", group: "Travel & Places"), | |
| 1064 | + Emoji(glyph: "🪐", name: "ringed planet", group: "Travel & Places"), | |
| 1065 | + Emoji(glyph: "⭐", name: "star", group: "Travel & Places"), | |
| 1066 | + Emoji(glyph: "🌟", name: "glowing star", group: "Travel & Places"), | |
| 1067 | + Emoji(glyph: "🌠", name: "shooting star", group: "Travel & Places"), | |
| 1068 | + Emoji(glyph: "🌌", name: "milky way", group: "Travel & Places"), | |
| 1069 | + Emoji(glyph: "☁️", name: "cloud", group: "Travel & Places"), | |
| 1070 | + Emoji(glyph: "⛅", name: "sun behind cloud", group: "Travel & Places"), | |
| 1071 | + Emoji(glyph: "⛈️", name: "cloud with lightning and rain", group: "Travel & Places"), | |
| 1072 | + Emoji(glyph: "🌤️", name: "sun behind small cloud", group: "Travel & Places"), | |
| 1073 | + Emoji(glyph: "🌥️", name: "sun behind large cloud", group: "Travel & Places"), | |
| 1074 | + Emoji(glyph: "🌦️", name: "sun behind rain cloud", group: "Travel & Places"), | |
| 1075 | + Emoji(glyph: "🌧️", name: "cloud with rain", group: "Travel & Places"), | |
| 1076 | + Emoji(glyph: "🌨️", name: "cloud with snow", group: "Travel & Places"), | |
| 1077 | + Emoji(glyph: "🌩️", name: "cloud with lightning", group: "Travel & Places"), | |
| 1078 | + Emoji(glyph: "🌪️", name: "tornado", group: "Travel & Places"), | |
| 1079 | + Emoji(glyph: "🌫️", name: "fog", group: "Travel & Places"), | |
| 1080 | + Emoji(glyph: "🌬️", name: "wind face", group: "Travel & Places"), | |
| 1081 | + Emoji(glyph: "🌀", name: "cyclone", group: "Travel & Places"), | |
| 1082 | + Emoji(glyph: "🌈", name: "rainbow", group: "Travel & Places"), | |
| 1083 | + Emoji(glyph: "🌂", name: "closed umbrella", group: "Travel & Places"), | |
| 1084 | + Emoji(glyph: "☂️", name: "umbrella", group: "Travel & Places"), | |
| 1085 | + Emoji(glyph: "☔", name: "umbrella with rain drops", group: "Travel & Places"), | |
| 1086 | + Emoji(glyph: "⛱️", name: "umbrella on ground", group: "Travel & Places"), | |
| 1087 | + Emoji(glyph: "⚡", name: "high voltage", group: "Travel & Places"), | |
| 1088 | + Emoji(glyph: "❄️", name: "snowflake", group: "Travel & Places"), | |
| 1089 | + Emoji(glyph: "☃️", name: "snowman", group: "Travel & Places"), | |
| 1090 | + Emoji(glyph: "⛄", name: "snowman without snow", group: "Travel & Places"), | |
| 1091 | + Emoji(glyph: "☄️", name: "comet", group: "Travel & Places"), | |
| 1092 | + Emoji(glyph: "🔥", name: "fire", group: "Travel & Places"), | |
| 1093 | + Emoji(glyph: "💧", name: "droplet", group: "Travel & Places"), | |
| 1094 | + Emoji(glyph: "🌊", name: "water wave", group: "Travel & Places"), | |
| 1095 | + Emoji(glyph: "🎃", name: "jack-o-lantern", group: "Activities"), | |
| 1096 | + Emoji(glyph: "🎄", name: "Christmas tree", group: "Activities"), | |
| 1097 | + Emoji(glyph: "🎆", name: "fireworks", group: "Activities"), | |
| 1098 | + Emoji(glyph: "🎇", name: "sparkler", group: "Activities"), | |
| 1099 | + Emoji(glyph: "🧨", name: "firecracker", group: "Activities"), | |
| 1100 | + Emoji(glyph: "✨", name: "sparkles", group: "Activities"), | |
| 1101 | + Emoji(glyph: "🎈", name: "balloon", group: "Activities"), | |
| 1102 | + Emoji(glyph: "🎉", name: "party popper", group: "Activities"), | |
| 1103 | + Emoji(glyph: "🎊", name: "confetti ball", group: "Activities"), | |
| 1104 | + Emoji(glyph: "🎋", name: "tanabata tree", group: "Activities"), | |
| 1105 | + Emoji(glyph: "🎍", name: "pine decoration", group: "Activities"), | |
| 1106 | + Emoji(glyph: "🎎", name: "Japanese dolls", group: "Activities"), | |
| 1107 | + Emoji(glyph: "🎏", name: "carp streamer", group: "Activities"), | |
| 1108 | + Emoji(glyph: "🎐", name: "wind chime", group: "Activities"), | |
| 1109 | + Emoji(glyph: "🎑", name: "moon viewing ceremony", group: "Activities"), | |
| 1110 | + Emoji(glyph: "🧧", name: "red envelope", group: "Activities"), | |
| 1111 | + Emoji(glyph: "🎀", name: "ribbon", group: "Activities"), | |
| 1112 | + Emoji(glyph: "🎁", name: "wrapped gift", group: "Activities"), | |
| 1113 | + Emoji(glyph: "🎗️", name: "reminder ribbon", group: "Activities"), | |
| 1114 | + Emoji(glyph: "🎟️", name: "admission tickets", group: "Activities"), | |
| 1115 | + Emoji(glyph: "🎫", name: "ticket", group: "Activities"), | |
| 1116 | + Emoji(glyph: "🎖️", name: "military medal", group: "Activities"), | |
| 1117 | + Emoji(glyph: "🏆", name: "trophy", group: "Activities"), | |
| 1118 | + Emoji(glyph: "🏅", name: "sports medal", group: "Activities"), | |
| 1119 | + Emoji(glyph: "🥇", name: "1st place medal", group: "Activities"), | |
| 1120 | + Emoji(glyph: "🥈", name: "2nd place medal", group: "Activities"), | |
| 1121 | + Emoji(glyph: "🥉", name: "3rd place medal", group: "Activities"), | |
| 1122 | + Emoji(glyph: "⚽", name: "soccer ball", group: "Activities"), | |
| 1123 | + Emoji(glyph: "⚾", name: "baseball", group: "Activities"), | |
| 1124 | + Emoji(glyph: "🥎", name: "softball", group: "Activities"), | |
| 1125 | + Emoji(glyph: "🏀", name: "basketball", group: "Activities"), | |
| 1126 | + Emoji(glyph: "🏐", name: "volleyball", group: "Activities"), | |
| 1127 | + Emoji(glyph: "🏈", name: "american football", group: "Activities"), | |
| 1128 | + Emoji(glyph: "🏉", name: "rugby football", group: "Activities"), | |
| 1129 | + Emoji(glyph: "🎾", name: "tennis", group: "Activities"), | |
| 1130 | + Emoji(glyph: "🥏", name: "flying disc", group: "Activities"), | |
| 1131 | + Emoji(glyph: "🎳", name: "bowling", group: "Activities"), | |
| 1132 | + Emoji(glyph: "🏏", name: "cricket game", group: "Activities"), | |
| 1133 | + Emoji(glyph: "🏑", name: "field hockey", group: "Activities"), | |
| 1134 | + Emoji(glyph: "🏒", name: "ice hockey", group: "Activities"), | |
| 1135 | + Emoji(glyph: "🥍", name: "lacrosse", group: "Activities"), | |
| 1136 | + Emoji(glyph: "🏓", name: "ping pong", group: "Activities"), | |
| 1137 | + Emoji(glyph: "🏸", name: "badminton", group: "Activities"), | |
| 1138 | + Emoji(glyph: "🥊", name: "boxing glove", group: "Activities"), | |
| 1139 | + Emoji(glyph: "🥋", name: "martial arts uniform", group: "Activities"), | |
| 1140 | + Emoji(glyph: "🥅", name: "goal net", group: "Activities"), | |
| 1141 | + Emoji(glyph: "⛳", name: "flag in hole", group: "Activities"), | |
| 1142 | + Emoji(glyph: "⛸️", name: "ice skate", group: "Activities"), | |
| 1143 | + Emoji(glyph: "🎣", name: "fishing pole", group: "Activities"), | |
| 1144 | + Emoji(glyph: "🤿", name: "diving mask", group: "Activities"), | |
| 1145 | + Emoji(glyph: "🎽", name: "running shirt", group: "Activities"), | |
| 1146 | + Emoji(glyph: "🎿", name: "skis", group: "Activities"), | |
| 1147 | + Emoji(glyph: "🛷", name: "sled", group: "Activities"), | |
| 1148 | + Emoji(glyph: "🥌", name: "curling stone", group: "Activities"), | |
| 1149 | + Emoji(glyph: "🎯", name: "bullseye", group: "Activities"), | |
| 1150 | + Emoji(glyph: "🪀", name: "yo-yo", group: "Activities"), | |
| 1151 | + Emoji(glyph: "🪁", name: "kite", group: "Activities"), | |
| 1152 | + Emoji(glyph: "🔫", name: "water pistol", group: "Activities"), | |
| 1153 | + Emoji(glyph: "🎱", name: "pool 8 ball", group: "Activities"), | |
| 1154 | + Emoji(glyph: "🔮", name: "crystal ball", group: "Activities"), | |
| 1155 | + Emoji(glyph: "🪄", name: "magic wand", group: "Activities"), | |
| 1156 | + Emoji(glyph: "🎮", name: "video game", group: "Activities"), | |
| 1157 | + Emoji(glyph: "🕹️", name: "joystick", group: "Activities"), | |
| 1158 | + Emoji(glyph: "🎰", name: "slot machine", group: "Activities"), | |
| 1159 | + Emoji(glyph: "🎲", name: "game die", group: "Activities"), | |
| 1160 | + Emoji(glyph: "🧩", name: "puzzle piece", group: "Activities"), | |
| 1161 | + Emoji(glyph: "🧸", name: "teddy bear", group: "Activities"), | |
| 1162 | + Emoji(glyph: "🪅", name: "piñata", group: "Activities"), | |
| 1163 | + Emoji(glyph: "🪩", name: "mirror ball", group: "Activities"), | |
| 1164 | + Emoji(glyph: "🪆", name: "nesting dolls", group: "Activities"), | |
| 1165 | + Emoji(glyph: "♠️", name: "spade suit", group: "Activities"), | |
| 1166 | + Emoji(glyph: "♥️", name: "heart suit", group: "Activities"), | |
| 1167 | + Emoji(glyph: "♦️", name: "diamond suit", group: "Activities"), | |
| 1168 | + Emoji(glyph: "♣️", name: "club suit", group: "Activities"), | |
| 1169 | + Emoji(glyph: "♟️", name: "chess pawn", group: "Activities"), | |
| 1170 | + Emoji(glyph: "🃏", name: "joker", group: "Activities"), | |
| 1171 | + Emoji(glyph: "🀄", name: "mahjong red dragon", group: "Activities"), | |
| 1172 | + Emoji(glyph: "🎴", name: "flower playing cards", group: "Activities"), | |
| 1173 | + Emoji(glyph: "🎭", name: "performing arts", group: "Activities"), | |
| 1174 | + Emoji(glyph: "🖼️", name: "framed picture", group: "Activities"), | |
| 1175 | + Emoji(glyph: "🎨", name: "artist palette", group: "Activities"), | |
| 1176 | + Emoji(glyph: "🧵", name: "thread", group: "Activities"), | |
| 1177 | + Emoji(glyph: "🪡", name: "sewing needle", group: "Activities"), | |
| 1178 | + Emoji(glyph: "🧶", name: "yarn", group: "Activities"), | |
| 1179 | + Emoji(glyph: "🪢", name: "knot", group: "Activities"), | |
| 1180 | + Emoji(glyph: "👓", name: "glasses", group: "Objects"), | |
| 1181 | + Emoji(glyph: "🕶️", name: "sunglasses", group: "Objects"), | |
| 1182 | + Emoji(glyph: "🥽", name: "goggles", group: "Objects"), | |
| 1183 | + Emoji(glyph: "🥼", name: "lab coat", group: "Objects"), | |
| 1184 | + Emoji(glyph: "🦺", name: "safety vest", group: "Objects"), | |
| 1185 | + Emoji(glyph: "👔", name: "necktie", group: "Objects"), | |
| 1186 | + Emoji(glyph: "👕", name: "t-shirt", group: "Objects"), | |
| 1187 | + Emoji(glyph: "👖", name: "jeans", group: "Objects"), | |
| 1188 | + Emoji(glyph: "🧣", name: "scarf", group: "Objects"), | |
| 1189 | + Emoji(glyph: "🧤", name: "gloves", group: "Objects"), | |
| 1190 | + Emoji(glyph: "🧥", name: "coat", group: "Objects"), | |
| 1191 | + Emoji(glyph: "🧦", name: "socks", group: "Objects"), | |
| 1192 | + Emoji(glyph: "👗", name: "dress", group: "Objects"), | |
| 1193 | + Emoji(glyph: "👘", name: "kimono", group: "Objects"), | |
| 1194 | + Emoji(glyph: "🥻", name: "sari", group: "Objects"), | |
| 1195 | + Emoji(glyph: "🩱", name: "one-piece swimsuit", group: "Objects"), | |
| 1196 | + Emoji(glyph: "🩲", name: "briefs", group: "Objects"), | |
| 1197 | + Emoji(glyph: "🩳", name: "shorts", group: "Objects"), | |
| 1198 | + Emoji(glyph: "👙", name: "bikini", group: "Objects"), | |
| 1199 | + Emoji(glyph: "👚", name: "woman’s clothes", group: "Objects"), | |
| 1200 | + Emoji(glyph: "🪭", name: "folding hand fan", group: "Objects"), | |
| 1201 | + Emoji(glyph: "👛", name: "purse", group: "Objects"), | |
| 1202 | + Emoji(glyph: "👜", name: "handbag", group: "Objects"), | |
| 1203 | + Emoji(glyph: "👝", name: "clutch bag", group: "Objects"), | |
| 1204 | + Emoji(glyph: "🛍️", name: "shopping bags", group: "Objects"), | |
| 1205 | + Emoji(glyph: "🎒", name: "backpack", group: "Objects"), | |
| 1206 | + Emoji(glyph: "🩴", name: "thong sandal", group: "Objects"), | |
| 1207 | + Emoji(glyph: "👞", name: "man’s shoe", group: "Objects"), | |
| 1208 | + Emoji(glyph: "👟", name: "running shoe", group: "Objects"), | |
| 1209 | + Emoji(glyph: "🥾", name: "hiking boot", group: "Objects"), | |
| 1210 | + Emoji(glyph: "🥿", name: "flat shoe", group: "Objects"), | |
| 1211 | + Emoji(glyph: "👠", name: "high-heeled shoe", group: "Objects"), | |
| 1212 | + Emoji(glyph: "👡", name: "woman’s sandal", group: "Objects"), | |
| 1213 | + Emoji(glyph: "🩰", name: "ballet shoes", group: "Objects"), | |
| 1214 | + Emoji(glyph: "👢", name: "woman’s boot", group: "Objects"), | |
| 1215 | + Emoji(glyph: "🪮", name: "hair pick", group: "Objects"), | |
| 1216 | + Emoji(glyph: "👑", name: "crown", group: "Objects"), | |
| 1217 | + Emoji(glyph: "👒", name: "woman’s hat", group: "Objects"), | |
| 1218 | + Emoji(glyph: "🎩", name: "top hat", group: "Objects"), | |
| 1219 | + Emoji(glyph: "🎓", name: "graduation cap", group: "Objects"), | |
| 1220 | + Emoji(glyph: "🧢", name: "billed cap", group: "Objects"), | |
| 1221 | + Emoji(glyph: "🪖", name: "military helmet", group: "Objects"), | |
| 1222 | + Emoji(glyph: "⛑️", name: "rescue worker’s helmet", group: "Objects"), | |
| 1223 | + Emoji(glyph: "📿", name: "prayer beads", group: "Objects"), | |
| 1224 | + Emoji(glyph: "💄", name: "lipstick", group: "Objects"), | |
| 1225 | + Emoji(glyph: "💍", name: "ring", group: "Objects"), | |
| 1226 | + Emoji(glyph: "💎", name: "gem stone", group: "Objects"), | |
| 1227 | + Emoji(glyph: "🔇", name: "muted speaker", group: "Objects"), | |
| 1228 | + Emoji(glyph: "🔈", name: "speaker low volume", group: "Objects"), | |
| 1229 | + Emoji(glyph: "🔉", name: "speaker medium volume", group: "Objects"), | |
| 1230 | + Emoji(glyph: "🔊", name: "speaker high volume", group: "Objects"), | |
| 1231 | + Emoji(glyph: "📢", name: "loudspeaker", group: "Objects"), | |
| 1232 | + Emoji(glyph: "📣", name: "megaphone", group: "Objects"), | |
| 1233 | + Emoji(glyph: "📯", name: "postal horn", group: "Objects"), | |
| 1234 | + Emoji(glyph: "🔔", name: "bell", group: "Objects"), | |
| 1235 | + Emoji(glyph: "🔕", name: "bell with slash", group: "Objects"), | |
| 1236 | + Emoji(glyph: "🎼", name: "musical score", group: "Objects"), | |
| 1237 | + Emoji(glyph: "🎵", name: "musical note", group: "Objects"), | |
| 1238 | + Emoji(glyph: "🎶", name: "musical notes", group: "Objects"), | |
| 1239 | + Emoji(glyph: "🎙️", name: "studio microphone", group: "Objects"), | |
| 1240 | + Emoji(glyph: "🎚️", name: "level slider", group: "Objects"), | |
| 1241 | + Emoji(glyph: "🎛️", name: "control knobs", group: "Objects"), | |
| 1242 | + Emoji(glyph: "🎤", name: "microphone", group: "Objects"), | |
| 1243 | + Emoji(glyph: "🎧", name: "headphone", group: "Objects"), | |
| 1244 | + Emoji(glyph: "📻", name: "radio", group: "Objects"), | |
| 1245 | + Emoji(glyph: "🎷", name: "saxophone", group: "Objects"), | |
| 1246 | + Emoji(glyph: "🪗", name: "accordion", group: "Objects"), | |
| 1247 | + Emoji(glyph: "🎸", name: "guitar", group: "Objects"), | |
| 1248 | + Emoji(glyph: "🎹", name: "musical keyboard", group: "Objects"), | |
| 1249 | + Emoji(glyph: "🎺", name: "trumpet", group: "Objects"), | |
| 1250 | + Emoji(glyph: "🎻", name: "violin", group: "Objects"), | |
| 1251 | + Emoji(glyph: "🪕", name: "banjo", group: "Objects"), | |
| 1252 | + Emoji(glyph: "🥁", name: "drum", group: "Objects"), | |
| 1253 | + Emoji(glyph: "🪘", name: "long drum", group: "Objects"), | |
| 1254 | + Emoji(glyph: "🪇", name: "maracas", group: "Objects"), | |
| 1255 | + Emoji(glyph: "🪈", name: "flute", group: "Objects"), | |
| 1256 | + Emoji(glyph: "📱", name: "mobile phone", group: "Objects"), | |
| 1257 | + Emoji(glyph: "📲", name: "mobile phone with arrow", group: "Objects"), | |
| 1258 | + Emoji(glyph: "☎️", name: "telephone", group: "Objects"), | |
| 1259 | + Emoji(glyph: "📞", name: "telephone receiver", group: "Objects"), | |
| 1260 | + Emoji(glyph: "📟", name: "pager", group: "Objects"), | |
| 1261 | + Emoji(glyph: "📠", name: "fax machine", group: "Objects"), | |
| 1262 | + Emoji(glyph: "🔋", name: "battery", group: "Objects"), | |
| 1263 | + Emoji(glyph: "🪫", name: "low battery", group: "Objects"), | |
| 1264 | + Emoji(glyph: "🔌", name: "electric plug", group: "Objects"), | |
| 1265 | + Emoji(glyph: "💻", name: "laptop", group: "Objects"), | |
| 1266 | + Emoji(glyph: "🖥️", name: "desktop computer", group: "Objects"), | |
| 1267 | + Emoji(glyph: "🖨️", name: "printer", group: "Objects"), | |
| 1268 | + Emoji(glyph: "⌨️", name: "keyboard", group: "Objects"), | |
| 1269 | + Emoji(glyph: "🖱️", name: "computer mouse", group: "Objects"), | |
| 1270 | + Emoji(glyph: "🖲️", name: "trackball", group: "Objects"), | |
| 1271 | + Emoji(glyph: "💽", name: "computer disk", group: "Objects"), | |
| 1272 | + Emoji(glyph: "💾", name: "floppy disk", group: "Objects"), | |
| 1273 | + Emoji(glyph: "💿", name: "optical disk", group: "Objects"), | |
| 1274 | + Emoji(glyph: "📀", name: "dvd", group: "Objects"), | |
| 1275 | + Emoji(glyph: "🧮", name: "abacus", group: "Objects"), | |
| 1276 | + Emoji(glyph: "🎥", name: "movie camera", group: "Objects"), | |
| 1277 | + Emoji(glyph: "🎞️", name: "film frames", group: "Objects"), | |
| 1278 | + Emoji(glyph: "📽️", name: "film projector", group: "Objects"), | |
| 1279 | + Emoji(glyph: "🎬", name: "clapper board", group: "Objects"), | |
| 1280 | + Emoji(glyph: "📺", name: "television", group: "Objects"), | |
| 1281 | + Emoji(glyph: "📷", name: "camera", group: "Objects"), | |
| 1282 | + Emoji(glyph: "📸", name: "camera with flash", group: "Objects"), | |
| 1283 | + Emoji(glyph: "📹", name: "video camera", group: "Objects"), | |
| 1284 | + Emoji(glyph: "📼", name: "videocassette", group: "Objects"), | |
| 1285 | + Emoji(glyph: "🔍", name: "magnifying glass tilted left", group: "Objects"), | |
| 1286 | + Emoji(glyph: "🔎", name: "magnifying glass tilted right", group: "Objects"), | |
| 1287 | + Emoji(glyph: "🕯️", name: "candle", group: "Objects"), | |
| 1288 | + Emoji(glyph: "💡", name: "light bulb", group: "Objects"), | |
| 1289 | + Emoji(glyph: "🔦", name: "flashlight", group: "Objects"), | |
| 1290 | + Emoji(glyph: "🏮", name: "red paper lantern", group: "Objects"), | |
| 1291 | + Emoji(glyph: "🪔", name: "diya lamp", group: "Objects"), | |
| 1292 | + Emoji(glyph: "📔", name: "notebook with decorative cover", group: "Objects"), | |
| 1293 | + Emoji(glyph: "📕", name: "closed book", group: "Objects"), | |
| 1294 | + Emoji(glyph: "📖", name: "open book", group: "Objects"), | |
| 1295 | + Emoji(glyph: "📗", name: "green book", group: "Objects"), | |
| 1296 | + Emoji(glyph: "📘", name: "blue book", group: "Objects"), | |
| 1297 | + Emoji(glyph: "📙", name: "orange book", group: "Objects"), | |
| 1298 | + Emoji(glyph: "📚", name: "books", group: "Objects"), | |
| 1299 | + Emoji(glyph: "📓", name: "notebook", group: "Objects"), | |
| 1300 | + Emoji(glyph: "📒", name: "ledger", group: "Objects"), | |
| 1301 | + Emoji(glyph: "📃", name: "page with curl", group: "Objects"), | |
| 1302 | + Emoji(glyph: "📜", name: "scroll", group: "Objects"), | |
| 1303 | + Emoji(glyph: "📄", name: "page facing up", group: "Objects"), | |
| 1304 | + Emoji(glyph: "📰", name: "newspaper", group: "Objects"), | |
| 1305 | + Emoji(glyph: "🗞️", name: "rolled-up newspaper", group: "Objects"), | |
| 1306 | + Emoji(glyph: "📑", name: "bookmark tabs", group: "Objects"), | |
| 1307 | + Emoji(glyph: "🔖", name: "bookmark", group: "Objects"), | |
| 1308 | + Emoji(glyph: "🏷️", name: "label", group: "Objects"), | |
| 1309 | + Emoji(glyph: "💰", name: "money bag", group: "Objects"), | |
| 1310 | + Emoji(glyph: "🪙", name: "coin", group: "Objects"), | |
| 1311 | + Emoji(glyph: "💴", name: "yen banknote", group: "Objects"), | |
| 1312 | + Emoji(glyph: "💵", name: "dollar banknote", group: "Objects"), | |
| 1313 | + Emoji(glyph: "💶", name: "euro banknote", group: "Objects"), | |
| 1314 | + Emoji(glyph: "💷", name: "pound banknote", group: "Objects"), | |
| 1315 | + Emoji(glyph: "💸", name: "money with wings", group: "Objects"), | |
| 1316 | + Emoji(glyph: "💳", name: "credit card", group: "Objects"), | |
| 1317 | + Emoji(glyph: "🧾", name: "receipt", group: "Objects"), | |
| 1318 | + Emoji(glyph: "💹", name: "chart increasing with yen", group: "Objects"), | |
| 1319 | + Emoji(glyph: "✉️", name: "envelope", group: "Objects"), | |
| 1320 | + Emoji(glyph: "📧", name: "e-mail", group: "Objects"), | |
| 1321 | + Emoji(glyph: "📨", name: "incoming envelope", group: "Objects"), | |
| 1322 | + Emoji(glyph: "📩", name: "envelope with arrow", group: "Objects"), | |
| 1323 | + Emoji(glyph: "📤", name: "outbox tray", group: "Objects"), | |
| 1324 | + Emoji(glyph: "📥", name: "inbox tray", group: "Objects"), | |
| 1325 | + Emoji(glyph: "📦", name: "package", group: "Objects"), | |
| 1326 | + Emoji(glyph: "📫", name: "closed mailbox with raised flag", group: "Objects"), | |
| 1327 | + Emoji(glyph: "📪", name: "closed mailbox with lowered flag", group: "Objects"), | |
| 1328 | + Emoji(glyph: "📬", name: "open mailbox with raised flag", group: "Objects"), | |
| 1329 | + Emoji(glyph: "📭", name: "open mailbox with lowered flag", group: "Objects"), | |
| 1330 | + Emoji(glyph: "📮", name: "postbox", group: "Objects"), | |
| 1331 | + Emoji(glyph: "🗳️", name: "ballot box with ballot", group: "Objects"), | |
| 1332 | + Emoji(glyph: "✏️", name: "pencil", group: "Objects"), | |
| 1333 | + Emoji(glyph: "✒️", name: "black nib", group: "Objects"), | |
| 1334 | + Emoji(glyph: "🖋️", name: "fountain pen", group: "Objects"), | |
| 1335 | + Emoji(glyph: "🖊️", name: "pen", group: "Objects"), | |
| 1336 | + Emoji(glyph: "🖌️", name: "paintbrush", group: "Objects"), | |
| 1337 | + Emoji(glyph: "🖍️", name: "crayon", group: "Objects"), | |
| 1338 | + Emoji(glyph: "📝", name: "memo", group: "Objects"), | |
| 1339 | + Emoji(glyph: "💼", name: "briefcase", group: "Objects"), | |
| 1340 | + Emoji(glyph: "📁", name: "file folder", group: "Objects"), | |
| 1341 | + Emoji(glyph: "📂", name: "open file folder", group: "Objects"), | |
| 1342 | + Emoji(glyph: "🗂️", name: "card index dividers", group: "Objects"), | |
| 1343 | + Emoji(glyph: "📅", name: "calendar", group: "Objects"), | |
| 1344 | + Emoji(glyph: "📆", name: "tear-off calendar", group: "Objects"), | |
| 1345 | + Emoji(glyph: "🗒️", name: "spiral notepad", group: "Objects"), | |
| 1346 | + Emoji(glyph: "🗓️", name: "spiral calendar", group: "Objects"), | |
| 1347 | + Emoji(glyph: "📇", name: "card index", group: "Objects"), | |
| 1348 | + Emoji(glyph: "📈", name: "chart increasing", group: "Objects"), | |
| 1349 | + Emoji(glyph: "📉", name: "chart decreasing", group: "Objects"), | |
| 1350 | + Emoji(glyph: "📊", name: "bar chart", group: "Objects"), | |
| 1351 | + Emoji(glyph: "📋", name: "clipboard", group: "Objects"), | |
| 1352 | + Emoji(glyph: "📌", name: "pushpin", group: "Objects"), | |
| 1353 | + Emoji(glyph: "📍", name: "round pushpin", group: "Objects"), | |
| 1354 | + Emoji(glyph: "📎", name: "paperclip", group: "Objects"), | |
| 1355 | + Emoji(glyph: "🖇️", name: "linked paperclips", group: "Objects"), | |
| 1356 | + Emoji(glyph: "📏", name: "straight ruler", group: "Objects"), | |
| 1357 | + Emoji(glyph: "📐", name: "triangular ruler", group: "Objects"), | |
| 1358 | + Emoji(glyph: "✂️", name: "scissors", group: "Objects"), | |
| 1359 | + Emoji(glyph: "🗃️", name: "card file box", group: "Objects"), | |
| 1360 | + Emoji(glyph: "🗄️", name: "file cabinet", group: "Objects"), | |
| 1361 | + Emoji(glyph: "🗑️", name: "wastebasket", group: "Objects"), | |
| 1362 | + Emoji(glyph: "🔒", name: "locked", group: "Objects"), | |
| 1363 | + Emoji(glyph: "🔓", name: "unlocked", group: "Objects"), | |
| 1364 | + Emoji(glyph: "🔏", name: "locked with pen", group: "Objects"), | |
| 1365 | + Emoji(glyph: "🔐", name: "locked with key", group: "Objects"), | |
| 1366 | + Emoji(glyph: "🔑", name: "key", group: "Objects"), | |
| 1367 | + Emoji(glyph: "🗝️", name: "old key", group: "Objects"), | |
| 1368 | + Emoji(glyph: "🔨", name: "hammer", group: "Objects"), | |
| 1369 | + Emoji(glyph: "🪓", name: "axe", group: "Objects"), | |
| 1370 | + Emoji(glyph: "⛏️", name: "pick", group: "Objects"), | |
| 1371 | + Emoji(glyph: "⚒️", name: "hammer and pick", group: "Objects"), | |
| 1372 | + Emoji(glyph: "🛠️", name: "hammer and wrench", group: "Objects"), | |
| 1373 | + Emoji(glyph: "🗡️", name: "dagger", group: "Objects"), | |
| 1374 | + Emoji(glyph: "⚔️", name: "crossed swords", group: "Objects"), | |
| 1375 | + Emoji(glyph: "💣", name: "bomb", group: "Objects"), | |
| 1376 | + Emoji(glyph: "🪃", name: "boomerang", group: "Objects"), | |
| 1377 | + Emoji(glyph: "🏹", name: "bow and arrow", group: "Objects"), | |
| 1378 | + Emoji(glyph: "🛡️", name: "shield", group: "Objects"), | |
| 1379 | + Emoji(glyph: "🪚", name: "carpentry saw", group: "Objects"), | |
| 1380 | + Emoji(glyph: "🔧", name: "wrench", group: "Objects"), | |
| 1381 | + Emoji(glyph: "🪛", name: "screwdriver", group: "Objects"), | |
| 1382 | + Emoji(glyph: "🔩", name: "nut and bolt", group: "Objects"), | |
| 1383 | + Emoji(glyph: "⚙️", name: "gear", group: "Objects"), | |
| 1384 | + Emoji(glyph: "🗜️", name: "clamp", group: "Objects"), | |
| 1385 | + Emoji(glyph: "⚖️", name: "balance scale", group: "Objects"), | |
| 1386 | + Emoji(glyph: "🦯", name: "white cane", group: "Objects"), | |
| 1387 | + Emoji(glyph: "🔗", name: "link", group: "Objects"), | |
| 1388 | + Emoji(glyph: "⛓️💥", name: "broken chain", group: "Objects"), | |
| 1389 | + Emoji(glyph: "⛓️", name: "chains", group: "Objects"), | |
| 1390 | + Emoji(glyph: "🪝", name: "hook", group: "Objects"), | |
| 1391 | + Emoji(glyph: "🧰", name: "toolbox", group: "Objects"), | |
| 1392 | + Emoji(glyph: "🧲", name: "magnet", group: "Objects"), | |
| 1393 | + Emoji(glyph: "🪜", name: "ladder", group: "Objects"), | |
| 1394 | + Emoji(glyph: "⚗️", name: "alembic", group: "Objects"), | |
| 1395 | + Emoji(glyph: "🧪", name: "test tube", group: "Objects"), | |
| 1396 | + Emoji(glyph: "🧫", name: "petri dish", group: "Objects"), | |
| 1397 | + Emoji(glyph: "🧬", name: "dna", group: "Objects"), | |
| 1398 | + Emoji(glyph: "🔬", name: "microscope", group: "Objects"), | |
| 1399 | + Emoji(glyph: "🔭", name: "telescope", group: "Objects"), | |
| 1400 | + Emoji(glyph: "📡", name: "satellite antenna", group: "Objects"), | |
| 1401 | + Emoji(glyph: "💉", name: "syringe", group: "Objects"), | |
| 1402 | + Emoji(glyph: "🩸", name: "drop of blood", group: "Objects"), | |
| 1403 | + Emoji(glyph: "💊", name: "pill", group: "Objects"), | |
| 1404 | + Emoji(glyph: "🩹", name: "adhesive bandage", group: "Objects"), | |
| 1405 | + Emoji(glyph: "🩼", name: "crutch", group: "Objects"), | |
| 1406 | + Emoji(glyph: "🩺", name: "stethoscope", group: "Objects"), | |
| 1407 | + Emoji(glyph: "🩻", name: "x-ray", group: "Objects"), | |
| 1408 | + Emoji(glyph: "🚪", name: "door", group: "Objects"), | |
| 1409 | + Emoji(glyph: "🛗", name: "elevator", group: "Objects"), | |
| 1410 | + Emoji(glyph: "🪞", name: "mirror", group: "Objects"), | |
| 1411 | + Emoji(glyph: "🪟", name: "window", group: "Objects"), | |
| 1412 | + Emoji(glyph: "🛏️", name: "bed", group: "Objects"), | |
| 1413 | + Emoji(glyph: "🛋️", name: "couch and lamp", group: "Objects"), | |
| 1414 | + Emoji(glyph: "🪑", name: "chair", group: "Objects"), | |
| 1415 | + Emoji(glyph: "🚽", name: "toilet", group: "Objects"), | |
| 1416 | + Emoji(glyph: "🪠", name: "plunger", group: "Objects"), | |
| 1417 | + Emoji(glyph: "🚿", name: "shower", group: "Objects"), | |
| 1418 | + Emoji(glyph: "🛁", name: "bathtub", group: "Objects"), | |
| 1419 | + Emoji(glyph: "🪤", name: "mouse trap", group: "Objects"), | |
| 1420 | + Emoji(glyph: "🪒", name: "razor", group: "Objects"), | |
| 1421 | + Emoji(glyph: "🧴", name: "lotion bottle", group: "Objects"), | |
| 1422 | + Emoji(glyph: "🧷", name: "safety pin", group: "Objects"), | |
| 1423 | + Emoji(glyph: "🧹", name: "broom", group: "Objects"), | |
| 1424 | + Emoji(glyph: "🧺", name: "basket", group: "Objects"), | |
| 1425 | + Emoji(glyph: "🧻", name: "roll of paper", group: "Objects"), | |
| 1426 | + Emoji(glyph: "🪣", name: "bucket", group: "Objects"), | |
| 1427 | + Emoji(glyph: "🧼", name: "soap", group: "Objects"), | |
| 1428 | + Emoji(glyph: "🫧", name: "bubbles", group: "Objects"), | |
| 1429 | + Emoji(glyph: "🪥", name: "toothbrush", group: "Objects"), | |
| 1430 | + Emoji(glyph: "🧽", name: "sponge", group: "Objects"), | |
| 1431 | + Emoji(glyph: "🧯", name: "fire extinguisher", group: "Objects"), | |
| 1432 | + Emoji(glyph: "🛒", name: "shopping cart", group: "Objects"), | |
| 1433 | + Emoji(glyph: "🚬", name: "cigarette", group: "Objects"), | |
| 1434 | + Emoji(glyph: "⚰️", name: "coffin", group: "Objects"), | |
| 1435 | + Emoji(glyph: "🪦", name: "headstone", group: "Objects"), | |
| 1436 | + Emoji(glyph: "⚱️", name: "funeral urn", group: "Objects"), | |
| 1437 | + Emoji(glyph: "🧿", name: "nazar amulet", group: "Objects"), | |
| 1438 | + Emoji(glyph: "🪬", name: "hamsa", group: "Objects"), | |
| 1439 | + Emoji(glyph: "🗿", name: "moai", group: "Objects"), | |
| 1440 | + Emoji(glyph: "🪧", name: "placard", group: "Objects"), | |
| 1441 | + Emoji(glyph: "🪪", name: "identification card", group: "Objects"), | |
| 1442 | + Emoji(glyph: "🏧", name: "ATM sign", group: "Symbols"), | |
| 1443 | + Emoji(glyph: "🚮", name: "litter in bin sign", group: "Symbols"), | |
| 1444 | + Emoji(glyph: "🚰", name: "potable water", group: "Symbols"), | |
| 1445 | + Emoji(glyph: "♿", name: "wheelchair symbol", group: "Symbols"), | |
| 1446 | + Emoji(glyph: "🚹", name: "men’s room", group: "Symbols"), | |
| 1447 | + Emoji(glyph: "🚺", name: "women’s room", group: "Symbols"), | |
| 1448 | + Emoji(glyph: "🚻", name: "restroom", group: "Symbols"), | |
| 1449 | + Emoji(glyph: "🚼", name: "baby symbol", group: "Symbols"), | |
| 1450 | + Emoji(glyph: "🚾", name: "water closet", group: "Symbols"), | |
| 1451 | + Emoji(glyph: "🛂", name: "passport control", group: "Symbols"), | |
| 1452 | + Emoji(glyph: "🛃", name: "customs", group: "Symbols"), | |
| 1453 | + Emoji(glyph: "🛄", name: "baggage claim", group: "Symbols"), | |
| 1454 | + Emoji(glyph: "🛅", name: "left luggage", group: "Symbols"), | |
| 1455 | + Emoji(glyph: "⚠️", name: "warning", group: "Symbols"), | |
| 1456 | + Emoji(glyph: "🚸", name: "children crossing", group: "Symbols"), | |
| 1457 | + Emoji(glyph: "⛔", name: "no entry", group: "Symbols"), | |
| 1458 | + Emoji(glyph: "🚫", name: "prohibited", group: "Symbols"), | |
| 1459 | + Emoji(glyph: "🚳", name: "no bicycles", group: "Symbols"), | |
| 1460 | + Emoji(glyph: "🚭", name: "no smoking", group: "Symbols"), | |
| 1461 | + Emoji(glyph: "🚯", name: "no littering", group: "Symbols"), | |
| 1462 | + Emoji(glyph: "🚱", name: "non-potable water", group: "Symbols"), | |
| 1463 | + Emoji(glyph: "🚷", name: "no pedestrians", group: "Symbols"), | |
| 1464 | + Emoji(glyph: "📵", name: "no mobile phones", group: "Symbols"), | |
| 1465 | + Emoji(glyph: "🔞", name: "no one under eighteen", group: "Symbols"), | |
| 1466 | + Emoji(glyph: "☢️", name: "radioactive", group: "Symbols"), | |
| 1467 | + Emoji(glyph: "☣️", name: "biohazard", group: "Symbols"), | |
| 1468 | + Emoji(glyph: "⬆️", name: "up arrow", group: "Symbols"), | |
| 1469 | + Emoji(glyph: "↗️", name: "up-right arrow", group: "Symbols"), | |
| 1470 | + Emoji(glyph: "➡️", name: "right arrow", group: "Symbols"), | |
| 1471 | + Emoji(glyph: "↘️", name: "down-right arrow", group: "Symbols"), | |
| 1472 | + Emoji(glyph: "⬇️", name: "down arrow", group: "Symbols"), | |
| 1473 | + Emoji(glyph: "↙️", name: "down-left arrow", group: "Symbols"), | |
| 1474 | + Emoji(glyph: "⬅️", name: "left arrow", group: "Symbols"), | |
| 1475 | + Emoji(glyph: "↖️", name: "up-left arrow", group: "Symbols"), | |
| 1476 | + Emoji(glyph: "↕️", name: "up-down arrow", group: "Symbols"), | |
| 1477 | + Emoji(glyph: "↔️", name: "left-right arrow", group: "Symbols"), | |
| 1478 | + Emoji(glyph: "↩️", name: "right arrow curving left", group: "Symbols"), | |
| 1479 | + Emoji(glyph: "↪️", name: "left arrow curving right", group: "Symbols"), | |
| 1480 | + Emoji(glyph: "⤴️", name: "right arrow curving up", group: "Symbols"), | |
| 1481 | + Emoji(glyph: "⤵️", name: "right arrow curving down", group: "Symbols"), | |
| 1482 | + Emoji(glyph: "🔃", name: "clockwise vertical arrows", group: "Symbols"), | |
| 1483 | + Emoji(glyph: "🔄", name: "counterclockwise arrows button", group: "Symbols"), | |
| 1484 | + Emoji(glyph: "🔙", name: "BACK arrow", group: "Symbols"), | |
| 1485 | + Emoji(glyph: "🔚", name: "END arrow", group: "Symbols"), | |
| 1486 | + Emoji(glyph: "🔛", name: "ON! arrow", group: "Symbols"), | |
| 1487 | + Emoji(glyph: "🔜", name: "SOON arrow", group: "Symbols"), | |
| 1488 | + Emoji(glyph: "🔝", name: "TOP arrow", group: "Symbols"), | |
| 1489 | + Emoji(glyph: "🛐", name: "place of worship", group: "Symbols"), | |
| 1490 | + Emoji(glyph: "⚛️", name: "atom symbol", group: "Symbols"), | |
| 1491 | + Emoji(glyph: "🕉️", name: "om", group: "Symbols"), | |
| 1492 | + Emoji(glyph: "✡️", name: "star of David", group: "Symbols"), | |
| 1493 | + Emoji(glyph: "☸️", name: "wheel of dharma", group: "Symbols"), | |
| 1494 | + Emoji(glyph: "☯️", name: "yin yang", group: "Symbols"), | |
| 1495 | + Emoji(glyph: "✝️", name: "latin cross", group: "Symbols"), | |
| 1496 | + Emoji(glyph: "☦️", name: "orthodox cross", group: "Symbols"), | |
| 1497 | + Emoji(glyph: "☪️", name: "star and crescent", group: "Symbols"), | |
| 1498 | + Emoji(glyph: "☮️", name: "peace symbol", group: "Symbols"), | |
| 1499 | + Emoji(glyph: "🕎", name: "menorah", group: "Symbols"), | |
| 1500 | + Emoji(glyph: "🔯", name: "dotted six-pointed star", group: "Symbols"), | |
| 1501 | + Emoji(glyph: "🪯", name: "khanda", group: "Symbols"), | |
| 1502 | + Emoji(glyph: "♈", name: "Aries", group: "Symbols"), | |
| 1503 | + Emoji(glyph: "♉", name: "Taurus", group: "Symbols"), | |
| 1504 | + Emoji(glyph: "♊", name: "Gemini", group: "Symbols"), | |
| 1505 | + Emoji(glyph: "♋", name: "Cancer", group: "Symbols"), | |
| 1506 | + Emoji(glyph: "♌", name: "Leo", group: "Symbols"), | |
| 1507 | + Emoji(glyph: "♍", name: "Virgo", group: "Symbols"), | |
| 1508 | + Emoji(glyph: "♎", name: "Libra", group: "Symbols"), | |
| 1509 | + Emoji(glyph: "♏", name: "Scorpio", group: "Symbols"), | |
| 1510 | + Emoji(glyph: "♐", name: "Sagittarius", group: "Symbols"), | |
| 1511 | + Emoji(glyph: "♑", name: "Capricorn", group: "Symbols"), | |
| 1512 | + Emoji(glyph: "♒", name: "Aquarius", group: "Symbols"), | |
| 1513 | + Emoji(glyph: "♓", name: "Pisces", group: "Symbols"), | |
| 1514 | + Emoji(glyph: "⛎", name: "Ophiuchus", group: "Symbols"), | |
| 1515 | + Emoji(glyph: "🔀", name: "shuffle tracks button", group: "Symbols"), | |
| 1516 | + Emoji(glyph: "🔁", name: "repeat button", group: "Symbols"), | |
| 1517 | + Emoji(glyph: "🔂", name: "repeat single button", group: "Symbols"), | |
| 1518 | + Emoji(glyph: "▶️", name: "play button", group: "Symbols"), | |
| 1519 | + Emoji(glyph: "⏩", name: "fast-forward button", group: "Symbols"), | |
| 1520 | + Emoji(glyph: "⏭️", name: "next track button", group: "Symbols"), | |
| 1521 | + Emoji(glyph: "⏯️", name: "play or pause button", group: "Symbols"), | |
| 1522 | + Emoji(glyph: "◀️", name: "reverse button", group: "Symbols"), | |
| 1523 | + Emoji(glyph: "⏪", name: "fast reverse button", group: "Symbols"), | |
| 1524 | + Emoji(glyph: "⏮️", name: "last track button", group: "Symbols"), | |
| 1525 | + Emoji(glyph: "🔼", name: "upwards button", group: "Symbols"), | |
| 1526 | + Emoji(glyph: "⏫", name: "fast up button", group: "Symbols"), | |
| 1527 | + Emoji(glyph: "🔽", name: "downwards button", group: "Symbols"), | |
| 1528 | + Emoji(glyph: "⏬", name: "fast down button", group: "Symbols"), | |
| 1529 | + Emoji(glyph: "⏸️", name: "pause button", group: "Symbols"), | |
| 1530 | + Emoji(glyph: "⏹️", name: "stop button", group: "Symbols"), | |
| 1531 | + Emoji(glyph: "⏺️", name: "record button", group: "Symbols"), | |
| 1532 | + Emoji(glyph: "⏏️", name: "eject button", group: "Symbols"), | |
| 1533 | + Emoji(glyph: "🎦", name: "cinema", group: "Symbols"), | |
| 1534 | + Emoji(glyph: "🔅", name: "dim button", group: "Symbols"), | |
| 1535 | + Emoji(glyph: "🔆", name: "bright button", group: "Symbols"), | |
| 1536 | + Emoji(glyph: "📶", name: "antenna bars", group: "Symbols"), | |
| 1537 | + Emoji(glyph: "🛜", name: "wireless", group: "Symbols"), | |
| 1538 | + Emoji(glyph: "📳", name: "vibration mode", group: "Symbols"), | |
| 1539 | + Emoji(glyph: "📴", name: "mobile phone off", group: "Symbols"), | |
| 1540 | + Emoji(glyph: "♀️", name: "female sign", group: "Symbols"), | |
| 1541 | + Emoji(glyph: "♂️", name: "male sign", group: "Symbols"), | |
| 1542 | + Emoji(glyph: "⚧️", name: "transgender symbol", group: "Symbols"), | |
| 1543 | + Emoji(glyph: "✖️", name: "multiply", group: "Symbols"), | |
| 1544 | + Emoji(glyph: "➕", name: "plus", group: "Symbols"), | |
| 1545 | + Emoji(glyph: "➖", name: "minus", group: "Symbols"), | |
| 1546 | + Emoji(glyph: "➗", name: "divide", group: "Symbols"), | |
| 1547 | + Emoji(glyph: "🟰", name: "heavy equals sign", group: "Symbols"), | |
| 1548 | + Emoji(glyph: "♾️", name: "infinity", group: "Symbols"), | |
| 1549 | + Emoji(glyph: "‼️", name: "double exclamation mark", group: "Symbols"), | |
| 1550 | + Emoji(glyph: "⁉️", name: "exclamation question mark", group: "Symbols"), | |
| 1551 | + Emoji(glyph: "❓", name: "red question mark", group: "Symbols"), | |
| 1552 | + Emoji(glyph: "❔", name: "white question mark", group: "Symbols"), | |
| 1553 | + Emoji(glyph: "❕", name: "white exclamation mark", group: "Symbols"), | |
| 1554 | + Emoji(glyph: "❗", name: "red exclamation mark", group: "Symbols"), | |
| 1555 | + Emoji(glyph: "〰️", name: "wavy dash", group: "Symbols"), | |
| 1556 | + Emoji(glyph: "💱", name: "currency exchange", group: "Symbols"), | |
| 1557 | + Emoji(glyph: "💲", name: "heavy dollar sign", group: "Symbols"), | |
| 1558 | + Emoji(glyph: "⚕️", name: "medical symbol", group: "Symbols"), | |
| 1559 | + Emoji(glyph: "♻️", name: "recycling symbol", group: "Symbols"), | |
| 1560 | + Emoji(glyph: "⚜️", name: "fleur-de-lis", group: "Symbols"), | |
| 1561 | + Emoji(glyph: "🔱", name: "trident emblem", group: "Symbols"), | |
| 1562 | + Emoji(glyph: "📛", name: "name badge", group: "Symbols"), | |
| 1563 | + Emoji(glyph: "🔰", name: "Japanese symbol for beginner", group: "Symbols"), | |
| 1564 | + Emoji(glyph: "⭕", name: "hollow red circle", group: "Symbols"), | |
| 1565 | + Emoji(glyph: "✅", name: "check mark button", group: "Symbols"), | |
| 1566 | + Emoji(glyph: "☑️", name: "check box with check", group: "Symbols"), | |
| 1567 | + Emoji(glyph: "✔️", name: "check mark", group: "Symbols"), | |
| 1568 | + Emoji(glyph: "❌", name: "cross mark", group: "Symbols"), | |
| 1569 | + Emoji(glyph: "❎", name: "cross mark button", group: "Symbols"), | |
| 1570 | + Emoji(glyph: "➰", name: "curly loop", group: "Symbols"), | |
| 1571 | + Emoji(glyph: "➿", name: "double curly loop", group: "Symbols"), | |
| 1572 | + Emoji(glyph: "〽️", name: "part alternation mark", group: "Symbols"), | |
| 1573 | + Emoji(glyph: "✳️", name: "eight-spoked asterisk", group: "Symbols"), | |
| 1574 | + Emoji(glyph: "✴️", name: "eight-pointed star", group: "Symbols"), | |
| 1575 | + Emoji(glyph: "❇️", name: "sparkle", group: "Symbols"), | |
| 1576 | + Emoji(glyph: "™️", name: "trade mark", group: "Symbols"), | |
| 1577 | + Emoji(glyph: "🔟", name: "keycap: 10", group: "Symbols"), | |
| 1578 | + Emoji(glyph: "🔠", name: "input latin uppercase", group: "Symbols"), | |
| 1579 | + Emoji(glyph: "🔡", name: "input latin lowercase", group: "Symbols"), | |
| 1580 | + Emoji(glyph: "🔢", name: "input numbers", group: "Symbols"), | |
| 1581 | + Emoji(glyph: "🔣", name: "input symbols", group: "Symbols"), | |
| 1582 | + Emoji(glyph: "🔤", name: "input latin letters", group: "Symbols"), | |
| 1583 | + Emoji(glyph: "🅰️", name: "A button (blood type)", group: "Symbols"), | |
| 1584 | + Emoji(glyph: "🆎", name: "AB button (blood type)", group: "Symbols"), | |
| 1585 | + Emoji(glyph: "🅱️", name: "B button (blood type)", group: "Symbols"), | |
| 1586 | + Emoji(glyph: "🆑", name: "CL button", group: "Symbols"), | |
| 1587 | + Emoji(glyph: "🆒", name: "COOL button", group: "Symbols"), | |
| 1588 | + Emoji(glyph: "🆓", name: "FREE button", group: "Symbols"), | |
| 1589 | + Emoji(glyph: "ℹ️", name: "information", group: "Symbols"), | |
| 1590 | + Emoji(glyph: "🆔", name: "ID button", group: "Symbols"), | |
| 1591 | + Emoji(glyph: "Ⓜ️", name: "circled M", group: "Symbols"), | |
| 1592 | + Emoji(glyph: "🆕", name: "NEW button", group: "Symbols"), | |
| 1593 | + Emoji(glyph: "🆖", name: "NG button", group: "Symbols"), | |
| 1594 | + Emoji(glyph: "🅾️", name: "O button (blood type)", group: "Symbols"), | |
| 1595 | + Emoji(glyph: "🆗", name: "OK button", group: "Symbols"), | |
| 1596 | + Emoji(glyph: "🅿️", name: "P button", group: "Symbols"), | |
| 1597 | + Emoji(glyph: "🆘", name: "SOS button", group: "Symbols"), | |
| 1598 | + Emoji(glyph: "🆙", name: "UP! button", group: "Symbols"), | |
| 1599 | + Emoji(glyph: "🆚", name: "VS button", group: "Symbols"), | |
| 1600 | + Emoji(glyph: "🈁", name: "Japanese “here” button", group: "Symbols"), | |
| 1601 | + Emoji(glyph: "🈂️", name: "Japanese “service charge” button", group: "Symbols"), | |
| 1602 | + Emoji(glyph: "🈷️", name: "Japanese “monthly amount” button", group: "Symbols"), | |
| 1603 | + Emoji(glyph: "🈶", name: "Japanese “not free of charge” button", group: "Symbols"), | |
| 1604 | + Emoji(glyph: "🈯", name: "Japanese “reserved” button", group: "Symbols"), | |
| 1605 | + Emoji(glyph: "🉐", name: "Japanese “bargain” button", group: "Symbols"), | |
| 1606 | + Emoji(glyph: "🈹", name: "Japanese “discount” button", group: "Symbols"), | |
| 1607 | + Emoji(glyph: "🈚", name: "Japanese “free of charge” button", group: "Symbols"), | |
| 1608 | + Emoji(glyph: "🈲", name: "Japanese “prohibited” button", group: "Symbols"), | |
| 1609 | + Emoji(glyph: "🉑", name: "Japanese “acceptable” button", group: "Symbols"), | |
| 1610 | + Emoji(glyph: "🈸", name: "Japanese “application” button", group: "Symbols"), | |
| 1611 | + Emoji(glyph: "🈴", name: "Japanese “passing grade” button", group: "Symbols"), | |
| 1612 | + Emoji(glyph: "🈳", name: "Japanese “vacancy” button", group: "Symbols"), | |
| 1613 | + Emoji(glyph: "㊗️", name: "Japanese “congratulations” button", group: "Symbols"), | |
| 1614 | + Emoji(glyph: "㊙️", name: "Japanese “secret” button", group: "Symbols"), | |
| 1615 | + Emoji(glyph: "🈺", name: "Japanese “open for business” button", group: "Symbols"), | |
| 1616 | + Emoji(glyph: "🈵", name: "Japanese “no vacancy” button", group: "Symbols"), | |
| 1617 | + Emoji(glyph: "🔴", name: "red circle", group: "Symbols"), | |
| 1618 | + Emoji(glyph: "🟠", name: "orange circle", group: "Symbols"), | |
| 1619 | + Emoji(glyph: "🟡", name: "yellow circle", group: "Symbols"), | |
| 1620 | + Emoji(glyph: "🟢", name: "green circle", group: "Symbols"), | |
| 1621 | + Emoji(glyph: "🔵", name: "blue circle", group: "Symbols"), | |
| 1622 | + Emoji(glyph: "🟣", name: "purple circle", group: "Symbols"), | |
| 1623 | + Emoji(glyph: "🟤", name: "brown circle", group: "Symbols"), | |
| 1624 | + Emoji(glyph: "⚫", name: "black circle", group: "Symbols"), | |
| 1625 | + Emoji(glyph: "⚪", name: "white circle", group: "Symbols"), | |
| 1626 | + Emoji(glyph: "🟥", name: "red square", group: "Symbols"), | |
| 1627 | + Emoji(glyph: "🟧", name: "orange square", group: "Symbols"), | |
| 1628 | + Emoji(glyph: "🟨", name: "yellow square", group: "Symbols"), | |
| 1629 | + Emoji(glyph: "🟩", name: "green square", group: "Symbols"), | |
| 1630 | + Emoji(glyph: "🟦", name: "blue square", group: "Symbols"), | |
| 1631 | + Emoji(glyph: "🟪", name: "purple square", group: "Symbols"), | |
| 1632 | + Emoji(glyph: "🟫", name: "brown square", group: "Symbols"), | |
| 1633 | + Emoji(glyph: "⬛", name: "black large square", group: "Symbols"), | |
| 1634 | + Emoji(glyph: "⬜", name: "white large square", group: "Symbols"), | |
| 1635 | + Emoji(glyph: "◼️", name: "black medium square", group: "Symbols"), | |
| 1636 | + Emoji(glyph: "◻️", name: "white medium square", group: "Symbols"), | |
| 1637 | + Emoji(glyph: "◾", name: "black medium-small square", group: "Symbols"), | |
| 1638 | + Emoji(glyph: "◽", name: "white medium-small square", group: "Symbols"), | |
| 1639 | + Emoji(glyph: "▪️", name: "black small square", group: "Symbols"), | |
| 1640 | + Emoji(glyph: "▫️", name: "white small square", group: "Symbols"), | |
| 1641 | + Emoji(glyph: "🔶", name: "large orange diamond", group: "Symbols"), | |
| 1642 | + Emoji(glyph: "🔷", name: "large blue diamond", group: "Symbols"), | |
| 1643 | + Emoji(glyph: "🔸", name: "small orange diamond", group: "Symbols"), | |
| 1644 | + Emoji(glyph: "🔹", name: "small blue diamond", group: "Symbols"), | |
| 1645 | + Emoji(glyph: "🔺", name: "red triangle pointed up", group: "Symbols"), | |
| 1646 | + Emoji(glyph: "🔻", name: "red triangle pointed down", group: "Symbols"), | |
| 1647 | + Emoji(glyph: "💠", name: "diamond with a dot", group: "Symbols"), | |
| 1648 | + Emoji(glyph: "🔘", name: "radio button", group: "Symbols"), | |
| 1649 | + Emoji(glyph: "🔳", name: "white square button", group: "Symbols"), | |
| 1650 | + Emoji(glyph: "🔲", name: "black square button", group: "Symbols"), | |
| 1651 | + Emoji(glyph: "🏁", name: "chequered flag", group: "Flags"), | |
| 1652 | + Emoji(glyph: "🚩", name: "triangular flag", group: "Flags"), | |
| 1653 | + Emoji(glyph: "🎌", name: "crossed flags", group: "Flags"), | |
| 1654 | + Emoji(glyph: "🏴", name: "black flag", group: "Flags"), | |
| 1655 | + Emoji(glyph: "🏳️", name: "white flag", group: "Flags"), | |
| 1656 | + Emoji(glyph: "🏳️🌈", name: "rainbow flag", group: "Flags"), | |
| 1657 | + Emoji(glyph: "🏳️⚧️", name: "transgender flag", group: "Flags"), | |
| 1658 | + Emoji(glyph: "🏴☠️", name: "pirate flag", group: "Flags"), | |
| 1659 | + Emoji(glyph: "🇦🇨", name: "flag: Ascension Island", group: "Flags"), | |
| 1660 | + Emoji(glyph: "🇦🇩", name: "flag: Andorra", group: "Flags"), | |
| 1661 | + Emoji(glyph: "🇦🇪", name: "flag: United Arab Emirates", group: "Flags"), | |
| 1662 | + Emoji(glyph: "🇦🇫", name: "flag: Afghanistan", group: "Flags"), | |
| 1663 | + Emoji(glyph: "🇦🇬", name: "flag: Antigua & Barbuda", group: "Flags"), | |
| 1664 | + Emoji(glyph: "🇦🇮", name: "flag: Anguilla", group: "Flags"), | |
| 1665 | + Emoji(glyph: "🇦🇱", name: "flag: Albania", group: "Flags"), | |
| 1666 | + Emoji(glyph: "🇦🇲", name: "flag: Armenia", group: "Flags"), | |
| 1667 | + Emoji(glyph: "🇦🇴", name: "flag: Angola", group: "Flags"), | |
| 1668 | + Emoji(glyph: "🇦🇶", name: "flag: Antarctica", group: "Flags"), | |
| 1669 | + Emoji(glyph: "🇦🇷", name: "flag: Argentina", group: "Flags"), | |
| 1670 | + Emoji(glyph: "🇦🇸", name: "flag: American Samoa", group: "Flags"), | |
| 1671 | + Emoji(glyph: "🇦🇹", name: "flag: Austria", group: "Flags"), | |
| 1672 | + Emoji(glyph: "🇦🇺", name: "flag: Australia", group: "Flags"), | |
| 1673 | + Emoji(glyph: "🇦🇼", name: "flag: Aruba", group: "Flags"), | |
| 1674 | + Emoji(glyph: "🇦🇽", name: "flag: Åland Islands", group: "Flags"), | |
| 1675 | + Emoji(glyph: "🇦🇿", name: "flag: Azerbaijan", group: "Flags"), | |
| 1676 | + Emoji(glyph: "🇧🇦", name: "flag: Bosnia & Herzegovina", group: "Flags"), | |
| 1677 | + Emoji(glyph: "🇧🇧", name: "flag: Barbados", group: "Flags"), | |
| 1678 | + Emoji(glyph: "🇧🇩", name: "flag: Bangladesh", group: "Flags"), | |
| 1679 | + Emoji(glyph: "🇧🇪", name: "flag: Belgium", group: "Flags"), | |
| 1680 | + Emoji(glyph: "🇧🇫", name: "flag: Burkina Faso", group: "Flags"), | |
| 1681 | + Emoji(glyph: "🇧🇬", name: "flag: Bulgaria", group: "Flags"), | |
| 1682 | + Emoji(glyph: "🇧🇭", name: "flag: Bahrain", group: "Flags"), | |
| 1683 | + Emoji(glyph: "🇧🇮", name: "flag: Burundi", group: "Flags"), | |
| 1684 | + Emoji(glyph: "🇧🇯", name: "flag: Benin", group: "Flags"), | |
| 1685 | + Emoji(glyph: "🇧🇱", name: "flag: St. Barthélemy", group: "Flags"), | |
| 1686 | + Emoji(glyph: "🇧🇲", name: "flag: Bermuda", group: "Flags"), | |
| 1687 | + Emoji(glyph: "🇧🇳", name: "flag: Brunei", group: "Flags"), | |
| 1688 | + Emoji(glyph: "🇧🇴", name: "flag: Bolivia", group: "Flags"), | |
| 1689 | + Emoji(glyph: "🇧🇶", name: "flag: Caribbean Netherlands", group: "Flags"), | |
| 1690 | + Emoji(glyph: "🇧🇷", name: "flag: Brazil", group: "Flags"), | |
| 1691 | + Emoji(glyph: "🇧🇸", name: "flag: Bahamas", group: "Flags"), | |
| 1692 | + Emoji(glyph: "🇧🇹", name: "flag: Bhutan", group: "Flags"), | |
| 1693 | + Emoji(glyph: "🇧🇻", name: "flag: Bouvet Island", group: "Flags"), | |
| 1694 | + Emoji(glyph: "🇧🇼", name: "flag: Botswana", group: "Flags"), | |
| 1695 | + Emoji(glyph: "🇧🇾", name: "flag: Belarus", group: "Flags"), | |
| 1696 | + Emoji(glyph: "🇧🇿", name: "flag: Belize", group: "Flags"), | |
| 1697 | + Emoji(glyph: "🇨🇦", name: "flag: Canada", group: "Flags"), | |
| 1698 | + Emoji(glyph: "🇨🇨", name: "flag: Cocos (Keeling) Islands", group: "Flags"), | |
| 1699 | + Emoji(glyph: "🇨🇩", name: "flag: Congo - Kinshasa", group: "Flags"), | |
| 1700 | + Emoji(glyph: "🇨🇫", name: "flag: Central African Republic", group: "Flags"), | |
| 1701 | + Emoji(glyph: "🇨🇬", name: "flag: Congo - Brazzaville", group: "Flags"), | |
| 1702 | + Emoji(glyph: "🇨🇭", name: "flag: Switzerland", group: "Flags"), | |
| 1703 | + Emoji(glyph: "🇨🇮", name: "flag: Côte d’Ivoire", group: "Flags"), | |
| 1704 | + Emoji(glyph: "🇨🇰", name: "flag: Cook Islands", group: "Flags"), | |
| 1705 | + Emoji(glyph: "🇨🇱", name: "flag: Chile", group: "Flags"), | |
| 1706 | + Emoji(glyph: "🇨🇲", name: "flag: Cameroon", group: "Flags"), | |
| 1707 | + Emoji(glyph: "🇨🇳", name: "flag: China", group: "Flags"), | |
| 1708 | + Emoji(glyph: "🇨🇴", name: "flag: Colombia", group: "Flags"), | |
| 1709 | + Emoji(glyph: "🇨🇵", name: "flag: Clipperton Island", group: "Flags"), | |
| 1710 | + Emoji(glyph: "🇨🇷", name: "flag: Costa Rica", group: "Flags"), | |
| 1711 | + Emoji(glyph: "🇨🇺", name: "flag: Cuba", group: "Flags"), | |
| 1712 | + Emoji(glyph: "🇨🇻", name: "flag: Cape Verde", group: "Flags"), | |
| 1713 | + Emoji(glyph: "🇨🇼", name: "flag: Curaçao", group: "Flags"), | |
| 1714 | + Emoji(glyph: "🇨🇽", name: "flag: Christmas Island", group: "Flags"), | |
| 1715 | + Emoji(glyph: "🇨🇾", name: "flag: Cyprus", group: "Flags"), | |
| 1716 | + Emoji(glyph: "🇨🇿", name: "flag: Czechia", group: "Flags"), | |
| 1717 | + Emoji(glyph: "🇩🇪", name: "flag: Germany", group: "Flags"), | |
| 1718 | + Emoji(glyph: "🇩🇬", name: "flag: Diego Garcia", group: "Flags"), | |
| 1719 | + Emoji(glyph: "🇩🇯", name: "flag: Djibouti", group: "Flags"), | |
| 1720 | + Emoji(glyph: "🇩🇰", name: "flag: Denmark", group: "Flags"), | |
| 1721 | + Emoji(glyph: "🇩🇲", name: "flag: Dominica", group: "Flags"), | |
| 1722 | + Emoji(glyph: "🇩🇴", name: "flag: Dominican Republic", group: "Flags"), | |
| 1723 | + Emoji(glyph: "🇩🇿", name: "flag: Algeria", group: "Flags"), | |
| 1724 | + Emoji(glyph: "🇪🇦", name: "flag: Ceuta & Melilla", group: "Flags"), | |
| 1725 | + Emoji(glyph: "🇪🇨", name: "flag: Ecuador", group: "Flags"), | |
| 1726 | + Emoji(glyph: "🇪🇪", name: "flag: Estonia", group: "Flags"), | |
| 1727 | + Emoji(glyph: "🇪🇬", name: "flag: Egypt", group: "Flags"), | |
| 1728 | + Emoji(glyph: "🇪🇭", name: "flag: Western Sahara", group: "Flags"), | |
| 1729 | + Emoji(glyph: "🇪🇷", name: "flag: Eritrea", group: "Flags"), | |
| 1730 | + Emoji(glyph: "🇪🇸", name: "flag: Spain", group: "Flags"), | |
| 1731 | + Emoji(glyph: "🇪🇹", name: "flag: Ethiopia", group: "Flags"), | |
| 1732 | + Emoji(glyph: "🇪🇺", name: "flag: European Union", group: "Flags"), | |
| 1733 | + Emoji(glyph: "🇫🇮", name: "flag: Finland", group: "Flags"), | |
| 1734 | + Emoji(glyph: "🇫🇯", name: "flag: Fiji", group: "Flags"), | |
| 1735 | + Emoji(glyph: "🇫🇰", name: "flag: Falkland Islands", group: "Flags"), | |
| 1736 | + Emoji(glyph: "🇫🇲", name: "flag: Micronesia", group: "Flags"), | |
| 1737 | + Emoji(glyph: "🇫🇴", name: "flag: Faroe Islands", group: "Flags"), | |
| 1738 | + Emoji(glyph: "🇫🇷", name: "flag: France", group: "Flags"), | |
| 1739 | + Emoji(glyph: "🇬🇦", name: "flag: Gabon", group: "Flags"), | |
| 1740 | + Emoji(glyph: "🇬🇧", name: "flag: United Kingdom", group: "Flags"), | |
| 1741 | + Emoji(glyph: "🇬🇩", name: "flag: Grenada", group: "Flags"), | |
| 1742 | + Emoji(glyph: "🇬🇪", name: "flag: Georgia", group: "Flags"), | |
| 1743 | + Emoji(glyph: "🇬🇫", name: "flag: French Guiana", group: "Flags"), | |
| 1744 | + Emoji(glyph: "🇬🇬", name: "flag: Guernsey", group: "Flags"), | |
| 1745 | + Emoji(glyph: "🇬🇭", name: "flag: Ghana", group: "Flags"), | |
| 1746 | + Emoji(glyph: "🇬🇮", name: "flag: Gibraltar", group: "Flags"), | |
| 1747 | + Emoji(glyph: "🇬🇱", name: "flag: Greenland", group: "Flags"), | |
| 1748 | + Emoji(glyph: "🇬🇲", name: "flag: Gambia", group: "Flags"), | |
| 1749 | + Emoji(glyph: "🇬🇳", name: "flag: Guinea", group: "Flags"), | |
| 1750 | + Emoji(glyph: "🇬🇵", name: "flag: Guadeloupe", group: "Flags"), | |
| 1751 | + Emoji(glyph: "🇬🇶", name: "flag: Equatorial Guinea", group: "Flags"), | |
| 1752 | + Emoji(glyph: "🇬🇷", name: "flag: Greece", group: "Flags"), | |
| 1753 | + Emoji(glyph: "🇬🇸", name: "flag: South Georgia & South Sandwich Islands", group: "Flags"), | |
| 1754 | + Emoji(glyph: "🇬🇹", name: "flag: Guatemala", group: "Flags"), | |
| 1755 | + Emoji(glyph: "🇬🇺", name: "flag: Guam", group: "Flags"), | |
| 1756 | + Emoji(glyph: "🇬🇼", name: "flag: Guinea-Bissau", group: "Flags"), | |
| 1757 | + Emoji(glyph: "🇬🇾", name: "flag: Guyana", group: "Flags"), | |
| 1758 | + Emoji(glyph: "🇭🇰", name: "flag: Hong Kong SAR China", group: "Flags"), | |
| 1759 | + Emoji(glyph: "🇭🇲", name: "flag: Heard & McDonald Islands", group: "Flags"), | |
| 1760 | + Emoji(glyph: "🇭🇳", name: "flag: Honduras", group: "Flags"), | |
| 1761 | + Emoji(glyph: "🇭🇷", name: "flag: Croatia", group: "Flags"), | |
| 1762 | + Emoji(glyph: "🇭🇹", name: "flag: Haiti", group: "Flags"), | |
| 1763 | + Emoji(glyph: "🇭🇺", name: "flag: Hungary", group: "Flags"), | |
| 1764 | + Emoji(glyph: "🇮🇨", name: "flag: Canary Islands", group: "Flags"), | |
| 1765 | + Emoji(glyph: "🇮🇩", name: "flag: Indonesia", group: "Flags"), | |
| 1766 | + Emoji(glyph: "🇮🇪", name: "flag: Ireland", group: "Flags"), | |
| 1767 | + Emoji(glyph: "🇮🇱", name: "flag: Israel", group: "Flags"), | |
| 1768 | + Emoji(glyph: "🇮🇲", name: "flag: Isle of Man", group: "Flags"), | |
| 1769 | + Emoji(glyph: "🇮🇳", name: "flag: India", group: "Flags"), | |
| 1770 | + Emoji(glyph: "🇮🇴", name: "flag: British Indian Ocean Territory", group: "Flags"), | |
| 1771 | + Emoji(glyph: "🇮🇶", name: "flag: Iraq", group: "Flags"), | |
| 1772 | + Emoji(glyph: "🇮🇷", name: "flag: Iran", group: "Flags"), | |
| 1773 | + Emoji(glyph: "🇮🇸", name: "flag: Iceland", group: "Flags"), | |
| 1774 | + Emoji(glyph: "🇮🇹", name: "flag: Italy", group: "Flags"), | |
| 1775 | + Emoji(glyph: "🇯🇪", name: "flag: Jersey", group: "Flags"), | |
| 1776 | + Emoji(glyph: "🇯🇲", name: "flag: Jamaica", group: "Flags"), | |
| 1777 | + Emoji(glyph: "🇯🇴", name: "flag: Jordan", group: "Flags"), | |
| 1778 | + Emoji(glyph: "🇯🇵", name: "flag: Japan", group: "Flags"), | |
| 1779 | + Emoji(glyph: "🇰🇪", name: "flag: Kenya", group: "Flags"), | |
| 1780 | + Emoji(glyph: "🇰🇬", name: "flag: Kyrgyzstan", group: "Flags"), | |
| 1781 | + Emoji(glyph: "🇰🇭", name: "flag: Cambodia", group: "Flags"), | |
| 1782 | + Emoji(glyph: "🇰🇮", name: "flag: Kiribati", group: "Flags"), | |
| 1783 | + Emoji(glyph: "🇰🇲", name: "flag: Comoros", group: "Flags"), | |
| 1784 | + Emoji(glyph: "🇰🇳", name: "flag: St. Kitts & Nevis", group: "Flags"), | |
| 1785 | + Emoji(glyph: "🇰🇵", name: "flag: North Korea", group: "Flags"), | |
| 1786 | + Emoji(glyph: "🇰🇷", name: "flag: South Korea", group: "Flags"), | |
| 1787 | + Emoji(glyph: "🇰🇼", name: "flag: Kuwait", group: "Flags"), | |
| 1788 | + Emoji(glyph: "🇰🇾", name: "flag: Cayman Islands", group: "Flags"), | |
| 1789 | + Emoji(glyph: "🇰🇿", name: "flag: Kazakhstan", group: "Flags"), | |
| 1790 | + Emoji(glyph: "🇱🇦", name: "flag: Laos", group: "Flags"), | |
| 1791 | + Emoji(glyph: "🇱🇧", name: "flag: Lebanon", group: "Flags"), | |
| 1792 | + Emoji(glyph: "🇱🇨", name: "flag: St. Lucia", group: "Flags"), | |
| 1793 | + Emoji(glyph: "🇱🇮", name: "flag: Liechtenstein", group: "Flags"), | |
| 1794 | + Emoji(glyph: "🇱🇰", name: "flag: Sri Lanka", group: "Flags"), | |
| 1795 | + Emoji(glyph: "🇱🇷", name: "flag: Liberia", group: "Flags"), | |
| 1796 | + Emoji(glyph: "🇱🇸", name: "flag: Lesotho", group: "Flags"), | |
| 1797 | + Emoji(glyph: "🇱🇹", name: "flag: Lithuania", group: "Flags"), | |
| 1798 | + Emoji(glyph: "🇱🇺", name: "flag: Luxembourg", group: "Flags"), | |
| 1799 | + Emoji(glyph: "🇱🇻", name: "flag: Latvia", group: "Flags"), | |
| 1800 | + Emoji(glyph: "🇱🇾", name: "flag: Libya", group: "Flags"), | |
| 1801 | + Emoji(glyph: "🇲🇦", name: "flag: Morocco", group: "Flags"), | |
| 1802 | + Emoji(glyph: "🇲🇨", name: "flag: Monaco", group: "Flags"), | |
| 1803 | + Emoji(glyph: "🇲🇩", name: "flag: Moldova", group: "Flags"), | |
| 1804 | + Emoji(glyph: "🇲🇪", name: "flag: Montenegro", group: "Flags"), | |
| 1805 | + Emoji(glyph: "🇲🇫", name: "flag: St. Martin", group: "Flags"), | |
| 1806 | + Emoji(glyph: "🇲🇬", name: "flag: Madagascar", group: "Flags"), | |
| 1807 | + Emoji(glyph: "🇲🇭", name: "flag: Marshall Islands", group: "Flags"), | |
| 1808 | + Emoji(glyph: "🇲🇰", name: "flag: North Macedonia", group: "Flags"), | |
| 1809 | + Emoji(glyph: "🇲🇱", name: "flag: Mali", group: "Flags"), | |
| 1810 | + Emoji(glyph: "🇲🇲", name: "flag: Myanmar (Burma)", group: "Flags"), | |
| 1811 | + Emoji(glyph: "🇲🇳", name: "flag: Mongolia", group: "Flags"), | |
| 1812 | + Emoji(glyph: "🇲🇴", name: "flag: Macao SAR China", group: "Flags"), | |
| 1813 | + Emoji(glyph: "🇲🇵", name: "flag: Northern Mariana Islands", group: "Flags"), | |
| 1814 | + Emoji(glyph: "🇲🇶", name: "flag: Martinique", group: "Flags"), | |
| 1815 | + Emoji(glyph: "🇲🇷", name: "flag: Mauritania", group: "Flags"), | |
| 1816 | + Emoji(glyph: "🇲🇸", name: "flag: Montserrat", group: "Flags"), | |
| 1817 | + Emoji(glyph: "🇲🇹", name: "flag: Malta", group: "Flags"), | |
| 1818 | + Emoji(glyph: "🇲🇺", name: "flag: Mauritius", group: "Flags"), | |
| 1819 | + Emoji(glyph: "🇲🇻", name: "flag: Maldives", group: "Flags"), | |
| 1820 | + Emoji(glyph: "🇲🇼", name: "flag: Malawi", group: "Flags"), | |
| 1821 | + Emoji(glyph: "🇲🇽", name: "flag: Mexico", group: "Flags"), | |
| 1822 | + Emoji(glyph: "🇲🇾", name: "flag: Malaysia", group: "Flags"), | |
| 1823 | + Emoji(glyph: "🇲🇿", name: "flag: Mozambique", group: "Flags"), | |
| 1824 | + Emoji(glyph: "🇳🇦", name: "flag: Namibia", group: "Flags"), | |
| 1825 | + Emoji(glyph: "🇳🇨", name: "flag: New Caledonia", group: "Flags"), | |
| 1826 | + Emoji(glyph: "🇳🇪", name: "flag: Niger", group: "Flags"), | |
| 1827 | + Emoji(glyph: "🇳🇫", name: "flag: Norfolk Island", group: "Flags"), | |
| 1828 | + Emoji(glyph: "🇳🇬", name: "flag: Nigeria", group: "Flags"), | |
| 1829 | + Emoji(glyph: "🇳🇮", name: "flag: Nicaragua", group: "Flags"), | |
| 1830 | + Emoji(glyph: "🇳🇱", name: "flag: Netherlands", group: "Flags"), | |
| 1831 | + Emoji(glyph: "🇳🇴", name: "flag: Norway", group: "Flags"), | |
| 1832 | + Emoji(glyph: "🇳🇵", name: "flag: Nepal", group: "Flags"), | |
| 1833 | + Emoji(glyph: "🇳🇷", name: "flag: Nauru", group: "Flags"), | |
| 1834 | + Emoji(glyph: "🇳🇺", name: "flag: Niue", group: "Flags"), | |
| 1835 | + Emoji(glyph: "🇳🇿", name: "flag: New Zealand", group: "Flags"), | |
| 1836 | + Emoji(glyph: "🇴🇲", name: "flag: Oman", group: "Flags"), | |
| 1837 | + Emoji(glyph: "🇵🇦", name: "flag: Panama", group: "Flags"), | |
| 1838 | + Emoji(glyph: "🇵🇪", name: "flag: Peru", group: "Flags"), | |
| 1839 | + Emoji(glyph: "🇵🇫", name: "flag: French Polynesia", group: "Flags"), | |
| 1840 | + Emoji(glyph: "🇵🇬", name: "flag: Papua New Guinea", group: "Flags"), | |
| 1841 | + Emoji(glyph: "🇵🇭", name: "flag: Philippines", group: "Flags"), | |
| 1842 | + Emoji(glyph: "🇵🇰", name: "flag: Pakistan", group: "Flags"), | |
| 1843 | + Emoji(glyph: "🇵🇱", name: "flag: Poland", group: "Flags"), | |
| 1844 | + Emoji(glyph: "🇵🇲", name: "flag: St. Pierre & Miquelon", group: "Flags"), | |
| 1845 | + Emoji(glyph: "🇵🇳", name: "flag: Pitcairn Islands", group: "Flags"), | |
| 1846 | + Emoji(glyph: "🇵🇷", name: "flag: Puerto Rico", group: "Flags"), | |
| 1847 | + Emoji(glyph: "🇵🇸", name: "flag: Palestinian Territories", group: "Flags"), | |
| 1848 | + Emoji(glyph: "🇵🇹", name: "flag: Portugal", group: "Flags"), | |
| 1849 | + Emoji(glyph: "🇵🇼", name: "flag: Palau", group: "Flags"), | |
| 1850 | + Emoji(glyph: "🇵🇾", name: "flag: Paraguay", group: "Flags"), | |
| 1851 | + Emoji(glyph: "🇶🇦", name: "flag: Qatar", group: "Flags"), | |
| 1852 | + Emoji(glyph: "🇷🇪", name: "flag: Réunion", group: "Flags"), | |
| 1853 | + Emoji(glyph: "🇷🇴", name: "flag: Romania", group: "Flags"), | |
| 1854 | + Emoji(glyph: "🇷🇸", name: "flag: Serbia", group: "Flags"), | |
| 1855 | + Emoji(glyph: "🇷🇺", name: "flag: Russia", group: "Flags"), | |
| 1856 | + Emoji(glyph: "🇷🇼", name: "flag: Rwanda", group: "Flags"), | |
| 1857 | + Emoji(glyph: "🇸🇦", name: "flag: Saudi Arabia", group: "Flags"), | |
| 1858 | + Emoji(glyph: "🇸🇧", name: "flag: Solomon Islands", group: "Flags"), | |
| 1859 | + Emoji(glyph: "🇸🇨", name: "flag: Seychelles", group: "Flags"), | |
| 1860 | + Emoji(glyph: "🇸🇩", name: "flag: Sudan", group: "Flags"), | |
| 1861 | + Emoji(glyph: "🇸🇪", name: "flag: Sweden", group: "Flags"), | |
| 1862 | + Emoji(glyph: "🇸🇬", name: "flag: Singapore", group: "Flags"), | |
| 1863 | + Emoji(glyph: "🇸🇭", name: "flag: St. Helena", group: "Flags"), | |
| 1864 | + Emoji(glyph: "🇸🇮", name: "flag: Slovenia", group: "Flags"), | |
| 1865 | + Emoji(glyph: "🇸🇯", name: "flag: Svalbard & Jan Mayen", group: "Flags"), | |
| 1866 | + Emoji(glyph: "🇸🇰", name: "flag: Slovakia", group: "Flags"), | |
| 1867 | + Emoji(glyph: "🇸🇱", name: "flag: Sierra Leone", group: "Flags"), | |
| 1868 | + Emoji(glyph: "🇸🇲", name: "flag: San Marino", group: "Flags"), | |
| 1869 | + Emoji(glyph: "🇸🇳", name: "flag: Senegal", group: "Flags"), | |
| 1870 | + Emoji(glyph: "🇸🇴", name: "flag: Somalia", group: "Flags"), | |
| 1871 | + Emoji(glyph: "🇸🇷", name: "flag: Suriname", group: "Flags"), | |
| 1872 | + Emoji(glyph: "🇸🇸", name: "flag: South Sudan", group: "Flags"), | |
| 1873 | + Emoji(glyph: "🇸🇹", name: "flag: São Tomé & Príncipe", group: "Flags"), | |
| 1874 | + Emoji(glyph: "🇸🇻", name: "flag: El Salvador", group: "Flags"), | |
| 1875 | + Emoji(glyph: "🇸🇽", name: "flag: Sint Maarten", group: "Flags"), | |
| 1876 | + Emoji(glyph: "🇸🇾", name: "flag: Syria", group: "Flags"), | |
| 1877 | + Emoji(glyph: "🇸🇿", name: "flag: Eswatini", group: "Flags"), | |
| 1878 | + Emoji(glyph: "🇹🇦", name: "flag: Tristan da Cunha", group: "Flags"), | |
| 1879 | + Emoji(glyph: "🇹🇨", name: "flag: Turks & Caicos Islands", group: "Flags"), | |
| 1880 | + Emoji(glyph: "🇹🇩", name: "flag: Chad", group: "Flags"), | |
| 1881 | + Emoji(glyph: "🇹🇫", name: "flag: French Southern Territories", group: "Flags"), | |
| 1882 | + Emoji(glyph: "🇹🇬", name: "flag: Togo", group: "Flags"), | |
| 1883 | + Emoji(glyph: "🇹🇭", name: "flag: Thailand", group: "Flags"), | |
| 1884 | + Emoji(glyph: "🇹🇯", name: "flag: Tajikistan", group: "Flags"), | |
| 1885 | + Emoji(glyph: "🇹🇰", name: "flag: Tokelau", group: "Flags"), | |
| 1886 | + Emoji(glyph: "🇹🇱", name: "flag: Timor-Leste", group: "Flags"), | |
| 1887 | + Emoji(glyph: "🇹🇲", name: "flag: Turkmenistan", group: "Flags"), | |
| 1888 | + Emoji(glyph: "🇹🇳", name: "flag: Tunisia", group: "Flags"), | |
| 1889 | + Emoji(glyph: "🇹🇴", name: "flag: Tonga", group: "Flags"), | |
| 1890 | + Emoji(glyph: "🇹🇷", name: "flag: Türkiye", group: "Flags"), | |
| 1891 | + Emoji(glyph: "🇹🇹", name: "flag: Trinidad & Tobago", group: "Flags"), | |
| 1892 | + Emoji(glyph: "🇹🇻", name: "flag: Tuvalu", group: "Flags"), | |
| 1893 | + Emoji(glyph: "🇹🇼", name: "flag: Taiwan", group: "Flags"), | |
| 1894 | + Emoji(glyph: "🇹🇿", name: "flag: Tanzania", group: "Flags"), | |
| 1895 | + Emoji(glyph: "🇺🇦", name: "flag: Ukraine", group: "Flags"), | |
| 1896 | + Emoji(glyph: "🇺🇬", name: "flag: Uganda", group: "Flags"), | |
| 1897 | + Emoji(glyph: "🇺🇲", name: "flag: U.S. Outlying Islands", group: "Flags"), | |
| 1898 | + Emoji(glyph: "🇺🇳", name: "flag: United Nations", group: "Flags"), | |
| 1899 | + Emoji(glyph: "🇺🇸", name: "flag: United States", group: "Flags"), | |
| 1900 | + Emoji(glyph: "🇺🇾", name: "flag: Uruguay", group: "Flags"), | |
| 1901 | + Emoji(glyph: "🇺🇿", name: "flag: Uzbekistan", group: "Flags"), | |
| 1902 | + Emoji(glyph: "🇻🇦", name: "flag: Vatican City", group: "Flags"), | |
| 1903 | + Emoji(glyph: "🇻🇨", name: "flag: St. Vincent & Grenadines", group: "Flags"), | |
| 1904 | + Emoji(glyph: "🇻🇪", name: "flag: Venezuela", group: "Flags"), | |
| 1905 | + Emoji(glyph: "🇻🇬", name: "flag: British Virgin Islands", group: "Flags"), | |
| 1906 | + Emoji(glyph: "🇻🇮", name: "flag: U.S. Virgin Islands", group: "Flags"), | |
| 1907 | + Emoji(glyph: "🇻🇳", name: "flag: Vietnam", group: "Flags"), | |
| 1908 | + Emoji(glyph: "🇻🇺", name: "flag: Vanuatu", group: "Flags"), | |
| 1909 | + Emoji(glyph: "🇼🇫", name: "flag: Wallis & Futuna", group: "Flags"), | |
| 1910 | + Emoji(glyph: "🇼🇸", name: "flag: Samoa", group: "Flags"), | |
| 1911 | + Emoji(glyph: "🇽🇰", name: "flag: Kosovo", group: "Flags"), | |
| 1912 | + Emoji(glyph: "🇾🇪", name: "flag: Yemen", group: "Flags"), | |
| 1913 | + Emoji(glyph: "🇾🇹", name: "flag: Mayotte", group: "Flags"), | |
| 1914 | + Emoji(glyph: "🇿🇦", name: "flag: South Africa", group: "Flags"), | |
| 1915 | + Emoji(glyph: "🇿🇲", name: "flag: Zambia", group: "Flags"), | |
| 1916 | + Emoji(glyph: "🇿🇼", name: "flag: Zimbabwe", group: "Flags"), | |
| 1917 | + Emoji(glyph: "🏴", name: "flag: England", group: "Flags"), | |
| 1918 | + Emoji(glyph: "🏴", name: "flag: Scotland", group: "Flags"), | |
| 1919 | + Emoji(glyph: "🏴", name: "flag: Wales", group: "Flags"), | |
| 1920 | + ] | |
| new file mode 100644 | |||
| @@ -0,0 +1,1920 @@ | |||
| 1 | +## Every emoji this client can draw, with the name to search it by. | ||
| 2 | +## | ||
| 3 | +## GENERATED by tools/emoji2nim.py from common/frq/emoji.cljc. Do not edit: | ||
| 4 | +## the catalogue is Unicode's own `emoji-test.txt` (15.1), filtered to what | ||
| 5 | +## the Twemoji pack has a picture for, and a second hand-maintained copy is | ||
| 6 | +## how the two languages start disagreeing about what can be drawn. | ||
| 7 | +## | ||
| 8 | +## Skin-tone variants are left out — they multiply the list by five and say | ||
| 9 | +## nothing a reaction needs to say. `glyphs` strips a tone before looking a | ||
| 10 | +## glyph up here, and keeps it for the drawing. | ||
| 11 | + | ||
| 12 | +type | ||
| 13 | + Emoji* = object | ||
| 14 | + glyph*, name*, group*: string | ||
| 15 | + | ||
| 16 | +const | ||
| 17 | + popular* = [ | ||
| 18 | + "👍", "❤️", "😂", "🎉", "👀", "🔥", "🙏", "😍", "😭", "😮", "👏", "💯", "✅", "🤔", "😅", "🚀" | ||
| 19 | + ] | ||
| 20 | + ## What a reaction usually is. The picker opens on these, because the | ||
| 21 | + ## whole point of reacting is that it costs less than typing. | ||
| 22 | + | ||
| 23 | + groups* = [ | ||
| 24 | + "Smileys & Emotion", | ||
| 25 | + "People & Body", | ||
| 26 | + "Animals & Nature", | ||
| 27 | + "Food & Drink", | ||
| 28 | + "Travel & Places", | ||
| 29 | + "Activities", | ||
| 30 | + "Objects", | ||
| 31 | + "Symbols", | ||
| 32 | + "Flags" | ||
| 33 | + ] | ||
| 34 | + | ||
| 35 | + catalog*: array[1884, Emoji] = [ | ||
| 36 | + Emoji(glyph: "😀", name: "grinning face", group: "Smileys & Emotion"), | ||
| 37 | + Emoji(glyph: "😃", name: "grinning face with big eyes", group: "Smileys & Emotion"), | ||
| 38 | + Emoji(glyph: "😄", name: "grinning face with smiling eyes", group: "Smileys & Emotion"), | ||
| 39 | + Emoji(glyph: "😁", name: "beaming face with smiling eyes", group: "Smileys & Emotion"), | ||
| 40 | + Emoji(glyph: "😆", name: "grinning squinting face", group: "Smileys & Emotion"), | ||
| 41 | + Emoji(glyph: "😅", name: "grinning face with sweat", group: "Smileys & Emotion"), | ||
| 42 | + Emoji(glyph: "🤣", name: "rolling on the floor laughing", group: "Smileys & Emotion"), | ||
| 43 | + Emoji(glyph: "😂", name: "face with tears of joy", group: "Smileys & Emotion"), | ||
| 44 | + Emoji(glyph: "🙂", name: "slightly smiling face", group: "Smileys & Emotion"), | ||
| 45 | + Emoji(glyph: "🙃", name: "upside-down face", group: "Smileys & Emotion"), | ||
| 46 | + Emoji(glyph: "🫠", name: "melting face", group: "Smileys & Emotion"), | ||
| 47 | + Emoji(glyph: "😉", name: "winking face", group: "Smileys & Emotion"), | ||
| 48 | + Emoji(glyph: "😊", name: "smiling face with smiling eyes", group: "Smileys & Emotion"), | ||
| 49 | + Emoji(glyph: "😇", name: "smiling face with halo", group: "Smileys & Emotion"), | ||
| 50 | + Emoji(glyph: "🥰", name: "smiling face with hearts", group: "Smileys & Emotion"), | ||
| 51 | + Emoji(glyph: "😍", name: "smiling face with heart-eyes", group: "Smileys & Emotion"), | ||
| 52 | + Emoji(glyph: "🤩", name: "star-struck", group: "Smileys & Emotion"), | ||
| 53 | + Emoji(glyph: "😘", name: "face blowing a kiss", group: "Smileys & Emotion"), | ||
| 54 | + Emoji(glyph: "😗", name: "kissing face", group: "Smileys & Emotion"), | ||
| 55 | + Emoji(glyph: "☺️", name: "smiling face", group: "Smileys & Emotion"), | ||
| 56 | + Emoji(glyph: "😚", name: "kissing face with closed eyes", group: "Smileys & Emotion"), | ||
| 57 | + Emoji(glyph: "😙", name: "kissing face with smiling eyes", group: "Smileys & Emotion"), | ||
| 58 | + Emoji(glyph: "🥲", name: "smiling face with tear", group: "Smileys & Emotion"), | ||
| 59 | + Emoji(glyph: "😋", name: "face savoring food", group: "Smileys & Emotion"), | ||
| 60 | + Emoji(glyph: "😛", name: "face with tongue", group: "Smileys & Emotion"), | ||
| 61 | + Emoji(glyph: "😜", name: "winking face with tongue", group: "Smileys & Emotion"), | ||
| 62 | + Emoji(glyph: "🤪", name: "zany face", group: "Smileys & Emotion"), | ||
| 63 | + Emoji(glyph: "😝", name: "squinting face with tongue", group: "Smileys & Emotion"), | ||
| 64 | + Emoji(glyph: "🤑", name: "money-mouth face", group: "Smileys & Emotion"), | ||
| 65 | + Emoji(glyph: "🤗", name: "smiling face with open hands", group: "Smileys & Emotion"), | ||
| 66 | + Emoji(glyph: "🤭", name: "face with hand over mouth", group: "Smileys & Emotion"), | ||
| 67 | + Emoji(glyph: "🫢", name: "face with open eyes and hand over mouth", group: "Smileys & Emotion"), | ||
| 68 | + Emoji(glyph: "🫣", name: "face with peeking eye", group: "Smileys & Emotion"), | ||
| 69 | + Emoji(glyph: "🤫", name: "shushing face", group: "Smileys & Emotion"), | ||
| 70 | + Emoji(glyph: "🤔", name: "thinking face", group: "Smileys & Emotion"), | ||
| 71 | + Emoji(glyph: "🫡", name: "saluting face", group: "Smileys & Emotion"), | ||
| 72 | + Emoji(glyph: "🤐", name: "zipper-mouth face", group: "Smileys & Emotion"), | ||
| 73 | + Emoji(glyph: "🤨", name: "face with raised eyebrow", group: "Smileys & Emotion"), | ||
| 74 | + Emoji(glyph: "😐", name: "neutral face", group: "Smileys & Emotion"), | ||
| 75 | + Emoji(glyph: "😑", name: "expressionless face", group: "Smileys & Emotion"), | ||
| 76 | + Emoji(glyph: "😶", name: "face without mouth", group: "Smileys & Emotion"), | ||
| 77 | + Emoji(glyph: "🫥", name: "dotted line face", group: "Smileys & Emotion"), | ||
| 78 | + Emoji(glyph: "😶🌫️", name: "face in clouds", group: "Smileys & Emotion"), | ||
| 79 | + Emoji(glyph: "😏", name: "smirking face", group: "Smileys & Emotion"), | ||
| 80 | + Emoji(glyph: "😒", name: "unamused face", group: "Smileys & Emotion"), | ||
| 81 | + Emoji(glyph: "🙄", name: "face with rolling eyes", group: "Smileys & Emotion"), | ||
| 82 | + Emoji(glyph: "😬", name: "grimacing face", group: "Smileys & Emotion"), | ||
| 83 | + Emoji(glyph: "😮💨", name: "face exhaling", group: "Smileys & Emotion"), | ||
| 84 | + Emoji(glyph: "🤥", name: "lying face", group: "Smileys & Emotion"), | ||
| 85 | + Emoji(glyph: "🫨", name: "shaking face", group: "Smileys & Emotion"), | ||
| 86 | + Emoji(glyph: "🙂↔️", name: "head shaking horizontally", group: "Smileys & Emotion"), | ||
| 87 | + Emoji(glyph: "🙂↕️", name: "head shaking vertically", group: "Smileys & Emotion"), | ||
| 88 | + Emoji(glyph: "😌", name: "relieved face", group: "Smileys & Emotion"), | ||
| 89 | + Emoji(glyph: "😔", name: "pensive face", group: "Smileys & Emotion"), | ||
| 90 | + Emoji(glyph: "😪", name: "sleepy face", group: "Smileys & Emotion"), | ||
| 91 | + Emoji(glyph: "🤤", name: "drooling face", group: "Smileys & Emotion"), | ||
| 92 | + Emoji(glyph: "😴", name: "sleeping face", group: "Smileys & Emotion"), | ||
| 93 | + Emoji(glyph: "😷", name: "face with medical mask", group: "Smileys & Emotion"), | ||
| 94 | + Emoji(glyph: "🤒", name: "face with thermometer", group: "Smileys & Emotion"), | ||
| 95 | + Emoji(glyph: "🤕", name: "face with head-bandage", group: "Smileys & Emotion"), | ||
| 96 | + Emoji(glyph: "🤢", name: "nauseated face", group: "Smileys & Emotion"), | ||
| 97 | + Emoji(glyph: "🤮", name: "face vomiting", group: "Smileys & Emotion"), | ||
| 98 | + Emoji(glyph: "🤧", name: "sneezing face", group: "Smileys & Emotion"), | ||
| 99 | + Emoji(glyph: "🥵", name: "hot face", group: "Smileys & Emotion"), | ||
| 100 | + Emoji(glyph: "🥶", name: "cold face", group: "Smileys & Emotion"), | ||
| 101 | + Emoji(glyph: "🥴", name: "woozy face", group: "Smileys & Emotion"), | ||
| 102 | + Emoji(glyph: "😵", name: "face with crossed-out eyes", group: "Smileys & Emotion"), | ||
| 103 | + Emoji(glyph: "😵💫", name: "face with spiral eyes", group: "Smileys & Emotion"), | ||
| 104 | + Emoji(glyph: "🤯", name: "exploding head", group: "Smileys & Emotion"), | ||
| 105 | + Emoji(glyph: "🤠", name: "cowboy hat face", group: "Smileys & Emotion"), | ||
| 106 | + Emoji(glyph: "🥳", name: "partying face", group: "Smileys & Emotion"), | ||
| 107 | + Emoji(glyph: "🥸", name: "disguised face", group: "Smileys & Emotion"), | ||
| 108 | + Emoji(glyph: "😎", name: "smiling face with sunglasses", group: "Smileys & Emotion"), | ||
| 109 | + Emoji(glyph: "🤓", name: "nerd face", group: "Smileys & Emotion"), | ||
| 110 | + Emoji(glyph: "🧐", name: "face with monocle", group: "Smileys & Emotion"), | ||
| 111 | + Emoji(glyph: "😕", name: "confused face", group: "Smileys & Emotion"), | ||
| 112 | + Emoji(glyph: "🫤", name: "face with diagonal mouth", group: "Smileys & Emotion"), | ||
| 113 | + Emoji(glyph: "😟", name: "worried face", group: "Smileys & Emotion"), | ||
| 114 | + Emoji(glyph: "🙁", name: "slightly frowning face", group: "Smileys & Emotion"), | ||
| 115 | + Emoji(glyph: "☹️", name: "frowning face", group: "Smileys & Emotion"), | ||
| 116 | + Emoji(glyph: "😮", name: "face with open mouth", group: "Smileys & Emotion"), | ||
| 117 | + Emoji(glyph: "😯", name: "hushed face", group: "Smileys & Emotion"), | ||
| 118 | + Emoji(glyph: "😲", name: "astonished face", group: "Smileys & Emotion"), | ||
| 119 | + Emoji(glyph: "😳", name: "flushed face", group: "Smileys & Emotion"), | ||
| 120 | + Emoji(glyph: "🥺", name: "pleading face", group: "Smileys & Emotion"), | ||
| 121 | + Emoji(glyph: "🥹", name: "face holding back tears", group: "Smileys & Emotion"), | ||
| 122 | + Emoji(glyph: "😦", name: "frowning face with open mouth", group: "Smileys & Emotion"), | ||
| 123 | + Emoji(glyph: "😧", name: "anguished face", group: "Smileys & Emotion"), | ||
| 124 | + Emoji(glyph: "😨", name: "fearful face", group: "Smileys & Emotion"), | ||
| 125 | + Emoji(glyph: "😰", name: "anxious face with sweat", group: "Smileys & Emotion"), | ||
| 126 | + Emoji(glyph: "😥", name: "sad but relieved face", group: "Smileys & Emotion"), | ||
| 127 | + Emoji(glyph: "😢", name: "crying face", group: "Smileys & Emotion"), | ||
| 128 | + Emoji(glyph: "😭", name: "loudly crying face", group: "Smileys & Emotion"), | ||
| 129 | + Emoji(glyph: "😱", name: "face screaming in fear", group: "Smileys & Emotion"), | ||
| 130 | + Emoji(glyph: "😖", name: "confounded face", group: "Smileys & Emotion"), | ||
| 131 | + Emoji(glyph: "😣", name: "persevering face", group: "Smileys & Emotion"), | ||
| 132 | + Emoji(glyph: "😞", name: "disappointed face", group: "Smileys & Emotion"), | ||
| 133 | + Emoji(glyph: "😓", name: "downcast face with sweat", group: "Smileys & Emotion"), | ||
| 134 | + Emoji(glyph: "😩", name: "weary face", group: "Smileys & Emotion"), | ||
| 135 | + Emoji(glyph: "😫", name: "tired face", group: "Smileys & Emotion"), | ||
| 136 | + Emoji(glyph: "🥱", name: "yawning face", group: "Smileys & Emotion"), | ||
| 137 | + Emoji(glyph: "😤", name: "face with steam from nose", group: "Smileys & Emotion"), | ||
| 138 | + Emoji(glyph: "😡", name: "enraged face", group: "Smileys & Emotion"), | ||
| 139 | + Emoji(glyph: "😠", name: "angry face", group: "Smileys & Emotion"), | ||
| 140 | + Emoji(glyph: "🤬", name: "face with symbols on mouth", group: "Smileys & Emotion"), | ||
| 141 | + Emoji(glyph: "😈", name: "smiling face with horns", group: "Smileys & Emotion"), | ||
| 142 | + Emoji(glyph: "👿", name: "angry face with horns", group: "Smileys & Emotion"), | ||
| 143 | + Emoji(glyph: "💀", name: "skull", group: "Smileys & Emotion"), | ||
| 144 | + Emoji(glyph: "☠️", name: "skull and crossbones", group: "Smileys & Emotion"), | ||
| 145 | + Emoji(glyph: "💩", name: "pile of poo", group: "Smileys & Emotion"), | ||
| 146 | + Emoji(glyph: "🤡", name: "clown face", group: "Smileys & Emotion"), | ||
| 147 | + Emoji(glyph: "👹", name: "ogre", group: "Smileys & Emotion"), | ||
| 148 | + Emoji(glyph: "👺", name: "goblin", group: "Smileys & Emotion"), | ||
| 149 | + Emoji(glyph: "👻", name: "ghost", group: "Smileys & Emotion"), | ||
| 150 | + Emoji(glyph: "👽", name: "alien", group: "Smileys & Emotion"), | ||
| 151 | + Emoji(glyph: "👾", name: "alien monster", group: "Smileys & Emotion"), | ||
| 152 | + Emoji(glyph: "🤖", name: "robot", group: "Smileys & Emotion"), | ||
| 153 | + Emoji(glyph: "😺", name: "grinning cat", group: "Smileys & Emotion"), | ||
| 154 | + Emoji(glyph: "😸", name: "grinning cat with smiling eyes", group: "Smileys & Emotion"), | ||
| 155 | + Emoji(glyph: "😹", name: "cat with tears of joy", group: "Smileys & Emotion"), | ||
| 156 | + Emoji(glyph: "😻", name: "smiling cat with heart-eyes", group: "Smileys & Emotion"), | ||
| 157 | + Emoji(glyph: "😼", name: "cat with wry smile", group: "Smileys & Emotion"), | ||
| 158 | + Emoji(glyph: "😽", name: "kissing cat", group: "Smileys & Emotion"), | ||
| 159 | + Emoji(glyph: "🙀", name: "weary cat", group: "Smileys & Emotion"), | ||
| 160 | + Emoji(glyph: "😿", name: "crying cat", group: "Smileys & Emotion"), | ||
| 161 | + Emoji(glyph: "😾", name: "pouting cat", group: "Smileys & Emotion"), | ||
| 162 | + Emoji(glyph: "🙈", name: "see-no-evil monkey", group: "Smileys & Emotion"), | ||
| 163 | + Emoji(glyph: "🙉", name: "hear-no-evil monkey", group: "Smileys & Emotion"), | ||
| 164 | + Emoji(glyph: "🙊", name: "speak-no-evil monkey", group: "Smileys & Emotion"), | ||
| 165 | + Emoji(glyph: "💌", name: "love letter", group: "Smileys & Emotion"), | ||
| 166 | + Emoji(glyph: "💘", name: "heart with arrow", group: "Smileys & Emotion"), | ||
| 167 | + Emoji(glyph: "💝", name: "heart with ribbon", group: "Smileys & Emotion"), | ||
| 168 | + Emoji(glyph: "💖", name: "sparkling heart", group: "Smileys & Emotion"), | ||
| 169 | + Emoji(glyph: "💗", name: "growing heart", group: "Smileys & Emotion"), | ||
| 170 | + Emoji(glyph: "💓", name: "beating heart", group: "Smileys & Emotion"), | ||
| 171 | + Emoji(glyph: "💞", name: "revolving hearts", group: "Smileys & Emotion"), | ||
| 172 | + Emoji(glyph: "💕", name: "two hearts", group: "Smileys & Emotion"), | ||
| 173 | + Emoji(glyph: "💟", name: "heart decoration", group: "Smileys & Emotion"), | ||
| 174 | + Emoji(glyph: "❣️", name: "heart exclamation", group: "Smileys & Emotion"), | ||
| 175 | + Emoji(glyph: "💔", name: "broken heart", group: "Smileys & Emotion"), | ||
| 176 | + Emoji(glyph: "❤️🔥", name: "heart on fire", group: "Smileys & Emotion"), | ||
| 177 | + Emoji(glyph: "❤️🩹", name: "mending heart", group: "Smileys & Emotion"), | ||
| 178 | + Emoji(glyph: "❤️", name: "red heart", group: "Smileys & Emotion"), | ||
| 179 | + Emoji(glyph: "🩷", name: "pink heart", group: "Smileys & Emotion"), | ||
| 180 | + Emoji(glyph: "🧡", name: "orange heart", group: "Smileys & Emotion"), | ||
| 181 | + Emoji(glyph: "💛", name: "yellow heart", group: "Smileys & Emotion"), | ||
| 182 | + Emoji(glyph: "💚", name: "green heart", group: "Smileys & Emotion"), | ||
| 183 | + Emoji(glyph: "💙", name: "blue heart", group: "Smileys & Emotion"), | ||
| 184 | + Emoji(glyph: "🩵", name: "light blue heart", group: "Smileys & Emotion"), | ||
| 185 | + Emoji(glyph: "💜", name: "purple heart", group: "Smileys & Emotion"), | ||
| 186 | + Emoji(glyph: "🤎", name: "brown heart", group: "Smileys & Emotion"), | ||
| 187 | + Emoji(glyph: "🖤", name: "black heart", group: "Smileys & Emotion"), | ||
| 188 | + Emoji(glyph: "🩶", name: "grey heart", group: "Smileys & Emotion"), | ||
| 189 | + Emoji(glyph: "🤍", name: "white heart", group: "Smileys & Emotion"), | ||
| 190 | + Emoji(glyph: "💋", name: "kiss mark", group: "Smileys & Emotion"), | ||
| 191 | + Emoji(glyph: "💯", name: "hundred points", group: "Smileys & Emotion"), | ||
| 192 | + Emoji(glyph: "💢", name: "anger symbol", group: "Smileys & Emotion"), | ||
| 193 | + Emoji(glyph: "💥", name: "collision", group: "Smileys & Emotion"), | ||
| 194 | + Emoji(glyph: "💫", name: "dizzy", group: "Smileys & Emotion"), | ||
| 195 | + Emoji(glyph: "💦", name: "sweat droplets", group: "Smileys & Emotion"), | ||
| 196 | + Emoji(glyph: "💨", name: "dashing away", group: "Smileys & Emotion"), | ||
| 197 | + Emoji(glyph: "🕳️", name: "hole", group: "Smileys & Emotion"), | ||
| 198 | + Emoji(glyph: "💬", name: "speech balloon", group: "Smileys & Emotion"), | ||
| 199 | + Emoji(glyph: "👁️🗨️", name: "eye in speech bubble", group: "Smileys & Emotion"), | ||
| 200 | + Emoji(glyph: "🗨️", name: "left speech bubble", group: "Smileys & Emotion"), | ||
| 201 | + Emoji(glyph: "🗯️", name: "right anger bubble", group: "Smileys & Emotion"), | ||
| 202 | + Emoji(glyph: "💭", name: "thought balloon", group: "Smileys & Emotion"), | ||
| 203 | + Emoji(glyph: "💤", name: "ZZZ", group: "Smileys & Emotion"), | ||
| 204 | + Emoji(glyph: "👋", name: "waving hand", group: "People & Body"), | ||
| 205 | + Emoji(glyph: "🤚", name: "raised back of hand", group: "People & Body"), | ||
| 206 | + Emoji(glyph: "🖐️", name: "hand with fingers splayed", group: "People & Body"), | ||
| 207 | + Emoji(glyph: "✋", name: "raised hand", group: "People & Body"), | ||
| 208 | + Emoji(glyph: "🖖", name: "vulcan salute", group: "People & Body"), | ||
| 209 | + Emoji(glyph: "🫱", name: "rightwards hand", group: "People & Body"), | ||
| 210 | + Emoji(glyph: "🫲", name: "leftwards hand", group: "People & Body"), | ||
| 211 | + Emoji(glyph: "🫳", name: "palm down hand", group: "People & Body"), | ||
| 212 | + Emoji(glyph: "🫴", name: "palm up hand", group: "People & Body"), | ||
| 213 | + Emoji(glyph: "🫷", name: "leftwards pushing hand", group: "People & Body"), | ||
| 214 | + Emoji(glyph: "🫸", name: "rightwards pushing hand", group: "People & Body"), | ||
| 215 | + Emoji(glyph: "👌", name: "OK hand", group: "People & Body"), | ||
| 216 | + Emoji(glyph: "🤌", name: "pinched fingers", group: "People & Body"), | ||
| 217 | + Emoji(glyph: "🤏", name: "pinching hand", group: "People & Body"), | ||
| 218 | + Emoji(glyph: "✌️", name: "victory hand", group: "People & Body"), | ||
| 219 | + Emoji(glyph: "🤞", name: "crossed fingers", group: "People & Body"), | ||
| 220 | + Emoji(glyph: "🫰", name: "hand with index finger and thumb crossed", group: "People & Body"), | ||
| 221 | + Emoji(glyph: "🤟", name: "love-you gesture", group: "People & Body"), | ||
| 222 | + Emoji(glyph: "🤘", name: "sign of the horns", group: "People & Body"), | ||
| 223 | + Emoji(glyph: "🤙", name: "call me hand", group: "People & Body"), | ||
| 224 | + Emoji(glyph: "👈", name: "backhand index pointing left", group: "People & Body"), | ||
| 225 | + Emoji(glyph: "👉", name: "backhand index pointing right", group: "People & Body"), | ||
| 226 | + Emoji(glyph: "👆", name: "backhand index pointing up", group: "People & Body"), | ||
| 227 | + Emoji(glyph: "🖕", name: "middle finger", group: "People & Body"), | ||
| 228 | + Emoji(glyph: "👇", name: "backhand index pointing down", group: "People & Body"), | ||
| 229 | + Emoji(glyph: "☝️", name: "index pointing up", group: "People & Body"), | ||
| 230 | + Emoji(glyph: "🫵", name: "index pointing at the viewer", group: "People & Body"), | ||
| 231 | + Emoji(glyph: "👍", name: "thumbs up", group: "People & Body"), | ||
| 232 | + Emoji(glyph: "👎", name: "thumbs down", group: "People & Body"), | ||
| 233 | + Emoji(glyph: "✊", name: "raised fist", group: "People & Body"), | ||
| 234 | + Emoji(glyph: "👊", name: "oncoming fist", group: "People & Body"), | ||
| 235 | + Emoji(glyph: "🤛", name: "left-facing fist", group: "People & Body"), | ||
| 236 | + Emoji(glyph: "🤜", name: "right-facing fist", group: "People & Body"), | ||
| 237 | + Emoji(glyph: "👏", name: "clapping hands", group: "People & Body"), | ||
| 238 | + Emoji(glyph: "🙌", name: "raising hands", group: "People & Body"), | ||
| 239 | + Emoji(glyph: "🫶", name: "heart hands", group: "People & Body"), | ||
| 240 | + Emoji(glyph: "👐", name: "open hands", group: "People & Body"), | ||
| 241 | + Emoji(glyph: "🤲", name: "palms up together", group: "People & Body"), | ||
| 242 | + Emoji(glyph: "🤝", name: "handshake", group: "People & Body"), | ||
| 243 | + Emoji(glyph: "🙏", name: "folded hands", group: "People & Body"), | ||
| 244 | + Emoji(glyph: "✍️", name: "writing hand", group: "People & Body"), | ||
| 245 | + Emoji(glyph: "💅", name: "nail polish", group: "People & Body"), | ||
| 246 | + Emoji(glyph: "🤳", name: "selfie", group: "People & Body"), | ||
| 247 | + Emoji(glyph: "💪", name: "flexed biceps", group: "People & Body"), | ||
| 248 | + Emoji(glyph: "🦾", name: "mechanical arm", group: "People & Body"), | ||
| 249 | + Emoji(glyph: "🦿", name: "mechanical leg", group: "People & Body"), | ||
| 250 | + Emoji(glyph: "🦵", name: "leg", group: "People & Body"), | ||
| 251 | + Emoji(glyph: "🦶", name: "foot", group: "People & Body"), | ||
| 252 | + Emoji(glyph: "👂", name: "ear", group: "People & Body"), | ||
| 253 | + Emoji(glyph: "🦻", name: "ear with hearing aid", group: "People & Body"), | ||
| 254 | + Emoji(glyph: "👃", name: "nose", group: "People & Body"), | ||
| 255 | + Emoji(glyph: "🧠", name: "brain", group: "People & Body"), | ||
| 256 | + Emoji(glyph: "🫀", name: "anatomical heart", group: "People & Body"), | ||
| 257 | + Emoji(glyph: "🫁", name: "lungs", group: "People & Body"), | ||
| 258 | + Emoji(glyph: "🦷", name: "tooth", group: "People & Body"), | ||
| 259 | + Emoji(glyph: "🦴", name: "bone", group: "People & Body"), | ||
| 260 | + Emoji(glyph: "👀", name: "eyes", group: "People & Body"), | ||
| 261 | + Emoji(glyph: "👁️", name: "eye", group: "People & Body"), | ||
| 262 | + Emoji(glyph: "👅", name: "tongue", group: "People & Body"), | ||
| 263 | + Emoji(glyph: "👄", name: "mouth", group: "People & Body"), | ||
| 264 | + Emoji(glyph: "🫦", name: "biting lip", group: "People & Body"), | ||
| 265 | + Emoji(glyph: "👶", name: "baby", group: "People & Body"), | ||
| 266 | + Emoji(glyph: "🧒", name: "child", group: "People & Body"), | ||
| 267 | + Emoji(glyph: "👦", name: "boy", group: "People & Body"), | ||
| 268 | + Emoji(glyph: "👧", name: "girl", group: "People & Body"), | ||
| 269 | + Emoji(glyph: "🧑", name: "person", group: "People & Body"), | ||
| 270 | + Emoji(glyph: "👱", name: "person: blond hair", group: "People & Body"), | ||
| 271 | + Emoji(glyph: "👨", name: "man", group: "People & Body"), | ||
| 272 | + Emoji(glyph: "🧔", name: "person: beard", group: "People & Body"), | ||
| 273 | + Emoji(glyph: "🧔♂️", name: "man: beard", group: "People & Body"), | ||
| 274 | + Emoji(glyph: "🧔♀️", name: "woman: beard", group: "People & Body"), | ||
| 275 | + Emoji(glyph: "👨🦰", name: "man: red hair", group: "People & Body"), | ||
| 276 | + Emoji(glyph: "👨🦱", name: "man: curly hair", group: "People & Body"), | ||
| 277 | + Emoji(glyph: "👨🦳", name: "man: white hair", group: "People & Body"), | ||
| 278 | + Emoji(glyph: "👨🦲", name: "man: bald", group: "People & Body"), | ||
| 279 | + Emoji(glyph: "👩", name: "woman", group: "People & Body"), | ||
| 280 | + Emoji(glyph: "👩🦰", name: "woman: red hair", group: "People & Body"), | ||
| 281 | + Emoji(glyph: "🧑🦰", name: "person: red hair", group: "People & Body"), | ||
| 282 | + Emoji(glyph: "👩🦱", name: "woman: curly hair", group: "People & Body"), | ||
| 283 | + Emoji(glyph: "🧑🦱", name: "person: curly hair", group: "People & Body"), | ||
| 284 | + Emoji(glyph: "👩🦳", name: "woman: white hair", group: "People & Body"), | ||
| 285 | + Emoji(glyph: "🧑🦳", name: "person: white hair", group: "People & Body"), | ||
| 286 | + Emoji(glyph: "👩🦲", name: "woman: bald", group: "People & Body"), | ||
| 287 | + Emoji(glyph: "🧑🦲", name: "person: bald", group: "People & Body"), | ||
| 288 | + Emoji(glyph: "👱♀️", name: "woman: blond hair", group: "People & Body"), | ||
| 289 | + Emoji(glyph: "👱♂️", name: "man: blond hair", group: "People & Body"), | ||
| 290 | + Emoji(glyph: "🧓", name: "older person", group: "People & Body"), | ||
| 291 | + Emoji(glyph: "👴", name: "old man", group: "People & Body"), | ||
| 292 | + Emoji(glyph: "👵", name: "old woman", group: "People & Body"), | ||
| 293 | + Emoji(glyph: "🙍", name: "person frowning", group: "People & Body"), | ||
| 294 | + Emoji(glyph: "🙍♂️", name: "man frowning", group: "People & Body"), | ||
| 295 | + Emoji(glyph: "🙍♀️", name: "woman frowning", group: "People & Body"), | ||
| 296 | + Emoji(glyph: "🙎", name: "person pouting", group: "People & Body"), | ||
| 297 | + Emoji(glyph: "🙎♂️", name: "man pouting", group: "People & Body"), | ||
| 298 | + Emoji(glyph: "🙎♀️", name: "woman pouting", group: "People & Body"), | ||
| 299 | + Emoji(glyph: "🙅", name: "person gesturing NO", group: "People & Body"), | ||
| 300 | + Emoji(glyph: "🙅♂️", name: "man gesturing NO", group: "People & Body"), | ||
| 301 | + Emoji(glyph: "🙅♀️", name: "woman gesturing NO", group: "People & Body"), | ||
| 302 | + Emoji(glyph: "🙆", name: "person gesturing OK", group: "People & Body"), | ||
| 303 | + Emoji(glyph: "🙆♂️", name: "man gesturing OK", group: "People & Body"), | ||
| 304 | + Emoji(glyph: "🙆♀️", name: "woman gesturing OK", group: "People & Body"), | ||
| 305 | + Emoji(glyph: "💁", name: "person tipping hand", group: "People & Body"), | ||
| 306 | + Emoji(glyph: "💁♂️", name: "man tipping hand", group: "People & Body"), | ||
| 307 | + Emoji(glyph: "💁♀️", name: "woman tipping hand", group: "People & Body"), | ||
| 308 | + Emoji(glyph: "🙋", name: "person raising hand", group: "People & Body"), | ||
| 309 | + Emoji(glyph: "🙋♂️", name: "man raising hand", group: "People & Body"), | ||
| 310 | + Emoji(glyph: "🙋♀️", name: "woman raising hand", group: "People & Body"), | ||
| 311 | + Emoji(glyph: "🧏", name: "deaf person", group: "People & Body"), | ||
| 312 | + Emoji(glyph: "🧏♂️", name: "deaf man", group: "People & Body"), | ||
| 313 | + Emoji(glyph: "🧏♀️", name: "deaf woman", group: "People & Body"), | ||
| 314 | + Emoji(glyph: "🙇", name: "person bowing", group: "People & Body"), | ||
| 315 | + Emoji(glyph: "🙇♂️", name: "man bowing", group: "People & Body"), | ||
| 316 | + Emoji(glyph: "🙇♀️", name: "woman bowing", group: "People & Body"), | ||
| 317 | + Emoji(glyph: "🤦", name: "person facepalming", group: "People & Body"), | ||
| 318 | + Emoji(glyph: "🤦♂️", name: "man facepalming", group: "People & Body"), | ||
| 319 | + Emoji(glyph: "🤦♀️", name: "woman facepalming", group: "People & Body"), | ||
| 320 | + Emoji(glyph: "🤷", name: "person shrugging", group: "People & Body"), | ||
| 321 | + Emoji(glyph: "🤷♂️", name: "man shrugging", group: "People & Body"), | ||
| 322 | + Emoji(glyph: "🤷♀️", name: "woman shrugging", group: "People & Body"), | ||
| 323 | + Emoji(glyph: "🧑⚕️", name: "health worker", group: "People & Body"), | ||
| 324 | + Emoji(glyph: "👨⚕️", name: "man health worker", group: "People & Body"), | ||
| 325 | + Emoji(glyph: "👩⚕️", name: "woman health worker", group: "People & Body"), | ||
| 326 | + Emoji(glyph: "🧑🎓", name: "student", group: "People & Body"), | ||
| 327 | + Emoji(glyph: "👨🎓", name: "man student", group: "People & Body"), | ||
| 328 | + Emoji(glyph: "👩🎓", name: "woman student", group: "People & Body"), | ||
| 329 | + Emoji(glyph: "🧑🏫", name: "teacher", group: "People & Body"), | ||
| 330 | + Emoji(glyph: "👨🏫", name: "man teacher", group: "People & Body"), | ||
| 331 | + Emoji(glyph: "👩🏫", name: "woman teacher", group: "People & Body"), | ||
| 332 | + Emoji(glyph: "🧑⚖️", name: "judge", group: "People & Body"), | ||
| 333 | + Emoji(glyph: "👨⚖️", name: "man judge", group: "People & Body"), | ||
| 334 | + Emoji(glyph: "👩⚖️", name: "woman judge", group: "People & Body"), | ||
| 335 | + Emoji(glyph: "🧑🌾", name: "farmer", group: "People & Body"), | ||
| 336 | + Emoji(glyph: "👨🌾", name: "man farmer", group: "People & Body"), | ||
| 337 | + Emoji(glyph: "👩🌾", name: "woman farmer", group: "People & Body"), | ||
| 338 | + Emoji(glyph: "🧑🍳", name: "cook", group: "People & Body"), | ||
| 339 | + Emoji(glyph: "👨🍳", name: "man cook", group: "People & Body"), | ||
| 340 | + Emoji(glyph: "👩🍳", name: "woman cook", group: "People & Body"), | ||
| 341 | + Emoji(glyph: "🧑🔧", name: "mechanic", group: "People & Body"), | ||
| 342 | + Emoji(glyph: "👨🔧", name: "man mechanic", group: "People & Body"), | ||
| 343 | + Emoji(glyph: "👩🔧", name: "woman mechanic", group: "People & Body"), | ||
| 344 | + Emoji(glyph: "🧑🏭", name: "factory worker", group: "People & Body"), | ||
| 345 | + Emoji(glyph: "👨🏭", name: "man factory worker", group: "People & Body"), | ||
| 346 | + Emoji(glyph: "👩🏭", name: "woman factory worker", group: "People & Body"), | ||
| 347 | + Emoji(glyph: "🧑💼", name: "office worker", group: "People & Body"), | ||
| 348 | + Emoji(glyph: "👨💼", name: "man office worker", group: "People & Body"), | ||
| 349 | + Emoji(glyph: "👩💼", name: "woman office worker", group: "People & Body"), | ||
| 350 | + Emoji(glyph: "🧑🔬", name: "scientist", group: "People & Body"), | ||
| 351 | + Emoji(glyph: "👨🔬", name: "man scientist", group: "People & Body"), | ||
| 352 | + Emoji(glyph: "👩🔬", name: "woman scientist", group: "People & Body"), | ||
| 353 | + Emoji(glyph: "🧑💻", name: "technologist", group: "People & Body"), | ||
| 354 | + Emoji(glyph: "👨💻", name: "man technologist", group: "People & Body"), | ||
| 355 | + Emoji(glyph: "👩💻", name: "woman technologist", group: "People & Body"), | ||
| 356 | + Emoji(glyph: "🧑🎤", name: "singer", group: "People & Body"), | ||
| 357 | + Emoji(glyph: "👨🎤", name: "man singer", group: "People & Body"), | ||
| 358 | + Emoji(glyph: "👩🎤", name: "woman singer", group: "People & Body"), | ||
| 359 | + Emoji(glyph: "🧑🎨", name: "artist", group: "People & Body"), | ||
| 360 | + Emoji(glyph: "👨🎨", name: "man artist", group: "People & Body"), | ||
| 361 | + Emoji(glyph: "👩🎨", name: "woman artist", group: "People & Body"), | ||
| 362 | + Emoji(glyph: "🧑✈️", name: "pilot", group: "People & Body"), | ||
| 363 | + Emoji(glyph: "👨✈️", name: "man pilot", group: "People & Body"), | ||
| 364 | + Emoji(glyph: "👩✈️", name: "woman pilot", group: "People & Body"), | ||
| 365 | + Emoji(glyph: "🧑🚀", name: "astronaut", group: "People & Body"), | ||
| 366 | + Emoji(glyph: "👨🚀", name: "man astronaut", group: "People & Body"), | ||
| 367 | + Emoji(glyph: "👩🚀", name: "woman astronaut", group: "People & Body"), | ||
| 368 | + Emoji(glyph: "🧑🚒", name: "firefighter", group: "People & Body"), | ||
| 369 | + Emoji(glyph: "👨🚒", name: "man firefighter", group: "People & Body"), | ||
| 370 | + Emoji(glyph: "👩🚒", name: "woman firefighter", group: "People & Body"), | ||
| 371 | + Emoji(glyph: "👮", name: "police officer", group: "People & Body"), | ||
| 372 | + Emoji(glyph: "👮♂️", name: "man police officer", group: "People & Body"), | ||
| 373 | + Emoji(glyph: "👮♀️", name: "woman police officer", group: "People & Body"), | ||
| 374 | + Emoji(glyph: "🕵️", name: "detective", group: "People & Body"), | ||
| 375 | + Emoji(glyph: "🕵️♂️", name: "man detective", group: "People & Body"), | ||
| 376 | + Emoji(glyph: "🕵️♀️", name: "woman detective", group: "People & Body"), | ||
| 377 | + Emoji(glyph: "💂", name: "guard", group: "People & Body"), | ||
| 378 | + Emoji(glyph: "💂♂️", name: "man guard", group: "People & Body"), | ||
| 379 | + Emoji(glyph: "💂♀️", name: "woman guard", group: "People & Body"), | ||
| 380 | + Emoji(glyph: "🥷", name: "ninja", group: "People & Body"), | ||
| 381 | + Emoji(glyph: "👷", name: "construction worker", group: "People & Body"), | ||
| 382 | + Emoji(glyph: "👷♂️", name: "man construction worker", group: "People & Body"), | ||
| 383 | + Emoji(glyph: "👷♀️", name: "woman construction worker", group: "People & Body"), | ||
| 384 | + Emoji(glyph: "🫅", name: "person with crown", group: "People & Body"), | ||
| 385 | + Emoji(glyph: "🤴", name: "prince", group: "People & Body"), | ||
| 386 | + Emoji(glyph: "👸", name: "princess", group: "People & Body"), | ||
| 387 | + Emoji(glyph: "👳", name: "person wearing turban", group: "People & Body"), | ||
| 388 | + Emoji(glyph: "👳♂️", name: "man wearing turban", group: "People & Body"), | ||
| 389 | + Emoji(glyph: "👳♀️", name: "woman wearing turban", group: "People & Body"), | ||
| 390 | + Emoji(glyph: "👲", name: "person with skullcap", group: "People & Body"), | ||
| 391 | + Emoji(glyph: "🧕", name: "woman with headscarf", group: "People & Body"), | ||
| 392 | + Emoji(glyph: "🤵", name: "person in tuxedo", group: "People & Body"), | ||
| 393 | + Emoji(glyph: "🤵♂️", name: "man in tuxedo", group: "People & Body"), | ||
| 394 | + Emoji(glyph: "🤵♀️", name: "woman in tuxedo", group: "People & Body"), | ||
| 395 | + Emoji(glyph: "👰", name: "person with veil", group: "People & Body"), | ||
| 396 | + Emoji(glyph: "👰♂️", name: "man with veil", group: "People & Body"), | ||
| 397 | + Emoji(glyph: "👰♀️", name: "woman with veil", group: "People & Body"), | ||
| 398 | + Emoji(glyph: "🤰", name: "pregnant woman", group: "People & Body"), | ||
| 399 | + Emoji(glyph: "🫃", name: "pregnant man", group: "People & Body"), | ||
| 400 | + Emoji(glyph: "🫄", name: "pregnant person", group: "People & Body"), | ||
| 401 | + Emoji(glyph: "🤱", name: "breast-feeding", group: "People & Body"), | ||
| 402 | + Emoji(glyph: "👩🍼", name: "woman feeding baby", group: "People & Body"), | ||
| 403 | + Emoji(glyph: "👨🍼", name: "man feeding baby", group: "People & Body"), | ||
| 404 | + Emoji(glyph: "🧑🍼", name: "person feeding baby", group: "People & Body"), | ||
| 405 | + Emoji(glyph: "👼", name: "baby angel", group: "People & Body"), | ||
| 406 | + Emoji(glyph: "🎅", name: "Santa Claus", group: "People & Body"), | ||
| 407 | + Emoji(glyph: "🤶", name: "Mrs. Claus", group: "People & Body"), | ||
| 408 | + Emoji(glyph: "🧑🎄", name: "mx claus", group: "People & Body"), | ||
| 409 | + Emoji(glyph: "🦸", name: "superhero", group: "People & Body"), | ||
| 410 | + Emoji(glyph: "🦸♂️", name: "man superhero", group: "People & Body"), | ||
| 411 | + Emoji(glyph: "🦸♀️", name: "woman superhero", group: "People & Body"), | ||
| 412 | + Emoji(glyph: "🦹", name: "supervillain", group: "People & Body"), | ||
| 413 | + Emoji(glyph: "🦹♂️", name: "man supervillain", group: "People & Body"), | ||
| 414 | + Emoji(glyph: "🦹♀️", name: "woman supervillain", group: "People & Body"), | ||
| 415 | + Emoji(glyph: "🧙", name: "mage", group: "People & Body"), | ||
| 416 | + Emoji(glyph: "🧙♂️", name: "man mage", group: "People & Body"), | ||
| 417 | + Emoji(glyph: "🧙♀️", name: "woman mage", group: "People & Body"), | ||
| 418 | + Emoji(glyph: "🧚", name: "fairy", group: "People & Body"), | ||
| 419 | + Emoji(glyph: "🧚♂️", name: "man fairy", group: "People & Body"), | ||
| 420 | + Emoji(glyph: "🧚♀️", name: "woman fairy", group: "People & Body"), | ||
| 421 | + Emoji(glyph: "🧛", name: "vampire", group: "People & Body"), | ||
| 422 | + Emoji(glyph: "🧛♂️", name: "man vampire", group: "People & Body"), | ||
| 423 | + Emoji(glyph: "🧛♀️", name: "woman vampire", group: "People & Body"), | ||
| 424 | + Emoji(glyph: "🧜", name: "merperson", group: "People & Body"), | ||
| 425 | + Emoji(glyph: "🧜♂️", name: "merman", group: "People & Body"), | ||
| 426 | + Emoji(glyph: "🧜♀️", name: "mermaid", group: "People & Body"), | ||
| 427 | + Emoji(glyph: "🧝", name: "elf", group: "People & Body"), | ||
| 428 | + Emoji(glyph: "🧝♂️", name: "man elf", group: "People & Body"), | ||
| 429 | + Emoji(glyph: "🧝♀️", name: "woman elf", group: "People & Body"), | ||
| 430 | + Emoji(glyph: "🧞", name: "genie", group: "People & Body"), | ||
| 431 | + Emoji(glyph: "🧞♂️", name: "man genie", group: "People & Body"), | ||
| 432 | + Emoji(glyph: "🧞♀️", name: "woman genie", group: "People & Body"), | ||
| 433 | + Emoji(glyph: "🧟", name: "zombie", group: "People & Body"), | ||
| 434 | + Emoji(glyph: "🧟♂️", name: "man zombie", group: "People & Body"), | ||
| 435 | + Emoji(glyph: "🧟♀️", name: "woman zombie", group: "People & Body"), | ||
| 436 | + Emoji(glyph: "🧌", name: "troll", group: "People & Body"), | ||
| 437 | + Emoji(glyph: "💆", name: "person getting massage", group: "People & Body"), | ||
| 438 | + Emoji(glyph: "💆♂️", name: "man getting massage", group: "People & Body"), | ||
| 439 | + Emoji(glyph: "💆♀️", name: "woman getting massage", group: "People & Body"), | ||
| 440 | + Emoji(glyph: "💇", name: "person getting haircut", group: "People & Body"), | ||
| 441 | + Emoji(glyph: "💇♂️", name: "man getting haircut", group: "People & Body"), | ||
| 442 | + Emoji(glyph: "💇♀️", name: "woman getting haircut", group: "People & Body"), | ||
| 443 | + Emoji(glyph: "🚶", name: "person walking", group: "People & Body"), | ||
| 444 | + Emoji(glyph: "🚶♂️", name: "man walking", group: "People & Body"), | ||
| 445 | + Emoji(glyph: "🚶♀️", name: "woman walking", group: "People & Body"), | ||
| 446 | + Emoji(glyph: "🚶➡️", name: "person walking facing right", group: "People & Body"), | ||
| 447 | + Emoji(glyph: "🚶♀️➡️", name: "woman walking facing right", group: "People & Body"), | ||
| 448 | + Emoji(glyph: "🚶♂️➡️", name: "man walking facing right", group: "People & Body"), | ||
| 449 | + Emoji(glyph: "🧍", name: "person standing", group: "People & Body"), | ||
| 450 | + Emoji(glyph: "🧍♂️", name: "man standing", group: "People & Body"), | ||
| 451 | + Emoji(glyph: "🧍♀️", name: "woman standing", group: "People & Body"), | ||
| 452 | + Emoji(glyph: "🧎", name: "person kneeling", group: "People & Body"), | ||
| 453 | + Emoji(glyph: "🧎♂️", name: "man kneeling", group: "People & Body"), | ||
| 454 | + Emoji(glyph: "🧎♀️", name: "woman kneeling", group: "People & Body"), | ||
| 455 | + Emoji(glyph: "🧎➡️", name: "person kneeling facing right", group: "People & Body"), | ||
| 456 | + Emoji(glyph: "🧎♀️➡️", name: "woman kneeling facing right", group: "People & Body"), | ||
| 457 | + Emoji(glyph: "🧎♂️➡️", name: "man kneeling facing right", group: "People & Body"), | ||
| 458 | + Emoji(glyph: "🧑🦯", name: "person with white cane", group: "People & Body"), | ||
| 459 | + Emoji(glyph: "🧑🦯➡️", name: "person with white cane facing right", group: "People & Body"), | ||
| 460 | + Emoji(glyph: "👨🦯", name: "man with white cane", group: "People & Body"), | ||
| 461 | + Emoji(glyph: "👨🦯➡️", name: "man with white cane facing right", group: "People & Body"), | ||
| 462 | + Emoji(glyph: "👩🦯", name: "woman with white cane", group: "People & Body"), | ||
| 463 | + Emoji(glyph: "👩🦯➡️", name: "woman with white cane facing right", group: "People & Body"), | ||
| 464 | + Emoji(glyph: "🧑🦼", name: "person in motorized wheelchair", group: "People & Body"), | ||
| 465 | + Emoji(glyph: "🧑🦼➡️", name: "person in motorized wheelchair facing right", group: "People & Body"), | ||
| 466 | + Emoji(glyph: "👨🦼", name: "man in motorized wheelchair", group: "People & Body"), | ||
| 467 | + Emoji(glyph: "👨🦼➡️", name: "man in motorized wheelchair facing right", group: "People & Body"), | ||
| 468 | + Emoji(glyph: "👩🦼", name: "woman in motorized wheelchair", group: "People & Body"), | ||
| 469 | + Emoji(glyph: "👩🦼➡️", name: "woman in motorized wheelchair facing right", group: "People & Body"), | ||
| 470 | + Emoji(glyph: "🧑🦽", name: "person in manual wheelchair", group: "People & Body"), | ||
| 471 | + Emoji(glyph: "🧑🦽➡️", name: "person in manual wheelchair facing right", group: "People & Body"), | ||
| 472 | + Emoji(glyph: "👨🦽", name: "man in manual wheelchair", group: "People & Body"), | ||
| 473 | + Emoji(glyph: "👨🦽➡️", name: "man in manual wheelchair facing right", group: "People & Body"), | ||
| 474 | + Emoji(glyph: "👩🦽", name: "woman in manual wheelchair", group: "People & Body"), | ||
| 475 | + Emoji(glyph: "👩🦽➡️", name: "woman in manual wheelchair facing right", group: "People & Body"), | ||
| 476 | + Emoji(glyph: "🏃", name: "person running", group: "People & Body"), | ||
| 477 | + Emoji(glyph: "🏃♂️", name: "man running", group: "People & Body"), | ||
| 478 | + Emoji(glyph: "🏃♀️", name: "woman running", group: "People & Body"), | ||
| 479 | + Emoji(glyph: "🏃➡️", name: "person running facing right", group: "People & Body"), | ||
| 480 | + Emoji(glyph: "🏃♀️➡️", name: "woman running facing right", group: "People & Body"), | ||
| 481 | + Emoji(glyph: "🏃♂️➡️", name: "man running facing right", group: "People & Body"), | ||
| 482 | + Emoji(glyph: "💃", name: "woman dancing", group: "People & Body"), | ||
| 483 | + Emoji(glyph: "🕺", name: "man dancing", group: "People & Body"), | ||
| 484 | + Emoji(glyph: "🕴️", name: "person in suit levitating", group: "People & Body"), | ||
| 485 | + Emoji(glyph: "👯", name: "people with bunny ears", group: "People & Body"), | ||
| 486 | + Emoji(glyph: "👯♂️", name: "men with bunny ears", group: "People & Body"), | ||
| 487 | + Emoji(glyph: "👯♀️", name: "women with bunny ears", group: "People & Body"), | ||
| 488 | + Emoji(glyph: "🧖", name: "person in steamy room", group: "People & Body"), | ||
| 489 | + Emoji(glyph: "🧖♂️", name: "man in steamy room", group: "People & Body"), | ||
| 490 | + Emoji(glyph: "🧖♀️", name: "woman in steamy room", group: "People & Body"), | ||
| 491 | + Emoji(glyph: "🧗", name: "person climbing", group: "People & Body"), | ||
| 492 | + Emoji(glyph: "🧗♂️", name: "man climbing", group: "People & Body"), | ||
| 493 | + Emoji(glyph: "🧗♀️", name: "woman climbing", group: "People & Body"), | ||
| 494 | + Emoji(glyph: "🤺", name: "person fencing", group: "People & Body"), | ||
| 495 | + Emoji(glyph: "🏇", name: "horse racing", group: "People & Body"), | ||
| 496 | + Emoji(glyph: "⛷️", name: "skier", group: "People & Body"), | ||
| 497 | + Emoji(glyph: "🏂", name: "snowboarder", group: "People & Body"), | ||
| 498 | + Emoji(glyph: "🏌️", name: "person golfing", group: "People & Body"), | ||
| 499 | + Emoji(glyph: "🏌️♂️", name: "man golfing", group: "People & Body"), | ||
| 500 | + Emoji(glyph: "🏌️♀️", name: "woman golfing", group: "People & Body"), | ||
| 501 | + Emoji(glyph: "🏄", name: "person surfing", group: "People & Body"), | ||
| 502 | + Emoji(glyph: "🏄♂️", name: "man surfing", group: "People & Body"), | ||
| 503 | + Emoji(glyph: "🏄♀️", name: "woman surfing", group: "People & Body"), | ||
| 504 | + Emoji(glyph: "🚣", name: "person rowing boat", group: "People & Body"), | ||
| 505 | + Emoji(glyph: "🚣♂️", name: "man rowing boat", group: "People & Body"), | ||
| 506 | + Emoji(glyph: "🚣♀️", name: "woman rowing boat", group: "People & Body"), | ||
| 507 | + Emoji(glyph: "🏊", name: "person swimming", group: "People & Body"), | ||
| 508 | + Emoji(glyph: "🏊♂️", name: "man swimming", group: "People & Body"), | ||
| 509 | + Emoji(glyph: "🏊♀️", name: "woman swimming", group: "People & Body"), | ||
| 510 | + Emoji(glyph: "⛹️", name: "person bouncing ball", group: "People & Body"), | ||
| 511 | + Emoji(glyph: "⛹️♂️", name: "man bouncing ball", group: "People & Body"), | ||
| 512 | + Emoji(glyph: "⛹️♀️", name: "woman bouncing ball", group: "People & Body"), | ||
| 513 | + Emoji(glyph: "🏋️", name: "person lifting weights", group: "People & Body"), | ||
| 514 | + Emoji(glyph: "🏋️♂️", name: "man lifting weights", group: "People & Body"), | ||
| 515 | + Emoji(glyph: "🏋️♀️", name: "woman lifting weights", group: "People & Body"), | ||
| 516 | + Emoji(glyph: "🚴", name: "person biking", group: "People & Body"), | ||
| 517 | + Emoji(glyph: "🚴♂️", name: "man biking", group: "People & Body"), | ||
| 518 | + Emoji(glyph: "🚴♀️", name: "woman biking", group: "People & Body"), | ||
| 519 | + Emoji(glyph: "🚵", name: "person mountain biking", group: "People & Body"), | ||
| 520 | + Emoji(glyph: "🚵♂️", name: "man mountain biking", group: "People & Body"), | ||
| 521 | + Emoji(glyph: "🚵♀️", name: "woman mountain biking", group: "People & Body"), | ||
| 522 | + Emoji(glyph: "🤸", name: "person cartwheeling", group: "People & Body"), | ||
| 523 | + Emoji(glyph: "🤸♂️", name: "man cartwheeling", group: "People & Body"), | ||
| 524 | + Emoji(glyph: "🤸♀️", name: "woman cartwheeling", group: "People & Body"), | ||
| 525 | + Emoji(glyph: "🤼", name: "people wrestling", group: "People & Body"), | ||
| 526 | + Emoji(glyph: "🤼♂️", name: "men wrestling", group: "People & Body"), | ||
| 527 | + Emoji(glyph: "🤼♀️", name: "women wrestling", group: "People & Body"), | ||
| 528 | + Emoji(glyph: "🤽", name: "person playing water polo", group: "People & Body"), | ||
| 529 | + Emoji(glyph: "🤽♂️", name: "man playing water polo", group: "People & Body"), | ||
| 530 | + Emoji(glyph: "🤽♀️", name: "woman playing water polo", group: "People & Body"), | ||
| 531 | + Emoji(glyph: "🤾", name: "person playing handball", group: "People & Body"), | ||
| 532 | + Emoji(glyph: "🤾♂️", name: "man playing handball", group: "People & Body"), | ||
| 533 | + Emoji(glyph: "🤾♀️", name: "woman playing handball", group: "People & Body"), | ||
| 534 | + Emoji(glyph: "🤹", name: "person juggling", group: "People & Body"), | ||
| 535 | + Emoji(glyph: "🤹♂️", name: "man juggling", group: "People & Body"), | ||
| 536 | + Emoji(glyph: "🤹♀️", name: "woman juggling", group: "People & Body"), | ||
| 537 | + Emoji(glyph: "🧘", name: "person in lotus position", group: "People & Body"), | ||
| 538 | + Emoji(glyph: "🧘♂️", name: "man in lotus position", group: "People & Body"), | ||
| 539 | + Emoji(glyph: "🧘♀️", name: "woman in lotus position", group: "People & Body"), | ||
| 540 | + Emoji(glyph: "🛀", name: "person taking bath", group: "People & Body"), | ||
| 541 | + Emoji(glyph: "🛌", name: "person in bed", group: "People & Body"), | ||
| 542 | + Emoji(glyph: "🧑🤝🧑", name: "people holding hands", group: "People & Body"), | ||
| 543 | + Emoji(glyph: "👭", name: "women holding hands", group: "People & Body"), | ||
| 544 | + Emoji(glyph: "👫", name: "woman and man holding hands", group: "People & Body"), | ||
| 545 | + Emoji(glyph: "👬", name: "men holding hands", group: "People & Body"), | ||
| 546 | + Emoji(glyph: "💏", name: "kiss", group: "People & Body"), | ||
| 547 | + Emoji(glyph: "👩❤️💋👨", name: "kiss: woman, man", group: "People & Body"), | ||
| 548 | + Emoji(glyph: "👨❤️💋👨", name: "kiss: man, man", group: "People & Body"), | ||
| 549 | + Emoji(glyph: "👩❤️💋👩", name: "kiss: woman, woman", group: "People & Body"), | ||
| 550 | + Emoji(glyph: "💑", name: "couple with heart", group: "People & Body"), | ||
| 551 | + Emoji(glyph: "👩❤️👨", name: "couple with heart: woman, man", group: "People & Body"), | ||
| 552 | + Emoji(glyph: "👨❤️👨", name: "couple with heart: man, man", group: "People & Body"), | ||
| 553 | + Emoji(glyph: "👩❤️👩", name: "couple with heart: woman, woman", group: "People & Body"), | ||
| 554 | + Emoji(glyph: "👨👩👦", name: "family: man, woman, boy", group: "People & Body"), | ||
| 555 | + Emoji(glyph: "👨👩👧", name: "family: man, woman, girl", group: "People & Body"), | ||
| 556 | + Emoji(glyph: "👨👩👧👦", name: "family: man, woman, girl, boy", group: "People & Body"), | ||
| 557 | + Emoji(glyph: "👨👩👦👦", name: "family: man, woman, boy, boy", group: "People & Body"), | ||
| 558 | + Emoji(glyph: "👨👩👧👧", name: "family: man, woman, girl, girl", group: "People & Body"), | ||
| 559 | + Emoji(glyph: "👨👨👦", name: "family: man, man, boy", group: "People & Body"), | ||
| 560 | + Emoji(glyph: "👨👨👧", name: "family: man, man, girl", group: "People & Body"), | ||
| 561 | + Emoji(glyph: "👨👨👧👦", name: "family: man, man, girl, boy", group: "People & Body"), | ||
| 562 | + Emoji(glyph: "👨👨👦👦", name: "family: man, man, boy, boy", group: "People & Body"), | ||
| 563 | + Emoji(glyph: "👨👨👧👧", name: "family: man, man, girl, girl", group: "People & Body"), | ||
| 564 | + Emoji(glyph: "👩👩👦", name: "family: woman, woman, boy", group: "People & Body"), | ||
| 565 | + Emoji(glyph: "👩👩👧", name: "family: woman, woman, girl", group: "People & Body"), | ||
| 566 | + Emoji(glyph: "👩👩👧👦", name: "family: woman, woman, girl, boy", group: "People & Body"), | ||
| 567 | + Emoji(glyph: "👩👩👦👦", name: "family: woman, woman, boy, boy", group: "People & Body"), | ||
| 568 | + Emoji(glyph: "👩👩👧👧", name: "family: woman, woman, girl, girl", group: "People & Body"), | ||
| 569 | + Emoji(glyph: "👨👦", name: "family: man, boy", group: "People & Body"), | ||
| 570 | + Emoji(glyph: "👨👦👦", name: "family: man, boy, boy", group: "People & Body"), | ||
| 571 | + Emoji(glyph: "👨👧", name: "family: man, girl", group: "People & Body"), | ||
| 572 | + Emoji(glyph: "👨👧👦", name: "family: man, girl, boy", group: "People & Body"), | ||
| 573 | + Emoji(glyph: "👨👧👧", name: "family: man, girl, girl", group: "People & Body"), | ||
| 574 | + Emoji(glyph: "👩👦", name: "family: woman, boy", group: "People & Body"), | ||
| 575 | + Emoji(glyph: "👩👦👦", name: "family: woman, boy, boy", group: "People & Body"), | ||
| 576 | + Emoji(glyph: "👩👧", name: "family: woman, girl", group: "People & Body"), | ||
| 577 | + Emoji(glyph: "👩👧👦", name: "family: woman, girl, boy", group: "People & Body"), | ||
| 578 | + Emoji(glyph: "👩👧👧", name: "family: woman, girl, girl", group: "People & Body"), | ||
| 579 | + Emoji(glyph: "🗣️", name: "speaking head", group: "People & Body"), | ||
| 580 | + Emoji(glyph: "👤", name: "bust in silhouette", group: "People & Body"), | ||
| 581 | + Emoji(glyph: "👥", name: "busts in silhouette", group: "People & Body"), | ||
| 582 | + Emoji(glyph: "🫂", name: "people hugging", group: "People & Body"), | ||
| 583 | + Emoji(glyph: "👪", name: "family", group: "People & Body"), | ||
| 584 | + Emoji(glyph: "🧑🧑🧒", name: "family: adult, adult, child", group: "People & Body"), | ||
| 585 | + Emoji(glyph: "🧑🧑🧒🧒", name: "family: adult, adult, child, child", group: "People & Body"), | ||
| 586 | + Emoji(glyph: "🧑🧒", name: "family: adult, child", group: "People & Body"), | ||
| 587 | + Emoji(glyph: "🧑🧒🧒", name: "family: adult, child, child", group: "People & Body"), | ||
| 588 | + Emoji(glyph: "👣", name: "footprints", group: "People & Body"), | ||
| 589 | + Emoji(glyph: "🐵", name: "monkey face", group: "Animals & Nature"), | ||
| 590 | + Emoji(glyph: "🐒", name: "monkey", group: "Animals & Nature"), | ||
| 591 | + Emoji(glyph: "🦍", name: "gorilla", group: "Animals & Nature"), | ||
| 592 | + Emoji(glyph: "🦧", name: "orangutan", group: "Animals & Nature"), | ||
| 593 | + Emoji(glyph: "🐶", name: "dog face", group: "Animals & Nature"), | ||
| 594 | + Emoji(glyph: "🐕", name: "dog", group: "Animals & Nature"), | ||
| 595 | + Emoji(glyph: "🦮", name: "guide dog", group: "Animals & Nature"), | ||
| 596 | + Emoji(glyph: "🐕🦺", name: "service dog", group: "Animals & Nature"), | ||
| 597 | + Emoji(glyph: "🐩", name: "poodle", group: "Animals & Nature"), | ||
| 598 | + Emoji(glyph: "🐺", name: "wolf", group: "Animals & Nature"), | ||
| 599 | + Emoji(glyph: "🦊", name: "fox", group: "Animals & Nature"), | ||
| 600 | + Emoji(glyph: "🦝", name: "raccoon", group: "Animals & Nature"), | ||
| 601 | + Emoji(glyph: "🐱", name: "cat face", group: "Animals & Nature"), | ||
| 602 | + Emoji(glyph: "🐈", name: "cat", group: "Animals & Nature"), | ||
| 603 | + Emoji(glyph: "🐈⬛", name: "black cat", group: "Animals & Nature"), | ||
| 604 | + Emoji(glyph: "🦁", name: "lion", group: "Animals & Nature"), | ||
| 605 | + Emoji(glyph: "🐯", name: "tiger face", group: "Animals & Nature"), | ||
| 606 | + Emoji(glyph: "🐅", name: "tiger", group: "Animals & Nature"), | ||
| 607 | + Emoji(glyph: "🐆", name: "leopard", group: "Animals & Nature"), | ||
| 608 | + Emoji(glyph: "🐴", name: "horse face", group: "Animals & Nature"), | ||
| 609 | + Emoji(glyph: "🫎", name: "moose", group: "Animals & Nature"), | ||
| 610 | + Emoji(glyph: "🫏", name: "donkey", group: "Animals & Nature"), | ||
| 611 | + Emoji(glyph: "🐎", name: "horse", group: "Animals & Nature"), | ||
| 612 | + Emoji(glyph: "🦄", name: "unicorn", group: "Animals & Nature"), | ||
| 613 | + Emoji(glyph: "🦓", name: "zebra", group: "Animals & Nature"), | ||
| 614 | + Emoji(glyph: "🦌", name: "deer", group: "Animals & Nature"), | ||
| 615 | + Emoji(glyph: "🦬", name: "bison", group: "Animals & Nature"), | ||
| 616 | + Emoji(glyph: "🐮", name: "cow face", group: "Animals & Nature"), | ||
| 617 | + Emoji(glyph: "🐂", name: "ox", group: "Animals & Nature"), | ||
| 618 | + Emoji(glyph: "🐃", name: "water buffalo", group: "Animals & Nature"), | ||
| 619 | + Emoji(glyph: "🐄", name: "cow", group: "Animals & Nature"), | ||
| 620 | + Emoji(glyph: "🐷", name: "pig face", group: "Animals & Nature"), | ||
| 621 | + Emoji(glyph: "🐖", name: "pig", group: "Animals & Nature"), | ||
| 622 | + Emoji(glyph: "🐗", name: "boar", group: "Animals & Nature"), | ||
| 623 | + Emoji(glyph: "🐽", name: "pig nose", group: "Animals & Nature"), | ||
| 624 | + Emoji(glyph: "🐏", name: "ram", group: "Animals & Nature"), | ||
| 625 | + Emoji(glyph: "🐑", name: "ewe", group: "Animals & Nature"), | ||
| 626 | + Emoji(glyph: "🐐", name: "goat", group: "Animals & Nature"), | ||
| 627 | + Emoji(glyph: "🐪", name: "camel", group: "Animals & Nature"), | ||
| 628 | + Emoji(glyph: "🐫", name: "two-hump camel", group: "Animals & Nature"), | ||
| 629 | + Emoji(glyph: "🦙", name: "llama", group: "Animals & Nature"), | ||
| 630 | + Emoji(glyph: "🦒", name: "giraffe", group: "Animals & Nature"), | ||
| 631 | + Emoji(glyph: "🐘", name: "elephant", group: "Animals & Nature"), | ||
| 632 | + Emoji(glyph: "🦣", name: "mammoth", group: "Animals & Nature"), | ||
| 633 | + Emoji(glyph: "🦏", name: "rhinoceros", group: "Animals & Nature"), | ||
| 634 | + Emoji(glyph: "🦛", name: "hippopotamus", group: "Animals & Nature"), | ||
| 635 | + Emoji(glyph: "🐭", name: "mouse face", group: "Animals & Nature"), | ||
| 636 | + Emoji(glyph: "🐁", name: "mouse", group: "Animals & Nature"), | ||
| 637 | + Emoji(glyph: "🐀", name: "rat", group: "Animals & Nature"), | ||
| 638 | + Emoji(glyph: "🐹", name: "hamster", group: "Animals & Nature"), | ||
| 639 | + Emoji(glyph: "🐰", name: "rabbit face", group: "Animals & Nature"), | ||
| 640 | + Emoji(glyph: "🐇", name: "rabbit", group: "Animals & Nature"), | ||
| 641 | + Emoji(glyph: "🐿️", name: "chipmunk", group: "Animals & Nature"), | ||
| 642 | + Emoji(glyph: "🦫", name: "beaver", group: "Animals & Nature"), | ||
| 643 | + Emoji(glyph: "🦔", name: "hedgehog", group: "Animals & Nature"), | ||
| 644 | + Emoji(glyph: "🦇", name: "bat", group: "Animals & Nature"), | ||
| 645 | + Emoji(glyph: "🐻", name: "bear", group: "Animals & Nature"), | ||
| 646 | + Emoji(glyph: "🐻❄️", name: "polar bear", group: "Animals & Nature"), | ||
| 647 | + Emoji(glyph: "🐨", name: "koala", group: "Animals & Nature"), | ||
| 648 | + Emoji(glyph: "🐼", name: "panda", group: "Animals & Nature"), | ||
| 649 | + Emoji(glyph: "🦥", name: "sloth", group: "Animals & Nature"), | ||
| 650 | + Emoji(glyph: "🦦", name: "otter", group: "Animals & Nature"), | ||
| 651 | + Emoji(glyph: "🦨", name: "skunk", group: "Animals & Nature"), | ||
| 652 | + Emoji(glyph: "🦘", name: "kangaroo", group: "Animals & Nature"), | ||
| 653 | + Emoji(glyph: "🦡", name: "badger", group: "Animals & Nature"), | ||
| 654 | + Emoji(glyph: "🐾", name: "paw prints", group: "Animals & Nature"), | ||
| 655 | + Emoji(glyph: "🦃", name: "turkey", group: "Animals & Nature"), | ||
| 656 | + Emoji(glyph: "🐔", name: "chicken", group: "Animals & Nature"), | ||
| 657 | + Emoji(glyph: "🐓", name: "rooster", group: "Animals & Nature"), | ||
| 658 | + Emoji(glyph: "🐣", name: "hatching chick", group: "Animals & Nature"), | ||
| 659 | + Emoji(glyph: "🐤", name: "baby chick", group: "Animals & Nature"), | ||
| 660 | + Emoji(glyph: "🐥", name: "front-facing baby chick", group: "Animals & Nature"), | ||
| 661 | + Emoji(glyph: "🐦", name: "bird", group: "Animals & Nature"), | ||
| 662 | + Emoji(glyph: "🐧", name: "penguin", group: "Animals & Nature"), | ||
| 663 | + Emoji(glyph: "🕊️", name: "dove", group: "Animals & Nature"), | ||
| 664 | + Emoji(glyph: "🦅", name: "eagle", group: "Animals & Nature"), | ||
| 665 | + Emoji(glyph: "🦆", name: "duck", group: "Animals & Nature"), | ||
| 666 | + Emoji(glyph: "🦢", name: "swan", group: "Animals & Nature"), | ||
| 667 | + Emoji(glyph: "🦉", name: "owl", group: "Animals & Nature"), | ||
| 668 | + Emoji(glyph: "🦤", name: "dodo", group: "Animals & Nature"), | ||
| 669 | + Emoji(glyph: "🪶", name: "feather", group: "Animals & Nature"), | ||
| 670 | + Emoji(glyph: "🦩", name: "flamingo", group: "Animals & Nature"), | ||
| 671 | + Emoji(glyph: "🦚", name: "peacock", group: "Animals & Nature"), | ||
| 672 | + Emoji(glyph: "🦜", name: "parrot", group: "Animals & Nature"), | ||
| 673 | + Emoji(glyph: "🪽", name: "wing", group: "Animals & Nature"), | ||
| 674 | + Emoji(glyph: "🐦⬛", name: "black bird", group: "Animals & Nature"), | ||
| 675 | + Emoji(glyph: "🪿", name: "goose", group: "Animals & Nature"), | ||
| 676 | + Emoji(glyph: "🐦🔥", name: "phoenix", group: "Animals & Nature"), | ||
| 677 | + Emoji(glyph: "🐸", name: "frog", group: "Animals & Nature"), | ||
| 678 | + Emoji(glyph: "🐊", name: "crocodile", group: "Animals & Nature"), | ||
| 679 | + Emoji(glyph: "🐢", name: "turtle", group: "Animals & Nature"), | ||
| 680 | + Emoji(glyph: "🦎", name: "lizard", group: "Animals & Nature"), | ||
| 681 | + Emoji(glyph: "🐍", name: "snake", group: "Animals & Nature"), | ||
| 682 | + Emoji(glyph: "🐲", name: "dragon face", group: "Animals & Nature"), | ||
| 683 | + Emoji(glyph: "🐉", name: "dragon", group: "Animals & Nature"), | ||
| 684 | + Emoji(glyph: "🦕", name: "sauropod", group: "Animals & Nature"), | ||
| 685 | + Emoji(glyph: "🦖", name: "T-Rex", group: "Animals & Nature"), | ||
| 686 | + Emoji(glyph: "🐳", name: "spouting whale", group: "Animals & Nature"), | ||
| 687 | + Emoji(glyph: "🐋", name: "whale", group: "Animals & Nature"), | ||
| 688 | + Emoji(glyph: "🐬", name: "dolphin", group: "Animals & Nature"), | ||
| 689 | + Emoji(glyph: "🦭", name: "seal", group: "Animals & Nature"), | ||
| 690 | + Emoji(glyph: "🐟", name: "fish", group: "Animals & Nature"), | ||
| 691 | + Emoji(glyph: "🐠", name: "tropical fish", group: "Animals & Nature"), | ||
| 692 | + Emoji(glyph: "🐡", name: "blowfish", group: "Animals & Nature"), | ||
| 693 | + Emoji(glyph: "🦈", name: "shark", group: "Animals & Nature"), | ||
| 694 | + Emoji(glyph: "🐙", name: "octopus", group: "Animals & Nature"), | ||
| 695 | + Emoji(glyph: "🐚", name: "spiral shell", group: "Animals & Nature"), | ||
| 696 | + Emoji(glyph: "🪸", name: "coral", group: "Animals & Nature"), | ||
| 697 | + Emoji(glyph: "🪼", name: "jellyfish", group: "Animals & Nature"), | ||
| 698 | + Emoji(glyph: "🐌", name: "snail", group: "Animals & Nature"), | ||
| 699 | + Emoji(glyph: "🦋", name: "butterfly", group: "Animals & Nature"), | ||
| 700 | + Emoji(glyph: "🐛", name: "bug", group: "Animals & Nature"), | ||
| 701 | + Emoji(glyph: "🐜", name: "ant", group: "Animals & Nature"), | ||
| 702 | + Emoji(glyph: "🐝", name: "honeybee", group: "Animals & Nature"), | ||
| 703 | + Emoji(glyph: "🪲", name: "beetle", group: "Animals & Nature"), | ||
| 704 | + Emoji(glyph: "🐞", name: "lady beetle", group: "Animals & Nature"), | ||
| 705 | + Emoji(glyph: "🦗", name: "cricket", group: "Animals & Nature"), | ||
| 706 | + Emoji(glyph: "🪳", name: "cockroach", group: "Animals & Nature"), | ||
| 707 | + Emoji(glyph: "🕷️", name: "spider", group: "Animals & Nature"), | ||
| 708 | + Emoji(glyph: "🕸️", name: "spider web", group: "Animals & Nature"), | ||
| 709 | + Emoji(glyph: "🦂", name: "scorpion", group: "Animals & Nature"), | ||
| 710 | + Emoji(glyph: "🦟", name: "mosquito", group: "Animals & Nature"), | ||
| 711 | + Emoji(glyph: "🪰", name: "fly", group: "Animals & Nature"), | ||
| 712 | + Emoji(glyph: "🪱", name: "worm", group: "Animals & Nature"), | ||
| 713 | + Emoji(glyph: "🦠", name: "microbe", group: "Animals & Nature"), | ||
| 714 | + Emoji(glyph: "💐", name: "bouquet", group: "Animals & Nature"), | ||
| 715 | + Emoji(glyph: "🌸", name: "cherry blossom", group: "Animals & Nature"), | ||
| 716 | + Emoji(glyph: "💮", name: "white flower", group: "Animals & Nature"), | ||
| 717 | + Emoji(glyph: "🪷", name: "lotus", group: "Animals & Nature"), | ||
| 718 | + Emoji(glyph: "🏵️", name: "rosette", group: "Animals & Nature"), | ||
| 719 | + Emoji(glyph: "🌹", name: "rose", group: "Animals & Nature"), | ||
| 720 | + Emoji(glyph: "🥀", name: "wilted flower", group: "Animals & Nature"), | ||
| 721 | + Emoji(glyph: "🌺", name: "hibiscus", group: "Animals & Nature"), | ||
| 722 | + Emoji(glyph: "🌻", name: "sunflower", group: "Animals & Nature"), | ||
| 723 | + Emoji(glyph: "🌼", name: "blossom", group: "Animals & Nature"), | ||
| 724 | + Emoji(glyph: "🌷", name: "tulip", group: "Animals & Nature"), | ||
| 725 | + Emoji(glyph: "🪻", name: "hyacinth", group: "Animals & Nature"), | ||
| 726 | + Emoji(glyph: "🌱", name: "seedling", group: "Animals & Nature"), | ||
| 727 | + Emoji(glyph: "🪴", name: "potted plant", group: "Animals & Nature"), | ||
| 728 | + Emoji(glyph: "🌲", name: "evergreen tree", group: "Animals & Nature"), | ||
| 729 | + Emoji(glyph: "🌳", name: "deciduous tree", group: "Animals & Nature"), | ||
| 730 | + Emoji(glyph: "🌴", name: "palm tree", group: "Animals & Nature"), | ||
| 731 | + Emoji(glyph: "🌵", name: "cactus", group: "Animals & Nature"), | ||
| 732 | + Emoji(glyph: "🌾", name: "sheaf of rice", group: "Animals & Nature"), | ||
| 733 | + Emoji(glyph: "🌿", name: "herb", group: "Animals & Nature"), | ||
| 734 | + Emoji(glyph: "☘️", name: "shamrock", group: "Animals & Nature"), | ||
| 735 | + Emoji(glyph: "🍀", name: "four leaf clover", group: "Animals & Nature"), | ||
| 736 | + Emoji(glyph: "🍁", name: "maple leaf", group: "Animals & Nature"), | ||
| 737 | + Emoji(glyph: "🍂", name: "fallen leaf", group: "Animals & Nature"), | ||
| 738 | + Emoji(glyph: "🍃", name: "leaf fluttering in wind", group: "Animals & Nature"), | ||
| 739 | + Emoji(glyph: "🪹", name: "empty nest", group: "Animals & Nature"), | ||
| 740 | + Emoji(glyph: "🪺", name: "nest with eggs", group: "Animals & Nature"), | ||
| 741 | + Emoji(glyph: "🍄", name: "mushroom", group: "Animals & Nature"), | ||
| 742 | + Emoji(glyph: "🍇", name: "grapes", group: "Food & Drink"), | ||
| 743 | + Emoji(glyph: "🍈", name: "melon", group: "Food & Drink"), | ||
| 744 | + Emoji(glyph: "🍉", name: "watermelon", group: "Food & Drink"), | ||
| 745 | + Emoji(glyph: "🍊", name: "tangerine", group: "Food & Drink"), | ||
| 746 | + Emoji(glyph: "🍋", name: "lemon", group: "Food & Drink"), | ||
| 747 | + Emoji(glyph: "🍋🟩", name: "lime", group: "Food & Drink"), | ||
| 748 | + Emoji(glyph: "🍌", name: "banana", group: "Food & Drink"), | ||
| 749 | + Emoji(glyph: "🍍", name: "pineapple", group: "Food & Drink"), | ||
| 750 | + Emoji(glyph: "🥭", name: "mango", group: "Food & Drink"), | ||
| 751 | + Emoji(glyph: "🍎", name: "red apple", group: "Food & Drink"), | ||
| 752 | + Emoji(glyph: "🍏", name: "green apple", group: "Food & Drink"), | ||
| 753 | + Emoji(glyph: "🍐", name: "pear", group: "Food & Drink"), | ||
| 754 | + Emoji(glyph: "🍑", name: "peach", group: "Food & Drink"), | ||
| 755 | + Emoji(glyph: "🍒", name: "cherries", group: "Food & Drink"), | ||
| 756 | + Emoji(glyph: "🍓", name: "strawberry", group: "Food & Drink"), | ||
| 757 | + Emoji(glyph: "🫐", name: "blueberries", group: "Food & Drink"), | ||
| 758 | + Emoji(glyph: "🥝", name: "kiwi fruit", group: "Food & Drink"), | ||
| 759 | + Emoji(glyph: "🍅", name: "tomato", group: "Food & Drink"), | ||
| 760 | + Emoji(glyph: "🫒", name: "olive", group: "Food & Drink"), | ||
| 761 | + Emoji(glyph: "🥥", name: "coconut", group: "Food & Drink"), | ||
| 762 | + Emoji(glyph: "🥑", name: "avocado", group: "Food & Drink"), | ||
| 763 | + Emoji(glyph: "🍆", name: "eggplant", group: "Food & Drink"), | ||
| 764 | + Emoji(glyph: "🥔", name: "potato", group: "Food & Drink"), | ||
| 765 | + Emoji(glyph: "🥕", name: "carrot", group: "Food & Drink"), | ||
| 766 | + Emoji(glyph: "🌽", name: "ear of corn", group: "Food & Drink"), | ||
| 767 | + Emoji(glyph: "🌶️", name: "hot pepper", group: "Food & Drink"), | ||
| 768 | + Emoji(glyph: "🫑", name: "bell pepper", group: "Food & Drink"), | ||
| 769 | + Emoji(glyph: "🥒", name: "cucumber", group: "Food & Drink"), | ||
| 770 | + Emoji(glyph: "🥬", name: "leafy green", group: "Food & Drink"), | ||
| 771 | + Emoji(glyph: "🥦", name: "broccoli", group: "Food & Drink"), | ||
| 772 | + Emoji(glyph: "🧄", name: "garlic", group: "Food & Drink"), | ||
| 773 | + Emoji(glyph: "🧅", name: "onion", group: "Food & Drink"), | ||
| 774 | + Emoji(glyph: "🥜", name: "peanuts", group: "Food & Drink"), | ||
| 775 | + Emoji(glyph: "🫘", name: "beans", group: "Food & Drink"), | ||
| 776 | + Emoji(glyph: "🌰", name: "chestnut", group: "Food & Drink"), | ||
| 777 | + Emoji(glyph: "🫚", name: "ginger root", group: "Food & Drink"), | ||
| 778 | + Emoji(glyph: "🫛", name: "pea pod", group: "Food & Drink"), | ||
| 779 | + Emoji(glyph: "🍄🟫", name: "brown mushroom", group: "Food & Drink"), | ||
| 780 | + Emoji(glyph: "🍞", name: "bread", group: "Food & Drink"), | ||
| 781 | + Emoji(glyph: "🥐", name: "croissant", group: "Food & Drink"), | ||
| 782 | + Emoji(glyph: "🥖", name: "baguette bread", group: "Food & Drink"), | ||
| 783 | + Emoji(glyph: "🫓", name: "flatbread", group: "Food & Drink"), | ||
| 784 | + Emoji(glyph: "🥨", name: "pretzel", group: "Food & Drink"), | ||
| 785 | + Emoji(glyph: "🥯", name: "bagel", group: "Food & Drink"), | ||
| 786 | + Emoji(glyph: "🥞", name: "pancakes", group: "Food & Drink"), | ||
| 787 | + Emoji(glyph: "🧇", name: "waffle", group: "Food & Drink"), | ||
| 788 | + Emoji(glyph: "🧀", name: "cheese wedge", group: "Food & Drink"), | ||
| 789 | + Emoji(glyph: "🍖", name: "meat on bone", group: "Food & Drink"), | ||
| 790 | + Emoji(glyph: "🍗", name: "poultry leg", group: "Food & Drink"), | ||
| 791 | + Emoji(glyph: "🥩", name: "cut of meat", group: "Food & Drink"), | ||
| 792 | + Emoji(glyph: "🥓", name: "bacon", group: "Food & Drink"), | ||
| 793 | + Emoji(glyph: "🍔", name: "hamburger", group: "Food & Drink"), | ||
| 794 | + Emoji(glyph: "🍟", name: "french fries", group: "Food & Drink"), | ||
| 795 | + Emoji(glyph: "🍕", name: "pizza", group: "Food & Drink"), | ||
| 796 | + Emoji(glyph: "🌭", name: "hot dog", group: "Food & Drink"), | ||
| 797 | + Emoji(glyph: "🥪", name: "sandwich", group: "Food & Drink"), | ||
| 798 | + Emoji(glyph: "🌮", name: "taco", group: "Food & Drink"), | ||
| 799 | + Emoji(glyph: "🌯", name: "burrito", group: "Food & Drink"), | ||
| 800 | + Emoji(glyph: "🫔", name: "tamale", group: "Food & Drink"), | ||
| 801 | + Emoji(glyph: "🥙", name: "stuffed flatbread", group: "Food & Drink"), | ||
| 802 | + Emoji(glyph: "🧆", name: "falafel", group: "Food & Drink"), | ||
| 803 | + Emoji(glyph: "🥚", name: "egg", group: "Food & Drink"), | ||
| 804 | + Emoji(glyph: "🍳", name: "cooking", group: "Food & Drink"), | ||
| 805 | + Emoji(glyph: "🥘", name: "shallow pan of food", group: "Food & Drink"), | ||
| 806 | + Emoji(glyph: "🍲", name: "pot of food", group: "Food & Drink"), | ||
| 807 | + Emoji(glyph: "🫕", name: "fondue", group: "Food & Drink"), | ||
| 808 | + Emoji(glyph: "🥣", name: "bowl with spoon", group: "Food & Drink"), | ||
| 809 | + Emoji(glyph: "🥗", name: "green salad", group: "Food & Drink"), | ||
| 810 | + Emoji(glyph: "🍿", name: "popcorn", group: "Food & Drink"), | ||
| 811 | + Emoji(glyph: "🧈", name: "butter", group: "Food & Drink"), | ||
| 812 | + Emoji(glyph: "🧂", name: "salt", group: "Food & Drink"), | ||
| 813 | + Emoji(glyph: "🥫", name: "canned food", group: "Food & Drink"), | ||
| 814 | + Emoji(glyph: "🍱", name: "bento box", group: "Food & Drink"), | ||
| 815 | + Emoji(glyph: "🍘", name: "rice cracker", group: "Food & Drink"), | ||
| 816 | + Emoji(glyph: "🍙", name: "rice ball", group: "Food & Drink"), | ||
| 817 | + Emoji(glyph: "🍚", name: "cooked rice", group: "Food & Drink"), | ||
| 818 | + Emoji(glyph: "🍛", name: "curry rice", group: "Food & Drink"), | ||
| 819 | + Emoji(glyph: "🍜", name: "steaming bowl", group: "Food & Drink"), | ||
| 820 | + Emoji(glyph: "🍝", name: "spaghetti", group: "Food & Drink"), | ||
| 821 | + Emoji(glyph: "🍠", name: "roasted sweet potato", group: "Food & Drink"), | ||
| 822 | + Emoji(glyph: "🍢", name: "oden", group: "Food & Drink"), | ||
| 823 | + Emoji(glyph: "🍣", name: "sushi", group: "Food & Drink"), | ||
| 824 | + Emoji(glyph: "🍤", name: "fried shrimp", group: "Food & Drink"), | ||
| 825 | + Emoji(glyph: "🍥", name: "fish cake with swirl", group: "Food & Drink"), | ||
| 826 | + Emoji(glyph: "🥮", name: "moon cake", group: "Food & Drink"), | ||
| 827 | + Emoji(glyph: "🍡", name: "dango", group: "Food & Drink"), | ||
| 828 | + Emoji(glyph: "🥟", name: "dumpling", group: "Food & Drink"), | ||
| 829 | + Emoji(glyph: "🥠", name: "fortune cookie", group: "Food & Drink"), | ||
| 830 | + Emoji(glyph: "🥡", name: "takeout box", group: "Food & Drink"), | ||
| 831 | + Emoji(glyph: "🦀", name: "crab", group: "Food & Drink"), | ||
| 832 | + Emoji(glyph: "🦞", name: "lobster", group: "Food & Drink"), | ||
| 833 | + Emoji(glyph: "🦐", name: "shrimp", group: "Food & Drink"), | ||
| 834 | + Emoji(glyph: "🦑", name: "squid", group: "Food & Drink"), | ||
| 835 | + Emoji(glyph: "🦪", name: "oyster", group: "Food & Drink"), | ||
| 836 | + Emoji(glyph: "🍦", name: "soft ice cream", group: "Food & Drink"), | ||
| 837 | + Emoji(glyph: "🍧", name: "shaved ice", group: "Food & Drink"), | ||
| 838 | + Emoji(glyph: "🍨", name: "ice cream", group: "Food & Drink"), | ||
| 839 | + Emoji(glyph: "🍩", name: "doughnut", group: "Food & Drink"), | ||
| 840 | + Emoji(glyph: "🍪", name: "cookie", group: "Food & Drink"), | ||
| 841 | + Emoji(glyph: "🎂", name: "birthday cake", group: "Food & Drink"), | ||
| 842 | + Emoji(glyph: "🍰", name: "shortcake", group: "Food & Drink"), | ||
| 843 | + Emoji(glyph: "🧁", name: "cupcake", group: "Food & Drink"), | ||
| 844 | + Emoji(glyph: "🥧", name: "pie", group: "Food & Drink"), | ||
| 845 | + Emoji(glyph: "🍫", name: "chocolate bar", group: "Food & Drink"), | ||
| 846 | + Emoji(glyph: "🍬", name: "candy", group: "Food & Drink"), | ||
| 847 | + Emoji(glyph: "🍭", name: "lollipop", group: "Food & Drink"), | ||
| 848 | + Emoji(glyph: "🍮", name: "custard", group: "Food & Drink"), | ||
| 849 | + Emoji(glyph: "🍯", name: "honey pot", group: "Food & Drink"), | ||
| 850 | + Emoji(glyph: "🍼", name: "baby bottle", group: "Food & Drink"), | ||
| 851 | + Emoji(glyph: "🥛", name: "glass of milk", group: "Food & Drink"), | ||
| 852 | + Emoji(glyph: "☕", name: "hot beverage", group: "Food & Drink"), | ||
| 853 | + Emoji(glyph: "🫖", name: "teapot", group: "Food & Drink"), | ||
| 854 | + Emoji(glyph: "🍵", name: "teacup without handle", group: "Food & Drink"), | ||
| 855 | + Emoji(glyph: "🍶", name: "sake", group: "Food & Drink"), | ||
| 856 | + Emoji(glyph: "🍾", name: "bottle with popping cork", group: "Food & Drink"), | ||
| 857 | + Emoji(glyph: "🍷", name: "wine glass", group: "Food & Drink"), | ||
| 858 | + Emoji(glyph: "🍸", name: "cocktail glass", group: "Food & Drink"), | ||
| 859 | + Emoji(glyph: "🍹", name: "tropical drink", group: "Food & Drink"), | ||
| 860 | + Emoji(glyph: "🍺", name: "beer mug", group: "Food & Drink"), | ||
| 861 | + Emoji(glyph: "🍻", name: "clinking beer mugs", group: "Food & Drink"), | ||
| 862 | + Emoji(glyph: "🥂", name: "clinking glasses", group: "Food & Drink"), | ||
| 863 | + Emoji(glyph: "🥃", name: "tumbler glass", group: "Food & Drink"), | ||
| 864 | + Emoji(glyph: "🫗", name: "pouring liquid", group: "Food & Drink"), | ||
| 865 | + Emoji(glyph: "🥤", name: "cup with straw", group: "Food & Drink"), | ||
| 866 | + Emoji(glyph: "🧋", name: "bubble tea", group: "Food & Drink"), | ||
| 867 | + Emoji(glyph: "🧃", name: "beverage box", group: "Food & Drink"), | ||
| 868 | + Emoji(glyph: "🧉", name: "mate", group: "Food & Drink"), | ||
| 869 | + Emoji(glyph: "🧊", name: "ice", group: "Food & Drink"), | ||
| 870 | + Emoji(glyph: "🥢", name: "chopsticks", group: "Food & Drink"), | ||
| 871 | + Emoji(glyph: "🍽️", name: "fork and knife with plate", group: "Food & Drink"), | ||
| 872 | + Emoji(glyph: "🍴", name: "fork and knife", group: "Food & Drink"), | ||
| 873 | + Emoji(glyph: "🥄", name: "spoon", group: "Food & Drink"), | ||
| 874 | + Emoji(glyph: "🔪", name: "kitchen knife", group: "Food & Drink"), | ||
| 875 | + Emoji(glyph: "🫙", name: "jar", group: "Food & Drink"), | ||
| 876 | + Emoji(glyph: "🏺", name: "amphora", group: "Food & Drink"), | ||
| 877 | + Emoji(glyph: "🌍", name: "globe showing Europe-Africa", group: "Travel & Places"), | ||
| 878 | + Emoji(glyph: "🌎", name: "globe showing Americas", group: "Travel & Places"), | ||
| 879 | + Emoji(glyph: "🌏", name: "globe showing Asia-Australia", group: "Travel & Places"), | ||
| 880 | + Emoji(glyph: "🌐", name: "globe with meridians", group: "Travel & Places"), | ||
| 881 | + Emoji(glyph: "🗺️", name: "world map", group: "Travel & Places"), | ||
| 882 | + Emoji(glyph: "🗾", name: "map of Japan", group: "Travel & Places"), | ||
| 883 | + Emoji(glyph: "🧭", name: "compass", group: "Travel & Places"), | ||
| 884 | + Emoji(glyph: "🏔️", name: "snow-capped mountain", group: "Travel & Places"), | ||
| 885 | + Emoji(glyph: "⛰️", name: "mountain", group: "Travel & Places"), | ||
| 886 | + Emoji(glyph: "🌋", name: "volcano", group: "Travel & Places"), | ||
| 887 | + Emoji(glyph: "🗻", name: "mount fuji", group: "Travel & Places"), | ||
| 888 | + Emoji(glyph: "🏕️", name: "camping", group: "Travel & Places"), | ||
| 889 | + Emoji(glyph: "🏖️", name: "beach with umbrella", group: "Travel & Places"), | ||
| 890 | + Emoji(glyph: "🏜️", name: "desert", group: "Travel & Places"), | ||
| 891 | + Emoji(glyph: "🏝️", name: "desert island", group: "Travel & Places"), | ||
| 892 | + Emoji(glyph: "🏞️", name: "national park", group: "Travel & Places"), | ||
| 893 | + Emoji(glyph: "🏟️", name: "stadium", group: "Travel & Places"), | ||
| 894 | + Emoji(glyph: "🏛️", name: "classical building", group: "Travel & Places"), | ||
| 895 | + Emoji(glyph: "🏗️", name: "building construction", group: "Travel & Places"), | ||
| 896 | + Emoji(glyph: "🧱", name: "brick", group: "Travel & Places"), | ||
| 897 | + Emoji(glyph: "🪨", name: "rock", group: "Travel & Places"), | ||
| 898 | + Emoji(glyph: "🪵", name: "wood", group: "Travel & Places"), | ||
| 899 | + Emoji(glyph: "🛖", name: "hut", group: "Travel & Places"), | ||
| 900 | + Emoji(glyph: "🏘️", name: "houses", group: "Travel & Places"), | ||
| 901 | + Emoji(glyph: "🏚️", name: "derelict house", group: "Travel & Places"), | ||
| 902 | + Emoji(glyph: "🏠", name: "house", group: "Travel & Places"), | ||
| 903 | + Emoji(glyph: "🏡", name: "house with garden", group: "Travel & Places"), | ||
| 904 | + Emoji(glyph: "🏢", name: "office building", group: "Travel & Places"), | ||
| 905 | + Emoji(glyph: "🏣", name: "Japanese post office", group: "Travel & Places"), | ||
| 906 | + Emoji(glyph: "🏤", name: "post office", group: "Travel & Places"), | ||
| 907 | + Emoji(glyph: "🏥", name: "hospital", group: "Travel & Places"), | ||
| 908 | + Emoji(glyph: "🏦", name: "bank", group: "Travel & Places"), | ||
| 909 | + Emoji(glyph: "🏨", name: "hotel", group: "Travel & Places"), | ||
| 910 | + Emoji(glyph: "🏩", name: "love hotel", group: "Travel & Places"), | ||
| 911 | + Emoji(glyph: "🏪", name: "convenience store", group: "Travel & Places"), | ||
| 912 | + Emoji(glyph: "🏫", name: "school", group: "Travel & Places"), | ||
| 913 | + Emoji(glyph: "🏬", name: "department store", group: "Travel & Places"), | ||
| 914 | + Emoji(glyph: "🏭", name: "factory", group: "Travel & Places"), | ||
| 915 | + Emoji(glyph: "🏯", name: "Japanese castle", group: "Travel & Places"), | ||
| 916 | + Emoji(glyph: "🏰", name: "castle", group: "Travel & Places"), | ||
| 917 | + Emoji(glyph: "💒", name: "wedding", group: "Travel & Places"), | ||
| 918 | + Emoji(glyph: "🗼", name: "Tokyo tower", group: "Travel & Places"), | ||
| 919 | + Emoji(glyph: "🗽", name: "Statue of Liberty", group: "Travel & Places"), | ||
| 920 | + Emoji(glyph: "⛪", name: "church", group: "Travel & Places"), | ||
| 921 | + Emoji(glyph: "🕌", name: "mosque", group: "Travel & Places"), | ||
| 922 | + Emoji(glyph: "🛕", name: "hindu temple", group: "Travel & Places"), | ||
| 923 | + Emoji(glyph: "🕍", name: "synagogue", group: "Travel & Places"), | ||
| 924 | + Emoji(glyph: "⛩️", name: "shinto shrine", group: "Travel & Places"), | ||
| 925 | + Emoji(glyph: "🕋", name: "kaaba", group: "Travel & Places"), | ||
| 926 | + Emoji(glyph: "⛲", name: "fountain", group: "Travel & Places"), | ||
| 927 | + Emoji(glyph: "⛺", name: "tent", group: "Travel & Places"), | ||
| 928 | + Emoji(glyph: "🌁", name: "foggy", group: "Travel & Places"), | ||
| 929 | + Emoji(glyph: "🌃", name: "night with stars", group: "Travel & Places"), | ||
| 930 | + Emoji(glyph: "🏙️", name: "cityscape", group: "Travel & Places"), | ||
| 931 | + Emoji(glyph: "🌄", name: "sunrise over mountains", group: "Travel & Places"), | ||
| 932 | + Emoji(glyph: "🌅", name: "sunrise", group: "Travel & Places"), | ||
| 933 | + Emoji(glyph: "🌆", name: "cityscape at dusk", group: "Travel & Places"), | ||
| 934 | + Emoji(glyph: "🌇", name: "sunset", group: "Travel & Places"), | ||
| 935 | + Emoji(glyph: "🌉", name: "bridge at night", group: "Travel & Places"), | ||
| 936 | + Emoji(glyph: "♨️", name: "hot springs", group: "Travel & Places"), | ||
| 937 | + Emoji(glyph: "🎠", name: "carousel horse", group: "Travel & Places"), | ||
| 938 | + Emoji(glyph: "🛝", name: "playground slide", group: "Travel & Places"), | ||
| 939 | + Emoji(glyph: "🎡", name: "ferris wheel", group: "Travel & Places"), | ||
| 940 | + Emoji(glyph: "🎢", name: "roller coaster", group: "Travel & Places"), | ||
| 941 | + Emoji(glyph: "💈", name: "barber pole", group: "Travel & Places"), | ||
| 942 | + Emoji(glyph: "🎪", name: "circus tent", group: "Travel & Places"), | ||
| 943 | + Emoji(glyph: "🚂", name: "locomotive", group: "Travel & Places"), | ||
| 944 | + Emoji(glyph: "🚃", name: "railway car", group: "Travel & Places"), | ||
| 945 | + Emoji(glyph: "🚄", name: "high-speed train", group: "Travel & Places"), | ||
| 946 | + Emoji(glyph: "🚅", name: "bullet train", group: "Travel & Places"), | ||
| 947 | + Emoji(glyph: "🚆", name: "train", group: "Travel & Places"), | ||
| 948 | + Emoji(glyph: "🚇", name: "metro", group: "Travel & Places"), | ||
| 949 | + Emoji(glyph: "🚈", name: "light rail", group: "Travel & Places"), | ||
| 950 | + Emoji(glyph: "🚉", name: "station", group: "Travel & Places"), | ||
| 951 | + Emoji(glyph: "🚊", name: "tram", group: "Travel & Places"), | ||
| 952 | + Emoji(glyph: "🚝", name: "monorail", group: "Travel & Places"), | ||
| 953 | + Emoji(glyph: "🚞", name: "mountain railway", group: "Travel & Places"), | ||
| 954 | + Emoji(glyph: "🚋", name: "tram car", group: "Travel & Places"), | ||
| 955 | + Emoji(glyph: "🚌", name: "bus", group: "Travel & Places"), | ||
| 956 | + Emoji(glyph: "🚍", name: "oncoming bus", group: "Travel & Places"), | ||
| 957 | + Emoji(glyph: "🚎", name: "trolleybus", group: "Travel & Places"), | ||
| 958 | + Emoji(glyph: "🚐", name: "minibus", group: "Travel & Places"), | ||
| 959 | + Emoji(glyph: "🚑", name: "ambulance", group: "Travel & Places"), | ||
| 960 | + Emoji(glyph: "🚒", name: "fire engine", group: "Travel & Places"), | ||
| 961 | + Emoji(glyph: "🚓", name: "police car", group: "Travel & Places"), | ||
| 962 | + Emoji(glyph: "🚔", name: "oncoming police car", group: "Travel & Places"), | ||
| 963 | + Emoji(glyph: "🚕", name: "taxi", group: "Travel & Places"), | ||
| 964 | + Emoji(glyph: "🚖", name: "oncoming taxi", group: "Travel & Places"), | ||
| 965 | + Emoji(glyph: "🚗", name: "automobile", group: "Travel & Places"), | ||
| 966 | + Emoji(glyph: "🚘", name: "oncoming automobile", group: "Travel & Places"), | ||
| 967 | + Emoji(glyph: "🚙", name: "sport utility vehicle", group: "Travel & Places"), | ||
| 968 | + Emoji(glyph: "🛻", name: "pickup truck", group: "Travel & Places"), | ||
| 969 | + Emoji(glyph: "🚚", name: "delivery truck", group: "Travel & Places"), | ||
| 970 | + Emoji(glyph: "🚛", name: "articulated lorry", group: "Travel & Places"), | ||
| 971 | + Emoji(glyph: "🚜", name: "tractor", group: "Travel & Places"), | ||
| 972 | + Emoji(glyph: "🏎️", name: "racing car", group: "Travel & Places"), | ||
| 973 | + Emoji(glyph: "🏍️", name: "motorcycle", group: "Travel & Places"), | ||
| 974 | + Emoji(glyph: "🛵", name: "motor scooter", group: "Travel & Places"), | ||
| 975 | + Emoji(glyph: "🦽", name: "manual wheelchair", group: "Travel & Places"), | ||
| 976 | + Emoji(glyph: "🦼", name: "motorized wheelchair", group: "Travel & Places"), | ||
| 977 | + Emoji(glyph: "🛺", name: "auto rickshaw", group: "Travel & Places"), | ||
| 978 | + Emoji(glyph: "🚲", name: "bicycle", group: "Travel & Places"), | ||
| 979 | + Emoji(glyph: "🛴", name: "kick scooter", group: "Travel & Places"), | ||
| 980 | + Emoji(glyph: "🛹", name: "skateboard", group: "Travel & Places"), | ||
| 981 | + Emoji(glyph: "🛼", name: "roller skate", group: "Travel & Places"), | ||
| 982 | + Emoji(glyph: "🚏", name: "bus stop", group: "Travel & Places"), | ||
| 983 | + Emoji(glyph: "🛣️", name: "motorway", group: "Travel & Places"), | ||
| 984 | + Emoji(glyph: "🛤️", name: "railway track", group: "Travel & Places"), | ||
| 985 | + Emoji(glyph: "🛢️", name: "oil drum", group: "Travel & Places"), | ||
| 986 | + Emoji(glyph: "⛽", name: "fuel pump", group: "Travel & Places"), | ||
| 987 | + Emoji(glyph: "🛞", name: "wheel", group: "Travel & Places"), | ||
| 988 | + Emoji(glyph: "🚨", name: "police car light", group: "Travel & Places"), | ||
| 989 | + Emoji(glyph: "🚥", name: "horizontal traffic light", group: "Travel & Places"), | ||
| 990 | + Emoji(glyph: "🚦", name: "vertical traffic light", group: "Travel & Places"), | ||
| 991 | + Emoji(glyph: "🛑", name: "stop sign", group: "Travel & Places"), | ||
| 992 | + Emoji(glyph: "🚧", name: "construction", group: "Travel & Places"), | ||
| 993 | + Emoji(glyph: "⚓", name: "anchor", group: "Travel & Places"), | ||
| 994 | + Emoji(glyph: "🛟", name: "ring buoy", group: "Travel & Places"), | ||
| 995 | + Emoji(glyph: "⛵", name: "sailboat", group: "Travel & Places"), | ||
| 996 | + Emoji(glyph: "🛶", name: "canoe", group: "Travel & Places"), | ||
| 997 | + Emoji(glyph: "🚤", name: "speedboat", group: "Travel & Places"), | ||
| 998 | + Emoji(glyph: "🛳️", name: "passenger ship", group: "Travel & Places"), | ||
| 999 | + Emoji(glyph: "⛴️", name: "ferry", group: "Travel & Places"), | ||
| 1000 | + Emoji(glyph: "🛥️", name: "motor boat", group: "Travel & Places"), | ||
| 1001 | + Emoji(glyph: "🚢", name: "ship", group: "Travel & Places"), | ||
| 1002 | + Emoji(glyph: "✈️", name: "airplane", group: "Travel & Places"), | ||
| 1003 | + Emoji(glyph: "🛩️", name: "small airplane", group: "Travel & Places"), | ||
| 1004 | + Emoji(glyph: "🛫", name: "airplane departure", group: "Travel & Places"), | ||
| 1005 | + Emoji(glyph: "🛬", name: "airplane arrival", group: "Travel & Places"), | ||
| 1006 | + Emoji(glyph: "🪂", name: "parachute", group: "Travel & Places"), | ||
| 1007 | + Emoji(glyph: "💺", name: "seat", group: "Travel & Places"), | ||
| 1008 | + Emoji(glyph: "🚁", name: "helicopter", group: "Travel & Places"), | ||
| 1009 | + Emoji(glyph: "🚟", name: "suspension railway", group: "Travel & Places"), | ||
| 1010 | + Emoji(glyph: "🚠", name: "mountain cableway", group: "Travel & Places"), | ||
| 1011 | + Emoji(glyph: "🚡", name: "aerial tramway", group: "Travel & Places"), | ||
| 1012 | + Emoji(glyph: "🛰️", name: "satellite", group: "Travel & Places"), | ||
| 1013 | + Emoji(glyph: "🚀", name: "rocket", group: "Travel & Places"), | ||
| 1014 | + Emoji(glyph: "🛸", name: "flying saucer", group: "Travel & Places"), | ||
| 1015 | + Emoji(glyph: "🛎️", name: "bellhop bell", group: "Travel & Places"), | ||
| 1016 | + Emoji(glyph: "🧳", name: "luggage", group: "Travel & Places"), | ||
| 1017 | + Emoji(glyph: "⌛", name: "hourglass done", group: "Travel & Places"), | ||
| 1018 | + Emoji(glyph: "⏳", name: "hourglass not done", group: "Travel & Places"), | ||
| 1019 | + Emoji(glyph: "⌚", name: "watch", group: "Travel & Places"), | ||
| 1020 | + Emoji(glyph: "⏰", name: "alarm clock", group: "Travel & Places"), | ||
| 1021 | + Emoji(glyph: "⏱️", name: "stopwatch", group: "Travel & Places"), | ||
| 1022 | + Emoji(glyph: "⏲️", name: "timer clock", group: "Travel & Places"), | ||
| 1023 | + Emoji(glyph: "🕰️", name: "mantelpiece clock", group: "Travel & Places"), | ||
| 1024 | + Emoji(glyph: "🕛", name: "twelve o’clock", group: "Travel & Places"), | ||
| 1025 | + Emoji(glyph: "🕧", name: "twelve-thirty", group: "Travel & Places"), | ||
| 1026 | + Emoji(glyph: "🕐", name: "one o’clock", group: "Travel & Places"), | ||
| 1027 | + Emoji(glyph: "🕜", name: "one-thirty", group: "Travel & Places"), | ||
| 1028 | + Emoji(glyph: "🕑", name: "two o’clock", group: "Travel & Places"), | ||
| 1029 | + Emoji(glyph: "🕝", name: "two-thirty", group: "Travel & Places"), | ||
| 1030 | + Emoji(glyph: "🕒", name: "three o’clock", group: "Travel & Places"), | ||
| 1031 | + Emoji(glyph: "🕞", name: "three-thirty", group: "Travel & Places"), | ||
| 1032 | + Emoji(glyph: "🕓", name: "four o’clock", group: "Travel & Places"), | ||
| 1033 | + Emoji(glyph: "🕟", name: "four-thirty", group: "Travel & Places"), | ||
| 1034 | + Emoji(glyph: "🕔", name: "five o’clock", group: "Travel & Places"), | ||
| 1035 | + Emoji(glyph: "🕠", name: "five-thirty", group: "Travel & Places"), | ||
| 1036 | + Emoji(glyph: "🕕", name: "six o’clock", group: "Travel & Places"), | ||
| 1037 | + Emoji(glyph: "🕡", name: "six-thirty", group: "Travel & Places"), | ||
| 1038 | + Emoji(glyph: "🕖", name: "seven o’clock", group: "Travel & Places"), | ||
| 1039 | + Emoji(glyph: "🕢", name: "seven-thirty", group: "Travel & Places"), | ||
| 1040 | + Emoji(glyph: "🕗", name: "eight o’clock", group: "Travel & Places"), | ||
| 1041 | + Emoji(glyph: "🕣", name: "eight-thirty", group: "Travel & Places"), | ||
| 1042 | + Emoji(glyph: "🕘", name: "nine o’clock", group: "Travel & Places"), | ||
| 1043 | + Emoji(glyph: "🕤", name: "nine-thirty", group: "Travel & Places"), | ||
| 1044 | + Emoji(glyph: "🕙", name: "ten o’clock", group: "Travel & Places"), | ||
| 1045 | + Emoji(glyph: "🕥", name: "ten-thirty", group: "Travel & Places"), | ||
| 1046 | + Emoji(glyph: "🕚", name: "eleven o’clock", group: "Travel & Places"), | ||
| 1047 | + Emoji(glyph: "🕦", name: "eleven-thirty", group: "Travel & Places"), | ||
| 1048 | + Emoji(glyph: "🌑", name: "new moon", group: "Travel & Places"), | ||
| 1049 | + Emoji(glyph: "🌒", name: "waxing crescent moon", group: "Travel & Places"), | ||
| 1050 | + Emoji(glyph: "🌓", name: "first quarter moon", group: "Travel & Places"), | ||
| 1051 | + Emoji(glyph: "🌔", name: "waxing gibbous moon", group: "Travel & Places"), | ||
| 1052 | + Emoji(glyph: "🌕", name: "full moon", group: "Travel & Places"), | ||
| 1053 | + Emoji(glyph: "🌖", name: "waning gibbous moon", group: "Travel & Places"), | ||
| 1054 | + Emoji(glyph: "🌗", name: "last quarter moon", group: "Travel & Places"), | ||
| 1055 | + Emoji(glyph: "🌘", name: "waning crescent moon", group: "Travel & Places"), | ||
| 1056 | + Emoji(glyph: "🌙", name: "crescent moon", group: "Travel & Places"), | ||
| 1057 | + Emoji(glyph: "🌚", name: "new moon face", group: "Travel & Places"), | ||
| 1058 | + Emoji(glyph: "🌛", name: "first quarter moon face", group: "Travel & Places"), | ||
| 1059 | + Emoji(glyph: "🌜", name: "last quarter moon face", group: "Travel & Places"), | ||
| 1060 | + Emoji(glyph: "🌡️", name: "thermometer", group: "Travel & Places"), | ||
| 1061 | + Emoji(glyph: "☀️", name: "sun", group: "Travel & Places"), | ||
| 1062 | + Emoji(glyph: "🌝", name: "full moon face", group: "Travel & Places"), | ||
| 1063 | + Emoji(glyph: "🌞", name: "sun with face", group: "Travel & Places"), | ||
| 1064 | + Emoji(glyph: "🪐", name: "ringed planet", group: "Travel & Places"), | ||
| 1065 | + Emoji(glyph: "⭐", name: "star", group: "Travel & Places"), | ||
| 1066 | + Emoji(glyph: "🌟", name: "glowing star", group: "Travel & Places"), | ||
| 1067 | + Emoji(glyph: "🌠", name: "shooting star", group: "Travel & Places"), | ||
| 1068 | + Emoji(glyph: "🌌", name: "milky way", group: "Travel & Places"), | ||
| 1069 | + Emoji(glyph: "☁️", name: "cloud", group: "Travel & Places"), | ||
| 1070 | + Emoji(glyph: "⛅", name: "sun behind cloud", group: "Travel & Places"), | ||
| 1071 | + Emoji(glyph: "⛈️", name: "cloud with lightning and rain", group: "Travel & Places"), | ||
| 1072 | + Emoji(glyph: "🌤️", name: "sun behind small cloud", group: "Travel & Places"), | ||
| 1073 | + Emoji(glyph: "🌥️", name: "sun behind large cloud", group: "Travel & Places"), | ||
| 1074 | + Emoji(glyph: "🌦️", name: "sun behind rain cloud", group: "Travel & Places"), | ||
| 1075 | + Emoji(glyph: "🌧️", name: "cloud with rain", group: "Travel & Places"), | ||
| 1076 | + Emoji(glyph: "🌨️", name: "cloud with snow", group: "Travel & Places"), | ||
| 1077 | + Emoji(glyph: "🌩️", name: "cloud with lightning", group: "Travel & Places"), | ||
| 1078 | + Emoji(glyph: "🌪️", name: "tornado", group: "Travel & Places"), | ||
| 1079 | + Emoji(glyph: "🌫️", name: "fog", group: "Travel & Places"), | ||
| 1080 | + Emoji(glyph: "🌬️", name: "wind face", group: "Travel & Places"), | ||
| 1081 | + Emoji(glyph: "🌀", name: "cyclone", group: "Travel & Places"), | ||
| 1082 | + Emoji(glyph: "🌈", name: "rainbow", group: "Travel & Places"), | ||
| 1083 | + Emoji(glyph: "🌂", name: "closed umbrella", group: "Travel & Places"), | ||
| 1084 | + Emoji(glyph: "☂️", name: "umbrella", group: "Travel & Places"), | ||
| 1085 | + Emoji(glyph: "☔", name: "umbrella with rain drops", group: "Travel & Places"), | ||
| 1086 | + Emoji(glyph: "⛱️", name: "umbrella on ground", group: "Travel & Places"), | ||
| 1087 | + Emoji(glyph: "⚡", name: "high voltage", group: "Travel & Places"), | ||
| 1088 | + Emoji(glyph: "❄️", name: "snowflake", group: "Travel & Places"), | ||
| 1089 | + Emoji(glyph: "☃️", name: "snowman", group: "Travel & Places"), | ||
| 1090 | + Emoji(glyph: "⛄", name: "snowman without snow", group: "Travel & Places"), | ||
| 1091 | + Emoji(glyph: "☄️", name: "comet", group: "Travel & Places"), | ||
| 1092 | + Emoji(glyph: "🔥", name: "fire", group: "Travel & Places"), | ||
| 1093 | + Emoji(glyph: "💧", name: "droplet", group: "Travel & Places"), | ||
| 1094 | + Emoji(glyph: "🌊", name: "water wave", group: "Travel & Places"), | ||
| 1095 | + Emoji(glyph: "🎃", name: "jack-o-lantern", group: "Activities"), | ||
| 1096 | + Emoji(glyph: "🎄", name: "Christmas tree", group: "Activities"), | ||
| 1097 | + Emoji(glyph: "🎆", name: "fireworks", group: "Activities"), | ||
| 1098 | + Emoji(glyph: "🎇", name: "sparkler", group: "Activities"), | ||
| 1099 | + Emoji(glyph: "🧨", name: "firecracker", group: "Activities"), | ||
| 1100 | + Emoji(glyph: "✨", name: "sparkles", group: "Activities"), | ||
| 1101 | + Emoji(glyph: "🎈", name: "balloon", group: "Activities"), | ||
| 1102 | + Emoji(glyph: "🎉", name: "party popper", group: "Activities"), | ||
| 1103 | + Emoji(glyph: "🎊", name: "confetti ball", group: "Activities"), | ||
| 1104 | + Emoji(glyph: "🎋", name: "tanabata tree", group: "Activities"), | ||
| 1105 | + Emoji(glyph: "🎍", name: "pine decoration", group: "Activities"), | ||
| 1106 | + Emoji(glyph: "🎎", name: "Japanese dolls", group: "Activities"), | ||
| 1107 | + Emoji(glyph: "🎏", name: "carp streamer", group: "Activities"), | ||
| 1108 | + Emoji(glyph: "🎐", name: "wind chime", group: "Activities"), | ||
| 1109 | + Emoji(glyph: "🎑", name: "moon viewing ceremony", group: "Activities"), | ||
| 1110 | + Emoji(glyph: "🧧", name: "red envelope", group: "Activities"), | ||
| 1111 | + Emoji(glyph: "🎀", name: "ribbon", group: "Activities"), | ||
| 1112 | + Emoji(glyph: "🎁", name: "wrapped gift", group: "Activities"), | ||
| 1113 | + Emoji(glyph: "🎗️", name: "reminder ribbon", group: "Activities"), | ||
| 1114 | + Emoji(glyph: "🎟️", name: "admission tickets", group: "Activities"), | ||
| 1115 | + Emoji(glyph: "🎫", name: "ticket", group: "Activities"), | ||
| 1116 | + Emoji(glyph: "🎖️", name: "military medal", group: "Activities"), | ||
| 1117 | + Emoji(glyph: "🏆", name: "trophy", group: "Activities"), | ||
| 1118 | + Emoji(glyph: "🏅", name: "sports medal", group: "Activities"), | ||
| 1119 | + Emoji(glyph: "🥇", name: "1st place medal", group: "Activities"), | ||
| 1120 | + Emoji(glyph: "🥈", name: "2nd place medal", group: "Activities"), | ||
| 1121 | + Emoji(glyph: "🥉", name: "3rd place medal", group: "Activities"), | ||
| 1122 | + Emoji(glyph: "⚽", name: "soccer ball", group: "Activities"), | ||
| 1123 | + Emoji(glyph: "⚾", name: "baseball", group: "Activities"), | ||
| 1124 | + Emoji(glyph: "🥎", name: "softball", group: "Activities"), | ||
| 1125 | + Emoji(glyph: "🏀", name: "basketball", group: "Activities"), | ||
| 1126 | + Emoji(glyph: "🏐", name: "volleyball", group: "Activities"), | ||
| 1127 | + Emoji(glyph: "🏈", name: "american football", group: "Activities"), | ||
| 1128 | + Emoji(glyph: "🏉", name: "rugby football", group: "Activities"), | ||
| 1129 | + Emoji(glyph: "🎾", name: "tennis", group: "Activities"), | ||
| 1130 | + Emoji(glyph: "🥏", name: "flying disc", group: "Activities"), | ||
| 1131 | + Emoji(glyph: "🎳", name: "bowling", group: "Activities"), | ||
| 1132 | + Emoji(glyph: "🏏", name: "cricket game", group: "Activities"), | ||
| 1133 | + Emoji(glyph: "🏑", name: "field hockey", group: "Activities"), | ||
| 1134 | + Emoji(glyph: "🏒", name: "ice hockey", group: "Activities"), | ||
| 1135 | + Emoji(glyph: "🥍", name: "lacrosse", group: "Activities"), | ||
| 1136 | + Emoji(glyph: "🏓", name: "ping pong", group: "Activities"), | ||
| 1137 | + Emoji(glyph: "🏸", name: "badminton", group: "Activities"), | ||
| 1138 | + Emoji(glyph: "🥊", name: "boxing glove", group: "Activities"), | ||
| 1139 | + Emoji(glyph: "🥋", name: "martial arts uniform", group: "Activities"), | ||
| 1140 | + Emoji(glyph: "🥅", name: "goal net", group: "Activities"), | ||
| 1141 | + Emoji(glyph: "⛳", name: "flag in hole", group: "Activities"), | ||
| 1142 | + Emoji(glyph: "⛸️", name: "ice skate", group: "Activities"), | ||
| 1143 | + Emoji(glyph: "🎣", name: "fishing pole", group: "Activities"), | ||
| 1144 | + Emoji(glyph: "🤿", name: "diving mask", group: "Activities"), | ||
| 1145 | + Emoji(glyph: "🎽", name: "running shirt", group: "Activities"), | ||
| 1146 | + Emoji(glyph: "🎿", name: "skis", group: "Activities"), | ||
| 1147 | + Emoji(glyph: "🛷", name: "sled", group: "Activities"), | ||
| 1148 | + Emoji(glyph: "🥌", name: "curling stone", group: "Activities"), | ||
| 1149 | + Emoji(glyph: "🎯", name: "bullseye", group: "Activities"), | ||
| 1150 | + Emoji(glyph: "🪀", name: "yo-yo", group: "Activities"), | ||
| 1151 | + Emoji(glyph: "🪁", name: "kite", group: "Activities"), | ||
| 1152 | + Emoji(glyph: "🔫", name: "water pistol", group: "Activities"), | ||
| 1153 | + Emoji(glyph: "🎱", name: "pool 8 ball", group: "Activities"), | ||
| 1154 | + Emoji(glyph: "🔮", name: "crystal ball", group: "Activities"), | ||
| 1155 | + Emoji(glyph: "🪄", name: "magic wand", group: "Activities"), | ||
| 1156 | + Emoji(glyph: "🎮", name: "video game", group: "Activities"), | ||
| 1157 | + Emoji(glyph: "🕹️", name: "joystick", group: "Activities"), | ||
| 1158 | + Emoji(glyph: "🎰", name: "slot machine", group: "Activities"), | ||
| 1159 | + Emoji(glyph: "🎲", name: "game die", group: "Activities"), | ||
| 1160 | + Emoji(glyph: "🧩", name: "puzzle piece", group: "Activities"), | ||
| 1161 | + Emoji(glyph: "🧸", name: "teddy bear", group: "Activities"), | ||
| 1162 | + Emoji(glyph: "🪅", name: "piñata", group: "Activities"), | ||
| 1163 | + Emoji(glyph: "🪩", name: "mirror ball", group: "Activities"), | ||
| 1164 | + Emoji(glyph: "🪆", name: "nesting dolls", group: "Activities"), | ||
| 1165 | + Emoji(glyph: "♠️", name: "spade suit", group: "Activities"), | ||
| 1166 | + Emoji(glyph: "♥️", name: "heart suit", group: "Activities"), | ||
| 1167 | + Emoji(glyph: "♦️", name: "diamond suit", group: "Activities"), | ||
| 1168 | + Emoji(glyph: "♣️", name: "club suit", group: "Activities"), | ||
| 1169 | + Emoji(glyph: "♟️", name: "chess pawn", group: "Activities"), | ||
| 1170 | + Emoji(glyph: "🃏", name: "joker", group: "Activities"), | ||
| 1171 | + Emoji(glyph: "🀄", name: "mahjong red dragon", group: "Activities"), | ||
| 1172 | + Emoji(glyph: "🎴", name: "flower playing cards", group: "Activities"), | ||
| 1173 | + Emoji(glyph: "🎭", name: "performing arts", group: "Activities"), | ||
| 1174 | + Emoji(glyph: "🖼️", name: "framed picture", group: "Activities"), | ||
| 1175 | + Emoji(glyph: "🎨", name: "artist palette", group: "Activities"), | ||
| 1176 | + Emoji(glyph: "🧵", name: "thread", group: "Activities"), | ||
| 1177 | + Emoji(glyph: "🪡", name: "sewing needle", group: "Activities"), | ||
| 1178 | + Emoji(glyph: "🧶", name: "yarn", group: "Activities"), | ||
| 1179 | + Emoji(glyph: "🪢", name: "knot", group: "Activities"), | ||
| 1180 | + Emoji(glyph: "👓", name: "glasses", group: "Objects"), | ||
| 1181 | + Emoji(glyph: "🕶️", name: "sunglasses", group: "Objects"), | ||
| 1182 | + Emoji(glyph: "🥽", name: "goggles", group: "Objects"), | ||
| 1183 | + Emoji(glyph: "🥼", name: "lab coat", group: "Objects"), | ||
| 1184 | + Emoji(glyph: "🦺", name: "safety vest", group: "Objects"), | ||
| 1185 | + Emoji(glyph: "👔", name: "necktie", group: "Objects"), | ||
| 1186 | + Emoji(glyph: "👕", name: "t-shirt", group: "Objects"), | ||
| 1187 | + Emoji(glyph: "👖", name: "jeans", group: "Objects"), | ||
| 1188 | + Emoji(glyph: "🧣", name: "scarf", group: "Objects"), | ||
| 1189 | + Emoji(glyph: "🧤", name: "gloves", group: "Objects"), | ||
| 1190 | + Emoji(glyph: "🧥", name: "coat", group: "Objects"), | ||
| 1191 | + Emoji(glyph: "🧦", name: "socks", group: "Objects"), | ||
| 1192 | + Emoji(glyph: "👗", name: "dress", group: "Objects"), | ||
| 1193 | + Emoji(glyph: "👘", name: "kimono", group: "Objects"), | ||
| 1194 | + Emoji(glyph: "🥻", name: "sari", group: "Objects"), | ||
| 1195 | + Emoji(glyph: "🩱", name: "one-piece swimsuit", group: "Objects"), | ||
| 1196 | + Emoji(glyph: "🩲", name: "briefs", group: "Objects"), | ||
| 1197 | + Emoji(glyph: "🩳", name: "shorts", group: "Objects"), | ||
| 1198 | + Emoji(glyph: "👙", name: "bikini", group: "Objects"), | ||
| 1199 | + Emoji(glyph: "👚", name: "woman’s clothes", group: "Objects"), | ||
| 1200 | + Emoji(glyph: "🪭", name: "folding hand fan", group: "Objects"), | ||
| 1201 | + Emoji(glyph: "👛", name: "purse", group: "Objects"), | ||
| 1202 | + Emoji(glyph: "👜", name: "handbag", group: "Objects"), | ||
| 1203 | + Emoji(glyph: "👝", name: "clutch bag", group: "Objects"), | ||
| 1204 | + Emoji(glyph: "🛍️", name: "shopping bags", group: "Objects"), | ||
| 1205 | + Emoji(glyph: "🎒", name: "backpack", group: "Objects"), | ||
| 1206 | + Emoji(glyph: "🩴", name: "thong sandal", group: "Objects"), | ||
| 1207 | + Emoji(glyph: "👞", name: "man’s shoe", group: "Objects"), | ||
| 1208 | + Emoji(glyph: "👟", name: "running shoe", group: "Objects"), | ||
| 1209 | + Emoji(glyph: "🥾", name: "hiking boot", group: "Objects"), | ||
| 1210 | + Emoji(glyph: "🥿", name: "flat shoe", group: "Objects"), | ||
| 1211 | + Emoji(glyph: "👠", name: "high-heeled shoe", group: "Objects"), | ||
| 1212 | + Emoji(glyph: "👡", name: "woman’s sandal", group: "Objects"), | ||
| 1213 | + Emoji(glyph: "🩰", name: "ballet shoes", group: "Objects"), | ||
| 1214 | + Emoji(glyph: "👢", name: "woman’s boot", group: "Objects"), | ||
| 1215 | + Emoji(glyph: "🪮", name: "hair pick", group: "Objects"), | ||
| 1216 | + Emoji(glyph: "👑", name: "crown", group: "Objects"), | ||
| 1217 | + Emoji(glyph: "👒", name: "woman’s hat", group: "Objects"), | ||
| 1218 | + Emoji(glyph: "🎩", name: "top hat", group: "Objects"), | ||
| 1219 | + Emoji(glyph: "🎓", name: "graduation cap", group: "Objects"), | ||
| 1220 | + Emoji(glyph: "🧢", name: "billed cap", group: "Objects"), | ||
| 1221 | + Emoji(glyph: "🪖", name: "military helmet", group: "Objects"), | ||
| 1222 | + Emoji(glyph: "⛑️", name: "rescue worker’s helmet", group: "Objects"), | ||
| 1223 | + Emoji(glyph: "📿", name: "prayer beads", group: "Objects"), | ||
| 1224 | + Emoji(glyph: "💄", name: "lipstick", group: "Objects"), | ||
| 1225 | + Emoji(glyph: "💍", name: "ring", group: "Objects"), | ||
| 1226 | + Emoji(glyph: "💎", name: "gem stone", group: "Objects"), | ||
| 1227 | + Emoji(glyph: "🔇", name: "muted speaker", group: "Objects"), | ||
| 1228 | + Emoji(glyph: "🔈", name: "speaker low volume", group: "Objects"), | ||
| 1229 | + Emoji(glyph: "🔉", name: "speaker medium volume", group: "Objects"), | ||
| 1230 | + Emoji(glyph: "🔊", name: "speaker high volume", group: "Objects"), | ||
| 1231 | + Emoji(glyph: "📢", name: "loudspeaker", group: "Objects"), | ||
| 1232 | + Emoji(glyph: "📣", name: "megaphone", group: "Objects"), | ||
| 1233 | + Emoji(glyph: "📯", name: "postal horn", group: "Objects"), | ||
| 1234 | + Emoji(glyph: "🔔", name: "bell", group: "Objects"), | ||
| 1235 | + Emoji(glyph: "🔕", name: "bell with slash", group: "Objects"), | ||
| 1236 | + Emoji(glyph: "🎼", name: "musical score", group: "Objects"), | ||
| 1237 | + Emoji(glyph: "🎵", name: "musical note", group: "Objects"), | ||
| 1238 | + Emoji(glyph: "🎶", name: "musical notes", group: "Objects"), | ||
| 1239 | + Emoji(glyph: "🎙️", name: "studio microphone", group: "Objects"), | ||
| 1240 | + Emoji(glyph: "🎚️", name: "level slider", group: "Objects"), | ||
| 1241 | + Emoji(glyph: "🎛️", name: "control knobs", group: "Objects"), | ||
| 1242 | + Emoji(glyph: "🎤", name: "microphone", group: "Objects"), | ||
| 1243 | + Emoji(glyph: "🎧", name: "headphone", group: "Objects"), | ||
| 1244 | + Emoji(glyph: "📻", name: "radio", group: "Objects"), | ||
| 1245 | + Emoji(glyph: "🎷", name: "saxophone", group: "Objects"), | ||
| 1246 | + Emoji(glyph: "🪗", name: "accordion", group: "Objects"), | ||
| 1247 | + Emoji(glyph: "🎸", name: "guitar", group: "Objects"), | ||
| 1248 | + Emoji(glyph: "🎹", name: "musical keyboard", group: "Objects"), | ||
| 1249 | + Emoji(glyph: "🎺", name: "trumpet", group: "Objects"), | ||
| 1250 | + Emoji(glyph: "🎻", name: "violin", group: "Objects"), | ||
| 1251 | + Emoji(glyph: "🪕", name: "banjo", group: "Objects"), | ||
| 1252 | + Emoji(glyph: "🥁", name: "drum", group: "Objects"), | ||
| 1253 | + Emoji(glyph: "🪘", name: "long drum", group: "Objects"), | ||
| 1254 | + Emoji(glyph: "🪇", name: "maracas", group: "Objects"), | ||
| 1255 | + Emoji(glyph: "🪈", name: "flute", group: "Objects"), | ||
| 1256 | + Emoji(glyph: "📱", name: "mobile phone", group: "Objects"), | ||
| 1257 | + Emoji(glyph: "📲", name: "mobile phone with arrow", group: "Objects"), | ||
| 1258 | + Emoji(glyph: "☎️", name: "telephone", group: "Objects"), | ||
| 1259 | + Emoji(glyph: "📞", name: "telephone receiver", group: "Objects"), | ||
| 1260 | + Emoji(glyph: "📟", name: "pager", group: "Objects"), | ||
| 1261 | + Emoji(glyph: "📠", name: "fax machine", group: "Objects"), | ||
| 1262 | + Emoji(glyph: "🔋", name: "battery", group: "Objects"), | ||
| 1263 | + Emoji(glyph: "🪫", name: "low battery", group: "Objects"), | ||
| 1264 | + Emoji(glyph: "🔌", name: "electric plug", group: "Objects"), | ||
| 1265 | + Emoji(glyph: "💻", name: "laptop", group: "Objects"), | ||
| 1266 | + Emoji(glyph: "🖥️", name: "desktop computer", group: "Objects"), | ||
| 1267 | + Emoji(glyph: "🖨️", name: "printer", group: "Objects"), | ||
| 1268 | + Emoji(glyph: "⌨️", name: "keyboard", group: "Objects"), | ||
| 1269 | + Emoji(glyph: "🖱️", name: "computer mouse", group: "Objects"), | ||
| 1270 | + Emoji(glyph: "🖲️", name: "trackball", group: "Objects"), | ||
| 1271 | + Emoji(glyph: "💽", name: "computer disk", group: "Objects"), | ||
| 1272 | + Emoji(glyph: "💾", name: "floppy disk", group: "Objects"), | ||
| 1273 | + Emoji(glyph: "💿", name: "optical disk", group: "Objects"), | ||
| 1274 | + Emoji(glyph: "📀", name: "dvd", group: "Objects"), | ||
| 1275 | + Emoji(glyph: "🧮", name: "abacus", group: "Objects"), | ||
| 1276 | + Emoji(glyph: "🎥", name: "movie camera", group: "Objects"), | ||
| 1277 | + Emoji(glyph: "🎞️", name: "film frames", group: "Objects"), | ||
| 1278 | + Emoji(glyph: "📽️", name: "film projector", group: "Objects"), | ||
| 1279 | + Emoji(glyph: "🎬", name: "clapper board", group: "Objects"), | ||
| 1280 | + Emoji(glyph: "📺", name: "television", group: "Objects"), | ||
| 1281 | + Emoji(glyph: "📷", name: "camera", group: "Objects"), | ||
| 1282 | + Emoji(glyph: "📸", name: "camera with flash", group: "Objects"), | ||
| 1283 | + Emoji(glyph: "📹", name: "video camera", group: "Objects"), | ||
| 1284 | + Emoji(glyph: "📼", name: "videocassette", group: "Objects"), | ||
| 1285 | + Emoji(glyph: "🔍", name: "magnifying glass tilted left", group: "Objects"), | ||
| 1286 | + Emoji(glyph: "🔎", name: "magnifying glass tilted right", group: "Objects"), | ||
| 1287 | + Emoji(glyph: "🕯️", name: "candle", group: "Objects"), | ||
| 1288 | + Emoji(glyph: "💡", name: "light bulb", group: "Objects"), | ||
| 1289 | + Emoji(glyph: "🔦", name: "flashlight", group: "Objects"), | ||
| 1290 | + Emoji(glyph: "🏮", name: "red paper lantern", group: "Objects"), | ||
| 1291 | + Emoji(glyph: "🪔", name: "diya lamp", group: "Objects"), | ||
| 1292 | + Emoji(glyph: "📔", name: "notebook with decorative cover", group: "Objects"), | ||
| 1293 | + Emoji(glyph: "📕", name: "closed book", group: "Objects"), | ||
| 1294 | + Emoji(glyph: "📖", name: "open book", group: "Objects"), | ||
| 1295 | + Emoji(glyph: "📗", name: "green book", group: "Objects"), | ||
| 1296 | + Emoji(glyph: "📘", name: "blue book", group: "Objects"), | ||
| 1297 | + Emoji(glyph: "📙", name: "orange book", group: "Objects"), | ||
| 1298 | + Emoji(glyph: "📚", name: "books", group: "Objects"), | ||
| 1299 | + Emoji(glyph: "📓", name: "notebook", group: "Objects"), | ||
| 1300 | + Emoji(glyph: "📒", name: "ledger", group: "Objects"), | ||
| 1301 | + Emoji(glyph: "📃", name: "page with curl", group: "Objects"), | ||
| 1302 | + Emoji(glyph: "📜", name: "scroll", group: "Objects"), | ||
| 1303 | + Emoji(glyph: "📄", name: "page facing up", group: "Objects"), | ||
| 1304 | + Emoji(glyph: "📰", name: "newspaper", group: "Objects"), | ||
| 1305 | + Emoji(glyph: "🗞️", name: "rolled-up newspaper", group: "Objects"), | ||
| 1306 | + Emoji(glyph: "📑", name: "bookmark tabs", group: "Objects"), | ||
| 1307 | + Emoji(glyph: "🔖", name: "bookmark", group: "Objects"), | ||
| 1308 | + Emoji(glyph: "🏷️", name: "label", group: "Objects"), | ||
| 1309 | + Emoji(glyph: "💰", name: "money bag", group: "Objects"), | ||
| 1310 | + Emoji(glyph: "🪙", name: "coin", group: "Objects"), | ||
| 1311 | + Emoji(glyph: "💴", name: "yen banknote", group: "Objects"), | ||
| 1312 | + Emoji(glyph: "💵", name: "dollar banknote", group: "Objects"), | ||
| 1313 | + Emoji(glyph: "💶", name: "euro banknote", group: "Objects"), | ||
| 1314 | + Emoji(glyph: "💷", name: "pound banknote", group: "Objects"), | ||
| 1315 | + Emoji(glyph: "💸", name: "money with wings", group: "Objects"), | ||
| 1316 | + Emoji(glyph: "💳", name: "credit card", group: "Objects"), | ||
| 1317 | + Emoji(glyph: "🧾", name: "receipt", group: "Objects"), | ||
| 1318 | + Emoji(glyph: "💹", name: "chart increasing with yen", group: "Objects"), | ||
| 1319 | + Emoji(glyph: "✉️", name: "envelope", group: "Objects"), | ||
| 1320 | + Emoji(glyph: "📧", name: "e-mail", group: "Objects"), | ||
| 1321 | + Emoji(glyph: "📨", name: "incoming envelope", group: "Objects"), | ||
| 1322 | + Emoji(glyph: "📩", name: "envelope with arrow", group: "Objects"), | ||
| 1323 | + Emoji(glyph: "📤", name: "outbox tray", group: "Objects"), | ||
| 1324 | + Emoji(glyph: "📥", name: "inbox tray", group: "Objects"), | ||
| 1325 | + Emoji(glyph: "📦", name: "package", group: "Objects"), | ||
| 1326 | + Emoji(glyph: "📫", name: "closed mailbox with raised flag", group: "Objects"), | ||
| 1327 | + Emoji(glyph: "📪", name: "closed mailbox with lowered flag", group: "Objects"), | ||
| 1328 | + Emoji(glyph: "📬", name: "open mailbox with raised flag", group: "Objects"), | ||
| 1329 | + Emoji(glyph: "📭", name: "open mailbox with lowered flag", group: "Objects"), | ||
| 1330 | + Emoji(glyph: "📮", name: "postbox", group: "Objects"), | ||
| 1331 | + Emoji(glyph: "🗳️", name: "ballot box with ballot", group: "Objects"), | ||
| 1332 | + Emoji(glyph: "✏️", name: "pencil", group: "Objects"), | ||
| 1333 | + Emoji(glyph: "✒️", name: "black nib", group: "Objects"), | ||
| 1334 | + Emoji(glyph: "🖋️", name: "fountain pen", group: "Objects"), | ||
| 1335 | + Emoji(glyph: "🖊️", name: "pen", group: "Objects"), | ||
| 1336 | + Emoji(glyph: "🖌️", name: "paintbrush", group: "Objects"), | ||
| 1337 | + Emoji(glyph: "🖍️", name: "crayon", group: "Objects"), | ||
| 1338 | + Emoji(glyph: "📝", name: "memo", group: "Objects"), | ||
| 1339 | + Emoji(glyph: "💼", name: "briefcase", group: "Objects"), | ||
| 1340 | + Emoji(glyph: "📁", name: "file folder", group: "Objects"), | ||
| 1341 | + Emoji(glyph: "📂", name: "open file folder", group: "Objects"), | ||
| 1342 | + Emoji(glyph: "🗂️", name: "card index dividers", group: "Objects"), | ||
| 1343 | + Emoji(glyph: "📅", name: "calendar", group: "Objects"), | ||
| 1344 | + Emoji(glyph: "📆", name: "tear-off calendar", group: "Objects"), | ||
| 1345 | + Emoji(glyph: "🗒️", name: "spiral notepad", group: "Objects"), | ||
| 1346 | + Emoji(glyph: "🗓️", name: "spiral calendar", group: "Objects"), | ||
| 1347 | + Emoji(glyph: "📇", name: "card index", group: "Objects"), | ||
| 1348 | + Emoji(glyph: "📈", name: "chart increasing", group: "Objects"), | ||
| 1349 | + Emoji(glyph: "📉", name: "chart decreasing", group: "Objects"), | ||
| 1350 | + Emoji(glyph: "📊", name: "bar chart", group: "Objects"), | ||
| 1351 | + Emoji(glyph: "📋", name: "clipboard", group: "Objects"), | ||
| 1352 | + Emoji(glyph: "📌", name: "pushpin", group: "Objects"), | ||
| 1353 | + Emoji(glyph: "📍", name: "round pushpin", group: "Objects"), | ||
| 1354 | + Emoji(glyph: "📎", name: "paperclip", group: "Objects"), | ||
| 1355 | + Emoji(glyph: "🖇️", name: "linked paperclips", group: "Objects"), | ||
| 1356 | + Emoji(glyph: "📏", name: "straight ruler", group: "Objects"), | ||
| 1357 | + Emoji(glyph: "📐", name: "triangular ruler", group: "Objects"), | ||
| 1358 | + Emoji(glyph: "✂️", name: "scissors", group: "Objects"), | ||
| 1359 | + Emoji(glyph: "🗃️", name: "card file box", group: "Objects"), | ||
| 1360 | + Emoji(glyph: "🗄️", name: "file cabinet", group: "Objects"), | ||
| 1361 | + Emoji(glyph: "🗑️", name: "wastebasket", group: "Objects"), | ||
| 1362 | + Emoji(glyph: "🔒", name: "locked", group: "Objects"), | ||
| 1363 | + Emoji(glyph: "🔓", name: "unlocked", group: "Objects"), | ||
| 1364 | + Emoji(glyph: "🔏", name: "locked with pen", group: "Objects"), | ||
| 1365 | + Emoji(glyph: "🔐", name: "locked with key", group: "Objects"), | ||
| 1366 | + Emoji(glyph: "🔑", name: "key", group: "Objects"), | ||
| 1367 | + Emoji(glyph: "🗝️", name: "old key", group: "Objects"), | ||
| 1368 | + Emoji(glyph: "🔨", name: "hammer", group: "Objects"), | ||
| 1369 | + Emoji(glyph: "🪓", name: "axe", group: "Objects"), | ||
| 1370 | + Emoji(glyph: "⛏️", name: "pick", group: "Objects"), | ||
| 1371 | + Emoji(glyph: "⚒️", name: "hammer and pick", group: "Objects"), | ||
| 1372 | + Emoji(glyph: "🛠️", name: "hammer and wrench", group: "Objects"), | ||
| 1373 | + Emoji(glyph: "🗡️", name: "dagger", group: "Objects"), | ||
| 1374 | + Emoji(glyph: "⚔️", name: "crossed swords", group: "Objects"), | ||
| 1375 | + Emoji(glyph: "💣", name: "bomb", group: "Objects"), | ||
| 1376 | + Emoji(glyph: "🪃", name: "boomerang", group: "Objects"), | ||
| 1377 | + Emoji(glyph: "🏹", name: "bow and arrow", group: "Objects"), | ||
| 1378 | + Emoji(glyph: "🛡️", name: "shield", group: "Objects"), | ||
| 1379 | + Emoji(glyph: "🪚", name: "carpentry saw", group: "Objects"), | ||
| 1380 | + Emoji(glyph: "🔧", name: "wrench", group: "Objects"), | ||
| 1381 | + Emoji(glyph: "🪛", name: "screwdriver", group: "Objects"), | ||
| 1382 | + Emoji(glyph: "🔩", name: "nut and bolt", group: "Objects"), | ||
| 1383 | + Emoji(glyph: "⚙️", name: "gear", group: "Objects"), | ||
| 1384 | + Emoji(glyph: "🗜️", name: "clamp", group: "Objects"), | ||
| 1385 | + Emoji(glyph: "⚖️", name: "balance scale", group: "Objects"), | ||
| 1386 | + Emoji(glyph: "🦯", name: "white cane", group: "Objects"), | ||
| 1387 | + Emoji(glyph: "🔗", name: "link", group: "Objects"), | ||
| 1388 | + Emoji(glyph: "⛓️💥", name: "broken chain", group: "Objects"), | ||
| 1389 | + Emoji(glyph: "⛓️", name: "chains", group: "Objects"), | ||
| 1390 | + Emoji(glyph: "🪝", name: "hook", group: "Objects"), | ||
| 1391 | + Emoji(glyph: "🧰", name: "toolbox", group: "Objects"), | ||
| 1392 | + Emoji(glyph: "🧲", name: "magnet", group: "Objects"), | ||
| 1393 | + Emoji(glyph: "🪜", name: "ladder", group: "Objects"), | ||
| 1394 | + Emoji(glyph: "⚗️", name: "alembic", group: "Objects"), | ||
| 1395 | + Emoji(glyph: "🧪", name: "test tube", group: "Objects"), | ||
| 1396 | + Emoji(glyph: "🧫", name: "petri dish", group: "Objects"), | ||
| 1397 | + Emoji(glyph: "🧬", name: "dna", group: "Objects"), | ||
| 1398 | + Emoji(glyph: "🔬", name: "microscope", group: "Objects"), | ||
| 1399 | + Emoji(glyph: "🔭", name: "telescope", group: "Objects"), | ||
| 1400 | + Emoji(glyph: "📡", name: "satellite antenna", group: "Objects"), | ||
| 1401 | + Emoji(glyph: "💉", name: "syringe", group: "Objects"), | ||
| 1402 | + Emoji(glyph: "🩸", name: "drop of blood", group: "Objects"), | ||
| 1403 | + Emoji(glyph: "💊", name: "pill", group: "Objects"), | ||
| 1404 | + Emoji(glyph: "🩹", name: "adhesive bandage", group: "Objects"), | ||
| 1405 | + Emoji(glyph: "🩼", name: "crutch", group: "Objects"), | ||
| 1406 | + Emoji(glyph: "🩺", name: "stethoscope", group: "Objects"), | ||
| 1407 | + Emoji(glyph: "🩻", name: "x-ray", group: "Objects"), | ||
| 1408 | + Emoji(glyph: "🚪", name: "door", group: "Objects"), | ||
| 1409 | + Emoji(glyph: "🛗", name: "elevator", group: "Objects"), | ||
| 1410 | + Emoji(glyph: "🪞", name: "mirror", group: "Objects"), | ||
| 1411 | + Emoji(glyph: "🪟", name: "window", group: "Objects"), | ||
| 1412 | + Emoji(glyph: "🛏️", name: "bed", group: "Objects"), | ||
| 1413 | + Emoji(glyph: "🛋️", name: "couch and lamp", group: "Objects"), | ||
| 1414 | + Emoji(glyph: "🪑", name: "chair", group: "Objects"), | ||
| 1415 | + Emoji(glyph: "🚽", name: "toilet", group: "Objects"), | ||
| 1416 | + Emoji(glyph: "🪠", name: "plunger", group: "Objects"), | ||
| 1417 | + Emoji(glyph: "🚿", name: "shower", group: "Objects"), | ||
| 1418 | + Emoji(glyph: "🛁", name: "bathtub", group: "Objects"), | ||
| 1419 | + Emoji(glyph: "🪤", name: "mouse trap", group: "Objects"), | ||
| 1420 | + Emoji(glyph: "🪒", name: "razor", group: "Objects"), | ||
| 1421 | + Emoji(glyph: "🧴", name: "lotion bottle", group: "Objects"), | ||
| 1422 | + Emoji(glyph: "🧷", name: "safety pin", group: "Objects"), | ||
| 1423 | + Emoji(glyph: "🧹", name: "broom", group: "Objects"), | ||
| 1424 | + Emoji(glyph: "🧺", name: "basket", group: "Objects"), | ||
| 1425 | + Emoji(glyph: "🧻", name: "roll of paper", group: "Objects"), | ||
| 1426 | + Emoji(glyph: "🪣", name: "bucket", group: "Objects"), | ||
| 1427 | + Emoji(glyph: "🧼", name: "soap", group: "Objects"), | ||
| 1428 | + Emoji(glyph: "🫧", name: "bubbles", group: "Objects"), | ||
| 1429 | + Emoji(glyph: "🪥", name: "toothbrush", group: "Objects"), | ||
| 1430 | + Emoji(glyph: "🧽", name: "sponge", group: "Objects"), | ||
| 1431 | + Emoji(glyph: "🧯", name: "fire extinguisher", group: "Objects"), | ||
| 1432 | + Emoji(glyph: "🛒", name: "shopping cart", group: "Objects"), | ||
| 1433 | + Emoji(glyph: "🚬", name: "cigarette", group: "Objects"), | ||
| 1434 | + Emoji(glyph: "⚰️", name: "coffin", group: "Objects"), | ||
| 1435 | + Emoji(glyph: "🪦", name: "headstone", group: "Objects"), | ||
| 1436 | + Emoji(glyph: "⚱️", name: "funeral urn", group: "Objects"), | ||
| 1437 | + Emoji(glyph: "🧿", name: "nazar amulet", group: "Objects"), | ||
| 1438 | + Emoji(glyph: "🪬", name: "hamsa", group: "Objects"), | ||
| 1439 | + Emoji(glyph: "🗿", name: "moai", group: "Objects"), | ||
| 1440 | + Emoji(glyph: "🪧", name: "placard", group: "Objects"), | ||
| 1441 | + Emoji(glyph: "🪪", name: "identification card", group: "Objects"), | ||
| 1442 | + Emoji(glyph: "🏧", name: "ATM sign", group: "Symbols"), | ||
| 1443 | + Emoji(glyph: "🚮", name: "litter in bin sign", group: "Symbols"), | ||
| 1444 | + Emoji(glyph: "🚰", name: "potable water", group: "Symbols"), | ||
| 1445 | + Emoji(glyph: "♿", name: "wheelchair symbol", group: "Symbols"), | ||
| 1446 | + Emoji(glyph: "🚹", name: "men’s room", group: "Symbols"), | ||
| 1447 | + Emoji(glyph: "🚺", name: "women’s room", group: "Symbols"), | ||
| 1448 | + Emoji(glyph: "🚻", name: "restroom", group: "Symbols"), | ||
| 1449 | + Emoji(glyph: "🚼", name: "baby symbol", group: "Symbols"), | ||
| 1450 | + Emoji(glyph: "🚾", name: "water closet", group: "Symbols"), | ||
| 1451 | + Emoji(glyph: "🛂", name: "passport control", group: "Symbols"), | ||
| 1452 | + Emoji(glyph: "🛃", name: "customs", group: "Symbols"), | ||
| 1453 | + Emoji(glyph: "🛄", name: "baggage claim", group: "Symbols"), | ||
| 1454 | + Emoji(glyph: "🛅", name: "left luggage", group: "Symbols"), | ||
| 1455 | + Emoji(glyph: "⚠️", name: "warning", group: "Symbols"), | ||
| 1456 | + Emoji(glyph: "🚸", name: "children crossing", group: "Symbols"), | ||
| 1457 | + Emoji(glyph: "⛔", name: "no entry", group: "Symbols"), | ||
| 1458 | + Emoji(glyph: "🚫", name: "prohibited", group: "Symbols"), | ||
| 1459 | + Emoji(glyph: "🚳", name: "no bicycles", group: "Symbols"), | ||
| 1460 | + Emoji(glyph: "🚭", name: "no smoking", group: "Symbols"), | ||
| 1461 | + Emoji(glyph: "🚯", name: "no littering", group: "Symbols"), | ||
| 1462 | + Emoji(glyph: "🚱", name: "non-potable water", group: "Symbols"), | ||
| 1463 | + Emoji(glyph: "🚷", name: "no pedestrians", group: "Symbols"), | ||
| 1464 | + Emoji(glyph: "📵", name: "no mobile phones", group: "Symbols"), | ||
| 1465 | + Emoji(glyph: "🔞", name: "no one under eighteen", group: "Symbols"), | ||
| 1466 | + Emoji(glyph: "☢️", name: "radioactive", group: "Symbols"), | ||
| 1467 | + Emoji(glyph: "☣️", name: "biohazard", group: "Symbols"), | ||
| 1468 | + Emoji(glyph: "⬆️", name: "up arrow", group: "Symbols"), | ||
| 1469 | + Emoji(glyph: "↗️", name: "up-right arrow", group: "Symbols"), | ||
| 1470 | + Emoji(glyph: "➡️", name: "right arrow", group: "Symbols"), | ||
| 1471 | + Emoji(glyph: "↘️", name: "down-right arrow", group: "Symbols"), | ||
| 1472 | + Emoji(glyph: "⬇️", name: "down arrow", group: "Symbols"), | ||
| 1473 | + Emoji(glyph: "↙️", name: "down-left arrow", group: "Symbols"), | ||
| 1474 | + Emoji(glyph: "⬅️", name: "left arrow", group: "Symbols"), | ||
| 1475 | + Emoji(glyph: "↖️", name: "up-left arrow", group: "Symbols"), | ||
| 1476 | + Emoji(glyph: "↕️", name: "up-down arrow", group: "Symbols"), | ||
| 1477 | + Emoji(glyph: "↔️", name: "left-right arrow", group: "Symbols"), | ||
| 1478 | + Emoji(glyph: "↩️", name: "right arrow curving left", group: "Symbols"), | ||
| 1479 | + Emoji(glyph: "↪️", name: "left arrow curving right", group: "Symbols"), | ||
| 1480 | + Emoji(glyph: "⤴️", name: "right arrow curving up", group: "Symbols"), | ||
| 1481 | + Emoji(glyph: "⤵️", name: "right arrow curving down", group: "Symbols"), | ||
| 1482 | + Emoji(glyph: "🔃", name: "clockwise vertical arrows", group: "Symbols"), | ||
| 1483 | + Emoji(glyph: "🔄", name: "counterclockwise arrows button", group: "Symbols"), | ||
| 1484 | + Emoji(glyph: "🔙", name: "BACK arrow", group: "Symbols"), | ||
| 1485 | + Emoji(glyph: "🔚", name: "END arrow", group: "Symbols"), | ||
| 1486 | + Emoji(glyph: "🔛", name: "ON! arrow", group: "Symbols"), | ||
| 1487 | + Emoji(glyph: "🔜", name: "SOON arrow", group: "Symbols"), | ||
| 1488 | + Emoji(glyph: "🔝", name: "TOP arrow", group: "Symbols"), | ||
| 1489 | + Emoji(glyph: "🛐", name: "place of worship", group: "Symbols"), | ||
| 1490 | + Emoji(glyph: "⚛️", name: "atom symbol", group: "Symbols"), | ||
| 1491 | + Emoji(glyph: "🕉️", name: "om", group: "Symbols"), | ||
| 1492 | + Emoji(glyph: "✡️", name: "star of David", group: "Symbols"), | ||
| 1493 | + Emoji(glyph: "☸️", name: "wheel of dharma", group: "Symbols"), | ||
| 1494 | + Emoji(glyph: "☯️", name: "yin yang", group: "Symbols"), | ||
| 1495 | + Emoji(glyph: "✝️", name: "latin cross", group: "Symbols"), | ||
| 1496 | + Emoji(glyph: "☦️", name: "orthodox cross", group: "Symbols"), | ||
| 1497 | + Emoji(glyph: "☪️", name: "star and crescent", group: "Symbols"), | ||
| 1498 | + Emoji(glyph: "☮️", name: "peace symbol", group: "Symbols"), | ||
| 1499 | + Emoji(glyph: "🕎", name: "menorah", group: "Symbols"), | ||
| 1500 | + Emoji(glyph: "🔯", name: "dotted six-pointed star", group: "Symbols"), | ||
| 1501 | + Emoji(glyph: "🪯", name: "khanda", group: "Symbols"), | ||
| 1502 | + Emoji(glyph: "♈", name: "Aries", group: "Symbols"), | ||
| 1503 | + Emoji(glyph: "♉", name: "Taurus", group: "Symbols"), | ||
| 1504 | + Emoji(glyph: "♊", name: "Gemini", group: "Symbols"), | ||
| 1505 | + Emoji(glyph: "♋", name: "Cancer", group: "Symbols"), | ||
| 1506 | + Emoji(glyph: "♌", name: "Leo", group: "Symbols"), | ||
| 1507 | + Emoji(glyph: "♍", name: "Virgo", group: "Symbols"), | ||
| 1508 | + Emoji(glyph: "♎", name: "Libra", group: "Symbols"), | ||
| 1509 | + Emoji(glyph: "♏", name: "Scorpio", group: "Symbols"), | ||
| 1510 | + Emoji(glyph: "♐", name: "Sagittarius", group: "Symbols"), | ||
| 1511 | + Emoji(glyph: "♑", name: "Capricorn", group: "Symbols"), | ||
| 1512 | + Emoji(glyph: "♒", name: "Aquarius", group: "Symbols"), | ||
| 1513 | + Emoji(glyph: "♓", name: "Pisces", group: "Symbols"), | ||
| 1514 | + Emoji(glyph: "⛎", name: "Ophiuchus", group: "Symbols"), | ||
| 1515 | + Emoji(glyph: "🔀", name: "shuffle tracks button", group: "Symbols"), | ||
| 1516 | + Emoji(glyph: "🔁", name: "repeat button", group: "Symbols"), | ||
| 1517 | + Emoji(glyph: "🔂", name: "repeat single button", group: "Symbols"), | ||
| 1518 | + Emoji(glyph: "▶️", name: "play button", group: "Symbols"), | ||
| 1519 | + Emoji(glyph: "⏩", name: "fast-forward button", group: "Symbols"), | ||
| 1520 | + Emoji(glyph: "⏭️", name: "next track button", group: "Symbols"), | ||
| 1521 | + Emoji(glyph: "⏯️", name: "play or pause button", group: "Symbols"), | ||
| 1522 | + Emoji(glyph: "◀️", name: "reverse button", group: "Symbols"), | ||
| 1523 | + Emoji(glyph: "⏪", name: "fast reverse button", group: "Symbols"), | ||
| 1524 | + Emoji(glyph: "⏮️", name: "last track button", group: "Symbols"), | ||
| 1525 | + Emoji(glyph: "🔼", name: "upwards button", group: "Symbols"), | ||
| 1526 | + Emoji(glyph: "⏫", name: "fast up button", group: "Symbols"), | ||
| 1527 | + Emoji(glyph: "🔽", name: "downwards button", group: "Symbols"), | ||
| 1528 | + Emoji(glyph: "⏬", name: "fast down button", group: "Symbols"), | ||
| 1529 | + Emoji(glyph: "⏸️", name: "pause button", group: "Symbols"), | ||
| 1530 | + Emoji(glyph: "⏹️", name: "stop button", group: "Symbols"), | ||
| 1531 | + Emoji(glyph: "⏺️", name: "record button", group: "Symbols"), | ||
| 1532 | + Emoji(glyph: "⏏️", name: "eject button", group: "Symbols"), | ||
| 1533 | + Emoji(glyph: "🎦", name: "cinema", group: "Symbols"), | ||
| 1534 | + Emoji(glyph: "🔅", name: "dim button", group: "Symbols"), | ||
| 1535 | + Emoji(glyph: "🔆", name: "bright button", group: "Symbols"), | ||
| 1536 | + Emoji(glyph: "📶", name: "antenna bars", group: "Symbols"), | ||
| 1537 | + Emoji(glyph: "🛜", name: "wireless", group: "Symbols"), | ||
| 1538 | + Emoji(glyph: "📳", name: "vibration mode", group: "Symbols"), | ||
| 1539 | + Emoji(glyph: "📴", name: "mobile phone off", group: "Symbols"), | ||
| 1540 | + Emoji(glyph: "♀️", name: "female sign", group: "Symbols"), | ||
| 1541 | + Emoji(glyph: "♂️", name: "male sign", group: "Symbols"), | ||
| 1542 | + Emoji(glyph: "⚧️", name: "transgender symbol", group: "Symbols"), | ||
| 1543 | + Emoji(glyph: "✖️", name: "multiply", group: "Symbols"), | ||
| 1544 | + Emoji(glyph: "➕", name: "plus", group: "Symbols"), | ||
| 1545 | + Emoji(glyph: "➖", name: "minus", group: "Symbols"), | ||
| 1546 | + Emoji(glyph: "➗", name: "divide", group: "Symbols"), | ||
| 1547 | + Emoji(glyph: "🟰", name: "heavy equals sign", group: "Symbols"), | ||
| 1548 | + Emoji(glyph: "♾️", name: "infinity", group: "Symbols"), | ||
| 1549 | + Emoji(glyph: "‼️", name: "double exclamation mark", group: "Symbols"), | ||
| 1550 | + Emoji(glyph: "⁉️", name: "exclamation question mark", group: "Symbols"), | ||
| 1551 | + Emoji(glyph: "❓", name: "red question mark", group: "Symbols"), | ||
| 1552 | + Emoji(glyph: "❔", name: "white question mark", group: "Symbols"), | ||
| 1553 | + Emoji(glyph: "❕", name: "white exclamation mark", group: "Symbols"), | ||
| 1554 | + Emoji(glyph: "❗", name: "red exclamation mark", group: "Symbols"), | ||
| 1555 | + Emoji(glyph: "〰️", name: "wavy dash", group: "Symbols"), | ||
| 1556 | + Emoji(glyph: "💱", name: "currency exchange", group: "Symbols"), | ||
| 1557 | + Emoji(glyph: "💲", name: "heavy dollar sign", group: "Symbols"), | ||
| 1558 | + Emoji(glyph: "⚕️", name: "medical symbol", group: "Symbols"), | ||
| 1559 | + Emoji(glyph: "♻️", name: "recycling symbol", group: "Symbols"), | ||
| 1560 | + Emoji(glyph: "⚜️", name: "fleur-de-lis", group: "Symbols"), | ||
| 1561 | + Emoji(glyph: "🔱", name: "trident emblem", group: "Symbols"), | ||
| 1562 | + Emoji(glyph: "📛", name: "name badge", group: "Symbols"), | ||
| 1563 | + Emoji(glyph: "🔰", name: "Japanese symbol for beginner", group: "Symbols"), | ||
| 1564 | + Emoji(glyph: "⭕", name: "hollow red circle", group: "Symbols"), | ||
| 1565 | + Emoji(glyph: "✅", name: "check mark button", group: "Symbols"), | ||
| 1566 | + Emoji(glyph: "☑️", name: "check box with check", group: "Symbols"), | ||
| 1567 | + Emoji(glyph: "✔️", name: "check mark", group: "Symbols"), | ||
| 1568 | + Emoji(glyph: "❌", name: "cross mark", group: "Symbols"), | ||
| 1569 | + Emoji(glyph: "❎", name: "cross mark button", group: "Symbols"), | ||
| 1570 | + Emoji(glyph: "➰", name: "curly loop", group: "Symbols"), | ||
| 1571 | + Emoji(glyph: "➿", name: "double curly loop", group: "Symbols"), | ||
| 1572 | + Emoji(glyph: "〽️", name: "part alternation mark", group: "Symbols"), | ||
| 1573 | + Emoji(glyph: "✳️", name: "eight-spoked asterisk", group: "Symbols"), | ||
| 1574 | + Emoji(glyph: "✴️", name: "eight-pointed star", group: "Symbols"), | ||
| 1575 | + Emoji(glyph: "❇️", name: "sparkle", group: "Symbols"), | ||
| 1576 | + Emoji(glyph: "™️", name: "trade mark", group: "Symbols"), | ||
| 1577 | + Emoji(glyph: "🔟", name: "keycap: 10", group: "Symbols"), | ||
| 1578 | + Emoji(glyph: "🔠", name: "input latin uppercase", group: "Symbols"), | ||
| 1579 | + Emoji(glyph: "🔡", name: "input latin lowercase", group: "Symbols"), | ||
| 1580 | + Emoji(glyph: "🔢", name: "input numbers", group: "Symbols"), | ||
| 1581 | + Emoji(glyph: "🔣", name: "input symbols", group: "Symbols"), | ||
| 1582 | + Emoji(glyph: "🔤", name: "input latin letters", group: "Symbols"), | ||
| 1583 | + Emoji(glyph: "🅰️", name: "A button (blood type)", group: "Symbols"), | ||
| 1584 | + Emoji(glyph: "🆎", name: "AB button (blood type)", group: "Symbols"), | ||
| 1585 | + Emoji(glyph: "🅱️", name: "B button (blood type)", group: "Symbols"), | ||
| 1586 | + Emoji(glyph: "🆑", name: "CL button", group: "Symbols"), | ||
| 1587 | + Emoji(glyph: "🆒", name: "COOL button", group: "Symbols"), | ||
| 1588 | + Emoji(glyph: "🆓", name: "FREE button", group: "Symbols"), | ||
| 1589 | + Emoji(glyph: "ℹ️", name: "information", group: "Symbols"), | ||
| 1590 | + Emoji(glyph: "🆔", name: "ID button", group: "Symbols"), | ||
| 1591 | + Emoji(glyph: "Ⓜ️", name: "circled M", group: "Symbols"), | ||
| 1592 | + Emoji(glyph: "🆕", name: "NEW button", group: "Symbols"), | ||
| 1593 | + Emoji(glyph: "🆖", name: "NG button", group: "Symbols"), | ||
| 1594 | + Emoji(glyph: "🅾️", name: "O button (blood type)", group: "Symbols"), | ||
| 1595 | + Emoji(glyph: "🆗", name: "OK button", group: "Symbols"), | ||
| 1596 | + Emoji(glyph: "🅿️", name: "P button", group: "Symbols"), | ||
| 1597 | + Emoji(glyph: "🆘", name: "SOS button", group: "Symbols"), | ||
| 1598 | + Emoji(glyph: "🆙", name: "UP! button", group: "Symbols"), | ||
| 1599 | + Emoji(glyph: "🆚", name: "VS button", group: "Symbols"), | ||
| 1600 | + Emoji(glyph: "🈁", name: "Japanese “here” button", group: "Symbols"), | ||
| 1601 | + Emoji(glyph: "🈂️", name: "Japanese “service charge” button", group: "Symbols"), | ||
| 1602 | + Emoji(glyph: "🈷️", name: "Japanese “monthly amount” button", group: "Symbols"), | ||
| 1603 | + Emoji(glyph: "🈶", name: "Japanese “not free of charge” button", group: "Symbols"), | ||
| 1604 | + Emoji(glyph: "🈯", name: "Japanese “reserved” button", group: "Symbols"), | ||
| 1605 | + Emoji(glyph: "🉐", name: "Japanese “bargain” button", group: "Symbols"), | ||
| 1606 | + Emoji(glyph: "🈹", name: "Japanese “discount” button", group: "Symbols"), | ||
| 1607 | + Emoji(glyph: "🈚", name: "Japanese “free of charge” button", group: "Symbols"), | ||
| 1608 | + Emoji(glyph: "🈲", name: "Japanese “prohibited” button", group: "Symbols"), | ||
| 1609 | + Emoji(glyph: "🉑", name: "Japanese “acceptable” button", group: "Symbols"), | ||
| 1610 | + Emoji(glyph: "🈸", name: "Japanese “application” button", group: "Symbols"), | ||
| 1611 | + Emoji(glyph: "🈴", name: "Japanese “passing grade” button", group: "Symbols"), | ||
| 1612 | + Emoji(glyph: "🈳", name: "Japanese “vacancy” button", group: "Symbols"), | ||
| 1613 | + Emoji(glyph: "㊗️", name: "Japanese “congratulations” button", group: "Symbols"), | ||
| 1614 | + Emoji(glyph: "㊙️", name: "Japanese “secret” button", group: "Symbols"), | ||
| 1615 | + Emoji(glyph: "🈺", name: "Japanese “open for business” button", group: "Symbols"), | ||
| 1616 | + Emoji(glyph: "🈵", name: "Japanese “no vacancy” button", group: "Symbols"), | ||
| 1617 | + Emoji(glyph: "🔴", name: "red circle", group: "Symbols"), | ||
| 1618 | + Emoji(glyph: "🟠", name: "orange circle", group: "Symbols"), | ||
| 1619 | + Emoji(glyph: "🟡", name: "yellow circle", group: "Symbols"), | ||
| 1620 | + Emoji(glyph: "🟢", name: "green circle", group: "Symbols"), | ||
| 1621 | + Emoji(glyph: "🔵", name: "blue circle", group: "Symbols"), | ||
| 1622 | + Emoji(glyph: "🟣", name: "purple circle", group: "Symbols"), | ||
| 1623 | + Emoji(glyph: "🟤", name: "brown circle", group: "Symbols"), | ||
| 1624 | + Emoji(glyph: "⚫", name: "black circle", group: "Symbols"), | ||
| 1625 | + Emoji(glyph: "⚪", name: "white circle", group: "Symbols"), | ||
| 1626 | + Emoji(glyph: "🟥", name: "red square", group: "Symbols"), | ||
| 1627 | + Emoji(glyph: "🟧", name: "orange square", group: "Symbols"), | ||
| 1628 | + Emoji(glyph: "🟨", name: "yellow square", group: "Symbols"), | ||
| 1629 | + Emoji(glyph: "🟩", name: "green square", group: "Symbols"), | ||
| 1630 | + Emoji(glyph: "🟦", name: "blue square", group: "Symbols"), | ||
| 1631 | + Emoji(glyph: "🟪", name: "purple square", group: "Symbols"), | ||
| 1632 | + Emoji(glyph: "🟫", name: "brown square", group: "Symbols"), | ||
| 1633 | + Emoji(glyph: "⬛", name: "black large square", group: "Symbols"), | ||
| 1634 | + Emoji(glyph: "⬜", name: "white large square", group: "Symbols"), | ||
| 1635 | + Emoji(glyph: "◼️", name: "black medium square", group: "Symbols"), | ||
| 1636 | + Emoji(glyph: "◻️", name: "white medium square", group: "Symbols"), | ||
| 1637 | + Emoji(glyph: "◾", name: "black medium-small square", group: "Symbols"), | ||
| 1638 | + Emoji(glyph: "◽", name: "white medium-small square", group: "Symbols"), | ||
| 1639 | + Emoji(glyph: "▪️", name: "black small square", group: "Symbols"), | ||
| 1640 | + Emoji(glyph: "▫️", name: "white small square", group: "Symbols"), | ||
| 1641 | + Emoji(glyph: "🔶", name: "large orange diamond", group: "Symbols"), | ||
| 1642 | + Emoji(glyph: "🔷", name: "large blue diamond", group: "Symbols"), | ||
| 1643 | + Emoji(glyph: "🔸", name: "small orange diamond", group: "Symbols"), | ||
| 1644 | + Emoji(glyph: "🔹", name: "small blue diamond", group: "Symbols"), | ||
| 1645 | + Emoji(glyph: "🔺", name: "red triangle pointed up", group: "Symbols"), | ||
| 1646 | + Emoji(glyph: "🔻", name: "red triangle pointed down", group: "Symbols"), | ||
| 1647 | + Emoji(glyph: "💠", name: "diamond with a dot", group: "Symbols"), | ||
| 1648 | + Emoji(glyph: "🔘", name: "radio button", group: "Symbols"), | ||
| 1649 | + Emoji(glyph: "🔳", name: "white square button", group: "Symbols"), | ||
| 1650 | + Emoji(glyph: "🔲", name: "black square button", group: "Symbols"), | ||
| 1651 | + Emoji(glyph: "🏁", name: "chequered flag", group: "Flags"), | ||
| 1652 | + Emoji(glyph: "🚩", name: "triangular flag", group: "Flags"), | ||
| 1653 | + Emoji(glyph: "🎌", name: "crossed flags", group: "Flags"), | ||
| 1654 | + Emoji(glyph: "🏴", name: "black flag", group: "Flags"), | ||
| 1655 | + Emoji(glyph: "🏳️", name: "white flag", group: "Flags"), | ||
| 1656 | + Emoji(glyph: "🏳️🌈", name: "rainbow flag", group: "Flags"), | ||
| 1657 | + Emoji(glyph: "🏳️⚧️", name: "transgender flag", group: "Flags"), | ||
| 1658 | + Emoji(glyph: "🏴☠️", name: "pirate flag", group: "Flags"), | ||
| 1659 | + Emoji(glyph: "🇦🇨", name: "flag: Ascension Island", group: "Flags"), | ||
| 1660 | + Emoji(glyph: "🇦🇩", name: "flag: Andorra", group: "Flags"), | ||
| 1661 | + Emoji(glyph: "🇦🇪", name: "flag: United Arab Emirates", group: "Flags"), | ||
| 1662 | + Emoji(glyph: "🇦🇫", name: "flag: Afghanistan", group: "Flags"), | ||
| 1663 | + Emoji(glyph: "🇦🇬", name: "flag: Antigua & Barbuda", group: "Flags"), | ||
| 1664 | + Emoji(glyph: "🇦🇮", name: "flag: Anguilla", group: "Flags"), | ||
| 1665 | + Emoji(glyph: "🇦🇱", name: "flag: Albania", group: "Flags"), | ||
| 1666 | + Emoji(glyph: "🇦🇲", name: "flag: Armenia", group: "Flags"), | ||
| 1667 | + Emoji(glyph: "🇦🇴", name: "flag: Angola", group: "Flags"), | ||
| 1668 | + Emoji(glyph: "🇦🇶", name: "flag: Antarctica", group: "Flags"), | ||
| 1669 | + Emoji(glyph: "🇦🇷", name: "flag: Argentina", group: "Flags"), | ||
| 1670 | + Emoji(glyph: "🇦🇸", name: "flag: American Samoa", group: "Flags"), | ||
| 1671 | + Emoji(glyph: "🇦🇹", name: "flag: Austria", group: "Flags"), | ||
| 1672 | + Emoji(glyph: "🇦🇺", name: "flag: Australia", group: "Flags"), | ||
| 1673 | + Emoji(glyph: "🇦🇼", name: "flag: Aruba", group: "Flags"), | ||
| 1674 | + Emoji(glyph: "🇦🇽", name: "flag: Åland Islands", group: "Flags"), | ||
| 1675 | + Emoji(glyph: "🇦🇿", name: "flag: Azerbaijan", group: "Flags"), | ||
| 1676 | + Emoji(glyph: "🇧🇦", name: "flag: Bosnia & Herzegovina", group: "Flags"), | ||
| 1677 | + Emoji(glyph: "🇧🇧", name: "flag: Barbados", group: "Flags"), | ||
| 1678 | + Emoji(glyph: "🇧🇩", name: "flag: Bangladesh", group: "Flags"), | ||
| 1679 | + Emoji(glyph: "🇧🇪", name: "flag: Belgium", group: "Flags"), | ||
| 1680 | + Emoji(glyph: "🇧🇫", name: "flag: Burkina Faso", group: "Flags"), | ||
| 1681 | + Emoji(glyph: "🇧🇬", name: "flag: Bulgaria", group: "Flags"), | ||
| 1682 | + Emoji(glyph: "🇧🇭", name: "flag: Bahrain", group: "Flags"), | ||
| 1683 | + Emoji(glyph: "🇧🇮", name: "flag: Burundi", group: "Flags"), | ||
| 1684 | + Emoji(glyph: "🇧🇯", name: "flag: Benin", group: "Flags"), | ||
| 1685 | + Emoji(glyph: "🇧🇱", name: "flag: St. Barthélemy", group: "Flags"), | ||
| 1686 | + Emoji(glyph: "🇧🇲", name: "flag: Bermuda", group: "Flags"), | ||
| 1687 | + Emoji(glyph: "🇧🇳", name: "flag: Brunei", group: "Flags"), | ||
| 1688 | + Emoji(glyph: "🇧🇴", name: "flag: Bolivia", group: "Flags"), | ||
| 1689 | + Emoji(glyph: "🇧🇶", name: "flag: Caribbean Netherlands", group: "Flags"), | ||
| 1690 | + Emoji(glyph: "🇧🇷", name: "flag: Brazil", group: "Flags"), | ||
| 1691 | + Emoji(glyph: "🇧🇸", name: "flag: Bahamas", group: "Flags"), | ||
| 1692 | + Emoji(glyph: "🇧🇹", name: "flag: Bhutan", group: "Flags"), | ||
| 1693 | + Emoji(glyph: "🇧🇻", name: "flag: Bouvet Island", group: "Flags"), | ||
| 1694 | + Emoji(glyph: "🇧🇼", name: "flag: Botswana", group: "Flags"), | ||
| 1695 | + Emoji(glyph: "🇧🇾", name: "flag: Belarus", group: "Flags"), | ||
| 1696 | + Emoji(glyph: "🇧🇿", name: "flag: Belize", group: "Flags"), | ||
| 1697 | + Emoji(glyph: "🇨🇦", name: "flag: Canada", group: "Flags"), | ||
| 1698 | + Emoji(glyph: "🇨🇨", name: "flag: Cocos (Keeling) Islands", group: "Flags"), | ||
| 1699 | + Emoji(glyph: "🇨🇩", name: "flag: Congo - Kinshasa", group: "Flags"), | ||
| 1700 | + Emoji(glyph: "🇨🇫", name: "flag: Central African Republic", group: "Flags"), | ||
| 1701 | + Emoji(glyph: "🇨🇬", name: "flag: Congo - Brazzaville", group: "Flags"), | ||
| 1702 | + Emoji(glyph: "🇨🇭", name: "flag: Switzerland", group: "Flags"), | ||
| 1703 | + Emoji(glyph: "🇨🇮", name: "flag: Côte d’Ivoire", group: "Flags"), | ||
| 1704 | + Emoji(glyph: "🇨🇰", name: "flag: Cook Islands", group: "Flags"), | ||
| 1705 | + Emoji(glyph: "🇨🇱", name: "flag: Chile", group: "Flags"), | ||
| 1706 | + Emoji(glyph: "🇨🇲", name: "flag: Cameroon", group: "Flags"), | ||
| 1707 | + Emoji(glyph: "🇨🇳", name: "flag: China", group: "Flags"), | ||
| 1708 | + Emoji(glyph: "🇨🇴", name: "flag: Colombia", group: "Flags"), | ||
| 1709 | + Emoji(glyph: "🇨🇵", name: "flag: Clipperton Island", group: "Flags"), | ||
| 1710 | + Emoji(glyph: "🇨🇷", name: "flag: Costa Rica", group: "Flags"), | ||
| 1711 | + Emoji(glyph: "🇨🇺", name: "flag: Cuba", group: "Flags"), | ||
| 1712 | + Emoji(glyph: "🇨🇻", name: "flag: Cape Verde", group: "Flags"), | ||
| 1713 | + Emoji(glyph: "🇨🇼", name: "flag: Curaçao", group: "Flags"), | ||
| 1714 | + Emoji(glyph: "🇨🇽", name: "flag: Christmas Island", group: "Flags"), | ||
| 1715 | + Emoji(glyph: "🇨🇾", name: "flag: Cyprus", group: "Flags"), | ||
| 1716 | + Emoji(glyph: "🇨🇿", name: "flag: Czechia", group: "Flags"), | ||
| 1717 | + Emoji(glyph: "🇩🇪", name: "flag: Germany", group: "Flags"), | ||
| 1718 | + Emoji(glyph: "🇩🇬", name: "flag: Diego Garcia", group: "Flags"), | ||
| 1719 | + Emoji(glyph: "🇩🇯", name: "flag: Djibouti", group: "Flags"), | ||
| 1720 | + Emoji(glyph: "🇩🇰", name: "flag: Denmark", group: "Flags"), | ||
| 1721 | + Emoji(glyph: "🇩🇲", name: "flag: Dominica", group: "Flags"), | ||
| 1722 | + Emoji(glyph: "🇩🇴", name: "flag: Dominican Republic", group: "Flags"), | ||
| 1723 | + Emoji(glyph: "🇩🇿", name: "flag: Algeria", group: "Flags"), | ||
| 1724 | + Emoji(glyph: "🇪🇦", name: "flag: Ceuta & Melilla", group: "Flags"), | ||
| 1725 | + Emoji(glyph: "🇪🇨", name: "flag: Ecuador", group: "Flags"), | ||
| 1726 | + Emoji(glyph: "🇪🇪", name: "flag: Estonia", group: "Flags"), | ||
| 1727 | + Emoji(glyph: "🇪🇬", name: "flag: Egypt", group: "Flags"), | ||
| 1728 | + Emoji(glyph: "🇪🇭", name: "flag: Western Sahara", group: "Flags"), | ||
| 1729 | + Emoji(glyph: "🇪🇷", name: "flag: Eritrea", group: "Flags"), | ||
| 1730 | + Emoji(glyph: "🇪🇸", name: "flag: Spain", group: "Flags"), | ||
| 1731 | + Emoji(glyph: "🇪🇹", name: "flag: Ethiopia", group: "Flags"), | ||
| 1732 | + Emoji(glyph: "🇪🇺", name: "flag: European Union", group: "Flags"), | ||
| 1733 | + Emoji(glyph: "🇫🇮", name: "flag: Finland", group: "Flags"), | ||
| 1734 | + Emoji(glyph: "🇫🇯", name: "flag: Fiji", group: "Flags"), | ||
| 1735 | + Emoji(glyph: "🇫🇰", name: "flag: Falkland Islands", group: "Flags"), | ||
| 1736 | + Emoji(glyph: "🇫🇲", name: "flag: Micronesia", group: "Flags"), | ||
| 1737 | + Emoji(glyph: "🇫🇴", name: "flag: Faroe Islands", group: "Flags"), | ||
| 1738 | + Emoji(glyph: "🇫🇷", name: "flag: France", group: "Flags"), | ||
| 1739 | + Emoji(glyph: "🇬🇦", name: "flag: Gabon", group: "Flags"), | ||
| 1740 | + Emoji(glyph: "🇬🇧", name: "flag: United Kingdom", group: "Flags"), | ||
| 1741 | + Emoji(glyph: "🇬🇩", name: "flag: Grenada", group: "Flags"), | ||
| 1742 | + Emoji(glyph: "🇬🇪", name: "flag: Georgia", group: "Flags"), | ||
| 1743 | + Emoji(glyph: "🇬🇫", name: "flag: French Guiana", group: "Flags"), | ||
| 1744 | + Emoji(glyph: "🇬🇬", name: "flag: Guernsey", group: "Flags"), | ||
| 1745 | + Emoji(glyph: "🇬🇭", name: "flag: Ghana", group: "Flags"), | ||
| 1746 | + Emoji(glyph: "🇬🇮", name: "flag: Gibraltar", group: "Flags"), | ||
| 1747 | + Emoji(glyph: "🇬🇱", name: "flag: Greenland", group: "Flags"), | ||
| 1748 | + Emoji(glyph: "🇬🇲", name: "flag: Gambia", group: "Flags"), | ||
| 1749 | + Emoji(glyph: "🇬🇳", name: "flag: Guinea", group: "Flags"), | ||
| 1750 | + Emoji(glyph: "🇬🇵", name: "flag: Guadeloupe", group: "Flags"), | ||
| 1751 | + Emoji(glyph: "🇬🇶", name: "flag: Equatorial Guinea", group: "Flags"), | ||
| 1752 | + Emoji(glyph: "🇬🇷", name: "flag: Greece", group: "Flags"), | ||
| 1753 | + Emoji(glyph: "🇬🇸", name: "flag: South Georgia & South Sandwich Islands", group: "Flags"), | ||
| 1754 | + Emoji(glyph: "🇬🇹", name: "flag: Guatemala", group: "Flags"), | ||
| 1755 | + Emoji(glyph: "🇬🇺", name: "flag: Guam", group: "Flags"), | ||
| 1756 | + Emoji(glyph: "🇬🇼", name: "flag: Guinea-Bissau", group: "Flags"), | ||
| 1757 | + Emoji(glyph: "🇬🇾", name: "flag: Guyana", group: "Flags"), | ||
| 1758 | + Emoji(glyph: "🇭🇰", name: "flag: Hong Kong SAR China", group: "Flags"), | ||
| 1759 | + Emoji(glyph: "🇭🇲", name: "flag: Heard & McDonald Islands", group: "Flags"), | ||
| 1760 | + Emoji(glyph: "🇭🇳", name: "flag: Honduras", group: "Flags"), | ||
| 1761 | + Emoji(glyph: "🇭🇷", name: "flag: Croatia", group: "Flags"), | ||
| 1762 | + Emoji(glyph: "🇭🇹", name: "flag: Haiti", group: "Flags"), | ||
| 1763 | + Emoji(glyph: "🇭🇺", name: "flag: Hungary", group: "Flags"), | ||
| 1764 | + Emoji(glyph: "🇮🇨", name: "flag: Canary Islands", group: "Flags"), | ||
| 1765 | + Emoji(glyph: "🇮🇩", name: "flag: Indonesia", group: "Flags"), | ||
| 1766 | + Emoji(glyph: "🇮🇪", name: "flag: Ireland", group: "Flags"), | ||
| 1767 | + Emoji(glyph: "🇮🇱", name: "flag: Israel", group: "Flags"), | ||
| 1768 | + Emoji(glyph: "🇮🇲", name: "flag: Isle of Man", group: "Flags"), | ||
| 1769 | + Emoji(glyph: "🇮🇳", name: "flag: India", group: "Flags"), | ||
| 1770 | + Emoji(glyph: "🇮🇴", name: "flag: British Indian Ocean Territory", group: "Flags"), | ||
| 1771 | + Emoji(glyph: "🇮🇶", name: "flag: Iraq", group: "Flags"), | ||
| 1772 | + Emoji(glyph: "🇮🇷", name: "flag: Iran", group: "Flags"), | ||
| 1773 | + Emoji(glyph: "🇮🇸", name: "flag: Iceland", group: "Flags"), | ||
| 1774 | + Emoji(glyph: "🇮🇹", name: "flag: Italy", group: "Flags"), | ||
| 1775 | + Emoji(glyph: "🇯🇪", name: "flag: Jersey", group: "Flags"), | ||
| 1776 | + Emoji(glyph: "🇯🇲", name: "flag: Jamaica", group: "Flags"), | ||
| 1777 | + Emoji(glyph: "🇯🇴", name: "flag: Jordan", group: "Flags"), | ||
| 1778 | + Emoji(glyph: "🇯🇵", name: "flag: Japan", group: "Flags"), | ||
| 1779 | + Emoji(glyph: "🇰🇪", name: "flag: Kenya", group: "Flags"), | ||
| 1780 | + Emoji(glyph: "🇰🇬", name: "flag: Kyrgyzstan", group: "Flags"), | ||
| 1781 | + Emoji(glyph: "🇰🇭", name: "flag: Cambodia", group: "Flags"), | ||
| 1782 | + Emoji(glyph: "🇰🇮", name: "flag: Kiribati", group: "Flags"), | ||
| 1783 | + Emoji(glyph: "🇰🇲", name: "flag: Comoros", group: "Flags"), | ||
| 1784 | + Emoji(glyph: "🇰🇳", name: "flag: St. Kitts & Nevis", group: "Flags"), | ||
| 1785 | + Emoji(glyph: "🇰🇵", name: "flag: North Korea", group: "Flags"), | ||
| 1786 | + Emoji(glyph: "🇰🇷", name: "flag: South Korea", group: "Flags"), | ||
| 1787 | + Emoji(glyph: "🇰🇼", name: "flag: Kuwait", group: "Flags"), | ||
| 1788 | + Emoji(glyph: "🇰🇾", name: "flag: Cayman Islands", group: "Flags"), | ||
| 1789 | + Emoji(glyph: "🇰🇿", name: "flag: Kazakhstan", group: "Flags"), | ||
| 1790 | + Emoji(glyph: "🇱🇦", name: "flag: Laos", group: "Flags"), | ||
| 1791 | + Emoji(glyph: "🇱🇧", name: "flag: Lebanon", group: "Flags"), | ||
| 1792 | + Emoji(glyph: "🇱🇨", name: "flag: St. Lucia", group: "Flags"), | ||
| 1793 | + Emoji(glyph: "🇱🇮", name: "flag: Liechtenstein", group: "Flags"), | ||
| 1794 | + Emoji(glyph: "🇱🇰", name: "flag: Sri Lanka", group: "Flags"), | ||
| 1795 | + Emoji(glyph: "🇱🇷", name: "flag: Liberia", group: "Flags"), | ||
| 1796 | + Emoji(glyph: "🇱🇸", name: "flag: Lesotho", group: "Flags"), | ||
| 1797 | + Emoji(glyph: "🇱🇹", name: "flag: Lithuania", group: "Flags"), | ||
| 1798 | + Emoji(glyph: "🇱🇺", name: "flag: Luxembourg", group: "Flags"), | ||
| 1799 | + Emoji(glyph: "🇱🇻", name: "flag: Latvia", group: "Flags"), | ||
| 1800 | + Emoji(glyph: "🇱🇾", name: "flag: Libya", group: "Flags"), | ||
| 1801 | + Emoji(glyph: "🇲🇦", name: "flag: Morocco", group: "Flags"), | ||
| 1802 | + Emoji(glyph: "🇲🇨", name: "flag: Monaco", group: "Flags"), | ||
| 1803 | + Emoji(glyph: "🇲🇩", name: "flag: Moldova", group: "Flags"), | ||
| 1804 | + Emoji(glyph: "🇲🇪", name: "flag: Montenegro", group: "Flags"), | ||
| 1805 | + Emoji(glyph: "🇲🇫", name: "flag: St. Martin", group: "Flags"), | ||
| 1806 | + Emoji(glyph: "🇲🇬", name: "flag: Madagascar", group: "Flags"), | ||
| 1807 | + Emoji(glyph: "🇲🇭", name: "flag: Marshall Islands", group: "Flags"), | ||
| 1808 | + Emoji(glyph: "🇲🇰", name: "flag: North Macedonia", group: "Flags"), | ||
| 1809 | + Emoji(glyph: "🇲🇱", name: "flag: Mali", group: "Flags"), | ||
| 1810 | + Emoji(glyph: "🇲🇲", name: "flag: Myanmar (Burma)", group: "Flags"), | ||
| 1811 | + Emoji(glyph: "🇲🇳", name: "flag: Mongolia", group: "Flags"), | ||
| 1812 | + Emoji(glyph: "🇲🇴", name: "flag: Macao SAR China", group: "Flags"), | ||
| 1813 | + Emoji(glyph: "🇲🇵", name: "flag: Northern Mariana Islands", group: "Flags"), | ||
| 1814 | + Emoji(glyph: "🇲🇶", name: "flag: Martinique", group: "Flags"), | ||
| 1815 | + Emoji(glyph: "🇲🇷", name: "flag: Mauritania", group: "Flags"), | ||
| 1816 | + Emoji(glyph: "🇲🇸", name: "flag: Montserrat", group: "Flags"), | ||
| 1817 | + Emoji(glyph: "🇲🇹", name: "flag: Malta", group: "Flags"), | ||
| 1818 | + Emoji(glyph: "🇲🇺", name: "flag: Mauritius", group: "Flags"), | ||
| 1819 | + Emoji(glyph: "🇲🇻", name: "flag: Maldives", group: "Flags"), | ||
| 1820 | + Emoji(glyph: "🇲🇼", name: "flag: Malawi", group: "Flags"), | ||
| 1821 | + Emoji(glyph: "🇲🇽", name: "flag: Mexico", group: "Flags"), | ||
| 1822 | + Emoji(glyph: "🇲🇾", name: "flag: Malaysia", group: "Flags"), | ||
| 1823 | + Emoji(glyph: "🇲🇿", name: "flag: Mozambique", group: "Flags"), | ||
| 1824 | + Emoji(glyph: "🇳🇦", name: "flag: Namibia", group: "Flags"), | ||
| 1825 | + Emoji(glyph: "🇳🇨", name: "flag: New Caledonia", group: "Flags"), | ||
| 1826 | + Emoji(glyph: "🇳🇪", name: "flag: Niger", group: "Flags"), | ||
| 1827 | + Emoji(glyph: "🇳🇫", name: "flag: Norfolk Island", group: "Flags"), | ||
| 1828 | + Emoji(glyph: "🇳🇬", name: "flag: Nigeria", group: "Flags"), | ||
| 1829 | + Emoji(glyph: "🇳🇮", name: "flag: Nicaragua", group: "Flags"), | ||
| 1830 | + Emoji(glyph: "🇳🇱", name: "flag: Netherlands", group: "Flags"), | ||
| 1831 | + Emoji(glyph: "🇳🇴", name: "flag: Norway", group: "Flags"), | ||
| 1832 | + Emoji(glyph: "🇳🇵", name: "flag: Nepal", group: "Flags"), | ||
| 1833 | + Emoji(glyph: "🇳🇷", name: "flag: Nauru", group: "Flags"), | ||
| 1834 | + Emoji(glyph: "🇳🇺", name: "flag: Niue", group: "Flags"), | ||
| 1835 | + Emoji(glyph: "🇳🇿", name: "flag: New Zealand", group: "Flags"), | ||
| 1836 | + Emoji(glyph: "🇴🇲", name: "flag: Oman", group: "Flags"), | ||
| 1837 | + Emoji(glyph: "🇵🇦", name: "flag: Panama", group: "Flags"), | ||
| 1838 | + Emoji(glyph: "🇵🇪", name: "flag: Peru", group: "Flags"), | ||
| 1839 | + Emoji(glyph: "🇵🇫", name: "flag: French Polynesia", group: "Flags"), | ||
| 1840 | + Emoji(glyph: "🇵🇬", name: "flag: Papua New Guinea", group: "Flags"), | ||
| 1841 | + Emoji(glyph: "🇵🇭", name: "flag: Philippines", group: "Flags"), | ||
| 1842 | + Emoji(glyph: "🇵🇰", name: "flag: Pakistan", group: "Flags"), | ||
| 1843 | + Emoji(glyph: "🇵🇱", name: "flag: Poland", group: "Flags"), | ||
| 1844 | + Emoji(glyph: "🇵🇲", name: "flag: St. Pierre & Miquelon", group: "Flags"), | ||
| 1845 | + Emoji(glyph: "🇵🇳", name: "flag: Pitcairn Islands", group: "Flags"), | ||
| 1846 | + Emoji(glyph: "🇵🇷", name: "flag: Puerto Rico", group: "Flags"), | ||
| 1847 | + Emoji(glyph: "🇵🇸", name: "flag: Palestinian Territories", group: "Flags"), | ||
| 1848 | + Emoji(glyph: "🇵🇹", name: "flag: Portugal", group: "Flags"), | ||
| 1849 | + Emoji(glyph: "🇵🇼", name: "flag: Palau", group: "Flags"), | ||
| 1850 | + Emoji(glyph: "🇵🇾", name: "flag: Paraguay", group: "Flags"), | ||
| 1851 | + Emoji(glyph: "🇶🇦", name: "flag: Qatar", group: "Flags"), | ||
| 1852 | + Emoji(glyph: "🇷🇪", name: "flag: Réunion", group: "Flags"), | ||
| 1853 | + Emoji(glyph: "🇷🇴", name: "flag: Romania", group: "Flags"), | ||
| 1854 | + Emoji(glyph: "🇷🇸", name: "flag: Serbia", group: "Flags"), | ||
| 1855 | + Emoji(glyph: "🇷🇺", name: "flag: Russia", group: "Flags"), | ||
| 1856 | + Emoji(glyph: "🇷🇼", name: "flag: Rwanda", group: "Flags"), | ||
| 1857 | + Emoji(glyph: "🇸🇦", name: "flag: Saudi Arabia", group: "Flags"), | ||
| 1858 | + Emoji(glyph: "🇸🇧", name: "flag: Solomon Islands", group: "Flags"), | ||
| 1859 | + Emoji(glyph: "🇸🇨", name: "flag: Seychelles", group: "Flags"), | ||
| 1860 | + Emoji(glyph: "🇸🇩", name: "flag: Sudan", group: "Flags"), | ||
| 1861 | + Emoji(glyph: "🇸🇪", name: "flag: Sweden", group: "Flags"), | ||
| 1862 | + Emoji(glyph: "🇸🇬", name: "flag: Singapore", group: "Flags"), | ||
| 1863 | + Emoji(glyph: "🇸🇭", name: "flag: St. Helena", group: "Flags"), | ||
| 1864 | + Emoji(glyph: "🇸🇮", name: "flag: Slovenia", group: "Flags"), | ||
| 1865 | + Emoji(glyph: "🇸🇯", name: "flag: Svalbard & Jan Mayen", group: "Flags"), | ||
| 1866 | + Emoji(glyph: "🇸🇰", name: "flag: Slovakia", group: "Flags"), | ||
| 1867 | + Emoji(glyph: "🇸🇱", name: "flag: Sierra Leone", group: "Flags"), | ||
| 1868 | + Emoji(glyph: "🇸🇲", name: "flag: San Marino", group: "Flags"), | ||
| 1869 | + Emoji(glyph: "🇸🇳", name: "flag: Senegal", group: "Flags"), | ||
| 1870 | + Emoji(glyph: "🇸🇴", name: "flag: Somalia", group: "Flags"), | ||
| 1871 | + Emoji(glyph: "🇸🇷", name: "flag: Suriname", group: "Flags"), | ||
| 1872 | + Emoji(glyph: "🇸🇸", name: "flag: South Sudan", group: "Flags"), | ||
| 1873 | + Emoji(glyph: "🇸🇹", name: "flag: São Tomé & Príncipe", group: "Flags"), | ||
| 1874 | + Emoji(glyph: "🇸🇻", name: "flag: El Salvador", group: "Flags"), | ||
| 1875 | + Emoji(glyph: "🇸🇽", name: "flag: Sint Maarten", group: "Flags"), | ||
| 1876 | + Emoji(glyph: "🇸🇾", name: "flag: Syria", group: "Flags"), | ||
| 1877 | + Emoji(glyph: "🇸🇿", name: "flag: Eswatini", group: "Flags"), | ||
| 1878 | + Emoji(glyph: "🇹🇦", name: "flag: Tristan da Cunha", group: "Flags"), | ||
| 1879 | + Emoji(glyph: "🇹🇨", name: "flag: Turks & Caicos Islands", group: "Flags"), | ||
| 1880 | + Emoji(glyph: "🇹🇩", name: "flag: Chad", group: "Flags"), | ||
| 1881 | + Emoji(glyph: "🇹🇫", name: "flag: French Southern Territories", group: "Flags"), | ||
| 1882 | + Emoji(glyph: "🇹🇬", name: "flag: Togo", group: "Flags"), | ||
| 1883 | + Emoji(glyph: "🇹🇭", name: "flag: Thailand", group: "Flags"), | ||
| 1884 | + Emoji(glyph: "🇹🇯", name: "flag: Tajikistan", group: "Flags"), | ||
| 1885 | + Emoji(glyph: "🇹🇰", name: "flag: Tokelau", group: "Flags"), | ||
| 1886 | + Emoji(glyph: "🇹🇱", name: "flag: Timor-Leste", group: "Flags"), | ||
| 1887 | + Emoji(glyph: "🇹🇲", name: "flag: Turkmenistan", group: "Flags"), | ||
| 1888 | + Emoji(glyph: "🇹🇳", name: "flag: Tunisia", group: "Flags"), | ||
| 1889 | + Emoji(glyph: "🇹🇴", name: "flag: Tonga", group: "Flags"), | ||
| 1890 | + Emoji(glyph: "🇹🇷", name: "flag: Türkiye", group: "Flags"), | ||
| 1891 | + Emoji(glyph: "🇹🇹", name: "flag: Trinidad & Tobago", group: "Flags"), | ||
| 1892 | + Emoji(glyph: "🇹🇻", name: "flag: Tuvalu", group: "Flags"), | ||
| 1893 | + Emoji(glyph: "🇹🇼", name: "flag: Taiwan", group: "Flags"), | ||
| 1894 | + Emoji(glyph: "🇹🇿", name: "flag: Tanzania", group: "Flags"), | ||
| 1895 | + Emoji(glyph: "🇺🇦", name: "flag: Ukraine", group: "Flags"), | ||
| 1896 | + Emoji(glyph: "🇺🇬", name: "flag: Uganda", group: "Flags"), | ||
| 1897 | + Emoji(glyph: "🇺🇲", name: "flag: U.S. Outlying Islands", group: "Flags"), | ||
| 1898 | + Emoji(glyph: "🇺🇳", name: "flag: United Nations", group: "Flags"), | ||
| 1899 | + Emoji(glyph: "🇺🇸", name: "flag: United States", group: "Flags"), | ||
| 1900 | + Emoji(glyph: "🇺🇾", name: "flag: Uruguay", group: "Flags"), | ||
| 1901 | + Emoji(glyph: "🇺🇿", name: "flag: Uzbekistan", group: "Flags"), | ||
| 1902 | + Emoji(glyph: "🇻🇦", name: "flag: Vatican City", group: "Flags"), | ||
| 1903 | + Emoji(glyph: "🇻🇨", name: "flag: St. Vincent & Grenadines", group: "Flags"), | ||
| 1904 | + Emoji(glyph: "🇻🇪", name: "flag: Venezuela", group: "Flags"), | ||
| 1905 | + Emoji(glyph: "🇻🇬", name: "flag: British Virgin Islands", group: "Flags"), | ||
| 1906 | + Emoji(glyph: "🇻🇮", name: "flag: U.S. Virgin Islands", group: "Flags"), | ||
| 1907 | + Emoji(glyph: "🇻🇳", name: "flag: Vietnam", group: "Flags"), | ||
| 1908 | + Emoji(glyph: "🇻🇺", name: "flag: Vanuatu", group: "Flags"), | ||
| 1909 | + Emoji(glyph: "🇼🇫", name: "flag: Wallis & Futuna", group: "Flags"), | ||
| 1910 | + Emoji(glyph: "🇼🇸", name: "flag: Samoa", group: "Flags"), | ||
| 1911 | + Emoji(glyph: "🇽🇰", name: "flag: Kosovo", group: "Flags"), | ||
| 1912 | + Emoji(glyph: "🇾🇪", name: "flag: Yemen", group: "Flags"), | ||
| 1913 | + Emoji(glyph: "🇾🇹", name: "flag: Mayotte", group: "Flags"), | ||
| 1914 | + Emoji(glyph: "🇿🇦", name: "flag: South Africa", group: "Flags"), | ||
| 1915 | + Emoji(glyph: "🇿🇲", name: "flag: Zambia", group: "Flags"), | ||
| 1916 | + Emoji(glyph: "🇿🇼", name: "flag: Zimbabwe", group: "Flags"), | ||
| 1917 | + Emoji(glyph: "🏴", name: "flag: England", group: "Flags"), | ||
| 1918 | + Emoji(glyph: "🏴", name: "flag: Scotland", group: "Flags"), | ||
| 1919 | + Emoji(glyph: "🏴", name: "flag: Wales", group: "Flags"), | ||
| 1920 | + ] | ||
added
nim/src/frq/glyphs.nim +119 -0 | new file mode 100644 | ||
| @@ -0,0 +1,119 @@ | ||
| 1 | +## Message text split into words and pictures. | |
| 2 | +## | |
| 3 | +## From `common/frq/glyphs.cljc`. What it is for: a node draws one picture, so | |
| 4 | +## the renderer needs to know where in a line the emoji are and where the | |
| 5 | +## letters are. | |
| 6 | + | |
| 7 | +import std/[sets, strutils, unicode] | |
| 8 | +import frq/emoji | |
| 9 | + | |
| 10 | +const tones = [0x1F3FB, 0x1F3FC, 0x1F3FD, 0x1F3FE, 0x1F3FF] | |
| 11 | + ## The five skin-tone modifiers. | |
| 12 | + ## | |
| 13 | + ## The catalogue leaves toned variants out on purpose — they multiply it by | |
| 14 | + ## five and say nothing a reaction needs to say — but the pack has a picture | |
| 15 | + ## for every one and falls back to the untoned picture where it has none. So | |
| 16 | + ## a tone is stripped for the lookup and kept for the drawing. | |
| 17 | + | |
| 18 | +type | |
| 19 | + RunKind* = enum gkText, gkEmoji | |
| 20 | + GlyphRun* = object | |
| 21 | + kind*: RunKind | |
| 22 | + value*: string | |
| 23 | + | |
| 24 | +var | |
| 25 | + pack {.threadvar.}: HashSet[string] | |
| 26 | + starts {.threadvar.}: HashSet[Rune] | |
| 27 | + scanLimit {.threadvar.}: int | |
| 28 | + built {.threadvar.}: bool | |
| 29 | + | |
| 30 | +proc build() = | |
| 31 | + ## The lookup tables, made once. | |
| 32 | + ## | |
| 33 | + ## `pack` is every glyph there is a picture for, which is exactly the | |
| 34 | + ## catalogue — a codepoint the pack has missed would be swapped out of the | |
| 35 | + ## text for a picture that does not exist and drawn as the same tofu by a | |
| 36 | + ## longer road. `starts` is their first runes, so a message with no emoji in | |
| 37 | + ## it — which is nearly all of them — costs one set lookup per character and | |
| 38 | + ## no substrings at all. | |
| 39 | + if built: return | |
| 40 | + built = true | |
| 41 | + pack = initHashSet[string]() | |
| 42 | + starts = initHashSet[Rune]() | |
| 43 | + var longest = 1 | |
| 44 | + for e in catalog: | |
| 45 | + pack.incl e.glyph | |
| 46 | + let rs = e.glyph.toRunes | |
| 47 | + if rs.len > 0: starts.incl rs[0] | |
| 48 | + if rs.len > longest: longest = rs.len | |
| 49 | + # Plus room for the tones the catalogue itself leaves out. A family is one | |
| 50 | + # glyph made of four people, three joiners and a tone each, so the scan | |
| 51 | + # cannot assume a cluster is short. | |
| 52 | + scanLimit = longest + 5 | |
| 53 | + | |
| 54 | +func untoned(rs: seq[Rune]): string = | |
| 55 | + for r in rs: | |
| 56 | + if r.int32 notin tones: result.add $r | |
| 57 | + | |
| 58 | +proc emojiAt(rs: seq[Rune], i: int): string = | |
| 59 | + ## The longest emoji the pack knows that starts at `i`, or "". | |
| 60 | + ## | |
| 61 | + ## Longest first, because the short one is a prefix of the long one: 👨 is | |
| 62 | + ## the head of 👨👩👧, and taking the man would leave his family as three | |
| 63 | + ## more glyphs and two tofu joiners. | |
| 64 | + var len = min(scanLimit, rs.len - i) | |
| 65 | + while len > 0: | |
| 66 | + var s = "" | |
| 67 | + for k in i ..< i + len: s.add $rs[k] | |
| 68 | + if s in pack or untoned(rs[i ..< i + len]) in pack: | |
| 69 | + return s | |
| 70 | + len -= 1 | |
| 71 | + "" | |
| 72 | + | |
| 73 | +proc runs*(text: string): seq[GlyphRun] = | |
| 74 | + ## `text` as alternating text and emoji runs, in order. | |
| 75 | + ## | |
| 76 | + ## An emoji run is one glyph: a node draws one picture, so two emoji side by | |
| 77 | + ## side are two runs and not one. | |
| 78 | + build() | |
| 79 | + let rs = text.toRunes | |
| 80 | + var buf = "" | |
| 81 | + var i = 0 | |
| 82 | + while i < rs.len: | |
| 83 | + var hit = "" | |
| 84 | + if rs[i] in starts: hit = emojiAt(rs, i) | |
| 85 | + if hit.len > 0: | |
| 86 | + if buf.len > 0: | |
| 87 | + result.add GlyphRun(kind: gkText, value: buf) | |
| 88 | + buf = "" | |
| 89 | + result.add GlyphRun(kind: gkEmoji, value: hit) | |
| 90 | + i += hit.toRunes.len | |
| 91 | + else: | |
| 92 | + buf.add $rs[i] | |
| 93 | + i += 1 | |
| 94 | + if buf.len > 0: | |
| 95 | + result.add GlyphRun(kind: gkText, value: buf) | |
| 96 | + | |
| 97 | +func hasEmoji*(rs: seq[GlyphRun]): bool = | |
| 98 | + ## Whether any run is a picture — which is what decides between a plain | |
| 99 | + ## label and a row that has to mix the two. | |
| 100 | + for r in rs: | |
| 101 | + if r.kind == gkEmoji: return true | |
| 102 | + false | |
| 103 | + | |
| 104 | +proc pickerEmoji*(search, group: string): seq[Emoji] = | |
| 105 | + ## What the picker is showing: the popular row, one group, or whatever the | |
| 106 | + ## search matches — by name, so "cat" finds the cat and the cat face, and by | |
| 107 | + ## the glyph itself, so pasting one finds it. | |
| 108 | + let q = search.strip().toLower() | |
| 109 | + if q.len > 0: | |
| 110 | + for e in catalog: | |
| 111 | + if q in e.name.toLower() or q in e.glyph: result.add e | |
| 112 | + elif group.len > 0: | |
| 113 | + for e in catalog: | |
| 114 | + if e.group == group: result.add e | |
| 115 | + else: | |
| 116 | + # A blank group is no group: the popular row is what nothing selected | |
| 117 | + # means, and an empty string would filter the catalogue down to nothing. | |
| 118 | + for g in popular: | |
| 119 | + result.add Emoji(glyph: g, name: g, group: "") | |
| new file mode 100644 | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | +## Message text split into words and pictures. | ||
| 2 | +## | ||
| 3 | +## From `common/frq/glyphs.cljc`. What it is for: a node draws one picture, so | ||
| 4 | +## the renderer needs to know where in a line the emoji are and where the | ||
| 5 | +## letters are. | ||
| 6 | + | ||
| 7 | +import std/[sets, strutils, unicode] | ||
| 8 | +import frq/emoji | ||
| 9 | + | ||
| 10 | +const tones = [0x1F3FB, 0x1F3FC, 0x1F3FD, 0x1F3FE, 0x1F3FF] | ||
| 11 | + ## The five skin-tone modifiers. | ||
| 12 | + ## | ||
| 13 | + ## The catalogue leaves toned variants out on purpose — they multiply it by | ||
| 14 | + ## five and say nothing a reaction needs to say — but the pack has a picture | ||
| 15 | + ## for every one and falls back to the untoned picture where it has none. So | ||
| 16 | + ## a tone is stripped for the lookup and kept for the drawing. | ||
| 17 | + | ||
| 18 | +type | ||
| 19 | + RunKind* = enum gkText, gkEmoji | ||
| 20 | + GlyphRun* = object | ||
| 21 | + kind*: RunKind | ||
| 22 | + value*: string | ||
| 23 | + | ||
| 24 | +var | ||
| 25 | + pack {.threadvar.}: HashSet[string] | ||
| 26 | + starts {.threadvar.}: HashSet[Rune] | ||
| 27 | + scanLimit {.threadvar.}: int | ||
| 28 | + built {.threadvar.}: bool | ||
| 29 | + | ||
| 30 | +proc build() = | ||
| 31 | + ## The lookup tables, made once. | ||
| 32 | + ## | ||
| 33 | + ## `pack` is every glyph there is a picture for, which is exactly the | ||
| 34 | + ## catalogue — a codepoint the pack has missed would be swapped out of the | ||
| 35 | + ## text for a picture that does not exist and drawn as the same tofu by a | ||
| 36 | + ## longer road. `starts` is their first runes, so a message with no emoji in | ||
| 37 | + ## it — which is nearly all of them — costs one set lookup per character and | ||
| 38 | + ## no substrings at all. | ||
| 39 | + if built: return | ||
| 40 | + built = true | ||
| 41 | + pack = initHashSet[string]() | ||
| 42 | + starts = initHashSet[Rune]() | ||
| 43 | + var longest = 1 | ||
| 44 | + for e in catalog: | ||
| 45 | + pack.incl e.glyph | ||
| 46 | + let rs = e.glyph.toRunes | ||
| 47 | + if rs.len > 0: starts.incl rs[0] | ||
| 48 | + if rs.len > longest: longest = rs.len | ||
| 49 | + # Plus room for the tones the catalogue itself leaves out. A family is one | ||
| 50 | + # glyph made of four people, three joiners and a tone each, so the scan | ||
| 51 | + # cannot assume a cluster is short. | ||
| 52 | + scanLimit = longest + 5 | ||
| 53 | + | ||
| 54 | +func untoned(rs: seq[Rune]): string = | ||
| 55 | + for r in rs: | ||
| 56 | + if r.int32 notin tones: result.add $r | ||
| 57 | + | ||
| 58 | +proc emojiAt(rs: seq[Rune], i: int): string = | ||
| 59 | + ## The longest emoji the pack knows that starts at `i`, or "". | ||
| 60 | + ## | ||
| 61 | + ## Longest first, because the short one is a prefix of the long one: 👨 is | ||
| 62 | + ## the head of 👨👩👧, and taking the man would leave his family as three | ||
| 63 | + ## more glyphs and two tofu joiners. | ||
| 64 | + var len = min(scanLimit, rs.len - i) | ||
| 65 | + while len > 0: | ||
| 66 | + var s = "" | ||
| 67 | + for k in i ..< i + len: s.add $rs[k] | ||
| 68 | + if s in pack or untoned(rs[i ..< i + len]) in pack: | ||
| 69 | + return s | ||
| 70 | + len -= 1 | ||
| 71 | + "" | ||
| 72 | + | ||
| 73 | +proc runs*(text: string): seq[GlyphRun] = | ||
| 74 | + ## `text` as alternating text and emoji runs, in order. | ||
| 75 | + ## | ||
| 76 | + ## An emoji run is one glyph: a node draws one picture, so two emoji side by | ||
| 77 | + ## side are two runs and not one. | ||
| 78 | + build() | ||
| 79 | + let rs = text.toRunes | ||
| 80 | + var buf = "" | ||
| 81 | + var i = 0 | ||
| 82 | + while i < rs.len: | ||
| 83 | + var hit = "" | ||
| 84 | + if rs[i] in starts: hit = emojiAt(rs, i) | ||
| 85 | + if hit.len > 0: | ||
| 86 | + if buf.len > 0: | ||
| 87 | + result.add GlyphRun(kind: gkText, value: buf) | ||
| 88 | + buf = "" | ||
| 89 | + result.add GlyphRun(kind: gkEmoji, value: hit) | ||
| 90 | + i += hit.toRunes.len | ||
| 91 | + else: | ||
| 92 | + buf.add $rs[i] | ||
| 93 | + i += 1 | ||
| 94 | + if buf.len > 0: | ||
| 95 | + result.add GlyphRun(kind: gkText, value: buf) | ||
| 96 | + | ||
| 97 | +func hasEmoji*(rs: seq[GlyphRun]): bool = | ||
| 98 | + ## Whether any run is a picture — which is what decides between a plain | ||
| 99 | + ## label and a row that has to mix the two. | ||
| 100 | + for r in rs: | ||
| 101 | + if r.kind == gkEmoji: return true | ||
| 102 | + false | ||
| 103 | + | ||
| 104 | +proc pickerEmoji*(search, group: string): seq[Emoji] = | ||
| 105 | + ## What the picker is showing: the popular row, one group, or whatever the | ||
| 106 | + ## search matches — by name, so "cat" finds the cat and the cat face, and by | ||
| 107 | + ## the glyph itself, so pasting one finds it. | ||
| 108 | + let q = search.strip().toLower() | ||
| 109 | + if q.len > 0: | ||
| 110 | + for e in catalog: | ||
| 111 | + if q in e.name.toLower() or q in e.glyph: result.add e | ||
| 112 | + elif group.len > 0: | ||
| 113 | + for e in catalog: | ||
| 114 | + if e.group == group: result.add e | ||
| 115 | + else: | ||
| 116 | + # A blank group is no group: the popular row is what nothing selected | ||
| 117 | + # means, and an empty string would filter the catalogue down to nothing. | ||
| 118 | + for g in popular: | ||
| 119 | + result.add Emoji(glyph: g, name: g, group: "") | ||
added
nim/src/frq/members.nim +123 -0 | new file mode 100644 | ||
| @@ -0,0 +1,123 @@ | ||
| 1 | +## Who is in a channel, and what the server says about them. | |
| 2 | +## | |
| 3 | +## From `common/frq/members.cljc`. The membership is a nick → mode-prefix | |
| 4 | +## table rather than a list of names, because the panel sorts ops first and a | |
| 5 | +## MODE has to find one person among many. | |
| 6 | + | |
| 7 | +import std/[algorithm, sequtils, strutils, tables] | |
| 8 | + | |
| 9 | +const | |
| 10 | + modePrefixes* = "~&@%+" | |
| 11 | + ## The characters a server puts in front of a nick in NAMES, and in the | |
| 12 | + ## same order the panel sorts them: owner, admin, op, half-op, voice. | |
| 13 | + | |
| 14 | + modeLetters = {'q': "~", 'a': "&", 'o': "@", 'h': "%", 'v': "+"}.toTable | |
| 15 | + | |
| 16 | +type | |
| 17 | + Member* = object | |
| 18 | + nick*: string | |
| 19 | + prefix*: string | |
| 20 | + | |
| 21 | +func splitPrefix*(entry: string): (string, string) = | |
| 22 | + ## One NAMES entry into `(prefix, nick)`. A nick never starts with one of | |
| 23 | + ## these, so what is in front of it is a mode and not part of the name. | |
| 24 | + if entry.len > 0 and entry[0] in modePrefixes: | |
| 25 | + ($entry[0], entry[1 .. ^1]) | |
| 26 | + else: | |
| 27 | + ("", entry) | |
| 28 | + | |
| 29 | +proc withNames*(acc: var Table[string, string], names: string) = | |
| 30 | + ## One 353 folded into the channel's pending list. | |
| 31 | + ## | |
| 32 | + ## Pending rather than live: the reply comes in as many lines as it takes | |
| 33 | + ## and ends with 366, and replacing the list on each of them would empty the | |
| 34 | + ## panel and refill it a name at a time. | |
| 35 | + for entry in names.split(' '): | |
| 36 | + if entry.strip().len == 0: continue | |
| 37 | + let (prefix, nick) = splitPrefix(entry) | |
| 38 | + if nick.len > 0: acc[nick] = prefix | |
| 39 | + | |
| 40 | +proc withMode*(users: var Table[string, string], modes: string, | |
| 41 | + args: seq[string]) = | |
| 42 | + ## A channel MODE, for the letters that change how someone is listed. | |
| 43 | + ## | |
| 44 | + ## `args` is whoever the modes were applied to, in order; anything else in | |
| 45 | + ## the mode string — a key, a limit, a ban — names no member and is skipped. | |
| 46 | + ## A mode that takes an argument without naming a member still eats one, and | |
| 47 | + ## reading the next letter's nick out of the wrong place would put a mode on | |
| 48 | + ## a stranger, so only the setting form takes one. | |
| 49 | + var adding = true | |
| 50 | + var i = 0 | |
| 51 | + for c in modes: | |
| 52 | + case c | |
| 53 | + of '+': adding = true | |
| 54 | + of '-': adding = false | |
| 55 | + else: | |
| 56 | + if c in modeLetters: | |
| 57 | + if i < args.len: | |
| 58 | + let nick = args[i] | |
| 59 | + if users.hasKey(nick): | |
| 60 | + users[nick] = if adding: modeLetters[c] else: "" | |
| 61 | + i += 1 | |
| 62 | + elif adding: | |
| 63 | + # Takes an argument but names nobody — a key or a limit. Eat it, or | |
| 64 | + # the next letter reads somebody else's nick. | |
| 65 | + i += 1 | |
| 66 | + | |
| 67 | +func prefixRank(prefix: string): int = | |
| 68 | + ## Where a prefix sorts. No prefix is last, which is why this is not simply | |
| 69 | + ## the index. | |
| 70 | + let i = modePrefixes.find(if prefix.len > 0: prefix[0] else: '\0') | |
| 71 | + if i < 0: modePrefixes.len else: i | |
| 72 | + | |
| 73 | +func memberList*(users: Table[string, string]): seq[Member] = | |
| 74 | + ## Ops first and then alphabetically — the order every other client lists | |
| 75 | + ## them in, and the one a reader scanning for a name expects. | |
| 76 | + for nick, prefix in users: | |
| 77 | + result.add Member(nick: nick, prefix: prefix) | |
| 78 | + result.sort(proc (a, b: Member): int = | |
| 79 | + let ra = prefixRank(a.prefix) | |
| 80 | + let rb = prefixRank(b.prefix) | |
| 81 | + if ra != rb: cmp(ra, rb) | |
| 82 | + else: cmp(a.nick.toLowerAscii, b.nick.toLowerAscii)) | |
| 83 | + | |
| 84 | +func commonPrefix(ss: seq[string]): string = | |
| 85 | + ## The longest string every one of `ss` starts with, ignoring case. | |
| 86 | + if ss.len == 0: return "" | |
| 87 | + result = ss[0] | |
| 88 | + for s in ss[1 .. ^1]: | |
| 89 | + var i = 0 | |
| 90 | + while i < min(result.len, s.len) and | |
| 91 | + result[i].toLowerAscii == s[i].toLowerAscii: | |
| 92 | + i += 1 | |
| 93 | + result = result[0 ..< i] | |
| 94 | + | |
| 95 | +func completeNick*(text: string, nicks: seq[string]): (string, bool) = | |
| 96 | + ## `text` with its last word completed against `nicks`. The bool is whether | |
| 97 | + ## anything was completed at all. | |
| 98 | + ## | |
| 99 | + ## What Tab does in every IRC client, and the rules are theirs. One match is | |
| 100 | + ## taken whole. Several are taken as far as they agree — the reader types | |
| 101 | + ## another letter and asks again, rather than being given somebody at | |
| 102 | + ## random. None leaves the draft alone. | |
| 103 | + ## | |
| 104 | + ## A name at the start of a line is addressed, so it gets `nick: `; anywhere | |
| 105 | + ## else it is mentioned mid-sentence and gets a plain space. That is the | |
| 106 | + ## convention freeq's own messages already follow. | |
| 107 | + ## | |
| 108 | + ## Case is ignored when matching and the nick's own case is what lands: | |
| 109 | + ## people type `nan<tab>` and mean `nandi.uk`. | |
| 110 | + let cut = max(text.rfind(' '), text.rfind('\n')) + 1 | |
| 111 | + let word = text[cut .. ^1] | |
| 112 | + if word.len == 0: return (text, false) | |
| 113 | + | |
| 114 | + let lower = word.toLowerAscii | |
| 115 | + var matches = nicks.filterIt(it.toLowerAscii.startsWith(lower)) | |
| 116 | + if matches.len == 0: return (text, false) | |
| 117 | + matches.sort() | |
| 118 | + | |
| 119 | + let done = | |
| 120 | + if matches.len == 1: matches[0] & (if cut == 0: ": " else: " ") | |
| 121 | + else: commonPrefix(matches) | |
| 122 | + if done.len <= word.len: return (text, false) | |
| 123 | + (text[0 ..< cut] & done, true) | |
| new file mode 100644 | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | +## Who is in a channel, and what the server says about them. | ||
| 2 | +## | ||
| 3 | +## From `common/frq/members.cljc`. The membership is a nick → mode-prefix | ||
| 4 | +## table rather than a list of names, because the panel sorts ops first and a | ||
| 5 | +## MODE has to find one person among many. | ||
| 6 | + | ||
| 7 | +import std/[algorithm, sequtils, strutils, tables] | ||
| 8 | + | ||
| 9 | +const | ||
| 10 | + modePrefixes* = "~&@%+" | ||
| 11 | + ## The characters a server puts in front of a nick in NAMES, and in the | ||
| 12 | + ## same order the panel sorts them: owner, admin, op, half-op, voice. | ||
| 13 | + | ||
| 14 | + modeLetters = {'q': "~", 'a': "&", 'o': "@", 'h': "%", 'v': "+"}.toTable | ||
| 15 | + | ||
| 16 | +type | ||
| 17 | + Member* = object | ||
| 18 | + nick*: string | ||
| 19 | + prefix*: string | ||
| 20 | + | ||
| 21 | +func splitPrefix*(entry: string): (string, string) = | ||
| 22 | + ## One NAMES entry into `(prefix, nick)`. A nick never starts with one of | ||
| 23 | + ## these, so what is in front of it is a mode and not part of the name. | ||
| 24 | + if entry.len > 0 and entry[0] in modePrefixes: | ||
| 25 | + ($entry[0], entry[1 .. ^1]) | ||
| 26 | + else: | ||
| 27 | + ("", entry) | ||
| 28 | + | ||
| 29 | +proc withNames*(acc: var Table[string, string], names: string) = | ||
| 30 | + ## One 353 folded into the channel's pending list. | ||
| 31 | + ## | ||
| 32 | + ## Pending rather than live: the reply comes in as many lines as it takes | ||
| 33 | + ## and ends with 366, and replacing the list on each of them would empty the | ||
| 34 | + ## panel and refill it a name at a time. | ||
| 35 | + for entry in names.split(' '): | ||
| 36 | + if entry.strip().len == 0: continue | ||
| 37 | + let (prefix, nick) = splitPrefix(entry) | ||
| 38 | + if nick.len > 0: acc[nick] = prefix | ||
| 39 | + | ||
| 40 | +proc withMode*(users: var Table[string, string], modes: string, | ||
| 41 | + args: seq[string]) = | ||
| 42 | + ## A channel MODE, for the letters that change how someone is listed. | ||
| 43 | + ## | ||
| 44 | + ## `args` is whoever the modes were applied to, in order; anything else in | ||
| 45 | + ## the mode string — a key, a limit, a ban — names no member and is skipped. | ||
| 46 | + ## A mode that takes an argument without naming a member still eats one, and | ||
| 47 | + ## reading the next letter's nick out of the wrong place would put a mode on | ||
| 48 | + ## a stranger, so only the setting form takes one. | ||
| 49 | + var adding = true | ||
| 50 | + var i = 0 | ||
| 51 | + for c in modes: | ||
| 52 | + case c | ||
| 53 | + of '+': adding = true | ||
| 54 | + of '-': adding = false | ||
| 55 | + else: | ||
| 56 | + if c in modeLetters: | ||
| 57 | + if i < args.len: | ||
| 58 | + let nick = args[i] | ||
| 59 | + if users.hasKey(nick): | ||
| 60 | + users[nick] = if adding: modeLetters[c] else: "" | ||
| 61 | + i += 1 | ||
| 62 | + elif adding: | ||
| 63 | + # Takes an argument but names nobody — a key or a limit. Eat it, or | ||
| 64 | + # the next letter reads somebody else's nick. | ||
| 65 | + i += 1 | ||
| 66 | + | ||
| 67 | +func prefixRank(prefix: string): int = | ||
| 68 | + ## Where a prefix sorts. No prefix is last, which is why this is not simply | ||
| 69 | + ## the index. | ||
| 70 | + let i = modePrefixes.find(if prefix.len > 0: prefix[0] else: '\0') | ||
| 71 | + if i < 0: modePrefixes.len else: i | ||
| 72 | + | ||
| 73 | +func memberList*(users: Table[string, string]): seq[Member] = | ||
| 74 | + ## Ops first and then alphabetically — the order every other client lists | ||
| 75 | + ## them in, and the one a reader scanning for a name expects. | ||
| 76 | + for nick, prefix in users: | ||
| 77 | + result.add Member(nick: nick, prefix: prefix) | ||
| 78 | + result.sort(proc (a, b: Member): int = | ||
| 79 | + let ra = prefixRank(a.prefix) | ||
| 80 | + let rb = prefixRank(b.prefix) | ||
| 81 | + if ra != rb: cmp(ra, rb) | ||
| 82 | + else: cmp(a.nick.toLowerAscii, b.nick.toLowerAscii)) | ||
| 83 | + | ||
| 84 | +func commonPrefix(ss: seq[string]): string = | ||
| 85 | + ## The longest string every one of `ss` starts with, ignoring case. | ||
| 86 | + if ss.len == 0: return "" | ||
| 87 | + result = ss[0] | ||
| 88 | + for s in ss[1 .. ^1]: | ||
| 89 | + var i = 0 | ||
| 90 | + while i < min(result.len, s.len) and | ||
| 91 | + result[i].toLowerAscii == s[i].toLowerAscii: | ||
| 92 | + i += 1 | ||
| 93 | + result = result[0 ..< i] | ||
| 94 | + | ||
| 95 | +func completeNick*(text: string, nicks: seq[string]): (string, bool) = | ||
| 96 | + ## `text` with its last word completed against `nicks`. The bool is whether | ||
| 97 | + ## anything was completed at all. | ||
| 98 | + ## | ||
| 99 | + ## What Tab does in every IRC client, and the rules are theirs. One match is | ||
| 100 | + ## taken whole. Several are taken as far as they agree — the reader types | ||
| 101 | + ## another letter and asks again, rather than being given somebody at | ||
| 102 | + ## random. None leaves the draft alone. | ||
| 103 | + ## | ||
| 104 | + ## A name at the start of a line is addressed, so it gets `nick: `; anywhere | ||
| 105 | + ## else it is mentioned mid-sentence and gets a plain space. That is the | ||
| 106 | + ## convention freeq's own messages already follow. | ||
| 107 | + ## | ||
| 108 | + ## Case is ignored when matching and the nick's own case is what lands: | ||
| 109 | + ## people type `nan<tab>` and mean `nandi.uk`. | ||
| 110 | + let cut = max(text.rfind(' '), text.rfind('\n')) + 1 | ||
| 111 | + let word = text[cut .. ^1] | ||
| 112 | + if word.len == 0: return (text, false) | ||
| 113 | + | ||
| 114 | + let lower = word.toLowerAscii | ||
| 115 | + var matches = nicks.filterIt(it.toLowerAscii.startsWith(lower)) | ||
| 116 | + if matches.len == 0: return (text, false) | ||
| 117 | + matches.sort() | ||
| 118 | + | ||
| 119 | + let done = | ||
| 120 | + if matches.len == 1: matches[0] & (if cut == 0: ": " else: " ") | ||
| 121 | + else: commonPrefix(matches) | ||
| 122 | + if done.len <= word.len: return (text, false) | ||
| 123 | + (text[0 ..< cut] & done, true) | ||
modified
nim/src/frq/model.nim +8 -2 | @@ -10,7 +10,7 @@ | ||
| 10 | 10 | ## and a missing key and a null key are the same thing on the other side. An |
| 11 | 11 | ## Option would have to be unwrapped at every boundary anyway. |
| 12 | 12 | |
| 13 | -import std/[options, strutils] | |
| 13 | +import std/[options, strutils, tables] | |
| 14 | 14 | |
| 15 | 15 | type |
| 16 | 16 | Reaction* = object |
| @@ -49,7 +49,13 @@ type | ||
| 49 | 49 | mention*: bool |
| 50 | 50 | joined*: bool |
| 51 | 51 | joining*: bool |
| 52 | - users*: seq[string] | |
| 52 | + users*: Table[string, string] | |
| 53 | + ## nick → mode prefix ("" for none). A table and not a list because the | |
| 54 | + ## people panel sorts ops first and a MODE has to find one person. | |
| 55 | + namesAcc*: Table[string, string] | |
| 56 | + ## The 353 replies so far. Pending rather than live: NAMES arrives over | |
| 57 | + ## as many lines as it takes and ends with 366, and replacing `users` on | |
| 58 | + ## each would empty the panel and refill it a name at a time. | |
| 53 | 59 | topic*: string |
| 54 | 60 | accessed*: int64 ## when this reader last opened it |
| 55 | 61 | lastActivity*: int64 |
| @@ -10,7 +10,7 @@ | |||
| 10 | ## and a missing key and a null key are the same thing on the other side. An | 10 | ## and a missing key and a null key are the same thing on the other side. An |
| 11 | ## Option would have to be unwrapped at every boundary anyway. | 11 | ## Option would have to be unwrapped at every boundary anyway. |
| 12 | 12 | ||
| 13 | -import std/[options, strutils] | 13 | +import std/[options, strutils, tables] |
| 14 | 14 | ||
| 15 | type | 15 | type |
| 16 | Reaction* = object | 16 | Reaction* = object |
| @@ -49,7 +49,13 @@ type | |||
| 49 | mention*: bool | 49 | mention*: bool |
| 50 | joined*: bool | 50 | joined*: bool |
| 51 | joining*: bool | 51 | joining*: bool |
| 52 | - users*: seq[string] | 52 | + users*: Table[string, string] |
| 53 | + ## nick → mode prefix ("" for none). A table and not a list because the | ||
| 54 | + ## people panel sorts ops first and a MODE has to find one person. | ||
| 55 | + namesAcc*: Table[string, string] | ||
| 56 | + ## The 353 replies so far. Pending rather than live: NAMES arrives over | ||
| 57 | + ## as many lines as it takes and ends with 366, and replacing `users` on | ||
| 58 | + ## each would empty the panel and refill it a name at a time. | ||
| 53 | topic*: string | 59 | topic*: string |
| 54 | accessed*: int64 ## when this reader last opened it | 60 | accessed*: int64 ## when this reader last opened it |
| 55 | lastActivity*: int64 | 61 | lastActivity*: int64 |
modified
nim/src/frq/reducer.nim +29 -9 | @@ -11,10 +11,10 @@ | ||
| 11 | 11 | ## payload: the alternative is a second serialisation to define and version, |
| 12 | 12 | ## for arguments that are always one string. |
| 13 | 13 | |
| 14 | -import std/[json, options, sequtils, strutils, tables] | |
| 14 | +import std/[json, options, strutils, tables] | |
| 15 | 15 | import std/sets |
| 16 | 16 | import frq/[cells, model, rooms, reactions, trace, ircparse, clock, |
| 17 | - atproto, handshake, textruns] | |
| 17 | + atproto, handshake, textruns, members] | |
| 18 | 18 | import frq/conn as tr |
| 19 | 19 | |
| 20 | 20 | proc split2(id: string): (string, string) = |
| @@ -384,8 +384,8 @@ proc drain*() = | ||
| 384 | 384 | if who == app.formNick: |
| 385 | 385 | r.joined = true |
| 386 | 386 | r.joining = false |
| 387 | - elif who notin r.users: | |
| 388 | - r.users.add who | |
| 387 | + elif not r.users.hasKey(who): | |
| 388 | + r.users[who] = "" | |
| 389 | 389 | app.rooms[room] = r |
| 390 | 390 | note(room, Message(frm: "*", text: who & " joined " & room, |
| 391 | 391 | at: at, system: true)) |
| @@ -395,20 +395,40 @@ proc drain*() = | ||
| 395 | 395 | let room = if p.params.len >= 1: p.params[0] else: app.current |
| 396 | 396 | if app.rooms.hasKey(room): |
| 397 | 397 | var r = app.rooms[room] |
| 398 | - r.users = r.users.filterIt(it != who) | |
| 398 | + r.users.del(who) | |
| 399 | 399 | app.rooms[room] = r |
| 400 | 400 | note(room, Message(frm: "*", text: who & " left", at: at, |
| 401 | 401 | system: true)) |
| 402 | 402 | |
| 403 | 403 | of "353": |
| 404 | - # NAMES: the membership, as a space-separated list in the trailing. | |
| 404 | + # NAMES, into the PENDING list. It arrives over as many lines as it | |
| 405 | + # takes and ends with 366; replacing `users` on each would empty the | |
| 406 | + # panel and refill it a name at a time. | |
| 405 | 407 | if p.params.len >= 2: |
| 406 | 408 | let room = p.params[^2] |
| 407 | 409 | if app.rooms.hasKey(room): |
| 408 | 410 | var r = app.rooms[room] |
| 409 | - for u in p.params[^1].split(' '): | |
| 410 | - let nick = u.strip(chars = {'@', '+', '~', '&', '%', ' '}) | |
| 411 | - if nick.len > 0 and nick notin r.users: r.users.add nick | |
| 411 | + r.namesAcc.withNames(p.params[^1]) | |
| 412 | + app.rooms[room] = r | |
| 413 | + | |
| 414 | + of "366": | |
| 415 | + # End of NAMES: the pending list becomes the list. | |
| 416 | + if p.params.len >= 1: | |
| 417 | + let room = p.params[^2] | |
| 418 | + if app.rooms.hasKey(room): | |
| 419 | + var r = app.rooms[room] | |
| 420 | + if r.namesAcc.len > 0: | |
| 421 | + r.users = r.namesAcc | |
| 422 | + r.namesAcc.clear() | |
| 423 | + app.rooms[room] = r | |
| 424 | + | |
| 425 | + of "MODE": | |
| 426 | + # A channel MODE, for the letters that change how someone is listed. | |
| 427 | + if p.params.len >= 2 and p.params[0].startsWith("#"): | |
| 428 | + let room = p.params[0] | |
| 429 | + if app.rooms.hasKey(room): | |
| 430 | + var r = app.rooms[room] | |
| 431 | + r.users.withMode(p.params[1], p.params[2 .. ^1]) | |
| 412 | 432 | app.rooms[room] = r |
| 413 | 433 | |
| 414 | 434 | of "332": |
| @@ -11,10 +11,10 @@ | |||
| 11 | ## payload: the alternative is a second serialisation to define and version, | 11 | ## payload: the alternative is a second serialisation to define and version, |
| 12 | ## for arguments that are always one string. | 12 | ## for arguments that are always one string. |
| 13 | 13 | ||
| 14 | -import std/[json, options, sequtils, strutils, tables] | 14 | +import std/[json, options, strutils, tables] |
| 15 | import std/sets | 15 | import std/sets |
| 16 | import frq/[cells, model, rooms, reactions, trace, ircparse, clock, | 16 | import frq/[cells, model, rooms, reactions, trace, ircparse, clock, |
| 17 | - atproto, handshake, textruns] | 17 | + atproto, handshake, textruns, members] |
| 18 | import frq/conn as tr | 18 | import frq/conn as tr |
| 19 | 19 | ||
| 20 | proc split2(id: string): (string, string) = | 20 | proc split2(id: string): (string, string) = |
| @@ -384,8 +384,8 @@ proc drain*() = | |||
| 384 | if who == app.formNick: | 384 | if who == app.formNick: |
| 385 | r.joined = true | 385 | r.joined = true |
| 386 | r.joining = false | 386 | r.joining = false |
| 387 | - elif who notin r.users: | 387 | + elif not r.users.hasKey(who): |
| 388 | - r.users.add who | 388 | + r.users[who] = "" |
| 389 | app.rooms[room] = r | 389 | app.rooms[room] = r |
| 390 | note(room, Message(frm: "*", text: who & " joined " & room, | 390 | note(room, Message(frm: "*", text: who & " joined " & room, |
| 391 | at: at, system: true)) | 391 | at: at, system: true)) |
| @@ -395,20 +395,40 @@ proc drain*() = | |||
| 395 | let room = if p.params.len >= 1: p.params[0] else: app.current | 395 | let room = if p.params.len >= 1: p.params[0] else: app.current |
| 396 | if app.rooms.hasKey(room): | 396 | if app.rooms.hasKey(room): |
| 397 | var r = app.rooms[room] | 397 | var r = app.rooms[room] |
| 398 | - r.users = r.users.filterIt(it != who) | 398 | + r.users.del(who) |
| 399 | app.rooms[room] = r | 399 | app.rooms[room] = r |
| 400 | note(room, Message(frm: "*", text: who & " left", at: at, | 400 | note(room, Message(frm: "*", text: who & " left", at: at, |
| 401 | system: true)) | 401 | system: true)) |
| 402 | 402 | ||
| 403 | of "353": | 403 | of "353": |
| 404 | - # NAMES: the membership, as a space-separated list in the trailing. | 404 | + # NAMES, into the PENDING list. It arrives over as many lines as it |
| 405 | + # takes and ends with 366; replacing `users` on each would empty the | ||
| 406 | + # panel and refill it a name at a time. | ||
| 405 | if p.params.len >= 2: | 407 | if p.params.len >= 2: |
| 406 | let room = p.params[^2] | 408 | let room = p.params[^2] |
| 407 | if app.rooms.hasKey(room): | 409 | if app.rooms.hasKey(room): |
| 408 | var r = app.rooms[room] | 410 | var r = app.rooms[room] |
| 409 | - for u in p.params[^1].split(' '): | 411 | + r.namesAcc.withNames(p.params[^1]) |
| 410 | - let nick = u.strip(chars = {'@', '+', '~', '&', '%', ' '}) | 412 | + app.rooms[room] = r |
| 411 | - if nick.len > 0 and nick notin r.users: r.users.add nick | 413 | + |
| 414 | + of "366": | ||
| 415 | + # End of NAMES: the pending list becomes the list. | ||
| 416 | + if p.params.len >= 1: | ||
| 417 | + let room = p.params[^2] | ||
| 418 | + if app.rooms.hasKey(room): | ||
| 419 | + var r = app.rooms[room] | ||
| 420 | + if r.namesAcc.len > 0: | ||
| 421 | + r.users = r.namesAcc | ||
| 422 | + r.namesAcc.clear() | ||
| 423 | + app.rooms[room] = r | ||
| 424 | + | ||
| 425 | + of "MODE": | ||
| 426 | + # A channel MODE, for the letters that change how someone is listed. | ||
| 427 | + if p.params.len >= 2 and p.params[0].startsWith("#"): | ||
| 428 | + let room = p.params[0] | ||
| 429 | + if app.rooms.hasKey(room): | ||
| 430 | + var r = app.rooms[room] | ||
| 431 | + r.users.withMode(p.params[1], p.params[2 .. ^1]) | ||
| 412 | app.rooms[room] = r | 432 | app.rooms[room] = r |
| 413 | 433 | ||
| 414 | of "332": | 434 | of "332": |
modified
nim/src/frq/screens/chat.nim +6 -4 | @@ -12,9 +12,9 @@ | ||
| 12 | 12 | ## dead buttons in ClojureDart and dead buttons here. When Flutter's camera |
| 13 | 13 | ## and audio plugins arrive this is the file they come back to. |
| 14 | 14 | |
| 15 | -import std/[algorithm, json, strutils] | |
| 15 | +import std/[algorithm, json, strutils, tables] | |
| 16 | 16 | import std/options |
| 17 | -import frq/[ui, cells, model, clock, reactions, textruns] | |
| 17 | +import frq/[ui, cells, model, clock, reactions, textruns, members] | |
| 18 | 18 | from frq/screens/connect import errorNote |
| 19 | 19 | |
| 20 | 20 | const |
| @@ -248,8 +248,10 @@ proc chatScreen*(s: State, connected: bool): Node = | ||
| 248 | 248 | if showUsers: |
| 249 | 249 | var panel = vbox(%*{"spacing": 4, "widthRequest": 150}, |
| 250 | 250 | title2("People")) |
| 251 | - for u in room.users: | |
| 252 | - panel.children.add label(u) | |
| 251 | + # Ops first, then alphabetically, with the mode prefix in front of the | |
| 252 | + # name — the order every other client lists them in. | |
| 253 | + for m in memberList(room.users): | |
| 254 | + panel.children.add label(m.prefix & m.nick) | |
| 253 | 255 | peoplePane.children.add panel |
| 254 | 256 | |
| 255 | 257 | var jump = vbox(%*{"key": "jump"}) |
| @@ -12,9 +12,9 @@ | |||
| 12 | ## dead buttons in ClojureDart and dead buttons here. When Flutter's camera | 12 | ## dead buttons in ClojureDart and dead buttons here. When Flutter's camera |
| 13 | ## and audio plugins arrive this is the file they come back to. | 13 | ## and audio plugins arrive this is the file they come back to. |
| 14 | 14 | ||
| 15 | -import std/[algorithm, json, strutils] | 15 | +import std/[algorithm, json, strutils, tables] |
| 16 | import std/options | 16 | import std/options |
| 17 | -import frq/[ui, cells, model, clock, reactions, textruns] | 17 | +import frq/[ui, cells, model, clock, reactions, textruns, members] |
| 18 | from frq/screens/connect import errorNote | 18 | from frq/screens/connect import errorNote |
| 19 | 19 | ||
| 20 | const | 20 | const |
| @@ -248,8 +248,10 @@ proc chatScreen*(s: State, connected: bool): Node = | |||
| 248 | if showUsers: | 248 | if showUsers: |
| 249 | var panel = vbox(%*{"spacing": 4, "widthRequest": 150}, | 249 | var panel = vbox(%*{"spacing": 4, "widthRequest": 150}, |
| 250 | title2("People")) | 250 | title2("People")) |
| 251 | - for u in room.users: | 251 | + # Ops first, then alphabetically, with the mode prefix in front of the |
| 252 | - panel.children.add label(u) | 252 | + # name — the order every other client lists them in. |
| 253 | + for m in memberList(room.users): | ||
| 254 | + panel.children.add label(m.prefix & m.nick) | ||
| 253 | peoplePane.children.add panel | 255 | peoplePane.children.add panel |
| 254 | 256 | ||
| 255 | var jump = vbox(%*{"key": "jump"}) | 257 | var jump = vbox(%*{"key": "jump"}) |
added
nim/src/frq/store.nim +137 -0 | new file mode 100644 | ||
| @@ -0,0 +1,137 @@ | ||
| 1 | +## What this client keeps on disk between runs. | |
| 2 | +## | |
| 3 | +## From `common/frq/store.cljc`. The Clojure writes EDN through the `frq.io` | |
| 4 | +## seam because ClojureDart had no portable filesystem; Nim has one, so the | |
| 5 | +## seam is gone and the format is JSON — nothing else reads these files, and a | |
| 6 | +## format with a parser in the standard library is one less thing to get wrong. | |
| 7 | +## | |
| 8 | +## Every read treats a file that will not parse as absent. A stale credential | |
| 9 | +## is not worth an error at startup, and a room with a broken marker would | |
| 10 | +## count its whole history unread — which is worse than a room that starts | |
| 11 | +## over. | |
| 12 | + | |
| 13 | +import std/[json, os, strutils, tables] | |
| 14 | +import frq/[model, trace] | |
| 15 | + | |
| 16 | +type | |
| 17 | + SavedSession* = object | |
| 18 | + ## The durable half of a sign-in. The web-token beside it is single-use | |
| 19 | + ## and deliberately not saved. | |
| 20 | + brokerToken*, handle*, did*, nick*: string | |
| 21 | + | |
| 22 | + SavedRoom* = object | |
| 23 | + ## A room and how much of it has been seen. | |
| 24 | + name*: string | |
| 25 | + accessed*: int64 | |
| 26 | + lastReadId*: string | |
| 27 | + lastReadAt*: int64 | |
| 28 | + | |
| 29 | +proc configDir*(): string = | |
| 30 | + ## Where this client's files go. | |
| 31 | + ## | |
| 32 | + ## `$XDG_CONFIG_HOME/frq`, or `~/.config/frq`. The Clojure asks the host | |
| 33 | + ## through `frq.io` because Android has no HOME to be relative to; this path | |
| 34 | + ## is the desktop's, and Android will want its own answer when the APK gets | |
| 35 | + ## a Nim core. | |
| 36 | + let xdg = getEnv("XDG_CONFIG_HOME") | |
| 37 | + if xdg.len > 0: xdg / "frq" else: getHomeDir() / ".config" / "frq" | |
| 38 | + | |
| 39 | +proc sessionFile*(): string = configDir() / "session.json" | |
| 40 | +proc roomsFile*(): string = configDir() / "rooms.json" | |
| 41 | +proc prefsFile*(): string = configDir() / "prefs.json" | |
| 42 | + | |
| 43 | +proc readJson(path: string): JsonNode = | |
| 44 | + ## The file as JSON, or nil where it is absent or will not parse. | |
| 45 | + if not fileExists(path): return nil | |
| 46 | + try: | |
| 47 | + parseJson(readFile(path)) | |
| 48 | + except CatchableError as e: | |
| 49 | + trace("store", "ignoring " & path & ": " & e.msg) | |
| 50 | + nil | |
| 51 | + | |
| 52 | +proc loadSession*(): (SavedSession, bool) = | |
| 53 | + ## The saved session, and whether there was one. | |
| 54 | + ## | |
| 55 | + ## A session with no broker token is not a session: the token is the whole | |
| 56 | + ## point of saving one, and the handle beside it is only there to say whose | |
| 57 | + ## it is. | |
| 58 | + let j = readJson(sessionFile()) | |
| 59 | + if j.isNil: return (SavedSession(), false) | |
| 60 | + let s = SavedSession(brokerToken: j{"brokerToken"}.getStr(), | |
| 61 | + handle: j{"handle"}.getStr(), | |
| 62 | + did: j{"did"}.getStr(), | |
| 63 | + nick: j{"nick"}.getStr()) | |
| 64 | + (s, s.brokerToken.len > 0) | |
| 65 | + | |
| 66 | +proc saveSession*(s: SavedSession): bool = | |
| 67 | + ## Written so nobody else can read it — the broker token goes through here | |
| 68 | + ## and nothing else does. | |
| 69 | + try: | |
| 70 | + createDir(configDir()) | |
| 71 | + let path = sessionFile() | |
| 72 | + writeFile(path, $(%*{"brokerToken": s.brokerToken, "handle": s.handle, | |
| 73 | + "did": s.did, "nick": s.nick})) | |
| 74 | + # Created first and restricted second, because there is no atomic | |
| 75 | + # create-with-mode here — the window is small and the alternative is a | |
| 76 | + # token written world-readable and never narrowed. | |
| 77 | + path.setFilePermissions({fpUserRead, fpUserWrite}) | |
| 78 | + true | |
| 79 | + except CatchableError as e: | |
| 80 | + trace("store", "could not save the session: " & e.msg) | |
| 81 | + false | |
| 82 | + | |
| 83 | +proc clearSession*() = | |
| 84 | + ## A token the broker no longer honours is dropped rather than replayed on | |
| 85 | + ## every Connect. | |
| 86 | + try: | |
| 87 | + removeFile(sessionFile()) | |
| 88 | + except CatchableError: | |
| 89 | + discard | |
| 90 | + | |
| 91 | +proc loadRooms*(): seq[SavedRoom] = | |
| 92 | + ## The rooms this client knows, most recently used first. | |
| 93 | + ## | |
| 94 | + ## This is the authority for what rooms exist. The server forgets them — it | |
| 95 | + ## has told us we are in rooms we are not, and left out ones we are — so a | |
| 96 | + ## room is gone when the reader closes it here and not before. | |
| 97 | + let j = readJson(roomsFile()) | |
| 98 | + if j.isNil or j.kind != JArray: return | |
| 99 | + for r in j: | |
| 100 | + let name = r{"name"}.getStr() | |
| 101 | + if name.len == 0: continue | |
| 102 | + result.add SavedRoom(name: name, | |
| 103 | + accessed: r{"accessed"}.getBiggestInt(), | |
| 104 | + lastReadId: r{"lastReadId"}.getStr(), | |
| 105 | + lastReadAt: r{"lastReadAt"}.getBiggestInt()) | |
| 106 | + | |
| 107 | +proc saveRooms*(rooms: OrderedTable[string, Room]): bool = | |
| 108 | + ## The marker goes with the name, which is the point of saving at all: a | |
| 109 | + ## phone that comes back to a hundred lines it has already read is a phone | |
| 110 | + ## that kept the names and lost the markers. | |
| 111 | + try: | |
| 112 | + createDir(configDir()) | |
| 113 | + var arr = newJArray() | |
| 114 | + for name, r in rooms: | |
| 115 | + arr.add %*{"name": name, "accessed": r.accessed, | |
| 116 | + "lastReadId": r.lastReadId, "lastReadAt": r.lastReadAt} | |
| 117 | + writeFile(roomsFile(), $arr) | |
| 118 | + true | |
| 119 | + except CatchableError as e: | |
| 120 | + trace("store", "could not save the rooms: " & e.msg) | |
| 121 | + false | |
| 122 | + | |
| 123 | +proc loadPrefs*(): Table[string, bool] = | |
| 124 | + let j = readJson(prefsFile()) | |
| 125 | + if j.isNil or j.kind != JObject: return | |
| 126 | + for k, v in j: | |
| 127 | + if v.kind == JBool: result[k] = v.getBool() | |
| 128 | + | |
| 129 | +proc savePrefs*(prefs: Table[string, bool]): bool = | |
| 130 | + try: | |
| 131 | + createDir(configDir()) | |
| 132 | + var o = newJObject() | |
| 133 | + for k, v in prefs: o[k] = %v | |
| 134 | + writeFile(prefsFile(), $o) | |
| 135 | + true | |
| 136 | + except CatchableError: | |
| 137 | + false | |
| new file mode 100644 | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | +## What this client keeps on disk between runs. | ||
| 2 | +## | ||
| 3 | +## From `common/frq/store.cljc`. The Clojure writes EDN through the `frq.io` | ||
| 4 | +## seam because ClojureDart had no portable filesystem; Nim has one, so the | ||
| 5 | +## seam is gone and the format is JSON — nothing else reads these files, and a | ||
| 6 | +## format with a parser in the standard library is one less thing to get wrong. | ||
| 7 | +## | ||
| 8 | +## Every read treats a file that will not parse as absent. A stale credential | ||
| 9 | +## is not worth an error at startup, and a room with a broken marker would | ||
| 10 | +## count its whole history unread — which is worse than a room that starts | ||
| 11 | +## over. | ||
| 12 | + | ||
| 13 | +import std/[json, os, strutils, tables] | ||
| 14 | +import frq/[model, trace] | ||
| 15 | + | ||
| 16 | +type | ||
| 17 | + SavedSession* = object | ||
| 18 | + ## The durable half of a sign-in. The web-token beside it is single-use | ||
| 19 | + ## and deliberately not saved. | ||
| 20 | + brokerToken*, handle*, did*, nick*: string | ||
| 21 | + | ||
| 22 | + SavedRoom* = object | ||
| 23 | + ## A room and how much of it has been seen. | ||
| 24 | + name*: string | ||
| 25 | + accessed*: int64 | ||
| 26 | + lastReadId*: string | ||
| 27 | + lastReadAt*: int64 | ||
| 28 | + | ||
| 29 | +proc configDir*(): string = | ||
| 30 | + ## Where this client's files go. | ||
| 31 | + ## | ||
| 32 | + ## `$XDG_CONFIG_HOME/frq`, or `~/.config/frq`. The Clojure asks the host | ||
| 33 | + ## through `frq.io` because Android has no HOME to be relative to; this path | ||
| 34 | + ## is the desktop's, and Android will want its own answer when the APK gets | ||
| 35 | + ## a Nim core. | ||
| 36 | + let xdg = getEnv("XDG_CONFIG_HOME") | ||
| 37 | + if xdg.len > 0: xdg / "frq" else: getHomeDir() / ".config" / "frq" | ||
| 38 | + | ||
| 39 | +proc sessionFile*(): string = configDir() / "session.json" | ||
| 40 | +proc roomsFile*(): string = configDir() / "rooms.json" | ||
| 41 | +proc prefsFile*(): string = configDir() / "prefs.json" | ||
| 42 | + | ||
| 43 | +proc readJson(path: string): JsonNode = | ||
| 44 | + ## The file as JSON, or nil where it is absent or will not parse. | ||
| 45 | + if not fileExists(path): return nil | ||
| 46 | + try: | ||
| 47 | + parseJson(readFile(path)) | ||
| 48 | + except CatchableError as e: | ||
| 49 | + trace("store", "ignoring " & path & ": " & e.msg) | ||
| 50 | + nil | ||
| 51 | + | ||
| 52 | +proc loadSession*(): (SavedSession, bool) = | ||
| 53 | + ## The saved session, and whether there was one. | ||
| 54 | + ## | ||
| 55 | + ## A session with no broker token is not a session: the token is the whole | ||
| 56 | + ## point of saving one, and the handle beside it is only there to say whose | ||
| 57 | + ## it is. | ||
| 58 | + let j = readJson(sessionFile()) | ||
| 59 | + if j.isNil: return (SavedSession(), false) | ||
| 60 | + let s = SavedSession(brokerToken: j{"brokerToken"}.getStr(), | ||
| 61 | + handle: j{"handle"}.getStr(), | ||
| 62 | + did: j{"did"}.getStr(), | ||
| 63 | + nick: j{"nick"}.getStr()) | ||
| 64 | + (s, s.brokerToken.len > 0) | ||
| 65 | + | ||
| 66 | +proc saveSession*(s: SavedSession): bool = | ||
| 67 | + ## Written so nobody else can read it — the broker token goes through here | ||
| 68 | + ## and nothing else does. | ||
| 69 | + try: | ||
| 70 | + createDir(configDir()) | ||
| 71 | + let path = sessionFile() | ||
| 72 | + writeFile(path, $(%*{"brokerToken": s.brokerToken, "handle": s.handle, | ||
| 73 | + "did": s.did, "nick": s.nick})) | ||
| 74 | + # Created first and restricted second, because there is no atomic | ||
| 75 | + # create-with-mode here — the window is small and the alternative is a | ||
| 76 | + # token written world-readable and never narrowed. | ||
| 77 | + path.setFilePermissions({fpUserRead, fpUserWrite}) | ||
| 78 | + true | ||
| 79 | + except CatchableError as e: | ||
| 80 | + trace("store", "could not save the session: " & e.msg) | ||
| 81 | + false | ||
| 82 | + | ||
| 83 | +proc clearSession*() = | ||
| 84 | + ## A token the broker no longer honours is dropped rather than replayed on | ||
| 85 | + ## every Connect. | ||
| 86 | + try: | ||
| 87 | + removeFile(sessionFile()) | ||
| 88 | + except CatchableError: | ||
| 89 | + discard | ||
| 90 | + | ||
| 91 | +proc loadRooms*(): seq[SavedRoom] = | ||
| 92 | + ## The rooms this client knows, most recently used first. | ||
| 93 | + ## | ||
| 94 | + ## This is the authority for what rooms exist. The server forgets them — it | ||
| 95 | + ## has told us we are in rooms we are not, and left out ones we are — so a | ||
| 96 | + ## room is gone when the reader closes it here and not before. | ||
| 97 | + let j = readJson(roomsFile()) | ||
| 98 | + if j.isNil or j.kind != JArray: return | ||
| 99 | + for r in j: | ||
| 100 | + let name = r{"name"}.getStr() | ||
| 101 | + if name.len == 0: continue | ||
| 102 | + result.add SavedRoom(name: name, | ||
| 103 | + accessed: r{"accessed"}.getBiggestInt(), | ||
| 104 | + lastReadId: r{"lastReadId"}.getStr(), | ||
| 105 | + lastReadAt: r{"lastReadAt"}.getBiggestInt()) | ||
| 106 | + | ||
| 107 | +proc saveRooms*(rooms: OrderedTable[string, Room]): bool = | ||
| 108 | + ## The marker goes with the name, which is the point of saving at all: a | ||
| 109 | + ## phone that comes back to a hundred lines it has already read is a phone | ||
| 110 | + ## that kept the names and lost the markers. | ||
| 111 | + try: | ||
| 112 | + createDir(configDir()) | ||
| 113 | + var arr = newJArray() | ||
| 114 | + for name, r in rooms: | ||
| 115 | + arr.add %*{"name": name, "accessed": r.accessed, | ||
| 116 | + "lastReadId": r.lastReadId, "lastReadAt": r.lastReadAt} | ||
| 117 | + writeFile(roomsFile(), $arr) | ||
| 118 | + true | ||
| 119 | + except CatchableError as e: | ||
| 120 | + trace("store", "could not save the rooms: " & e.msg) | ||
| 121 | + false | ||
| 122 | + | ||
| 123 | +proc loadPrefs*(): Table[string, bool] = | ||
| 124 | + let j = readJson(prefsFile()) | ||
| 125 | + if j.isNil or j.kind != JObject: return | ||
| 126 | + for k, v in j: | ||
| 127 | + if v.kind == JBool: result[k] = v.getBool() | ||
| 128 | + | ||
| 129 | +proc savePrefs*(prefs: Table[string, bool]): bool = | ||
| 130 | + try: | ||
| 131 | + createDir(configDir()) | ||
| 132 | + var o = newJObject() | ||
| 133 | + for k, v in prefs: o[k] = %v | ||
| 134 | + writeFile(prefsFile(), $o) | ||
| 135 | + true | ||
| 136 | + except CatchableError: | ||
| 137 | + false | ||
modified
nim/src/frq_core.nim +1 -1 | @@ -206,7 +206,7 @@ proc frq_ui_demo*() {.exportc, dynlib.} = | ||
| 206 | 206 | app.rooms.ensureRoom("#test") |
| 207 | 207 | var r = app.rooms["#test"] |
| 208 | 208 | r.joined = true |
| 209 | - r.users = @["me", "alice", "bob"] | |
| 209 | + r.users = {"me": "", "alice": "@", "bob": ""}.toTable | |
| 210 | 210 | r.topic = "a room" |
| 211 | 211 | let t0 = 1_700_000_000_000'i64 |
| 212 | 212 | r.messages = @[ |
| @@ -206,7 +206,7 @@ proc frq_ui_demo*() {.exportc, dynlib.} = | |||
| 206 | app.rooms.ensureRoom("#test") | 206 | app.rooms.ensureRoom("#test") |
| 207 | var r = app.rooms["#test"] | 207 | var r = app.rooms["#test"] |
| 208 | r.joined = true | 208 | r.joined = true |
| 209 | - r.users = @["me", "alice", "bob"] | 209 | + r.users = {"me": "", "alice": "@", "bob": ""}.toTable |
| 210 | r.topic = "a room" | 210 | r.topic = "a room" |
| 211 | let t0 = 1_700_000_000_000'i64 | 211 | let t0 = 1_700_000_000_000'i64 |
| 212 | r.messages = @[ | 212 | r.messages = @[ |
modified
nim/tests/tchat.nim +1 -1 | @@ -19,7 +19,7 @@ proc withRoom(): State = | ||
| 19 | 19 | result = initState() |
| 20 | 20 | var r = initRoom("#test") |
| 21 | 21 | r.joined = true |
| 22 | - r.users = @["alice", "bob"] | |
| 22 | + r.users = {"alice": "@", "bob": ""}.toTable | |
| 23 | 23 | r.messages = @[ |
| 24 | 24 | Message(id: "1", frm: "alice", text: "hello", at: 1_700_000_000_000), |
| 25 | 25 | Message(id: "2", frm: "frq-guest", text: "hi back", at: 1_700_000_060_000)] |
| @@ -19,7 +19,7 @@ proc withRoom(): State = | |||
| 19 | result = initState() | 19 | result = initState() |
| 20 | var r = initRoom("#test") | 20 | var r = initRoom("#test") |
| 21 | r.joined = true | 21 | r.joined = true |
| 22 | - r.users = @["alice", "bob"] | 22 | + r.users = {"alice": "@", "bob": ""}.toTable |
| 23 | r.messages = @[ | 23 | r.messages = @[ |
| 24 | Message(id: "1", frm: "alice", text: "hello", at: 1_700_000_000_000), | 24 | Message(id: "1", frm: "alice", text: "hello", at: 1_700_000_000_000), |
| 25 | Message(id: "2", frm: "frq-guest", text: "hi back", at: 1_700_000_060_000)] | 25 | Message(id: "2", frm: "frq-guest", text: "hi back", at: 1_700_000_060_000)] |
added
nim/tests/tglyphs.nim +93 -0 | new file mode 100644 | ||
| @@ -0,0 +1,93 @@ | ||
| 1 | +## Splitting a line into words and pictures. | |
| 2 | + | |
| 3 | +import std/[sequtils, strutils, unittest] | |
| 4 | +import frq/[glyphs, emoji] | |
| 5 | + | |
| 6 | +proc kinds(s: string): seq[RunKind] = runs(s).mapIt(it.kind) | |
| 7 | +proc values(s: string): seq[string] = runs(s).mapIt(it.value) | |
| 8 | + | |
| 9 | +suite "the catalogue": | |
| 10 | + test "is the whole of Unicode's list, filtered to what can be drawn": | |
| 11 | + check catalog.len == 1884 | |
| 12 | + check popular.len == 16 | |
| 13 | + check groups.len == 9 | |
| 14 | + test "every entry has all three fields": | |
| 15 | + for e in catalog: | |
| 16 | + check e.glyph.len > 0 | |
| 17 | + check e.name.len > 0 | |
| 18 | + check e.group.len > 0 | |
| 19 | + | |
| 20 | +suite "runs": | |
| 21 | + test "plain text is one run": | |
| 22 | + check kinds("hello") == @[gkText] | |
| 23 | + check values("hello") == @["hello"] | |
| 24 | + | |
| 25 | + test "a bare emoji is one picture": | |
| 26 | + check kinds("👍") == @[gkEmoji] | |
| 27 | + check values("👍") == @["👍"] | |
| 28 | + | |
| 29 | + test "text around an emoji": | |
| 30 | + check kinds("hi 👍 there") == @[gkText, gkEmoji, gkText] | |
| 31 | + check values("hi 👍 there") == @["hi ", "👍", " there"] | |
| 32 | + | |
| 33 | + test "two emoji side by side are two runs": | |
| 34 | + # A node draws one picture. | |
| 35 | + check kinds("👍🎉") == @[gkEmoji, gkEmoji] | |
| 36 | + | |
| 37 | + test "empty text is no runs": | |
| 38 | + check runs("").len == 0 | |
| 39 | + | |
| 40 | + test "a family is one glyph, not its parts": | |
| 41 | + # 👨 is the head of 👨👩👧; taking the man would leave his family as | |
| 42 | + # three more glyphs and two tofu joiners. | |
| 43 | + let got = runs("👨👩👧") | |
| 44 | + check got.len == 1 | |
| 45 | + check got[0].kind == gkEmoji | |
| 46 | + | |
| 47 | + test "a toned emoji is one picture, and keeps its tone": | |
| 48 | + # The catalogue leaves toned variants out; the pack has them, so the tone | |
| 49 | + # is stripped for the lookup and kept for the drawing. | |
| 50 | + let got = runs("👍🏽") | |
| 51 | + check got.len == 1 | |
| 52 | + check got[0].kind == gkEmoji | |
| 53 | + check "🏽" in got[0].value | |
| 54 | + | |
| 55 | + test "a character the pack has no picture for stays text": | |
| 56 | + check kinds("←") == @[gkText] # ← is not in the pack | |
| 57 | + | |
| 58 | + test "non-ASCII text that is not emoji is left alone": | |
| 59 | + check values("héllo wörld") == @["héllo wörld"] | |
| 60 | + | |
| 61 | +suite "hasEmoji": | |
| 62 | + test "yes": | |
| 63 | + check runs("a 👍").hasEmoji | |
| 64 | + test "no": | |
| 65 | + check not runs("just words").hasEmoji | |
| 66 | + | |
| 67 | +suite "pickerEmoji": | |
| 68 | + test "nothing selected shows the popular row": | |
| 69 | + let got = pickerEmoji("", "") | |
| 70 | + check got.len == popular.len | |
| 71 | + check got[0].glyph == popular[0] | |
| 72 | + | |
| 73 | + test "a group shows that group": | |
| 74 | + let got = pickerEmoji("", "Flags") | |
| 75 | + check got.len > 0 | |
| 76 | + check got.allIt(it.group == "Flags") | |
| 77 | + | |
| 78 | + test "search finds by name": | |
| 79 | + let got = pickerEmoji("grinning", "") | |
| 80 | + check got.len > 0 | |
| 81 | + check got.allIt("grinning" in it.name.toLower()) | |
| 82 | + | |
| 83 | + test "search finds the cat and the cat face": | |
| 84 | + check pickerEmoji("cat", "").len > 1 | |
| 85 | + | |
| 86 | + test "search finds a pasted glyph": | |
| 87 | + let got = pickerEmoji("👍", "") | |
| 88 | + check got.len == 1 | |
| 89 | + check got[0].glyph == "👍" | |
| 90 | + | |
| 91 | + test "search beats a selected group": | |
| 92 | + # A search is what the reader just typed; the group is where they were. | |
| 93 | + check pickerEmoji("grinning", "Flags").allIt(it.group != "Flags") | |
| new file mode 100644 | |||
| @@ -0,0 +1,93 @@ | |||
| 1 | +## Splitting a line into words and pictures. | ||
| 2 | + | ||
| 3 | +import std/[sequtils, strutils, unittest] | ||
| 4 | +import frq/[glyphs, emoji] | ||
| 5 | + | ||
| 6 | +proc kinds(s: string): seq[RunKind] = runs(s).mapIt(it.kind) | ||
| 7 | +proc values(s: string): seq[string] = runs(s).mapIt(it.value) | ||
| 8 | + | ||
| 9 | +suite "the catalogue": | ||
| 10 | + test "is the whole of Unicode's list, filtered to what can be drawn": | ||
| 11 | + check catalog.len == 1884 | ||
| 12 | + check popular.len == 16 | ||
| 13 | + check groups.len == 9 | ||
| 14 | + test "every entry has all three fields": | ||
| 15 | + for e in catalog: | ||
| 16 | + check e.glyph.len > 0 | ||
| 17 | + check e.name.len > 0 | ||
| 18 | + check e.group.len > 0 | ||
| 19 | + | ||
| 20 | +suite "runs": | ||
| 21 | + test "plain text is one run": | ||
| 22 | + check kinds("hello") == @[gkText] | ||
| 23 | + check values("hello") == @["hello"] | ||
| 24 | + | ||
| 25 | + test "a bare emoji is one picture": | ||
| 26 | + check kinds("👍") == @[gkEmoji] | ||
| 27 | + check values("👍") == @["👍"] | ||
| 28 | + | ||
| 29 | + test "text around an emoji": | ||
| 30 | + check kinds("hi 👍 there") == @[gkText, gkEmoji, gkText] | ||
| 31 | + check values("hi 👍 there") == @["hi ", "👍", " there"] | ||
| 32 | + | ||
| 33 | + test "two emoji side by side are two runs": | ||
| 34 | + # A node draws one picture. | ||
| 35 | + check kinds("👍🎉") == @[gkEmoji, gkEmoji] | ||
| 36 | + | ||
| 37 | + test "empty text is no runs": | ||
| 38 | + check runs("").len == 0 | ||
| 39 | + | ||
| 40 | + test "a family is one glyph, not its parts": | ||
| 41 | + # 👨 is the head of 👨👩👧; taking the man would leave his family as | ||
| 42 | + # three more glyphs and two tofu joiners. | ||
| 43 | + let got = runs("👨👩👧") | ||
| 44 | + check got.len == 1 | ||
| 45 | + check got[0].kind == gkEmoji | ||
| 46 | + | ||
| 47 | + test "a toned emoji is one picture, and keeps its tone": | ||
| 48 | + # The catalogue leaves toned variants out; the pack has them, so the tone | ||
| 49 | + # is stripped for the lookup and kept for the drawing. | ||
| 50 | + let got = runs("👍🏽") | ||
| 51 | + check got.len == 1 | ||
| 52 | + check got[0].kind == gkEmoji | ||
| 53 | + check "🏽" in got[0].value | ||
| 54 | + | ||
| 55 | + test "a character the pack has no picture for stays text": | ||
| 56 | + check kinds("←") == @[gkText] # ← is not in the pack | ||
| 57 | + | ||
| 58 | + test "non-ASCII text that is not emoji is left alone": | ||
| 59 | + check values("héllo wörld") == @["héllo wörld"] | ||
| 60 | + | ||
| 61 | +suite "hasEmoji": | ||
| 62 | + test "yes": | ||
| 63 | + check runs("a 👍").hasEmoji | ||
| 64 | + test "no": | ||
| 65 | + check not runs("just words").hasEmoji | ||
| 66 | + | ||
| 67 | +suite "pickerEmoji": | ||
| 68 | + test "nothing selected shows the popular row": | ||
| 69 | + let got = pickerEmoji("", "") | ||
| 70 | + check got.len == popular.len | ||
| 71 | + check got[0].glyph == popular[0] | ||
| 72 | + | ||
| 73 | + test "a group shows that group": | ||
| 74 | + let got = pickerEmoji("", "Flags") | ||
| 75 | + check got.len > 0 | ||
| 76 | + check got.allIt(it.group == "Flags") | ||
| 77 | + | ||
| 78 | + test "search finds by name": | ||
| 79 | + let got = pickerEmoji("grinning", "") | ||
| 80 | + check got.len > 0 | ||
| 81 | + check got.allIt("grinning" in it.name.toLower()) | ||
| 82 | + | ||
| 83 | + test "search finds the cat and the cat face": | ||
| 84 | + check pickerEmoji("cat", "").len > 1 | ||
| 85 | + | ||
| 86 | + test "search finds a pasted glyph": | ||
| 87 | + let got = pickerEmoji("👍", "") | ||
| 88 | + check got.len == 1 | ||
| 89 | + check got[0].glyph == "👍" | ||
| 90 | + | ||
| 91 | + test "search beats a selected group": | ||
| 92 | + # A search is what the reader just typed; the group is where they were. | ||
| 93 | + check pickerEmoji("grinning", "Flags").allIt(it.group != "Flags") | ||
added
nim/tests/tmembers.nim +110 -0 | new file mode 100644 | ||
| @@ -0,0 +1,110 @@ | ||
| 1 | +## Membership, modes, and Tab completion. | |
| 2 | + | |
| 3 | +import std/[sequtils, tables, unittest] | |
| 4 | +import frq/members | |
| 5 | + | |
| 6 | +suite "splitPrefix": | |
| 7 | + test "a mode in front of a nick": | |
| 8 | + check splitPrefix("@alice") == ("@", "alice") | |
| 9 | + check splitPrefix("+bob") == ("+", "bob") | |
| 10 | + test "a bare nick": | |
| 11 | + check splitPrefix("carol") == ("", "carol") | |
| 12 | + test "an empty entry": | |
| 13 | + check splitPrefix("") == ("", "") | |
| 14 | + | |
| 15 | +suite "withNames": | |
| 16 | + test "folds a 353 into the pending list": | |
| 17 | + var acc = initTable[string, string]() | |
| 18 | + acc.withNames("@alice bob +carol") | |
| 19 | + check acc["alice"] == "@" | |
| 20 | + check acc["bob"] == "" | |
| 21 | + check acc["carol"] == "+" | |
| 22 | + | |
| 23 | + test "several replies accumulate rather than replace": | |
| 24 | + # NAMES arrives over as many lines as it takes. | |
| 25 | + var acc = initTable[string, string]() | |
| 26 | + acc.withNames("@alice") | |
| 27 | + acc.withNames("bob") | |
| 28 | + check acc.len == 2 | |
| 29 | + | |
| 30 | + test "runs of spaces do not become members": | |
| 31 | + var acc = initTable[string, string]() | |
| 32 | + acc.withNames("alice bob") | |
| 33 | + check acc.len == 2 | |
| 34 | + | |
| 35 | +suite "withMode": | |
| 36 | + setup: | |
| 37 | + var users = {"alice": "", "bob": "", "carol": ""}.toTable | |
| 38 | + | |
| 39 | + test "granting op": | |
| 40 | + users.withMode("+o", @["alice"]) | |
| 41 | + check users["alice"] == "@" | |
| 42 | + | |
| 43 | + test "taking it away": | |
| 44 | + users.withMode("+o", @["alice"]) | |
| 45 | + users.withMode("-o", @["alice"]) | |
| 46 | + check users["alice"] == "" | |
| 47 | + | |
| 48 | + test "several at once, in order": | |
| 49 | + users.withMode("+ov", @["alice", "bob"]) | |
| 50 | + check users["alice"] == "@" | |
| 51 | + check users["bob"] == "+" | |
| 52 | + | |
| 53 | + test "a mode naming nobody still eats its argument": | |
| 54 | + # The rule this exists for: `+ko secret alice` sets a key and then ops | |
| 55 | + # alice. Reading the next letter's nick out of the wrong place would put | |
| 56 | + # the op on whoever `secret` happened to match. | |
| 57 | + users.withMode("+ko", @["secret", "alice"]) | |
| 58 | + check users["alice"] == "@" | |
| 59 | + check users["bob"] == "" | |
| 60 | + | |
| 61 | + test "a mode for somebody who is not here changes nothing": | |
| 62 | + users.withMode("+o", @["stranger"]) | |
| 63 | + check "stranger" notin users | |
| 64 | + | |
| 65 | + test "removing a mode takes no argument on some servers, and we do not eat one": | |
| 66 | + users.withMode("+o", @["alice"]) | |
| 67 | + users.withMode("-l+v", @["bob"]) | |
| 68 | + check users["bob"] == "+" | |
| 69 | + | |
| 70 | +suite "memberList": | |
| 71 | + test "ops first, then alphabetically": | |
| 72 | + let users = {"zoe": "", "alice": "", "bob": "@", "carol": "+"}.toTable | |
| 73 | + check memberList(users).mapIt(it.nick) == @["bob", "carol", "alice", "zoe"] | |
| 74 | + | |
| 75 | + test "the prefix order is the server's": | |
| 76 | + let users = {"v": "+", "o": "@", "q": "~", "plain": ""}.toTable | |
| 77 | + check memberList(users).mapIt(it.nick) == @["q", "o", "v", "plain"] | |
| 78 | + | |
| 79 | + test "case does not decide the alphabetical order": | |
| 80 | + let users = {"Bob": "", "alice": ""}.toTable | |
| 81 | + check memberList(users).mapIt(it.nick) == @["alice", "Bob"] | |
| 82 | + | |
| 83 | +suite "completeNick": | |
| 84 | + let nicks = @["alice", "alison", "bob"] | |
| 85 | + | |
| 86 | + test "one match is taken whole": | |
| 87 | + check completeNick("hi bo", nicks) == ("hi bob ", true) | |
| 88 | + | |
| 89 | + test "at the start of a line it is an address, elsewhere a mention": | |
| 90 | + # `eve: watch this` reads as talking TO eve; mid-sentence it is just a | |
| 91 | + # name, so it gets a plain space. | |
| 92 | + check completeNick("bo", nicks)[0] == "bob: " | |
| 93 | + check completeNick("hi bo", nicks)[0] == "hi bob " | |
| 94 | + | |
| 95 | + test "several matches go as far as they agree": | |
| 96 | + check completeNick("al", nicks) == ("ali", true) | |
| 97 | + | |
| 98 | + test "no match leaves the draft alone": | |
| 99 | + check completeNick("zz", nicks) == ("zz", false) | |
| 100 | + | |
| 101 | + test "nothing to complete": | |
| 102 | + check completeNick("", nicks)[1] == false | |
| 103 | + check completeNick("hi ", nicks)[1] == false | |
| 104 | + | |
| 105 | + test "case is ignored, and the nick's own case lands": | |
| 106 | + check completeNick("hi BO", nicks) == ("hi bob ", true) | |
| 107 | + | |
| 108 | + test "a completed word is not completed again": | |
| 109 | + # "ali" already agrees with both; there is nothing more to add. | |
| 110 | + check completeNick("ali", nicks)[1] == false | |
| new file mode 100644 | |||
| @@ -0,0 +1,110 @@ | |||
| 1 | +## Membership, modes, and Tab completion. | ||
| 2 | + | ||
| 3 | +import std/[sequtils, tables, unittest] | ||
| 4 | +import frq/members | ||
| 5 | + | ||
| 6 | +suite "splitPrefix": | ||
| 7 | + test "a mode in front of a nick": | ||
| 8 | + check splitPrefix("@alice") == ("@", "alice") | ||
| 9 | + check splitPrefix("+bob") == ("+", "bob") | ||
| 10 | + test "a bare nick": | ||
| 11 | + check splitPrefix("carol") == ("", "carol") | ||
| 12 | + test "an empty entry": | ||
| 13 | + check splitPrefix("") == ("", "") | ||
| 14 | + | ||
| 15 | +suite "withNames": | ||
| 16 | + test "folds a 353 into the pending list": | ||
| 17 | + var acc = initTable[string, string]() | ||
| 18 | + acc.withNames("@alice bob +carol") | ||
| 19 | + check acc["alice"] == "@" | ||
| 20 | + check acc["bob"] == "" | ||
| 21 | + check acc["carol"] == "+" | ||
| 22 | + | ||
| 23 | + test "several replies accumulate rather than replace": | ||
| 24 | + # NAMES arrives over as many lines as it takes. | ||
| 25 | + var acc = initTable[string, string]() | ||
| 26 | + acc.withNames("@alice") | ||
| 27 | + acc.withNames("bob") | ||
| 28 | + check acc.len == 2 | ||
| 29 | + | ||
| 30 | + test "runs of spaces do not become members": | ||
| 31 | + var acc = initTable[string, string]() | ||
| 32 | + acc.withNames("alice bob") | ||
| 33 | + check acc.len == 2 | ||
| 34 | + | ||
| 35 | +suite "withMode": | ||
| 36 | + setup: | ||
| 37 | + var users = {"alice": "", "bob": "", "carol": ""}.toTable | ||
| 38 | + | ||
| 39 | + test "granting op": | ||
| 40 | + users.withMode("+o", @["alice"]) | ||
| 41 | + check users["alice"] == "@" | ||
| 42 | + | ||
| 43 | + test "taking it away": | ||
| 44 | + users.withMode("+o", @["alice"]) | ||
| 45 | + users.withMode("-o", @["alice"]) | ||
| 46 | + check users["alice"] == "" | ||
| 47 | + | ||
| 48 | + test "several at once, in order": | ||
| 49 | + users.withMode("+ov", @["alice", "bob"]) | ||
| 50 | + check users["alice"] == "@" | ||
| 51 | + check users["bob"] == "+" | ||
| 52 | + | ||
| 53 | + test "a mode naming nobody still eats its argument": | ||
| 54 | + # The rule this exists for: `+ko secret alice` sets a key and then ops | ||
| 55 | + # alice. Reading the next letter's nick out of the wrong place would put | ||
| 56 | + # the op on whoever `secret` happened to match. | ||
| 57 | + users.withMode("+ko", @["secret", "alice"]) | ||
| 58 | + check users["alice"] == "@" | ||
| 59 | + check users["bob"] == "" | ||
| 60 | + | ||
| 61 | + test "a mode for somebody who is not here changes nothing": | ||
| 62 | + users.withMode("+o", @["stranger"]) | ||
| 63 | + check "stranger" notin users | ||
| 64 | + | ||
| 65 | + test "removing a mode takes no argument on some servers, and we do not eat one": | ||
| 66 | + users.withMode("+o", @["alice"]) | ||
| 67 | + users.withMode("-l+v", @["bob"]) | ||
| 68 | + check users["bob"] == "+" | ||
| 69 | + | ||
| 70 | +suite "memberList": | ||
| 71 | + test "ops first, then alphabetically": | ||
| 72 | + let users = {"zoe": "", "alice": "", "bob": "@", "carol": "+"}.toTable | ||
| 73 | + check memberList(users).mapIt(it.nick) == @["bob", "carol", "alice", "zoe"] | ||
| 74 | + | ||
| 75 | + test "the prefix order is the server's": | ||
| 76 | + let users = {"v": "+", "o": "@", "q": "~", "plain": ""}.toTable | ||
| 77 | + check memberList(users).mapIt(it.nick) == @["q", "o", "v", "plain"] | ||
| 78 | + | ||
| 79 | + test "case does not decide the alphabetical order": | ||
| 80 | + let users = {"Bob": "", "alice": ""}.toTable | ||
| 81 | + check memberList(users).mapIt(it.nick) == @["alice", "Bob"] | ||
| 82 | + | ||
| 83 | +suite "completeNick": | ||
| 84 | + let nicks = @["alice", "alison", "bob"] | ||
| 85 | + | ||
| 86 | + test "one match is taken whole": | ||
| 87 | + check completeNick("hi bo", nicks) == ("hi bob ", true) | ||
| 88 | + | ||
| 89 | + test "at the start of a line it is an address, elsewhere a mention": | ||
| 90 | + # `eve: watch this` reads as talking TO eve; mid-sentence it is just a | ||
| 91 | + # name, so it gets a plain space. | ||
| 92 | + check completeNick("bo", nicks)[0] == "bob: " | ||
| 93 | + check completeNick("hi bo", nicks)[0] == "hi bob " | ||
| 94 | + | ||
| 95 | + test "several matches go as far as they agree": | ||
| 96 | + check completeNick("al", nicks) == ("ali", true) | ||
| 97 | + | ||
| 98 | + test "no match leaves the draft alone": | ||
| 99 | + check completeNick("zz", nicks) == ("zz", false) | ||
| 100 | + | ||
| 101 | + test "nothing to complete": | ||
| 102 | + check completeNick("", nicks)[1] == false | ||
| 103 | + check completeNick("hi ", nicks)[1] == false | ||
| 104 | + | ||
| 105 | + test "case is ignored, and the nick's own case lands": | ||
| 106 | + check completeNick("hi BO", nicks) == ("hi bob ", true) | ||
| 107 | + | ||
| 108 | + test "a completed word is not completed again": | ||
| 109 | + # "ali" already agrees with both; there is nothing more to add. | ||
| 110 | + check completeNick("ali", nicks)[1] == false | ||
added
nim/tests/tstore.nim +119 -0 | new file mode 100644 | ||
| @@ -0,0 +1,119 @@ | ||
| 1 | +## What survives a restart. Every case runs against a real directory under a | |
| 2 | +## temporary XDG_CONFIG_HOME, because the thing being tested is files. | |
| 3 | + | |
| 4 | +import std/[os, tables, unittest] | |
| 5 | +import frq/[store, model] | |
| 6 | + | |
| 7 | +template withTempConfig(body: untyped) = | |
| 8 | + let dir = getTempDir() / "frq-test-store-" & $getCurrentProcessId() | |
| 9 | + removeDir(dir) | |
| 10 | + createDir(dir) | |
| 11 | + putEnv("XDG_CONFIG_HOME", dir) | |
| 12 | + defer: | |
| 13 | + delEnv("XDG_CONFIG_HOME") | |
| 14 | + removeDir(dir) | |
| 15 | + body | |
| 16 | + | |
| 17 | +suite "the session": | |
| 18 | + test "absent when nothing was saved": | |
| 19 | + withTempConfig: | |
| 20 | + check loadSession()[1] == false | |
| 21 | + | |
| 22 | + test "round-trips": | |
| 23 | + withTempConfig: | |
| 24 | + check saveSession(SavedSession(brokerToken: "tok", handle: "alice", | |
| 25 | + did: "did:plc:x", nick: "alice")) | |
| 26 | + let (s, ok) = loadSession() | |
| 27 | + check ok | |
| 28 | + check s.brokerToken == "tok" | |
| 29 | + check s.handle == "alice" | |
| 30 | + check s.did == "did:plc:x" | |
| 31 | + | |
| 32 | + test "one with no broker token is not a session": | |
| 33 | + # The token is the whole point of saving one. | |
| 34 | + withTempConfig: | |
| 35 | + check saveSession(SavedSession(handle: "alice")) | |
| 36 | + check loadSession()[1] == false | |
| 37 | + | |
| 38 | + test "a file that will not parse is treated as absent": | |
| 39 | + # A stale credential is not worth an error at startup. | |
| 40 | + withTempConfig: | |
| 41 | + createDir(configDir()) | |
| 42 | + writeFile(sessionFile(), "{ this is not json") | |
| 43 | + check loadSession()[1] == false | |
| 44 | + | |
| 45 | + test "is written so nobody else can read it": | |
| 46 | + withTempConfig: | |
| 47 | + check saveSession(SavedSession(brokerToken: "tok")) | |
| 48 | + let perms = getFilePermissions(sessionFile()) | |
| 49 | + check fpGroupRead notin perms | |
| 50 | + check fpOthersRead notin perms | |
| 51 | + | |
| 52 | + test "clearing it leaves nothing behind": | |
| 53 | + withTempConfig: | |
| 54 | + check saveSession(SavedSession(brokerToken: "tok")) | |
| 55 | + clearSession() | |
| 56 | + check loadSession()[1] == false | |
| 57 | + | |
| 58 | + test "clearing one that is not there is not an error": | |
| 59 | + withTempConfig: | |
| 60 | + clearSession() | |
| 61 | + | |
| 62 | +suite "the rooms": | |
| 63 | + test "none when nothing was saved": | |
| 64 | + withTempConfig: | |
| 65 | + check loadRooms().len == 0 | |
| 66 | + | |
| 67 | + test "round-trip, with the markers": | |
| 68 | + # A phone that kept the names and lost the markers comes back to a | |
| 69 | + # hundred lines it has already read. | |
| 70 | + withTempConfig: | |
| 71 | + var rooms = initOrderedTable[string, Room]() | |
| 72 | + var a = initRoom("#one") | |
| 73 | + a.accessed = 5 | |
| 74 | + a.lastReadId = "m1" | |
| 75 | + a.lastReadAt = 1234 | |
| 76 | + rooms["#one"] = a | |
| 77 | + rooms["#two"] = initRoom("#two") | |
| 78 | + check saveRooms(rooms) | |
| 79 | + | |
| 80 | + let got = loadRooms() | |
| 81 | + check got.len == 2 | |
| 82 | + check got[0].name == "#one" | |
| 83 | + check got[0].accessed == 5 | |
| 84 | + check got[0].lastReadId == "m1" | |
| 85 | + check got[0].lastReadAt == 1234 | |
| 86 | + | |
| 87 | + test "order is kept — most recently used first is the file's own order": | |
| 88 | + withTempConfig: | |
| 89 | + var rooms = initOrderedTable[string, Room]() | |
| 90 | + for n in ["#c", "#a", "#b"]: rooms[n] = initRoom(n) | |
| 91 | + check saveRooms(rooms) | |
| 92 | + check loadRooms().len == 3 | |
| 93 | + check loadRooms()[0].name == "#c" | |
| 94 | + | |
| 95 | + test "a record with no name is dropped rather than defaulted": | |
| 96 | + withTempConfig: | |
| 97 | + createDir(configDir()) | |
| 98 | + writeFile(roomsFile(), """[{"name":"#ok"},{"accessed":3}]""") | |
| 99 | + let got = loadRooms() | |
| 100 | + check got.len == 1 | |
| 101 | + check got[0].name == "#ok" | |
| 102 | + | |
| 103 | + test "a file that will not parse is no rooms, not an error": | |
| 104 | + withTempConfig: | |
| 105 | + createDir(configDir()) | |
| 106 | + writeFile(roomsFile(), "not json at all") | |
| 107 | + check loadRooms().len == 0 | |
| 108 | + | |
| 109 | +suite "the preferences": | |
| 110 | + test "round-trip": | |
| 111 | + withTempConfig: | |
| 112 | + check savePrefs({"hideJoinPart": true, "showUsers": false}.toTable) | |
| 113 | + let got = loadPrefs() | |
| 114 | + check got["hideJoinPart"] == true | |
| 115 | + check got["showUsers"] == false | |
| 116 | + | |
| 117 | + test "absent is empty": | |
| 118 | + withTempConfig: | |
| 119 | + check loadPrefs().len == 0 | |
| new file mode 100644 | |||
| @@ -0,0 +1,119 @@ | |||
| 1 | +## What survives a restart. Every case runs against a real directory under a | ||
| 2 | +## temporary XDG_CONFIG_HOME, because the thing being tested is files. | ||
| 3 | + | ||
| 4 | +import std/[os, tables, unittest] | ||
| 5 | +import frq/[store, model] | ||
| 6 | + | ||
| 7 | +template withTempConfig(body: untyped) = | ||
| 8 | + let dir = getTempDir() / "frq-test-store-" & $getCurrentProcessId() | ||
| 9 | + removeDir(dir) | ||
| 10 | + createDir(dir) | ||
| 11 | + putEnv("XDG_CONFIG_HOME", dir) | ||
| 12 | + defer: | ||
| 13 | + delEnv("XDG_CONFIG_HOME") | ||
| 14 | + removeDir(dir) | ||
| 15 | + body | ||
| 16 | + | ||
| 17 | +suite "the session": | ||
| 18 | + test "absent when nothing was saved": | ||
| 19 | + withTempConfig: | ||
| 20 | + check loadSession()[1] == false | ||
| 21 | + | ||
| 22 | + test "round-trips": | ||
| 23 | + withTempConfig: | ||
| 24 | + check saveSession(SavedSession(brokerToken: "tok", handle: "alice", | ||
| 25 | + did: "did:plc:x", nick: "alice")) | ||
| 26 | + let (s, ok) = loadSession() | ||
| 27 | + check ok | ||
| 28 | + check s.brokerToken == "tok" | ||
| 29 | + check s.handle == "alice" | ||
| 30 | + check s.did == "did:plc:x" | ||
| 31 | + | ||
| 32 | + test "one with no broker token is not a session": | ||
| 33 | + # The token is the whole point of saving one. | ||
| 34 | + withTempConfig: | ||
| 35 | + check saveSession(SavedSession(handle: "alice")) | ||
| 36 | + check loadSession()[1] == false | ||
| 37 | + | ||
| 38 | + test "a file that will not parse is treated as absent": | ||
| 39 | + # A stale credential is not worth an error at startup. | ||
| 40 | + withTempConfig: | ||
| 41 | + createDir(configDir()) | ||
| 42 | + writeFile(sessionFile(), "{ this is not json") | ||
| 43 | + check loadSession()[1] == false | ||
| 44 | + | ||
| 45 | + test "is written so nobody else can read it": | ||
| 46 | + withTempConfig: | ||
| 47 | + check saveSession(SavedSession(brokerToken: "tok")) | ||
| 48 | + let perms = getFilePermissions(sessionFile()) | ||
| 49 | + check fpGroupRead notin perms | ||
| 50 | + check fpOthersRead notin perms | ||
| 51 | + | ||
| 52 | + test "clearing it leaves nothing behind": | ||
| 53 | + withTempConfig: | ||
| 54 | + check saveSession(SavedSession(brokerToken: "tok")) | ||
| 55 | + clearSession() | ||
| 56 | + check loadSession()[1] == false | ||
| 57 | + | ||
| 58 | + test "clearing one that is not there is not an error": | ||
| 59 | + withTempConfig: | ||
| 60 | + clearSession() | ||
| 61 | + | ||
| 62 | +suite "the rooms": | ||
| 63 | + test "none when nothing was saved": | ||
| 64 | + withTempConfig: | ||
| 65 | + check loadRooms().len == 0 | ||
| 66 | + | ||
| 67 | + test "round-trip, with the markers": | ||
| 68 | + # A phone that kept the names and lost the markers comes back to a | ||
| 69 | + # hundred lines it has already read. | ||
| 70 | + withTempConfig: | ||
| 71 | + var rooms = initOrderedTable[string, Room]() | ||
| 72 | + var a = initRoom("#one") | ||
| 73 | + a.accessed = 5 | ||
| 74 | + a.lastReadId = "m1" | ||
| 75 | + a.lastReadAt = 1234 | ||
| 76 | + rooms["#one"] = a | ||
| 77 | + rooms["#two"] = initRoom("#two") | ||
| 78 | + check saveRooms(rooms) | ||
| 79 | + | ||
| 80 | + let got = loadRooms() | ||
| 81 | + check got.len == 2 | ||
| 82 | + check got[0].name == "#one" | ||
| 83 | + check got[0].accessed == 5 | ||
| 84 | + check got[0].lastReadId == "m1" | ||
| 85 | + check got[0].lastReadAt == 1234 | ||
| 86 | + | ||
| 87 | + test "order is kept — most recently used first is the file's own order": | ||
| 88 | + withTempConfig: | ||
| 89 | + var rooms = initOrderedTable[string, Room]() | ||
| 90 | + for n in ["#c", "#a", "#b"]: rooms[n] = initRoom(n) | ||
| 91 | + check saveRooms(rooms) | ||
| 92 | + check loadRooms().len == 3 | ||
| 93 | + check loadRooms()[0].name == "#c" | ||
| 94 | + | ||
| 95 | + test "a record with no name is dropped rather than defaulted": | ||
| 96 | + withTempConfig: | ||
| 97 | + createDir(configDir()) | ||
| 98 | + writeFile(roomsFile(), """[{"name":"#ok"},{"accessed":3}]""") | ||
| 99 | + let got = loadRooms() | ||
| 100 | + check got.len == 1 | ||
| 101 | + check got[0].name == "#ok" | ||
| 102 | + | ||
| 103 | + test "a file that will not parse is no rooms, not an error": | ||
| 104 | + withTempConfig: | ||
| 105 | + createDir(configDir()) | ||
| 106 | + writeFile(roomsFile(), "not json at all") | ||
| 107 | + check loadRooms().len == 0 | ||
| 108 | + | ||
| 109 | +suite "the preferences": | ||
| 110 | + test "round-trip": | ||
| 111 | + withTempConfig: | ||
| 112 | + check savePrefs({"hideJoinPart": true, "showUsers": false}.toTable) | ||
| 113 | + let got = loadPrefs() | ||
| 114 | + check got["hideJoinPart"] == true | ||
| 115 | + check got["showUsers"] == false | ||
| 116 | + | ||
| 117 | + test "absent is empty": | ||
| 118 | + withTempConfig: | ||
| 119 | + check loadPrefs().len == 0 | ||
added
tools/emoji2nim.py +78 -0 | new file mode 100644 | ||
| @@ -0,0 +1,78 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +"""Generate nim/src/frq/emoji.nim from common/frq/emoji.cljc. | |
| 3 | + | |
| 4 | +The catalogue is 1,885 rows of data that Unicode generated in the first | |
| 5 | +place — retyping it by hand into a second language is how the two copies | |
| 6 | +start disagreeing. This reads the Clojure and emits the Nim, so the port is | |
| 7 | +a transcription a machine did and can redo. | |
| 8 | + | |
| 9 | + python3 tools/emoji2nim.py | |
| 10 | +""" | |
| 11 | +import re | |
| 12 | +import sys | |
| 13 | +from pathlib import Path | |
| 14 | + | |
| 15 | +root = Path(__file__).resolve().parent.parent | |
| 16 | +src = (root / "common/frq/emoji.cljc").read_text() | |
| 17 | +out = root / "nim/src/frq/emoji.nim" | |
| 18 | + | |
| 19 | +def strings(block: str): | |
| 20 | + """Every "..." in order, with Clojure's escapes undone.""" | |
| 21 | + return [s.encode().decode("unicode_escape") if "\\" in s else s | |
| 22 | + for s in re.findall(r'"((?:[^"\\]|\\.)*)"', block)] | |
| 23 | + | |
| 24 | +def section(name: str) -> str: | |
| 25 | + # To the next top-level `(def ` or to EOF — `catalog` is last in the file | |
| 26 | + # and has no blank line after it. | |
| 27 | + m = re.search(r'\(def ' + name + r'\b(.*?)(?=\n\(def |\Z)', src, re.S) | |
| 28 | + if not m: | |
| 29 | + sys.exit(f"emoji2nim: no `(def {name} ...)` in emoji.cljc") | |
| 30 | + body = m.group(1) | |
| 31 | + # Drop the docstring, which is the first string and full of prose. | |
| 32 | + return body[body.index("["):] if "[" in body else body | |
| 33 | + | |
| 34 | +popular = strings(section("popular")) | |
| 35 | +groups = strings(section("groups")) | |
| 36 | +rows = [strings(r) for r in re.findall(r'\["(?:[^"\\]|\\.)*"\s+"(?:[^"\\]|\\.)*"\s+"(?:[^"\\]|\\.)*"\]', | |
| 37 | + section("catalog"))] | |
| 38 | + | |
| 39 | +def nimstr(s: str) -> str: | |
| 40 | + return '"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"' | |
| 41 | + | |
| 42 | +lines = [ | |
| 43 | + "## Every emoji this client can draw, with the name to search it by.", | |
| 44 | + "##", | |
| 45 | + "## GENERATED by tools/emoji2nim.py from common/frq/emoji.cljc. Do not edit:", | |
| 46 | + "## the catalogue is Unicode's own `emoji-test.txt` (15.1), filtered to what", | |
| 47 | + "## the Twemoji pack has a picture for, and a second hand-maintained copy is", | |
| 48 | + "## how the two languages start disagreeing about what can be drawn.", | |
| 49 | + "##", | |
| 50 | + "## Skin-tone variants are left out — they multiply the list by five and say", | |
| 51 | + "## nothing a reaction needs to say. `glyphs` strips a tone before looking a", | |
| 52 | + "## glyph up here, and keeps it for the drawing.", | |
| 53 | + "", | |
| 54 | + "type", | |
| 55 | + " Emoji* = object", | |
| 56 | + " glyph*, name*, group*: string", | |
| 57 | + "", | |
| 58 | + "const", | |
| 59 | + " popular* = [", | |
| 60 | + " " + ", ".join(nimstr(p) for p in popular), | |
| 61 | + " ]", | |
| 62 | + " ## What a reaction usually is. The picker opens on these, because the", | |
| 63 | + " ## whole point of reacting is that it costs less than typing.", | |
| 64 | + "", | |
| 65 | + " groups* = [", | |
| 66 | + " " + ",\n ".join(nimstr(g) for g in groups), | |
| 67 | + " ]", | |
| 68 | + "", | |
| 69 | + f" catalog*: array[{len(rows)}, Emoji] = [", | |
| 70 | +] | |
| 71 | +for glyph, name, group in rows: | |
| 72 | + lines.append(f" Emoji(glyph: {nimstr(glyph)}, name: {nimstr(name)}, " | |
| 73 | + f"group: {nimstr(group)}),") | |
| 74 | +lines += [" ]", ""] | |
| 75 | + | |
| 76 | +out.write_text("\n".join(lines)) | |
| 77 | +print(f"wrote {out.relative_to(root)}: {len(rows)} emoji, " | |
| 78 | + f"{len(popular)} popular, {len(groups)} groups") | |
| new file mode 100644 | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | +#!/usr/bin/env python3 | ||
| 2 | +"""Generate nim/src/frq/emoji.nim from common/frq/emoji.cljc. | ||
| 3 | + | ||
| 4 | +The catalogue is 1,885 rows of data that Unicode generated in the first | ||
| 5 | +place — retyping it by hand into a second language is how the two copies | ||
| 6 | +start disagreeing. This reads the Clojure and emits the Nim, so the port is | ||
| 7 | +a transcription a machine did and can redo. | ||
| 8 | + | ||
| 9 | + python3 tools/emoji2nim.py | ||
| 10 | +""" | ||
| 11 | +import re | ||
| 12 | +import sys | ||
| 13 | +from pathlib import Path | ||
| 14 | + | ||
| 15 | +root = Path(__file__).resolve().parent.parent | ||
| 16 | +src = (root / "common/frq/emoji.cljc").read_text() | ||
| 17 | +out = root / "nim/src/frq/emoji.nim" | ||
| 18 | + | ||
| 19 | +def strings(block: str): | ||
| 20 | + """Every "..." in order, with Clojure's escapes undone.""" | ||
| 21 | + return [s.encode().decode("unicode_escape") if "\\" in s else s | ||
| 22 | + for s in re.findall(r'"((?:[^"\\]|\\.)*)"', block)] | ||
| 23 | + | ||
| 24 | +def section(name: str) -> str: | ||
| 25 | + # To the next top-level `(def ` or to EOF — `catalog` is last in the file | ||
| 26 | + # and has no blank line after it. | ||
| 27 | + m = re.search(r'\(def ' + name + r'\b(.*?)(?=\n\(def |\Z)', src, re.S) | ||
| 28 | + if not m: | ||
| 29 | + sys.exit(f"emoji2nim: no `(def {name} ...)` in emoji.cljc") | ||
| 30 | + body = m.group(1) | ||
| 31 | + # Drop the docstring, which is the first string and full of prose. | ||
| 32 | + return body[body.index("["):] if "[" in body else body | ||
| 33 | + | ||
| 34 | +popular = strings(section("popular")) | ||
| 35 | +groups = strings(section("groups")) | ||
| 36 | +rows = [strings(r) for r in re.findall(r'\["(?:[^"\\]|\\.)*"\s+"(?:[^"\\]|\\.)*"\s+"(?:[^"\\]|\\.)*"\]', | ||
| 37 | + section("catalog"))] | ||
| 38 | + | ||
| 39 | +def nimstr(s: str) -> str: | ||
| 40 | + return '"' + s.replace("\\", "\\\\").replace('"', '\\"') + '"' | ||
| 41 | + | ||
| 42 | +lines = [ | ||
| 43 | + "## Every emoji this client can draw, with the name to search it by.", | ||
| 44 | + "##", | ||
| 45 | + "## GENERATED by tools/emoji2nim.py from common/frq/emoji.cljc. Do not edit:", | ||
| 46 | + "## the catalogue is Unicode's own `emoji-test.txt` (15.1), filtered to what", | ||
| 47 | + "## the Twemoji pack has a picture for, and a second hand-maintained copy is", | ||
| 48 | + "## how the two languages start disagreeing about what can be drawn.", | ||
| 49 | + "##", | ||
| 50 | + "## Skin-tone variants are left out — they multiply the list by five and say", | ||
| 51 | + "## nothing a reaction needs to say. `glyphs` strips a tone before looking a", | ||
| 52 | + "## glyph up here, and keeps it for the drawing.", | ||
| 53 | + "", | ||
| 54 | + "type", | ||
| 55 | + " Emoji* = object", | ||
| 56 | + " glyph*, name*, group*: string", | ||
| 57 | + "", | ||
| 58 | + "const", | ||
| 59 | + " popular* = [", | ||
| 60 | + " " + ", ".join(nimstr(p) for p in popular), | ||
| 61 | + " ]", | ||
| 62 | + " ## What a reaction usually is. The picker opens on these, because the", | ||
| 63 | + " ## whole point of reacting is that it costs less than typing.", | ||
| 64 | + "", | ||
| 65 | + " groups* = [", | ||
| 66 | + " " + ",\n ".join(nimstr(g) for g in groups), | ||
| 67 | + " ]", | ||
| 68 | + "", | ||
| 69 | + f" catalog*: array[{len(rows)}, Emoji] = [", | ||
| 70 | +] | ||
| 71 | +for glyph, name, group in rows: | ||
| 72 | + lines.append(f" Emoji(glyph: {nimstr(glyph)}, name: {nimstr(name)}, " | ||
| 73 | + f"group: {nimstr(group)}),") | ||
| 74 | +lines += [" ]", ""] | ||
| 75 | + | ||
| 76 | +out.write_text("\n".join(lines)) | ||
| 77 | +print(f"wrote {out.relative_to(root)}: {len(rows)} emoji, " | ||
| 78 | + f"{len(popular)} popular, {len(groups)} groups") | ||