diff --git a/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt b/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt index 76588430c2bbc1c344cc57bab93209d4e4159574..00d0edbbbac978120087539ac150523a3df4f197 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/dagger/AppModule.kt @@ -19,22 +19,36 @@ package de.kuschku.quasseldroid.dagger +import android.app.Application +import android.content.Context +import androidx.fragment.app.FragmentActivity +import com.google.gson.Gson import com.google.gson.GsonBuilder import dagger.Module import dagger.Provides +import de.kuschku.quasseldroid.Quasseldroid +import de.kuschku.quasseldroid.util.AndroidEmojiProvider import de.kuschku.quasseldroid.util.avatars.MatrixApi +import de.kuschku.quasseldroid.util.emoji.EmojiProvider import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory @Module object AppModule { @Provides - fun provideGson() = GsonBuilder().setPrettyPrinting().create() + fun bindApplication(app: Quasseldroid): Application = app @Provides - fun provideMatrixApi() = Retrofit.Builder() + fun provideGson(): Gson = GsonBuilder().setPrettyPrinting().create() + + @Provides + fun provideMatrixApi(): MatrixApi = Retrofit.Builder() .baseUrl("https://matrix.org/") .addConverterFactory(GsonConverterFactory.create(GsonBuilder().setLenient().create())) .build() .create(MatrixApi::class.java) + + @Provides + fun provideEmojiProvider(context: Application, gson: Gson): EmojiProvider = + AndroidEmojiProvider(context.applicationContext, gson) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt index af6ecf7fef5df05ae1cb15c93241bc540c1d8677..58ad4ebd9982da92b5b42526028cd9f3a9bcdb0b 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteAdapter.kt @@ -217,8 +217,9 @@ class AutoCompleteAdapter @Inject constructor( fun bindImpl(data: AutoCompleteItem.EmojiItem, messageSettings: MessageSettings) { value = data - binding.emoji.text = data.replacement - binding.shortCode.text = data.shortCodes.joinToString(", ") + binding.emoji.text = data.emoji.replacement + binding.label.text = data.emoji.label + binding.tags.text = data.emoji.tags.joinToString(", ") } } } diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt index e88ee27a6cca4382ec706e0746110e0f1d22690b..187d4b1fe351fcb87ce34719761ad8ade629f677 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/AutoCompleteHelper.kt @@ -38,7 +38,7 @@ import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.util.ColorContext import de.kuschku.quasseldroid.util.avatars.AvatarHelper -import de.kuschku.quasseldroid.util.emoji.EmojiData +import de.kuschku.quasseldroid.util.emoji.EmojiHandler import de.kuschku.quasseldroid.util.helper.styledAttributes import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.irc.format.ContentFormatter @@ -54,7 +54,8 @@ class AutoCompleteHelper( private val messageSettings: MessageSettings, private val ircFormatDeserializer: IrcFormatDeserializer, private val contentFormatter: ContentFormatter, - private val helper: EditorViewModelHelper + private val helper: EditorViewModelHelper, + private val emojiHandler: EmojiHandler, ) { private var autocompleteListener: ((AutoCompletionState) -> Unit)? = null private var dataListeners: List<((List<AutoCompleteItem>) -> Unit)> = emptyList() @@ -246,11 +247,9 @@ class AutoCompleteHelper( ) } - fun getEmojis() = EmojiData.processedEmojiMap.filter { - it.shortCodes.any { - it.contains(lastWord.first.trim(':')) - } - } + fun getEmojis() = emojiHandler.fuzzyLookup( + emojiHandler.normalizeShortcode(lastWord.first) + ).map { AutoCompleteItem.EmojiItem(it) } when (lastWord.first.firstOrNull()) { '/' -> getAliases() diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt index 26fb83a0b3b4cda7b3208671d5d7fd83389f3816..8874c6fb3d0b8a51d016155f8cc4f08dd396d147 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/input/ChatlineFragment.kt @@ -40,7 +40,7 @@ import de.kuschku.quasseldroid.R import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings -import de.kuschku.quasseldroid.util.emoji.EmojiData +import de.kuschku.quasseldroid.util.emoji.EmojiHandler import de.kuschku.quasseldroid.util.helper.* import de.kuschku.quasseldroid.util.irc.format.ContentFormatter import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer @@ -98,6 +98,9 @@ class ChatlineFragment : ServiceBoundFragment() { @Inject lateinit var autoCompleteAdapter: AutoCompleteAdapter + @Inject + lateinit var emojiHandler: EmojiHandler + lateinit var editorHelper: EditorHelper lateinit var autoCompleteHelper: AutoCompleteHelper @@ -126,7 +129,8 @@ class ChatlineFragment : ServiceBoundFragment() { messageSettings, ircFormatDeserializer, contentFormatter, - modelHelper + modelHelper, + emojiHandler ) editorHelper = EditorHelper( @@ -176,7 +180,7 @@ class ChatlineFragment : ServiceBoundFragment() { fun send() { val safeText = - if (messageSettings.replaceEmoji) EmojiData.replaceShortCodes(chatline.safeText) + if (messageSettings.replaceEmoji) emojiHandler.replaceShortcodes(chatline.safeText) else chatline.safeText if (safeText.isNotEmpty()) { diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt index 0aece28be6c180599f3a01955ac2fe853cf78d8f..e7e3400d7a416e13fbc0c82402a0c1f7faebe9c2 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/chat/topic/TopicFragment.kt @@ -37,6 +37,7 @@ import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.ui.chat.input.* +import de.kuschku.quasseldroid.util.emoji.EmojiHandler import de.kuschku.quasseldroid.util.helper.toLiveData import de.kuschku.quasseldroid.util.irc.format.ContentFormatter import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer @@ -80,6 +81,9 @@ class TopicFragment : ServiceBoundSettingsFragment(), Savable { @Inject lateinit var modelHelper: EditorViewModelHelper + @Inject + lateinit var emojiHandler: EmojiHandler + private lateinit var editorHelper: EditorHelper override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, @@ -93,7 +97,8 @@ class TopicFragment : ServiceBoundSettingsFragment(), Savable { messageSettings, formatDeserializer, contentFormatter, - modelHelper + modelHelper, + emojiHandler ) editorHelper = EditorHelper( diff --git a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt index 6ce93b82e66bd5517abba91af1b4eefd974841d8..e0a1c30709edbd13705ba2a5dbcb633c6bb6c2ce 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/ui/coresettings/aliasitem/AliasItemFragment.kt @@ -38,6 +38,7 @@ import de.kuschku.quasseldroid.settings.AppearanceSettings import de.kuschku.quasseldroid.settings.AutoCompleteSettings import de.kuschku.quasseldroid.settings.MessageSettings import de.kuschku.quasseldroid.ui.chat.input.* +import de.kuschku.quasseldroid.util.emoji.EmojiHandler import de.kuschku.quasseldroid.util.irc.format.ContentFormatter import de.kuschku.quasseldroid.util.irc.format.IrcFormatDeserializer import de.kuschku.quasseldroid.util.irc.format.IrcFormatSerializer @@ -84,6 +85,9 @@ class AliasItemFragment : ServiceBoundSettingsFragment(), Savable, Changeable { @Inject lateinit var modelHelper: EditorViewModelHelper + @Inject + lateinit var emojiHandler: EmojiHandler + private lateinit var editorHelper: EditorHelper private var rule: IAliasManager.Alias? = null @@ -104,7 +108,8 @@ class AliasItemFragment : ServiceBoundSettingsFragment(), Savable, Changeable { messageSettings, formatDeserializer, contentFormatter, - modelHelper + modelHelper, + emojiHandler ) editorHelper = EditorHelper( diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/AndroidEmojiProvider.kt b/app/src/main/java/de/kuschku/quasseldroid/util/AndroidEmojiProvider.kt new file mode 100644 index 0000000000000000000000000000000000000000..e0eea29ac6c6712f68f80dcd56863462b4cffabb --- /dev/null +++ b/app/src/main/java/de/kuschku/quasseldroid/util/AndroidEmojiProvider.kt @@ -0,0 +1,41 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2023 Janne Mareike Koschinski + * Copyright (c) 2023 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.util + +import android.content.Context +import com.google.gson.Gson +import de.kuschku.quasseldroid.util.emoji.EmojiHandler +import de.kuschku.quasseldroid.util.emoji.EmojiProvider +import de.kuschku.quasseldroid.util.helper.fromJson +import java.io.IOException + +class AndroidEmojiProvider(context: Context, gson: Gson) : EmojiProvider { + override val emoji: List<EmojiHandler.Emoji> = try { + context.assets.open("emoji.json").use { + gson.fromJson(it.bufferedReader(Charsets.UTF_8)) + } + } catch (e: IOException) { + throw IllegalStateException("emoji.json missing from assets.", e) + } + + override val shortcodes: Map<String, EmojiHandler.Emoji> = emoji.flatMap { entry -> + entry.shortcodes.map { Pair(it, entry) } + }.toMap() +} diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt b/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt index 6d168b88b8e3b8a4442ddedbd079fa05968f2537..c7a28dfaa4b9bda44a1a3c28bdc4a87d7f12b502 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/Patterns.kt @@ -19,7 +19,6 @@ package de.kuschku.quasseldroid.util -import de.kuschku.quasseldroid.util.emoji.EmojiData import org.intellij.lang.annotations.Language @SuppressWarnings("Access") @@ -122,10 +121,6 @@ object Patterns { /** * Regular expression to detect emoji */ - val EMOJI_STRING = EmojiData.emojis.joinToString( - prefix = """(?:\s|\Q""", - separator = """\E|\Q""", - postfix = """\E)+""" - ) + private const val EMOJI_STRING = "\\uD83E\\uDDD1(?:\\uD83C\\uDFFF\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFE])|\\uD83C\\uDFFE\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83C\\uDFFD\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83C\\uDFFC\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83C\\uDFFB\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFC-\\uDFFF]))|\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC69(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68(?:\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D\\uD83D\\uDC68|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFF]))|\\uD83E\\uDDD1(?:\\uD83C\\uDFFF\\u200D\\u2764\\uFE0F\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFE])|\\uD83C\\uDFFE\\u200D\\u2764\\uFE0F\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83C\\uDFFD\\u200D\\u2764\\uFE0F\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83C\\uDFFC\\u200D\\u2764\\uFE0F\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83C\\uDFFB\\u200D\\u2764\\uFE0F\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFC-\\uDFFF]))|\\uD83D\\uDC69(?:\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC8B\\u200D(?:\\uD83D[\\uDC68\\uDC69])|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D\\u2764\\uFE0F\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFB-\\uDFFF]))|\\uD83C\\uDFF4\\uDB40\\uDC67\\uDB40\\uDC62(?:\\uDB40\\uDC77\\uDB40\\uDC6C\\uDB40\\uDC73|\\uDB40\\uDC73\\uDB40\\uDC63\\uDB40\\uDC74|\\uDB40\\uDC65\\uDB40\\uDC6E\\uDB40\\uDC67)\\uDB40\\uDC7F|\\uD83D\\uDC68\\uD83C\\uDFFF\\u200D\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFE])|\\uD83D\\uDC68\\uD83C\\uDFFE\\u200D\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83D\\uDC68\\uD83C\\uDFFD\\u200D\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83D\\uDC68\\uD83C\\uDFFC\\u200D\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83D\\uDC68\\uD83C\\uDFFB\\u200D\\uD83E\\uDD1D\\u200D\\uD83D\\uDC68(?:\\uD83C[\\uDFFC-\\uDFFF])|\\uD83D\\uDC69(?:\\u200D\\uD83D\\uDC69\\u200D(?:\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67]))|\\uD83C\\uDFFF\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFB-\\uDFFE])|\\uD83C\\uDFFE\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83C\\uDFFD\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83C\\uDFFC\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83C\\uDFFB\\u200D\\uD83E\\uDD1D\\u200D(?:\\uD83D[\\uDC68\\uDC69])(?:\\uD83C[\\uDFFC-\\uDFFF]))|\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D\\uD83E\\uDD1D\\u200D\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC68\\u200D(?:\\uD83D[\\uDC68\\uDC69])\\u200D(?:\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC67\\u200D(?:\\uD83D[\\uDC66\\uDC67]))|\\uD83D\\uDC68\\u200D\\u2764\\uFE0F\\u200D\\uD83D\\uDC68|\\uD83D\\uDC69\\u200D\\u2764\\uFE0F\\u200D(?:\\uD83D[\\uDC68\\uDC69])|\\uD83E\\uDDD1\\u200D\\uD83E\\uDD1D\\u200D\\uD83E\\uDDD1|\\uD83D\\uDC69\\u200D\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|\\uD83D\\uDC68(?:\\u200D(?:\\uD83D\\uDC66\\u200D\\uD83D\\uDC66|(?:\\uD83D[\\uDC67-\\uDC69])\\u200D(?:\\uD83D[\\uDC66\\uDC67]))|(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2695\\u2696\\u2708]\\uFE0F)|\\uD83E\\uDEF1(?:\\uD83C\\uDFFF\\u200D\\uD83E\\uDEF2(?:\\uD83C[\\uDFFB-\\uDFFE])|\\uD83C\\uDFFE\\u200D\\uD83E\\uDEF2(?:\\uD83C[\\uDFFB-\\uDFFD\\uDFFF])|\\uD83C\\uDFFD\\u200D\\uD83E\\uDEF2(?:\\uD83C[\\uDFFB\\uDFFC\\uDFFE\\uDFFF])|\\uD83C\\uDFFC\\u200D\\uD83E\\uDEF2(?:\\uD83C[\\uDFFB\\uDFFD-\\uDFFF])|\\uD83C\\uDFFB\\u200D\\uD83E\\uDEF2(?:\\uD83C[\\uDFFC-\\uDFFF]))|(?:\\uD83D\\uDC41\\uFE0F\\u200D\\uD83D\\uDDE8|\\uD83C\\uDFF3\\uFE0F\\u200D\\u26A7|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E\\uDC70\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3D\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDD])(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642]|(?:\\u26F9|\\uD83C[\\uDFCB\\uDFCC]|\\uD83D\\uDD75)(?:\\uFE0F|\\uD83C[\\uDFFB-\\uDFFF])\\u200D[\\u2640\\u2642])\\uFE0F|(?:\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFF])|\\uD83D\\uDC69(?:\\uD83C[\\uDFFB-\\uDFFF]))\\u200D[\\u2695\\u2696\\u2708]\\uFE0F|\\uD83D\\uDC69\\u200D(?:\\uD83D[\\uDC67\\uDC69])\\u200D(?:\\uD83D[\\uDC66\\uDC67])|\\uD83C\\uDFF3\\uFE0F\\u200D\\uD83C\\uDF08|(?:\\uD83D\\uDE36\\u200D\\uD83C\\uDF2B|\\uD83D\\uDC3B\\u200D\\u2744|\\uD83C\\uDFF4\\u200D\\u2620|(?:\\uD83C[\\uDFC3\\uDFC4\\uDFCA]|\\uD83D[\\uDC6E-\\uDC71\\uDC73\\uDC77\\uDC81\\uDC82\\uDC86\\uDC87\\uDE45-\\uDE47\\uDE4B\\uDE4D\\uDE4E\\uDEA3\\uDEB4-\\uDEB6]|\\uD83E[\\uDD26\\uDD35\\uDD37-\\uDD39\\uDD3C-\\uDD3E\\uDDB8\\uDDB9\\uDDCD-\\uDDCF\\uDDD4\\uDDD6-\\uDDDF])\\u200D[\\u2640\\u2642])\\uFE0F|\\uD83E\\uDDD1(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\uD83E\\uDDD1\\u200D[\\u2695\\u2696\\u2708]\\uFE0F|\\u2764\\uFE0F\\u200D(?:\\uD83D\\uDD25|\\uD83E\\uDE79)|(?:\\uD83D[\\uDC68\\uDC69])(?:(?:\\uD83C[\\uDFFB-\\uDFFF])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|\\u200D[\\u2695\\u2696\\u2708]\\uFE0F)|\\uD83D\\uDE35\\u200D\\uD83D\\uDCAB|\\uD83D\\uDE2E\\u200D\\uD83D\\uDCA8|\\uD83D\\uDC15\\u200D\\uD83E\\uDDBA|\\uD83D\\uDC08\\u200D\\u2B1B|\\uD83E\\uDDD1\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF84\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|(?:\\uD83D[\\uDC68\\uDC69])\\u200D(?:\\uD83C[\\uDF3E\\uDF73\\uDF7C\\uDF93\\uDFA4\\uDFA8\\uDFEB\\uDFED]|\\uD83D[\\uDC66\\uDC67\\uDCBB\\uDCBC\\uDD27\\uDD2C\\uDE80\\uDE92]|\\uD83E[\\uDDAF-\\uDDB3\\uDDBC\\uDDBD])|[#\\*0-9]\\uFE0F\\u20E3|\\uD83C\\uDDFD\\uD83C\\uDDF0|\\uD83C\\uDDF6\\uD83C\\uDDE6|\\uD83C\\uDDF4\\uD83C\\uDDF2|\\uD83C\\uDDFF(?:\\uD83C[\\uDDE6\\uDDF2\\uDDFC])|\\uD83C\\uDDFE(?:\\uD83C[\\uDDEA\\uDDF9])|\\uD83C\\uDDFC(?:\\uD83C[\\uDDEB\\uDDF8])|\\uD83C\\uDDFB(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDEE\\uDDF3\\uDDFA])|\\uD83C\\uDDFA(?:\\uD83C[\\uDDE6\\uDDEC\\uDDF2\\uDDF3\\uDDF8\\uDDFE\\uDDFF])|\\uD83C\\uDDF9(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDED\\uDDEF-\\uDDF4\\uDDF7\\uDDF9\\uDDFB\\uDDFC\\uDDFF])|\\uD83C\\uDDF8(?:\\uD83C[\\uDDE6-\\uDDEA\\uDDEC-\\uDDF4\\uDDF7-\\uDDF9\\uDDFB\\uDDFD-\\uDDFF])|\\uD83C\\uDDF7(?:\\uD83C[\\uDDEA\\uDDF4\\uDDF8\\uDDFA\\uDDFC])|\\uD83C\\uDDF5(?:\\uD83C[\\uDDE6\\uDDEA-\\uDDED\\uDDF0-\\uDDF3\\uDDF7-\\uDDF9\\uDDFC\\uDDFE])|\\uD83C\\uDDF3(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA-\\uDDEC\\uDDEE\\uDDF1\\uDDF4\\uDDF5\\uDDF7\\uDDFA\\uDDFF])|\\uD83C\\uDDF2(?:\\uD83C[\\uDDE6\\uDDE8-\\uDDED\\uDDF0-\\uDDFF])|\\uD83C\\uDDF1(?:\\uD83C[\\uDDE6-\\uDDE8\\uDDEE\\uDDF0\\uDDF7-\\uDDFB\\uDDFE])|\\uD83C\\uDDF0(?:\\uD83C[\\uDDEA\\uDDEC-\\uDDEE\\uDDF2\\uDDF3\\uDDF5\\uDDF7\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDEF(?:\\uD83C[\\uDDEA\\uDDF2\\uDDF4\\uDDF5])|\\uD83C\\uDDEE(?:\\uD83C[\\uDDE8-\\uDDEA\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9])|\\uD83C\\uDDED(?:\\uD83C[\\uDDF0\\uDDF2\\uDDF3\\uDDF7\\uDDF9\\uDDFA])|\\uD83C\\uDDEC(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEE\\uDDF1-\\uDDF3\\uDDF5-\\uDDFA\\uDDFC\\uDDFE])|\\uD83C\\uDDEB(?:\\uD83C[\\uDDEE-\\uDDF0\\uDDF2\\uDDF4\\uDDF7])|\\uD83C\\uDDEA(?:\\uD83C[\\uDDE6\\uDDE8\\uDDEA\\uDDEC\\uDDED\\uDDF7-\\uDDFA])|\\uD83C\\uDDE9(?:\\uD83C[\\uDDEA\\uDDEC\\uDDEF\\uDDF0\\uDDF2\\uDDF4\\uDDFF])|\\uD83C\\uDDE8(?:\\uD83C[\\uDDE6\\uDDE8\\uDDE9\\uDDEB-\\uDDEE\\uDDF0-\\uDDF5\\uDDF7\\uDDFA-\\uDDFF])|\\uD83C\\uDDE7(?:\\uD83C[\\uDDE6\\uDDE7\\uDDE9-\\uDDEF\\uDDF1-\\uDDF4\\uDDF6-\\uDDF9\\uDDFB\\uDDFC\\uDDFE\\uDDFF])|\\uD83C\\uDDE6(?:\\uD83C[\\uDDE8-\\uDDEC\\uDDEE\\uDDF1\\uDDF2\\uDDF4\\uDDF6-\\uDDFA\\uDDFC\\uDDFD\\uDDFF])|(?:[\\u270A\\u270B]|\\uD83C[\\uDF85\\uDFC3\\uDFC7]|\\uD83D[\\uDC43\\uDC4A-\\uDC4C\\uDC4F\\uDC50\\uDC66-\\uDC69\\uDC6B-\\uDC6E\\uDC70-\\uDC78\\uDC7C\\uDC81-\\uDC83\\uDC85-\\uDC87\\uDC8F\\uDC91\\uDCAA\\uDD7A\\uDD95\\uDD96\\uDE45-\\uDE47\\uDE4B-\\uDE4F\\uDEA3\\uDEB4-\\uDEB6\\uDEC0\\uDECC]|\\uD83E[\\uDD0C\\uDD0F\\uDD18-\\uDD1F\\uDD26\\uDD30-\\uDD39\\uDD3D\\uDD3E\\uDD77\\uDDB5\\uDDB6\\uDDB8\\uDDB9\\uDDBB\\uDDCD-\\uDDCF\\uDDD1-\\uDDDD\\uDEC3-\\uDEC5\\uDEF0-\\uDEF6])(?:\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\u261D\\u26F9\\u270C\\u270D]|\\uD83C[\\uDFC2\\uDFC4\\uDFCA-\\uDFCC]|\\uD83D[\\uDC42\\uDC46-\\uDC49\\uDC4D\\uDC4E\\uDD74\\uDD75\\uDD90])(?:\\uFE0F|\\uD83C[\\uDFFB-\\uDFFF])|(?:[\\xA9\\xAE\\u203C\\u2049\\u2122\\u2139\\u2194-\\u2199\\u21A9\\u21AA\\u231A\\u231B\\u2328\\u23CF\\u23E9\\u23EA\\u23ED-\\u23EF\\u23F1-\\u23F3\\u23F8-\\u23FA\\u24C2\\u25AA\\u25AB\\u25B6\\u25C0\\u25FB-\\u25FE\\u2600-\\u2604\\u260E\\u2611\\u2614\\u2615\\u2618\\u2620\\u2622\\u2623\\u2626\\u262A\\u262E\\u262F\\u2638-\\u263A\\u2640\\u2642\\u2648-\\u2653\\u265F\\u2660\\u2663\\u2665\\u2666\\u2668\\u267B\\u267E\\u267F\\u2692-\\u2697\\u2699\\u269B\\u269C\\u26A0\\u26A1\\u26A7\\u26AA\\u26AB\\u26B0\\u26B1\\u26BD\\u26BE\\u26C4\\u26C5\\u26C8\\u26CF\\u26D1\\u26D3\\u26D4\\u26E9\\u26EA\\u26F0-\\u26F5\\u26F7\\u26F8\\u26FA\\u26FD\\u2702\\u2708\\u2709\\u270F\\u2712\\u2714\\u2716\\u271D\\u2721\\u2733\\u2734\\u2744\\u2747\\u2753\\u2757\\u2763\\u2764\\u27A1\\u2934\\u2935\\u2B05-\\u2B07\\u2B1B\\u2B1C\\u2B50\\u2B55\\u3030\\u303D\\u3297\\u3299]|\\uD83C[\\uDC04\\uDD70\\uDD71\\uDD7E\\uDD7F\\uDE02\\uDE1A\\uDE2F\\uDE37\\uDF0D-\\uDF0F\\uDF15\\uDF1C\\uDF21\\uDF24-\\uDF2C\\uDF36\\uDF78\\uDF7D\\uDF93\\uDF96\\uDF97\\uDF99-\\uDF9B\\uDF9E\\uDF9F\\uDFA7\\uDFAC-\\uDFAE\\uDFC6\\uDFCD\\uDFCE\\uDFD4-\\uDFE0\\uDFED\\uDFF3\\uDFF5\\uDFF7]|\\uD83D[\\uDC08\\uDC15\\uDC1F\\uDC26\\uDC3F\\uDC41\\uDC53\\uDC6A\\uDC7D\\uDCA3\\uDCB0\\uDCB3\\uDCBB\\uDCBF\\uDCCB\\uDCDA\\uDCDF\\uDCE4-\\uDCE6\\uDCEA-\\uDCED\\uDCF7\\uDCF9-\\uDCFB\\uDCFD\\uDD08\\uDD0D\\uDD12\\uDD13\\uDD49\\uDD4A\\uDD50-\\uDD67\\uDD6F\\uDD70\\uDD73\\uDD76-\\uDD79\\uDD87\\uDD8A-\\uDD8D\\uDDA5\\uDDA8\\uDDB1\\uDDB2\\uDDBC\\uDDC2-\\uDDC4\\uDDD1-\\uDDD3\\uDDDC-\\uDDDE\\uDDE1\\uDDE3\\uDDE8\\uDDEF\\uDDF3\\uDDFA\\uDE10\\uDE87\\uDE8D\\uDE91\\uDE94\\uDE98\\uDEAD\\uDEB2\\uDEB9\\uDEBA\\uDEBC\\uDECB\\uDECD-\\uDECF\\uDEE0-\\uDEE5\\uDEE9\\uDEF0\\uDEF3])\\uFE0F|[\\u23EB\\u23EC\\u23F0\\u26CE\\u2705\\u270A\\u270B\\u2728\\u274C\\u274E\\u2754\\u2755\\u2795-\\u2797\\u27B0\\u27BF]|\\uD83C[\\uDCCF\\uDD8E\\uDD91-\\uDD9A\\uDDE6-\\uDDFF\\uDE01\\uDE32-\\uDE36\\uDE38-\\uDE3A\\uDE50\\uDE51\\uDF00-\\uDF0C\\uDF10-\\uDF14\\uDF16-\\uDF1B\\uDF1D-\\uDF20\\uDF2D-\\uDF35\\uDF37-\\uDF77\\uDF79-\\uDF7C\\uDF7E-\\uDF92\\uDFA0-\\uDFA6\\uDFA8-\\uDFAB\\uDFAF-\\uDFC1\\uDFC3\\uDFC5\\uDFC7-\\uDFC9\\uDFCF-\\uDFD3\\uDFE1-\\uDFEC\\uDFEE-\\uDFF0\\uDFF4\\uDFF8-\\uDFFF]|\\uD83D[\\uDC00-\\uDC07\\uDC09-\\uDC14\\uDC16-\\uDC1E\\uDC20-\\uDC25\\uDC27-\\uDC3E\\uDC40\\uDC43-\\uDC45\\uDC4A-\\uDC4C\\uDC4F-\\uDC52\\uDC54-\\uDC69\\uDC6B-\\uDC7C\\uDC7E-\\uDCA2\\uDCA4-\\uDCAF\\uDCB1\\uDCB2\\uDCB4-\\uDCBA\\uDCBC-\\uDCBE\\uDCC0-\\uDCCA\\uDCCC-\\uDCD9\\uDCDB-\\uDCDE\\uDCE0-\\uDCE3\\uDCE7-\\uDCE9\\uDCEE-\\uDCF6\\uDCF8\\uDCFC\\uDCFF-\\uDD07\\uDD09-\\uDD0C\\uDD0E-\\uDD11\\uDD14-\\uDD3D\\uDD4B-\\uDD4E\\uDD7A\\uDD95\\uDD96\\uDDA4\\uDDFB-\\uDE0F\\uDE11-\\uDE4F\\uDE80-\\uDE86\\uDE88-\\uDE8C\\uDE8E-\\uDE90\\uDE92\\uDE93\\uDE95-\\uDE97\\uDE99-\\uDEAC\\uDEAE-\\uDEB1\\uDEB3-\\uDEB8\\uDEBB\\uDEBD-\\uDEC5\\uDECC\\uDED0-\\uDED2\\uDED5-\\uDED7\\uDEDD-\\uDEDF\\uDEEB\\uDEEC\\uDEF4-\\uDEFC\\uDFE0-\\uDFEB\\uDFF0]|\\uD83E[\\uDD0C-\\uDD3A\\uDD3C-\\uDD45\\uDD47-\\uDDFF\\uDE70-\\uDE74\\uDE78-\\uDE7C\\uDE80-\\uDE86\\uDE90-\\uDEAC\\uDEB0-\\uDEBA\\uDEC0-\\uDEC5\\uDED0-\\uDED9\\uDEE0-\\uDEE7\\uDEF0-\\uDEF6]" val EMOJI = Regex(EMOJI_STRING) } diff --git a/app/src/main/java/de/kuschku/quasseldroid/util/helper/GsonHelper.kt b/app/src/main/java/de/kuschku/quasseldroid/util/helper/GsonHelper.kt index 550fc382db8404830a1a26bc054671e37cd67f86..0c7657f404ad09c3ee90991dd675a5b5022a65a3 100644 --- a/app/src/main/java/de/kuschku/quasseldroid/util/helper/GsonHelper.kt +++ b/app/src/main/java/de/kuschku/quasseldroid/util/helper/GsonHelper.kt @@ -1,8 +1,8 @@ /* * Quasseldroid - Quassel client for Android * - * Copyright (c) 2020 Janne Mareike Koschinski - * Copyright (c) 2020 The Quassel Project + * Copyright (c) 2023 Janne Mareike Koschinski + * Copyright (c) 2023 The Quassel Project * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3 as published @@ -20,9 +20,30 @@ package de.kuschku.quasseldroid.util.helper import com.google.gson.Gson -import java.io.File +import com.google.gson.JsonElement +import com.google.gson.reflect.TypeToken import java.io.Reader -inline fun <reified T> Gson.fromJson(file: File): T = this.fromJson(file.reader(), T::class.java) -inline fun <reified T> Gson.fromJson(text: String): T = this.fromJson(text, T::class.java) -inline fun <reified T> Gson.fromJson(reader: Reader): T = this.fromJson(reader, T::class.java) +inline fun <reified T> Gson.fromJson(jsonElement: JsonElement): T = + if (T::class.java.typeParameters.isEmpty()) { + this.fromJson(jsonElement, T::class.java) + } else { + val type = object : TypeToken<T>() {}.type + this.fromJson(jsonElement, type) + } + +inline fun <reified T> Gson.fromJson(reader: Reader): T = + if (T::class.java.typeParameters.isEmpty()) { + this.fromJson(reader, T::class.java) + } else { + val type = object : TypeToken<T>() {}.type + this.fromJson(reader, type) + } + +inline fun <reified T> Gson.fromJson(text: String): T = + if (T::class.java.typeParameters.isEmpty()) { + this.fromJson(text, T::class.java) + } else { + val type = object : TypeToken<T>() {}.type + this.fromJson(text, type) + } diff --git a/app/src/main/res/layout/widget_emoji.xml b/app/src/main/res/layout/widget_emoji.xml index 8b261e4eb44997ade64014756f0b968f80c87cf5..8b8e3084a6a61602c4284da405f67223db7bb1f8 100644 --- a/app/src/main/res/layout/widget_emoji.xml +++ b/app/src/main/res/layout/widget_emoji.xml @@ -23,32 +23,51 @@ android:layout_height="wrap_content" android:background="?attr/backgroundMenuItem" android:minHeight="48dp" + android:orientation="horizontal" android:paddingLeft="16dp" - android:paddingTop="8dp" + android:paddingTop="4dp" android:paddingRight="16dp" - android:paddingBottom="8dp"> + android:paddingBottom="4dp" + android:textAppearance="?android:attr/textAppearanceListItemSmall"> <TextView android:id="@+id/emoji" - android:layout_width="32dp" - android:layout_height="32dp" - android:layout_gravity="center_vertical|start" + android:layout_width="@dimen/avatar_size" + android:layout_height="@dimen/avatar_size" + android:layout_gravity="center" android:layout_marginEnd="16dp" - android:fontFamily="sans-serif-medium" - android:gravity="center_vertical|start" - android:singleLine="true" - android:textColor="?attr/colorTextPrimary" + android:textAlignment="center" android:textSize="24dp" tools:ignore="SpUsage" tools:text="♥" /> - <TextView - android:id="@+id/shortCode" - android:layout_width="wrap_content" + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_gravity="center_vertical|start" - android:singleLine="true" - android:textColor="?attr/colorTextSecondary" - android:textSize="12sp" - tools:text=":heart:" /> + android:layout_gravity="center_vertical" + android:orientation="vertical"> + + <TextView + android:id="@+id/label" + style="@style/Widget.RtlConformTextView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:singleLine="true" + android:textColor="?attr/colorTextPrimary" + android:textSize="13sp" + tools:text="smiling face with hearts" /> + + <TextView + android:id="@+id/tags" + style="@style/Widget.RtlConformTextView" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:singleLine="true" + android:textColor="?attr/colorTextSecondary" + android:textSize="12sp" + tools:text="adore, crush, hearts, in love" + tools:visibility="visible" /> + </LinearLayout> </LinearLayout> diff --git a/app/src/test/java/de/kuschku/quasseldroid/util/emoji/EmojiDataTest.kt b/app/src/test/java/de/kuschku/quasseldroid/util/emoji/EmojiDataTest.kt index 014cda5005100515ea8cb877144bf2fe3f61d79c..ee15c46fb20649bfb93d01d1b0921360b36430f0 100644 --- a/app/src/test/java/de/kuschku/quasseldroid/util/emoji/EmojiDataTest.kt +++ b/app/src/test/java/de/kuschku/quasseldroid/util/emoji/EmojiDataTest.kt @@ -20,26 +20,67 @@ package de.kuschku.quasseldroid.util.emoji import android.os.Build +import android.text.Editable import android.text.SpannableStringBuilder +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.google.gson.reflect.TypeToken import de.kuschku.quasseldroid.QuasseldroidTest import org.junit.Assert.assertEquals +import org.junit.Assert.assertTrue import org.junit.Test import org.junit.runner.RunWith import org.robolectric.RobolectricTestRunner import org.robolectric.annotation.Config +import java.io.Reader + +inline fun <reified T> Gson.fromJson(reader: Reader): T = + if (T::class.java.typeParameters.isEmpty()) { + this.fromJson(reader, T::class.java) + } else { + val type = object : TypeToken<T>() {}.type + this.fromJson(reader, type) + } + +fun EmojiHandler.replaceShortcodes(source: String): String = + this.replaceShortcodes(SpannableStringBuilder(source)).toString() @Config(application = QuasseldroidTest::class, sdk = [Build.VERSION_CODES.P]) @RunWith(RobolectricTestRunner::class) class EmojiDataTest { + object TestEmojiProvider : EmojiProvider { + private val gson: Gson = GsonBuilder().create() + override val emoji: List<EmojiHandler.Emoji> = gson.fromJson( + TestEmojiProvider::class.java.getResourceAsStream("/emoji.json")!!.reader(Charsets.UTF_8) + ) + override val shortcodes: Map<String, EmojiHandler.Emoji> = emoji.flatMap { entry -> + entry.shortcodes.map { Pair(it, entry) } + }.toMap() + } + + private val handler = EmojiHandler(TestEmojiProvider) + @Test - fun replaceShortCodes() { - assertEquals("\ud83d\udc4d", replaceShortCodes(":like:")) - assertEquals("this\ud83d\udc4disa\ud83d\udc1e\ud83d\udc4dtest", - replaceShortCodes("this:like:isa:beetle::+1:test")) + fun findShortCodes() { + assertTrue(EmojiHandler.shortcodeRegex.matches(":like:")) + assertTrue(EmojiHandler.shortcodeRegex.matches(":+1:")) + assertTrue(EmojiHandler.shortcodeRegex.matches(":beetle:")) } - companion object { - private fun replaceShortCodes(text: String): String = - EmojiData.replaceShortCodes(SpannableStringBuilder(text)).toString() + @Test + fun replaceShortCodes() { + assertEquals("\uD83D\uDC4D️", + handler.replaceShortcodes(":like:") + ) + assertEquals("\uD83D\uDC4D️", + handler.replaceShortcodes(":+1:") + ) + assertEquals("\uD83D\uDC1E\uD83D\uDC4D️", + handler.replaceShortcodes(":ladybug::+1:") + ) + assertEquals( + "this\uD83D\uDC4D️isa\uD83D\uDC1E\uD83D\uDC4D️test", + handler.replaceShortcodes("this:like:isa:ladybug::+1:test") + ) } } diff --git a/app/src/test/resources/emoji.json b/app/src/test/resources/emoji.json new file mode 120000 index 0000000000000000000000000000000000000000..35938a2d61084cbfb4a6aca99f6630aacf06075a --- /dev/null +++ b/app/src/test/resources/emoji.json @@ -0,0 +1 @@ +/data/janne/droid/app/src/main/assets/emoji.json \ No newline at end of file diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiData.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiData.kt deleted file mode 100644 index 80fe823a1c729416cc97694dfc6f735a70625cd4..0000000000000000000000000000000000000000 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiData.kt +++ /dev/null @@ -1,1758 +0,0 @@ -/* - * Quasseldroid - Quassel client for Android - * - * Copyright (c) 2020 Janne Mareike Koschinski - * Copyright (c) 2020 The Quassel Project - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3 as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -package de.kuschku.quasseldroid.util.emoji - -import android.os.Build -import android.text.Editable -import de.kuschku.quasseldroid.viewmodel.data.AutoCompleteItem - -object EmojiData { - val rawEmojiMap = mapOf( - "umbrella_with_rain_drops" to "\u2614", - "coffee" to "\u2615", - "aries" to "\u2648", - "taurus" to "\u2649", - "sagittarius" to "\u2650", - "capricorn" to "\u2651", - "aquarius" to "\u2652", - "pisces" to "\u2653", - "anchor" to "\u2693", - "white_check_mark" to "\u2705", - "sparkles" to "\u2728", - "question" to "\u2753", - "grey_question" to "\u2754", - "grey_exclamation" to "\u2755", - "exclamation" to "\u2757", - "heavy_exclamation_mark" to "\u2757", - "heavy_plus_sign" to "\u2795", - "heavy_minus_sign" to "\u2796", - "heavy_division_sign" to "\u2797", - "hash" to "\u0023\uFE0F\u20E3", - "keycap_star" to "\u002A\uFE0F\u20E3", - "zero" to "\u0030\uFE0F\u20E3", - "one" to "\u0031\uFE0F\u20E3", - "two" to "\u0032\uFE0F\u20E3", - "three" to "\u0033\uFE0F\u20E3", - "four" to "\u0034\uFE0F\u20E3", - "five" to "\u0035\uFE0F\u20E3", - "six" to "\u0036\uFE0F\u20E3", - "seven" to "\u0037\uFE0F\u20E3", - "eight" to "\u0038\uFE0F\u20E3", - "nine" to "\u0039\uFE0F\u20E3", - "copyright" to "\u00A9\uFE0F", - "registered" to "\u00AE\uFE0F", - "mahjong" to "\uD83C\uDC04", - "black_joker" to "\uD83C\uDCCF", - "a" to "\uD83C\uDD70\uFE0F", - "b" to "\uD83C\uDD71\uFE0F", - "o2" to "\uD83C\uDD7E\uFE0F", - "parking" to "\uD83C\uDD7F\uFE0F", - "ab" to "\uD83C\uDD8E", - "cl" to "\uD83C\uDD91", - "cool" to "\uD83C\uDD92", - "free" to "\uD83C\uDD93", - "id" to "\uD83C\uDD94", - "new" to "\uD83C\uDD95", - "ng" to "\uD83C\uDD96", - "ok" to "\uD83C\uDD97", - "sos" to "\uD83C\uDD98", - "up" to "\uD83C\uDD99", - "vs" to "\uD83C\uDD9A", - "flag-ac" to "\uD83C\uDDE6\uD83C\uDDE8", - "flag-ad" to "\uD83C\uDDE6\uD83C\uDDE9", - "flag-ae" to "\uD83C\uDDE6\uD83C\uDDEA", - "flag-af" to "\uD83C\uDDE6\uD83C\uDDEB", - "flag-ag" to "\uD83C\uDDE6\uD83C\uDDEC", - "flag-ai" to "\uD83C\uDDE6\uD83C\uDDEE", - "flag-al" to "\uD83C\uDDE6\uD83C\uDDF1", - "flag-am" to "\uD83C\uDDE6\uD83C\uDDF2", - "flag-ao" to "\uD83C\uDDE6\uD83C\uDDF4", - "flag-aq" to "\uD83C\uDDE6\uD83C\uDDF6", - "flag-ar" to "\uD83C\uDDE6\uD83C\uDDF7", - "flag-as" to "\uD83C\uDDE6\uD83C\uDDF8", - "flag-at" to "\uD83C\uDDE6\uD83C\uDDF9", - "flag-au" to "\uD83C\uDDE6\uD83C\uDDFA", - "flag-aw" to "\uD83C\uDDE6\uD83C\uDDFC", - "flag-ax" to "\uD83C\uDDE6\uD83C\uDDFD", - "flag-az" to "\uD83C\uDDE6\uD83C\uDDFF", - "flag-ba" to "\uD83C\uDDE7\uD83C\uDDE6", - "flag-bb" to "\uD83C\uDDE7\uD83C\uDDE7", - "flag-bd" to "\uD83C\uDDE7\uD83C\uDDE9", - "flag-be" to "\uD83C\uDDE7\uD83C\uDDEA", - "flag-bf" to "\uD83C\uDDE7\uD83C\uDDEB", - "flag-bg" to "\uD83C\uDDE7\uD83C\uDDEC", - "flag-bh" to "\uD83C\uDDE7\uD83C\uDDED", - "flag-bi" to "\uD83C\uDDE7\uD83C\uDDEE", - "flag-bj" to "\uD83C\uDDE7\uD83C\uDDEF", - "flag-bl" to "\uD83C\uDDE7\uD83C\uDDF1", - "flag-bm" to "\uD83C\uDDE7\uD83C\uDDF2", - "flag-bn" to "\uD83C\uDDE7\uD83C\uDDF3", - "flag-bo" to "\uD83C\uDDE7\uD83C\uDDF4", - "flag-bq" to "\uD83C\uDDE7\uD83C\uDDF6", - "flag-br" to "\uD83C\uDDE7\uD83C\uDDF7", - "flag-bs" to "\uD83C\uDDE7\uD83C\uDDF8", - "flag-bt" to "\uD83C\uDDE7\uD83C\uDDF9", - "flag-bv" to "\uD83C\uDDE7\uD83C\uDDFB", - "flag-bw" to "\uD83C\uDDE7\uD83C\uDDFC", - "flag-by" to "\uD83C\uDDE7\uD83C\uDDFE", - "flag-bz" to "\uD83C\uDDE7\uD83C\uDDFF", - "flag-ca" to "\uD83C\uDDE8\uD83C\uDDE6", - "flag-cc" to "\uD83C\uDDE8\uD83C\uDDE8", - "flag-cd" to "\uD83C\uDDE8\uD83C\uDDE9", - "flag-cf" to "\uD83C\uDDE8\uD83C\uDDEB", - "flag-cg" to "\uD83C\uDDE8\uD83C\uDDEC", - "flag-ch" to "\uD83C\uDDE8\uD83C\uDDED", - "flag-ci" to "\uD83C\uDDE8\uD83C\uDDEE", - "flag-ck" to "\uD83C\uDDE8\uD83C\uDDF0", - "flag-cl" to "\uD83C\uDDE8\uD83C\uDDF1", - "flag-cm" to "\uD83C\uDDE8\uD83C\uDDF2", - "cn" to "\uD83C\uDDE8\uD83C\uDDF3", - "flag-cn" to "\uD83C\uDDE8\uD83C\uDDF3", - "flag-co" to "\uD83C\uDDE8\uD83C\uDDF4", - "flag-cp" to "\uD83C\uDDE8\uD83C\uDDF5", - "flag-cr" to "\uD83C\uDDE8\uD83C\uDDF7", - "flag-cu" to "\uD83C\uDDE8\uD83C\uDDFA", - "flag-cv" to "\uD83C\uDDE8\uD83C\uDDFB", - "flag-cw" to "\uD83C\uDDE8\uD83C\uDDFC", - "flag-cx" to "\uD83C\uDDE8\uD83C\uDDFD", - "flag-cy" to "\uD83C\uDDE8\uD83C\uDDFE", - "flag-cz" to "\uD83C\uDDE8\uD83C\uDDFF", - "de" to "\uD83C\uDDE9\uD83C\uDDEA", - "flag-de" to "\uD83C\uDDE9\uD83C\uDDEA", - "flag-dg" to "\uD83C\uDDE9\uD83C\uDDEC", - "flag-dj" to "\uD83C\uDDE9\uD83C\uDDEF", - "flag-dk" to "\uD83C\uDDE9\uD83C\uDDF0", - "flag-dm" to "\uD83C\uDDE9\uD83C\uDDF2", - "flag-do" to "\uD83C\uDDE9\uD83C\uDDF4", - "flag-dz" to "\uD83C\uDDE9\uD83C\uDDFF", - "flag-ea" to "\uD83C\uDDEA\uD83C\uDDE6", - "flag-ec" to "\uD83C\uDDEA\uD83C\uDDE8", - "flag-ee" to "\uD83C\uDDEA\uD83C\uDDEA", - "flag-eg" to "\uD83C\uDDEA\uD83C\uDDEC", - "flag-eh" to "\uD83C\uDDEA\uD83C\uDDED", - "flag-er" to "\uD83C\uDDEA\uD83C\uDDF7", - "es" to "\uD83C\uDDEA\uD83C\uDDF8", - "flag-es" to "\uD83C\uDDEA\uD83C\uDDF8", - "flag-et" to "\uD83C\uDDEA\uD83C\uDDF9", - "flag-eu" to "\uD83C\uDDEA\uD83C\uDDFA", - "flag-fi" to "\uD83C\uDDEB\uD83C\uDDEE", - "flag-fj" to "\uD83C\uDDEB\uD83C\uDDEF", - "flag-fk" to "\uD83C\uDDEB\uD83C\uDDF0", - "flag-fm" to "\uD83C\uDDEB\uD83C\uDDF2", - "flag-fo" to "\uD83C\uDDEB\uD83C\uDDF4", - "fr" to "\uD83C\uDDEB\uD83C\uDDF7", - "flag-fr" to "\uD83C\uDDEB\uD83C\uDDF7", - "flag-ga" to "\uD83C\uDDEC\uD83C\uDDE6", - "gb" to "\uD83C\uDDEC\uD83C\uDDE7", - "uk" to "\uD83C\uDDEC\uD83C\uDDE7", - "flag-gb" to "\uD83C\uDDEC\uD83C\uDDE7", - "flag-gd" to "\uD83C\uDDEC\uD83C\uDDE9", - "flag-ge" to "\uD83C\uDDEC\uD83C\uDDEA", - "flag-gf" to "\uD83C\uDDEC\uD83C\uDDEB", - "flag-gg" to "\uD83C\uDDEC\uD83C\uDDEC", - "flag-gh" to "\uD83C\uDDEC\uD83C\uDDED", - "flag-gi" to "\uD83C\uDDEC\uD83C\uDDEE", - "flag-gl" to "\uD83C\uDDEC\uD83C\uDDF1", - "flag-gm" to "\uD83C\uDDEC\uD83C\uDDF2", - "flag-gn" to "\uD83C\uDDEC\uD83C\uDDF3", - "flag-gp" to "\uD83C\uDDEC\uD83C\uDDF5", - "flag-gq" to "\uD83C\uDDEC\uD83C\uDDF6", - "flag-gr" to "\uD83C\uDDEC\uD83C\uDDF7", - "flag-gs" to "\uD83C\uDDEC\uD83C\uDDF8", - "flag-gt" to "\uD83C\uDDEC\uD83C\uDDF9", - "flag-gu" to "\uD83C\uDDEC\uD83C\uDDFA", - "flag-gw" to "\uD83C\uDDEC\uD83C\uDDFC", - "flag-gy" to "\uD83C\uDDEC\uD83C\uDDFE", - "flag-hk" to "\uD83C\uDDED\uD83C\uDDF0", - "flag-hm" to "\uD83C\uDDED\uD83C\uDDF2", - "flag-hn" to "\uD83C\uDDED\uD83C\uDDF3", - "flag-hr" to "\uD83C\uDDED\uD83C\uDDF7", - "flag-ht" to "\uD83C\uDDED\uD83C\uDDF9", - "flag-hu" to "\uD83C\uDDED\uD83C\uDDFA", - "flag-ic" to "\uD83C\uDDEE\uD83C\uDDE8", - "flag-id" to "\uD83C\uDDEE\uD83C\uDDE9", - "flag-ie" to "\uD83C\uDDEE\uD83C\uDDEA", - "flag-il" to "\uD83C\uDDEE\uD83C\uDDF1", - "flag-im" to "\uD83C\uDDEE\uD83C\uDDF2", - "flag-in" to "\uD83C\uDDEE\uD83C\uDDF3", - "flag-io" to "\uD83C\uDDEE\uD83C\uDDF4", - "flag-iq" to "\uD83C\uDDEE\uD83C\uDDF6", - "flag-ir" to "\uD83C\uDDEE\uD83C\uDDF7", - "flag-is" to "\uD83C\uDDEE\uD83C\uDDF8", - "it" to "\uD83C\uDDEE\uD83C\uDDF9", - "flag-it" to "\uD83C\uDDEE\uD83C\uDDF9", - "flag-je" to "\uD83C\uDDEF\uD83C\uDDEA", - "flag-jm" to "\uD83C\uDDEF\uD83C\uDDF2", - "flag-jo" to "\uD83C\uDDEF\uD83C\uDDF4", - "jp" to "\uD83C\uDDEF\uD83C\uDDF5", - "flag-jp" to "\uD83C\uDDEF\uD83C\uDDF5", - "flag-ke" to "\uD83C\uDDF0\uD83C\uDDEA", - "flag-kg" to "\uD83C\uDDF0\uD83C\uDDEC", - "flag-kh" to "\uD83C\uDDF0\uD83C\uDDED", - "flag-ki" to "\uD83C\uDDF0\uD83C\uDDEE", - "flag-km" to "\uD83C\uDDF0\uD83C\uDDF2", - "flag-kn" to "\uD83C\uDDF0\uD83C\uDDF3", - "flag-kp" to "\uD83C\uDDF0\uD83C\uDDF5", - "kr" to "\uD83C\uDDF0\uD83C\uDDF7", - "flag-kr" to "\uD83C\uDDF0\uD83C\uDDF7", - "flag-kw" to "\uD83C\uDDF0\uD83C\uDDFC", - "flag-ky" to "\uD83C\uDDF0\uD83C\uDDFE", - "flag-kz" to "\uD83C\uDDF0\uD83C\uDDFF", - "flag-la" to "\uD83C\uDDF1\uD83C\uDDE6", - "flag-lb" to "\uD83C\uDDF1\uD83C\uDDE7", - "flag-lc" to "\uD83C\uDDF1\uD83C\uDDE8", - "flag-li" to "\uD83C\uDDF1\uD83C\uDDEE", - "flag-lk" to "\uD83C\uDDF1\uD83C\uDDF0", - "flag-lr" to "\uD83C\uDDF1\uD83C\uDDF7", - "flag-ls" to "\uD83C\uDDF1\uD83C\uDDF8", - "flag-lt" to "\uD83C\uDDF1\uD83C\uDDF9", - "flag-lu" to "\uD83C\uDDF1\uD83C\uDDFA", - "flag-lv" to "\uD83C\uDDF1\uD83C\uDDFB", - "flag-ly" to "\uD83C\uDDF1\uD83C\uDDFE", - "flag-ma" to "\uD83C\uDDF2\uD83C\uDDE6", - "flag-mc" to "\uD83C\uDDF2\uD83C\uDDE8", - "flag-md" to "\uD83C\uDDF2\uD83C\uDDE9", - "flag-me" to "\uD83C\uDDF2\uD83C\uDDEA", - "flag-mf" to "\uD83C\uDDF2\uD83C\uDDEB", - "flag-mg" to "\uD83C\uDDF2\uD83C\uDDEC", - "flag-mh" to "\uD83C\uDDF2\uD83C\uDDED", - "flag-mk" to "\uD83C\uDDF2\uD83C\uDDF0", - "flag-ml" to "\uD83C\uDDF2\uD83C\uDDF1", - "flag-mm" to "\uD83C\uDDF2\uD83C\uDDF2", - "flag-mn" to "\uD83C\uDDF2\uD83C\uDDF3", - "flag-mo" to "\uD83C\uDDF2\uD83C\uDDF4", - "flag-mp" to "\uD83C\uDDF2\uD83C\uDDF5", - "flag-mq" to "\uD83C\uDDF2\uD83C\uDDF6", - "flag-mr" to "\uD83C\uDDF2\uD83C\uDDF7", - "flag-ms" to "\uD83C\uDDF2\uD83C\uDDF8", - "flag-mt" to "\uD83C\uDDF2\uD83C\uDDF9", - "flag-mu" to "\uD83C\uDDF2\uD83C\uDDFA", - "flag-mv" to "\uD83C\uDDF2\uD83C\uDDFB", - "flag-mw" to "\uD83C\uDDF2\uD83C\uDDFC", - "flag-mx" to "\uD83C\uDDF2\uD83C\uDDFD", - "flag-my" to "\uD83C\uDDF2\uD83C\uDDFE", - "flag-mz" to "\uD83C\uDDF2\uD83C\uDDFF", - "flag-na" to "\uD83C\uDDF3\uD83C\uDDE6", - "flag-nc" to "\uD83C\uDDF3\uD83C\uDDE8", - "flag-ne" to "\uD83C\uDDF3\uD83C\uDDEA", - "flag-nf" to "\uD83C\uDDF3\uD83C\uDDEB", - "flag-ng" to "\uD83C\uDDF3\uD83C\uDDEC", - "flag-ni" to "\uD83C\uDDF3\uD83C\uDDEE", - "flag-nl" to "\uD83C\uDDF3\uD83C\uDDF1", - "flag-no" to "\uD83C\uDDF3\uD83C\uDDF4", - "flag-np" to "\uD83C\uDDF3\uD83C\uDDF5", - "flag-nr" to "\uD83C\uDDF3\uD83C\uDDF7", - "flag-nu" to "\uD83C\uDDF3\uD83C\uDDFA", - "flag-nz" to "\uD83C\uDDF3\uD83C\uDDFF", - "flag-om" to "\uD83C\uDDF4\uD83C\uDDF2", - "flag-pa" to "\uD83C\uDDF5\uD83C\uDDE6", - "flag-pe" to "\uD83C\uDDF5\uD83C\uDDEA", - "flag-pf" to "\uD83C\uDDF5\uD83C\uDDEB", - "flag-pg" to "\uD83C\uDDF5\uD83C\uDDEC", - "flag-ph" to "\uD83C\uDDF5\uD83C\uDDED", - "flag-pk" to "\uD83C\uDDF5\uD83C\uDDF0", - "flag-pl" to "\uD83C\uDDF5\uD83C\uDDF1", - "flag-pm" to "\uD83C\uDDF5\uD83C\uDDF2", - "flag-pn" to "\uD83C\uDDF5\uD83C\uDDF3", - "flag-pr" to "\uD83C\uDDF5\uD83C\uDDF7", - "flag-ps" to "\uD83C\uDDF5\uD83C\uDDF8", - "flag-pt" to "\uD83C\uDDF5\uD83C\uDDF9", - "flag-pw" to "\uD83C\uDDF5\uD83C\uDDFC", - "flag-py" to "\uD83C\uDDF5\uD83C\uDDFE", - "flag-qa" to "\uD83C\uDDF6\uD83C\uDDE6", - "flag-re" to "\uD83C\uDDF7\uD83C\uDDEA", - "flag-ro" to "\uD83C\uDDF7\uD83C\uDDF4", - "flag-rs" to "\uD83C\uDDF7\uD83C\uDDF8", - "ru" to "\uD83C\uDDF7\uD83C\uDDFA", - "flag-ru" to "\uD83C\uDDF7\uD83C\uDDFA", - "flag-rw" to "\uD83C\uDDF7\uD83C\uDDFC", - "flag-sa" to "\uD83C\uDDF8\uD83C\uDDE6", - "flag-sb" to "\uD83C\uDDF8\uD83C\uDDE7", - "flag-sc" to "\uD83C\uDDF8\uD83C\uDDE8", - "flag-sd" to "\uD83C\uDDF8\uD83C\uDDE9", - "flag-se" to "\uD83C\uDDF8\uD83C\uDDEA", - "flag-sg" to "\uD83C\uDDF8\uD83C\uDDEC", - "flag-sh" to "\uD83C\uDDF8\uD83C\uDDED", - "flag-si" to "\uD83C\uDDF8\uD83C\uDDEE", - "flag-sj" to "\uD83C\uDDF8\uD83C\uDDEF", - "flag-sk" to "\uD83C\uDDF8\uD83C\uDDF0", - "flag-sl" to "\uD83C\uDDF8\uD83C\uDDF1", - "flag-sm" to "\uD83C\uDDF8\uD83C\uDDF2", - "flag-sn" to "\uD83C\uDDF8\uD83C\uDDF3", - "flag-so" to "\uD83C\uDDF8\uD83C\uDDF4", - "flag-sr" to "\uD83C\uDDF8\uD83C\uDDF7", - "flag-ss" to "\uD83C\uDDF8\uD83C\uDDF8", - "flag-st" to "\uD83C\uDDF8\uD83C\uDDF9", - "flag-sv" to "\uD83C\uDDF8\uD83C\uDDFB", - "flag-sx" to "\uD83C\uDDF8\uD83C\uDDFD", - "flag-sy" to "\uD83C\uDDF8\uD83C\uDDFE", - "flag-sz" to "\uD83C\uDDF8\uD83C\uDDFF", - "flag-ta" to "\uD83C\uDDF9\uD83C\uDDE6", - "flag-tc" to "\uD83C\uDDF9\uD83C\uDDE8", - "flag-td" to "\uD83C\uDDF9\uD83C\uDDE9", - "flag-tf" to "\uD83C\uDDF9\uD83C\uDDEB", - "flag-tg" to "\uD83C\uDDF9\uD83C\uDDEC", - "flag-th" to "\uD83C\uDDF9\uD83C\uDDED", - "flag-tj" to "\uD83C\uDDF9\uD83C\uDDEF", - "flag-tk" to "\uD83C\uDDF9\uD83C\uDDF0", - "flag-tl" to "\uD83C\uDDF9\uD83C\uDDF1", - "flag-tm" to "\uD83C\uDDF9\uD83C\uDDF2", - "flag-tn" to "\uD83C\uDDF9\uD83C\uDDF3", - "flag-to" to "\uD83C\uDDF9\uD83C\uDDF4", - "flag-tr" to "\uD83C\uDDF9\uD83C\uDDF7", - "flag-tt" to "\uD83C\uDDF9\uD83C\uDDF9", - "flag-tv" to "\uD83C\uDDF9\uD83C\uDDFB", - "flag-tw" to "\uD83C\uDDF9\uD83C\uDDFC", - "flag-tz" to "\uD83C\uDDF9\uD83C\uDDFF", - "flag-ua" to "\uD83C\uDDFA\uD83C\uDDE6", - "flag-ug" to "\uD83C\uDDFA\uD83C\uDDEC", - "flag-um" to "\uD83C\uDDFA\uD83C\uDDF2", - "flag-un" to "\uD83C\uDDFA\uD83C\uDDF3", - "us" to "\uD83C\uDDFA\uD83C\uDDF8", - "flag-us" to "\uD83C\uDDFA\uD83C\uDDF8", - "flag-uy" to "\uD83C\uDDFA\uD83C\uDDFE", - "flag-uz" to "\uD83C\uDDFA\uD83C\uDDFF", - "flag-va" to "\uD83C\uDDFB\uD83C\uDDE6", - "flag-vc" to "\uD83C\uDDFB\uD83C\uDDE8", - "flag-ve" to "\uD83C\uDDFB\uD83C\uDDEA", - "flag-vg" to "\uD83C\uDDFB\uD83C\uDDEC", - "flag-vi" to "\uD83C\uDDFB\uD83C\uDDEE", - "flag-vn" to "\uD83C\uDDFB\uD83C\uDDF3", - "flag-vu" to "\uD83C\uDDFB\uD83C\uDDFA", - "flag-wf" to "\uD83C\uDDFC\uD83C\uDDEB", - "flag-ws" to "\uD83C\uDDFC\uD83C\uDDF8", - "flag-xk" to "\uD83C\uDDFD\uD83C\uDDF0", - "flag-ye" to "\uD83C\uDDFE\uD83C\uDDEA", - "flag-yt" to "\uD83C\uDDFE\uD83C\uDDF9", - "flag-za" to "\uD83C\uDDFF\uD83C\uDDE6", - "flag-zm" to "\uD83C\uDDFF\uD83C\uDDF2", - "flag-zw" to "\uD83C\uDDFF\uD83C\uDDFC", - "koko" to "\uD83C\uDE01", - "sa" to "\uD83C\uDE02\uFE0F", - "u7121" to "\uD83C\uDE1A", - "u6307" to "\uD83C\uDE2F", - "u7981" to "\uD83C\uDE32", - "u7a7a" to "\uD83C\uDE33", - "u5408" to "\uD83C\uDE34", - "u6e80" to "\uD83C\uDE35", - "u6709" to "\uD83C\uDE36", - "u6708" to "\uD83C\uDE37\uFE0F", - "u7533" to "\uD83C\uDE38", - "u5272" to "\uD83C\uDE39", - "u55b6" to "\uD83C\uDE3A", - "ideograph_advantage" to "\uD83C\uDE50", - "accept" to "\uD83C\uDE51", - "cyclone" to "\uD83C\uDF00", - "foggy" to "\uD83C\uDF01", - "closed_umbrella" to "\uD83C\uDF02", - "night_with_stars" to "\uD83C\uDF03", - "sunrise_over_mountains" to "\uD83C\uDF04", - "sunrise" to "\uD83C\uDF05", - "city_sunset" to "\uD83C\uDF06", - "city_sunrise" to "\uD83C\uDF07", - "rainbow" to "\uD83C\uDF08", - "bridge_at_night" to "\uD83C\uDF09", - "ocean" to "\uD83C\uDF0A", - "volcano" to "\uD83C\uDF0B", - "milky_way" to "\uD83C\uDF0C", - "earth_africa" to "\uD83C\uDF0D", - "earth_americas" to "\uD83C\uDF0E", - "earth_asia" to "\uD83C\uDF0F", - "globe_with_meridians" to "\uD83C\uDF10", - "new_moon" to "\uD83C\uDF11", - "waxing_crescent_moon" to "\uD83C\uDF12", - "first_quarter_moon" to "\uD83C\uDF13", - "moon" to "\uD83C\uDF14", - "waxing_gibbous_moon" to "\uD83C\uDF14", - "full_moon" to "\uD83C\uDF15", - "waning_gibbous_moon" to "\uD83C\uDF16", - "last_quarter_moon" to "\uD83C\uDF17", - "waning_crescent_moon" to "\uD83C\uDF18", - "crescent_moon" to "\uD83C\uDF19", - "new_moon_with_face" to "\uD83C\uDF1A", - "first_quarter_moon_with_face" to "\uD83C\uDF1B", - "last_quarter_moon_with_face" to "\uD83C\uDF1C", - "full_moon_with_face" to "\uD83C\uDF1D", - "sun_with_face" to "\uD83C\uDF1E", - "star2" to "\uD83C\uDF1F", - "stars" to "\uD83C\uDF20", - "thermometer" to "\uD83C\uDF21\uFE0F", - "mostly_sunny" to "\uD83C\uDF24\uFE0F", - "sun_small_cloud" to "\uD83C\uDF24\uFE0F", - "barely_sunny" to "\uD83C\uDF25\uFE0F", - "sun_behind_cloud" to "\uD83C\uDF25\uFE0F", - "partly_sunny_rain" to "\uD83C\uDF26\uFE0F", - "sun_behind_rain_cloud" to "\uD83C\uDF26\uFE0F", - "rain_cloud" to "\uD83C\uDF27\uFE0F", - "snow_cloud" to "\uD83C\uDF28\uFE0F", - "lightning" to "\uD83C\uDF29\uFE0F", - "lightning_cloud" to "\uD83C\uDF29\uFE0F", - "tornado" to "\uD83C\uDF2A\uFE0F", - "tornado_cloud" to "\uD83C\uDF2A\uFE0F", - "fog" to "\uD83C\uDF2B\uFE0F", - "wind_blowing_face" to "\uD83C\uDF2C\uFE0F", - "hotdog" to "\uD83C\uDF2D", - "taco" to "\uD83C\uDF2E", - "burrito" to "\uD83C\uDF2F", - "chestnut" to "\uD83C\uDF30", - "seedling" to "\uD83C\uDF31", - "evergreen_tree" to "\uD83C\uDF32", - "deciduous_tree" to "\uD83C\uDF33", - "palm_tree" to "\uD83C\uDF34", - "cactus" to "\uD83C\uDF35", - "hot_pepper" to "\uD83C\uDF36\uFE0F", - "tulip" to "\uD83C\uDF37", - "cherry_blossom" to "\uD83C\uDF38", - "rose" to "\uD83C\uDF39", - "hibiscus" to "\uD83C\uDF3A", - "sunflower" to "\uD83C\uDF3B", - "blossom" to "\uD83C\uDF3C", - "corn" to "\uD83C\uDF3D", - "ear_of_rice" to "\uD83C\uDF3E", - "herb" to "\uD83C\uDF3F", - "four_leaf_clover" to "\uD83C\uDF40", - "maple_leaf" to "\uD83C\uDF41", - "fallen_leaf" to "\uD83C\uDF42", - "leaves" to "\uD83C\uDF43", - "mushroom" to "\uD83C\uDF44", - "tomato" to "\uD83C\uDF45", - "eggplant" to "\uD83C\uDF46", - "grapes" to "\uD83C\uDF47", - "melon" to "\uD83C\uDF48", - "watermelon" to "\uD83C\uDF49", - "tangerine" to "\uD83C\uDF4A", - "lemon" to "\uD83C\uDF4B", - "banana" to "\uD83C\uDF4C", - "pineapple" to "\uD83C\uDF4D", - "apple" to "\uD83C\uDF4E", - "green_apple" to "\uD83C\uDF4F", - "pear" to "\uD83C\uDF50", - "peach" to "\uD83C\uDF51", - "cherries" to "\uD83C\uDF52", - "strawberry" to "\uD83C\uDF53", - "hamburger" to "\uD83C\uDF54", - "pizza" to "\uD83C\uDF55", - "meat_on_bone" to "\uD83C\uDF56", - "poultry_leg" to "\uD83C\uDF57", - "rice_cracker" to "\uD83C\uDF58", - "rice_ball" to "\uD83C\uDF59", - "rice" to "\uD83C\uDF5A", - "curry" to "\uD83C\uDF5B", - "ramen" to "\uD83C\uDF5C", - "spaghetti" to "\uD83C\uDF5D", - "bread" to "\uD83C\uDF5E", - "fries" to "\uD83C\uDF5F", - "sweet_potato" to "\uD83C\uDF60", - "dango" to "\uD83C\uDF61", - "oden" to "\uD83C\uDF62", - "sushi" to "\uD83C\uDF63", - "fried_shrimp" to "\uD83C\uDF64", - "fish_cake" to "\uD83C\uDF65", - "icecream" to "\uD83C\uDF66", - "shaved_ice" to "\uD83C\uDF67", - "ice_cream" to "\uD83C\uDF68", - "doughnut" to "\uD83C\uDF69", - "cookie" to "\uD83C\uDF6A", - "chocolate_bar" to "\uD83C\uDF6B", - "candy" to "\uD83C\uDF6C", - "lollipop" to "\uD83C\uDF6D", - "custard" to "\uD83C\uDF6E", - "honey_pot" to "\uD83C\uDF6F", - "cake" to "\uD83C\uDF70", - "bento" to "\uD83C\uDF71", - "stew" to "\uD83C\uDF72", - "fried_egg" to "\uD83C\uDF73", - "cooking" to "\uD83C\uDF73", - "fork_and_knife" to "\uD83C\uDF74", - "tea" to "\uD83C\uDF75", - "sake" to "\uD83C\uDF76", - "wine_glass" to "\uD83C\uDF77", - "cocktail" to "\uD83C\uDF78", - "tropical_drink" to "\uD83C\uDF79", - "beer" to "\uD83C\uDF7A", - "beers" to "\uD83C\uDF7B", - "baby_bottle" to "\uD83C\uDF7C", - "knife_fork_plate" to "\uD83C\uDF7D\uFE0F", - "champagne" to "\uD83C\uDF7E", - "popcorn" to "\uD83C\uDF7F", - "ribbon" to "\uD83C\uDF80", - "gift" to "\uD83C\uDF81", - "birthday" to "\uD83C\uDF82", - "jack_o_lantern" to "\uD83C\uDF83", - "christmas_tree" to "\uD83C\uDF84", - "santa" to "\uD83C\uDF85", - "fireworks" to "\uD83C\uDF86", - "sparkler" to "\uD83C\uDF87", - "balloon" to "\uD83C\uDF88", - "tada" to "\uD83C\uDF89", - "confetti_ball" to "\uD83C\uDF8A", - "tanabata_tree" to "\uD83C\uDF8B", - "crossed_flags" to "\uD83C\uDF8C", - "bamboo" to "\uD83C\uDF8D", - "dolls" to "\uD83C\uDF8E", - "flags" to "\uD83C\uDF8F", - "wind_chime" to "\uD83C\uDF90", - "rice_scene" to "\uD83C\uDF91", - "school_satchel" to "\uD83C\uDF92", - "mortar_board" to "\uD83C\uDF93", - "medal" to "\uD83C\uDF96\uFE0F", - "reminder_ribbon" to "\uD83C\uDF97\uFE0F", - "studio_microphone" to "\uD83C\uDF99\uFE0F", - "level_slider" to "\uD83C\uDF9A\uFE0F", - "control_knobs" to "\uD83C\uDF9B\uFE0F", - "film_frames" to "\uD83C\uDF9E\uFE0F", - "admission_tickets" to "\uD83C\uDF9F\uFE0F", - "carousel_horse" to "\uD83C\uDFA0", - "ferris_wheel" to "\uD83C\uDFA1", - "roller_coaster" to "\uD83C\uDFA2", - "fishing_pole_and_fish" to "\uD83C\uDFA3", - "microphone" to "\uD83C\uDFA4", - "movie_camera" to "\uD83C\uDFA5", - "cinema" to "\uD83C\uDFA6", - "headphones" to "\uD83C\uDFA7", - "art" to "\uD83C\uDFA8", - "tophat" to "\uD83C\uDFA9", - "circus_tent" to "\uD83C\uDFAA", - "ticket" to "\uD83C\uDFAB", - "clapper" to "\uD83C\uDFAC", - "performing_arts" to "\uD83C\uDFAD", - "video_game" to "\uD83C\uDFAE", - "dart" to "\uD83C\uDFAF", - "slot_machine" to "\uD83C\uDFB0", - "8ball" to "\uD83C\uDFB1", - "game_die" to "\uD83C\uDFB2", - "bowling" to "\uD83C\uDFB3", - "flower_playing_cards" to "\uD83C\uDFB4", - "musical_note" to "\uD83C\uDFB5", - "notes" to "\uD83C\uDFB6", - "saxophone" to "\uD83C\uDFB7", - "guitar" to "\uD83C\uDFB8", - "musical_keyboard" to "\uD83C\uDFB9", - "trumpet" to "\uD83C\uDFBA", - "violin" to "\uD83C\uDFBB", - "musical_score" to "\uD83C\uDFBC", - "running_shirt_with_sash" to "\uD83C\uDFBD", - "tennis" to "\uD83C\uDFBE", - "ski" to "\uD83C\uDFBF", - "basketball" to "\uD83C\uDFC0", - "checkered_flag" to "\uD83C\uDFC1", - "snowboarder" to "\uD83C\uDFC2", - "woman-running" to "\uD83C\uDFC3\u200D\u2640\uFE0F", - "man-running" to "\uD83C\uDFC3\u200D\u2642\uFE0F", - "runner" to "\uD83C\uDFC3\u200D\u2642\uFE0F", - "running" to "\uD83C\uDFC3\u200D\u2642\uFE0F", - "woman-surfing" to "\uD83C\uDFC4\u200D\u2640\uFE0F", - "man-surfing" to "\uD83C\uDFC4\u200D\u2642\uFE0F", - "surfer" to "\uD83C\uDFC4\u200D\u2642\uFE0F", - "sports_medal" to "\uD83C\uDFC5", - "trophy" to "\uD83C\uDFC6", - "horse_racing" to "\uD83C\uDFC7", - "football" to "\uD83C\uDFC8", - "rugby_football" to "\uD83C\uDFC9", - "woman-swimming" to "\uD83C\uDFCA\u200D\u2640\uFE0F", - "man-swimming" to "\uD83C\uDFCA\u200D\u2642\uFE0F", - "swimmer" to "\uD83C\uDFCA\u200D\u2642\uFE0F", - "woman-lifting-weights" to "\uD83C\uDFCB\uFE0F\u200D\u2640\uFE0F", - "man-lifting-weights" to "\uD83C\uDFCB\uFE0F\u200D\u2642\uFE0F", - "weight_lifter" to "\uD83C\uDFCB\uFE0F\u200D\u2642\uFE0F", - "woman-golfing" to "\uD83C\uDFCC\uFE0F\u200D\u2640\uFE0F", - "man-golfing" to "\uD83C\uDFCC\uFE0F\u200D\u2642\uFE0F", - "golfer" to "\uD83C\uDFCC\uFE0F\u200D\u2642\uFE0F", - "racing_motorcycle" to "\uD83C\uDFCD\uFE0F", - "racing_car" to "\uD83C\uDFCE\uFE0F", - "cricket_bat_and_ball" to "\uD83C\uDFCF", - "volleyball" to "\uD83C\uDFD0", - "field_hockey_stick_and_ball" to "\uD83C\uDFD1", - "ice_hockey_stick_and_puck" to "\uD83C\uDFD2", - "table_tennis_paddle_and_ball" to "\uD83C\uDFD3", - "snow_capped_mountain" to "\uD83C\uDFD4\uFE0F", - "camping" to "\uD83C\uDFD5\uFE0F", - "beach_with_umbrella" to "\uD83C\uDFD6\uFE0F", - "building_construction" to "\uD83C\uDFD7\uFE0F", - "house_buildings" to "\uD83C\uDFD8\uFE0F", - "cityscape" to "\uD83C\uDFD9\uFE0F", - "derelict_house_building" to "\uD83C\uDFDA\uFE0F", - "classical_building" to "\uD83C\uDFDB\uFE0F", - "desert" to "\uD83C\uDFDC\uFE0F", - "desert_island" to "\uD83C\uDFDD\uFE0F", - "national_park" to "\uD83C\uDFDE\uFE0F", - "stadium" to "\uD83C\uDFDF\uFE0F", - "house" to "\uD83C\uDFE0", - "house_with_garden" to "\uD83C\uDFE1", - "office" to "\uD83C\uDFE2", - "post_office" to "\uD83C\uDFE3", - "european_post_office" to "\uD83C\uDFE4", - "hospital" to "\uD83C\uDFE5", - "bank" to "\uD83C\uDFE6", - "atm" to "\uD83C\uDFE7", - "hotel" to "\uD83C\uDFE8", - "love_hotel" to "\uD83C\uDFE9", - "convenience_store" to "\uD83C\uDFEA", - "school" to "\uD83C\uDFEB", - "department_store" to "\uD83C\uDFEC", - "factory" to "\uD83C\uDFED", - "izakaya_lantern" to "\uD83C\uDFEE", - "lantern" to "\uD83C\uDFEE", - "japanese_castle" to "\uD83C\uDFEF", - "european_castle" to "\uD83C\uDFF0", - "rainbow-flag" to "\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08", - "waving_white_flag" to "\uD83C\uDFF3\uFE0F", - "flag-england" to "\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67\uDB40\uDC7F", - "flag-scotland" to "\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74\uDB40\uDC7F", - "flag-wales" to "\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73\uDB40\uDC7F", - "waving_black_flag" to "\uD83C\uDFF4", - "rosette" to "\uD83C\uDFF5\uFE0F", - "label" to "\uD83C\uDFF7\uFE0F", - "badminton_racquet_and_shuttlecock" to "\uD83C\uDFF8", - "bow_and_arrow" to "\uD83C\uDFF9", - "amphora" to "\uD83C\uDFFA", - "skin-tone-2" to "\uD83C\uDFFB", - "skin-tone-3" to "\uD83C\uDFFC", - "skin-tone-4" to "\uD83C\uDFFD", - "skin-tone-5" to "\uD83C\uDFFE", - "skin-tone-6" to "\uD83C\uDFFF", - "rat" to "\uD83D\uDC00", - "mouse2" to "\uD83D\uDC01", - "ox" to "\uD83D\uDC02", - "water_buffalo" to "\uD83D\uDC03", - "cow2" to "\uD83D\uDC04", - "tiger2" to "\uD83D\uDC05", - "leopard" to "\uD83D\uDC06", - "rabbit2" to "\uD83D\uDC07", - "cat2" to "\uD83D\uDC08", - "dragon" to "\uD83D\uDC09", - "crocodile" to "\uD83D\uDC0A", - "whale2" to "\uD83D\uDC0B", - "snail" to "\uD83D\uDC0C", - "snake" to "\uD83D\uDC0D", - "racehorse" to "\uD83D\uDC0E", - "ram" to "\uD83D\uDC0F", - "goat" to "\uD83D\uDC10", - "sheep" to "\uD83D\uDC11", - "monkey" to "\uD83D\uDC12", - "rooster" to "\uD83D\uDC13", - "chicken" to "\uD83D\uDC14", - "dog2" to "\uD83D\uDC15", - "pig2" to "\uD83D\uDC16", - "boar" to "\uD83D\uDC17", - "elephant" to "\uD83D\uDC18", - "octopus" to "\uD83D\uDC19", - "shell" to "\uD83D\uDC1A", - "bug" to "\uD83D\uDC1B", - "ant" to "\uD83D\uDC1C", - "bee" to "\uD83D\uDC1D", - "honeybee" to "\uD83D\uDC1D", - "beetle" to "\uD83D\uDC1E", - "fish" to "\uD83D\uDC1F", - "tropical_fish" to "\uD83D\uDC20", - "blowfish" to "\uD83D\uDC21", - "turtle" to "\uD83D\uDC22", - "hatching_chick" to "\uD83D\uDC23", - "baby_chick" to "\uD83D\uDC24", - "hatched_chick" to "\uD83D\uDC25", - "bird" to "\uD83D\uDC26", - "penguin" to "\uD83D\uDC27", - "koala" to "\uD83D\uDC28", - "poodle" to "\uD83D\uDC29", - "dromedary_camel" to "\uD83D\uDC2A", - "camel" to "\uD83D\uDC2B", - "dolphin" to "\uD83D\uDC2C", - "flipper" to "\uD83D\uDC2C", - "mouse" to "\uD83D\uDC2D", - "cow" to "\uD83D\uDC2E", - "tiger" to "\uD83D\uDC2F", - "rabbit" to "\uD83D\uDC30", - "cat" to "\uD83D\uDC31", - "dragon_face" to "\uD83D\uDC32", - "whale" to "\uD83D\uDC33", - "horse" to "\uD83D\uDC34", - "monkey_face" to "\uD83D\uDC35", - "dog" to "\uD83D\uDC36", - "pig" to "\uD83D\uDC37", - "frog" to "\uD83D\uDC38", - "hamster" to "\uD83D\uDC39", - "wolf" to "\uD83D\uDC3A", - "bear" to "\uD83D\uDC3B", - "panda_face" to "\uD83D\uDC3C", - "pig_nose" to "\uD83D\uDC3D", - "feet" to "\uD83D\uDC3E", - "paw_prints" to "\uD83D\uDC3E", - "chipmunk" to "\uD83D\uDC3F\uFE0F", - "eyes" to "\uD83D\uDC40", - "eye-in-speech-bubble" to "\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8\uFE0F", - "eye" to "\uD83D\uDC41\uFE0F", - "ear" to "\uD83D\uDC42", - "nose" to "\uD83D\uDC43", - "lips" to "\uD83D\uDC44", - "tongue" to "\uD83D\uDC45", - "point_up_2" to "\uD83D\uDC46", - "point_down" to "\uD83D\uDC47", - "point_left" to "\uD83D\uDC48", - "point_right" to "\uD83D\uDC49", - "facepunch" to "\uD83D\uDC4A", - "punch" to "\uD83D\uDC4A", - "wave" to "\uD83D\uDC4B", - "ok_hand" to "\uD83D\uDC4C", - "+1" to "\uD83D\uDC4D", - "thumbsup" to "\uD83D\uDC4D", - "-1" to "\uD83D\uDC4E", - "thumbsdown" to "\uD83D\uDC4E", - "clap" to "\uD83D\uDC4F", - "open_hands" to "\uD83D\uDC50", - "crown" to "\uD83D\uDC51", - "womans_hat" to "\uD83D\uDC52", - "eyeglasses" to "\uD83D\uDC53", - "necktie" to "\uD83D\uDC54", - "shirt" to "\uD83D\uDC55", - "tshirt" to "\uD83D\uDC55", - "jeans" to "\uD83D\uDC56", - "dress" to "\uD83D\uDC57", - "kimono" to "\uD83D\uDC58", - "bikini" to "\uD83D\uDC59", - "womans_clothes" to "\uD83D\uDC5A", - "purse" to "\uD83D\uDC5B", - "handbag" to "\uD83D\uDC5C", - "pouch" to "\uD83D\uDC5D", - "mans_shoe" to "\uD83D\uDC5E", - "shoe" to "\uD83D\uDC5E", - "athletic_shoe" to "\uD83D\uDC5F", - "high_heel" to "\uD83D\uDC60", - "sandal" to "\uD83D\uDC61", - "boot" to "\uD83D\uDC62", - "footprints" to "\uD83D\uDC63", - "bust_in_silhouette" to "\uD83D\uDC64", - "busts_in_silhouette" to "\uD83D\uDC65", - "boy" to "\uD83D\uDC66", - "girl" to "\uD83D\uDC67", - "male-farmer" to "\uD83D\uDC68\u200D\uD83C\uDF3E", - "male-cook" to "\uD83D\uDC68\u200D\uD83C\uDF73", - "male-student" to "\uD83D\uDC68\u200D\uD83C\uDF93", - "male-singer" to "\uD83D\uDC68\u200D\uD83C\uDFA4", - "male-artist" to "\uD83D\uDC68\u200D\uD83C\uDFA8", - "male-teacher" to "\uD83D\uDC68\u200D\uD83C\uDFEB", - "male-factory-worker" to "\uD83D\uDC68\u200D\uD83C\uDFED", - "man-boy-boy" to "\uD83D\uDC68\u200D\uD83D\uDC66\u200D\uD83D\uDC66", - "man-boy" to "\uD83D\uDC68\u200D\uD83D\uDC66", - "man-girl-boy" to "\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC66", - "man-girl-girl" to "\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67", - "man-girl" to "\uD83D\uDC68\u200D\uD83D\uDC67", - "man-man-boy" to "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC66", - "man-man-boy-boy" to "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC66\u200D\uD83D\uDC66", - "man-man-girl" to "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67", - "man-man-girl-boy" to "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC66", - "man-man-girl-girl" to "\uD83D\uDC68\u200D\uD83D\uDC68\u200D\uD83D\uDC67\u200D\uD83D\uDC67", - "man-woman-boy" to "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66", - "family" to "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66", - "man-woman-boy-boy" to "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66", - "man-woman-girl" to "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67", - "man-woman-girl-boy" to "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66", - "man-woman-girl-girl" to "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67", - "male-technologist" to "\uD83D\uDC68\u200D\uD83D\uDCBB", - "male-office-worker" to "\uD83D\uDC68\u200D\uD83D\uDCBC", - "male-mechanic" to "\uD83D\uDC68\u200D\uD83D\uDD27", - "male-scientist" to "\uD83D\uDC68\u200D\uD83D\uDD2C", - "male-astronaut" to "\uD83D\uDC68\u200D\uD83D\uDE80", - "male-firefighter" to "\uD83D\uDC68\u200D\uD83D\uDE92", - "male-doctor" to "\uD83D\uDC68\u200D\u2695\uFE0F", - "male-judge" to "\uD83D\uDC68\u200D\u2696\uFE0F", - "male-pilot" to "\uD83D\uDC68\u200D\u2708\uFE0F", - "man-heart-man" to "\uD83D\uDC68\u200D\u2764\uFE0F\u200D\uD83D\uDC68", - "man-kiss-man" to "\uD83D\uDC68\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68", - "man" to "\uD83D\uDC68", - "female-farmer" to "\uD83D\uDC69\u200D\uD83C\uDF3E", - "female-cook" to "\uD83D\uDC69\u200D\uD83C\uDF73", - "female-student" to "\uD83D\uDC69\u200D\uD83C\uDF93", - "female-singer" to "\uD83D\uDC69\u200D\uD83C\uDFA4", - "female-artist" to "\uD83D\uDC69\u200D\uD83C\uDFA8", - "female-teacher" to "\uD83D\uDC69\u200D\uD83C\uDFEB", - "female-factory-worker" to "\uD83D\uDC69\u200D\uD83C\uDFED", - "woman-boy-boy" to "\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66", - "woman-boy" to "\uD83D\uDC69\u200D\uD83D\uDC66", - "woman-girl-boy" to "\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66", - "woman-girl-girl" to "\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67", - "woman-girl" to "\uD83D\uDC69\u200D\uD83D\uDC67", - "woman-woman-boy" to "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66", - "woman-woman-boy-boy" to "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66", - "woman-woman-girl" to "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67", - "woman-woman-girl-boy" to "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66", - "woman-woman-girl-girl" to "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67", - "female-technologist" to "\uD83D\uDC69\u200D\uD83D\uDCBB", - "female-office-worker" to "\uD83D\uDC69\u200D\uD83D\uDCBC", - "female-mechanic" to "\uD83D\uDC69\u200D\uD83D\uDD27", - "female-scientist" to "\uD83D\uDC69\u200D\uD83D\uDD2C", - "female-astronaut" to "\uD83D\uDC69\u200D\uD83D\uDE80", - "female-firefighter" to "\uD83D\uDC69\u200D\uD83D\uDE92", - "female-doctor" to "\uD83D\uDC69\u200D\u2695\uFE0F", - "female-judge" to "\uD83D\uDC69\u200D\u2696\uFE0F", - "female-pilot" to "\uD83D\uDC69\u200D\u2708\uFE0F", - "woman-heart-man" to "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC68", - "couple_with_heart" to "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC68", - "woman-heart-woman" to "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC69", - "woman-kiss-man" to "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68", - "couplekiss" to "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68", - "woman-kiss-woman" to "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC69", - "woman" to "\uD83D\uDC69", - "couple" to "\uD83D\uDC6B", - "man_and_woman_holding_hands" to "\uD83D\uDC6B", - "two_men_holding_hands" to "\uD83D\uDC6C", - "two_women_holding_hands" to "\uD83D\uDC6D", - "female-police-officer" to "\uD83D\uDC6E\u200D\u2640\uFE0F", - "male-police-officer" to "\uD83D\uDC6E\u200D\u2642\uFE0F", - "cop" to "\uD83D\uDC6E\u200D\u2642\uFE0F", - "woman-with-bunny-ears-partying" to "\uD83D\uDC6F\u200D\u2640\uFE0F", - "dancers" to "\uD83D\uDC6F\u200D\u2640\uFE0F", - "man-with-bunny-ears-partying" to "\uD83D\uDC6F\u200D\u2642\uFE0F", - "bride_with_veil" to "\uD83D\uDC70", - "blond-haired-woman" to "\uD83D\uDC71\u200D\u2640\uFE0F", - "blond-haired-man" to "\uD83D\uDC71\u200D\u2642\uFE0F", - "person_with_blond_hair" to "\uD83D\uDC71\u200D\u2642\uFE0F", - "man_with_gua_pi_mao" to "\uD83D\uDC72", - "woman-wearing-turban" to "\uD83D\uDC73\u200D\u2640\uFE0F", - "man-wearing-turban" to "\uD83D\uDC73\u200D\u2642\uFE0F", - "man_with_turban" to "\uD83D\uDC73\u200D\u2642\uFE0F", - "older_man" to "\uD83D\uDC74", - "older_woman" to "\uD83D\uDC75", - "baby" to "\uD83D\uDC76", - "female-construction-worker" to "\uD83D\uDC77\u200D\u2640\uFE0F", - "male-construction-worker" to "\uD83D\uDC77\u200D\u2642\uFE0F", - "construction_worker" to "\uD83D\uDC77\u200D\u2642\uFE0F", - "princess" to "\uD83D\uDC78", - "japanese_ogre" to "\uD83D\uDC79", - "japanese_goblin" to "\uD83D\uDC7A", - "ghost" to "\uD83D\uDC7B", - "angel" to "\uD83D\uDC7C", - "alien" to "\uD83D\uDC7D", - "space_invader" to "\uD83D\uDC7E", - "imp" to "\uD83D\uDC7F", - "skull" to "\uD83D\uDC80", - "woman-tipping-hand" to "\uD83D\uDC81\u200D\u2640\uFE0F", - "information_desk_person" to "\uD83D\uDC81\u200D\u2640\uFE0F", - "man-tipping-hand" to "\uD83D\uDC81\u200D\u2642\uFE0F", - "female-guard" to "\uD83D\uDC82\u200D\u2640\uFE0F", - "male-guard" to "\uD83D\uDC82\u200D\u2642\uFE0F", - "guardsman" to "\uD83D\uDC82\u200D\u2642\uFE0F", - "dancer" to "\uD83D\uDC83", - "lipstick" to "\uD83D\uDC84", - "nail_care" to "\uD83D\uDC85", - "woman-getting-massage" to "\uD83D\uDC86\u200D\u2640\uFE0F", - "massage" to "\uD83D\uDC86\u200D\u2640\uFE0F", - "man-getting-massage" to "\uD83D\uDC86\u200D\u2642\uFE0F", - "woman-getting-haircut" to "\uD83D\uDC87\u200D\u2640\uFE0F", - "haircut" to "\uD83D\uDC87\u200D\u2640\uFE0F", - "man-getting-haircut" to "\uD83D\uDC87\u200D\u2642\uFE0F", - "barber" to "\uD83D\uDC88", - "syringe" to "\uD83D\uDC89", - "pill" to "\uD83D\uDC8A", - "kiss" to "\uD83D\uDC8B", - "love_letter" to "\uD83D\uDC8C", - "ring" to "\uD83D\uDC8D", - "gem" to "\uD83D\uDC8E", - "bouquet" to "\uD83D\uDC90", - "wedding" to "\uD83D\uDC92", - "heartbeat" to "\uD83D\uDC93", - "broken_heart" to "\uD83D\uDC94", - "two_hearts" to "\uD83D\uDC95", - "sparkling_heart" to "\uD83D\uDC96", - "heartpulse" to "\uD83D\uDC97", - "cupid" to "\uD83D\uDC98", - "blue_heart" to "\uD83D\uDC99", - "green_heart" to "\uD83D\uDC9A", - "yellow_heart" to "\uD83D\uDC9B", - "purple_heart" to "\uD83D\uDC9C", - "gift_heart" to "\uD83D\uDC9D", - "revolving_hearts" to "\uD83D\uDC9E", - "heart_decoration" to "\uD83D\uDC9F", - "diamond_shape_with_a_dot_inside" to "\uD83D\uDCA0", - "bulb" to "\uD83D\uDCA1", - "anger" to "\uD83D\uDCA2", - "bomb" to "\uD83D\uDCA3", - "zzz" to "\uD83D\uDCA4", - "boom" to "\uD83D\uDCA5", - "collision" to "\uD83D\uDCA5", - "sweat_drops" to "\uD83D\uDCA6", - "droplet" to "\uD83D\uDCA7", - "dash" to "\uD83D\uDCA8", - "hankey" to "\uD83D\uDCA9", - "poop" to "\uD83D\uDCA9", - "shit" to "\uD83D\uDCA9", - "muscle" to "\uD83D\uDCAA", - "dizzy" to "\uD83D\uDCAB", - "speech_balloon" to "\uD83D\uDCAC", - "thought_balloon" to "\uD83D\uDCAD", - "white_flower" to "\uD83D\uDCAE", - "100" to "\uD83D\uDCAF", - "moneybag" to "\uD83D\uDCB0", - "currency_exchange" to "\uD83D\uDCB1", - "heavy_dollar_sign" to "\uD83D\uDCB2", - "credit_card" to "\uD83D\uDCB3", - "yen" to "\uD83D\uDCB4", - "dollar" to "\uD83D\uDCB5", - "euro" to "\uD83D\uDCB6", - "pound" to "\uD83D\uDCB7", - "money_with_wings" to "\uD83D\uDCB8", - "chart" to "\uD83D\uDCB9", - "seat" to "\uD83D\uDCBA", - "computer" to "\uD83D\uDCBB", - "briefcase" to "\uD83D\uDCBC", - "minidisc" to "\uD83D\uDCBD", - "floppy_disk" to "\uD83D\uDCBE", - "cd" to "\uD83D\uDCBF", - "dvd" to "\uD83D\uDCC0", - "file_folder" to "\uD83D\uDCC1", - "open_file_folder" to "\uD83D\uDCC2", - "page_with_curl" to "\uD83D\uDCC3", - "page_facing_up" to "\uD83D\uDCC4", - "date" to "\uD83D\uDCC5", - "calendar" to "\uD83D\uDCC6", - "card_index" to "\uD83D\uDCC7", - "chart_with_upwards_trend" to "\uD83D\uDCC8", - "chart_with_downwards_trend" to "\uD83D\uDCC9", - "bar_chart" to "\uD83D\uDCCA", - "clipboard" to "\uD83D\uDCCB", - "pushpin" to "\uD83D\uDCCC", - "round_pushpin" to "\uD83D\uDCCD", - "paperclip" to "\uD83D\uDCCE", - "straight_ruler" to "\uD83D\uDCCF", - "triangular_ruler" to "\uD83D\uDCD0", - "bookmark_tabs" to "\uD83D\uDCD1", - "ledger" to "\uD83D\uDCD2", - "notebook" to "\uD83D\uDCD3", - "notebook_with_decorative_cover" to "\uD83D\uDCD4", - "closed_book" to "\uD83D\uDCD5", - "book" to "\uD83D\uDCD6", - "open_book" to "\uD83D\uDCD6", - "green_book" to "\uD83D\uDCD7", - "blue_book" to "\uD83D\uDCD8", - "orange_book" to "\uD83D\uDCD9", - "books" to "\uD83D\uDCDA", - "name_badge" to "\uD83D\uDCDB", - "scroll" to "\uD83D\uDCDC", - "memo" to "\uD83D\uDCDD", - "pencil" to "\uD83D\uDCDD", - "telephone_receiver" to "\uD83D\uDCDE", - "pager" to "\uD83D\uDCDF", - "fax" to "\uD83D\uDCE0", - "satellite_antenna" to "\uD83D\uDCE1", - "loudspeaker" to "\uD83D\uDCE2", - "mega" to "\uD83D\uDCE3", - "outbox_tray" to "\uD83D\uDCE4", - "inbox_tray" to "\uD83D\uDCE5", - "package" to "\uD83D\uDCE6", - "e-mail" to "\uD83D\uDCE7", - "incoming_envelope" to "\uD83D\uDCE8", - "envelope_with_arrow" to "\uD83D\uDCE9", - "mailbox_closed" to "\uD83D\uDCEA", - "mailbox" to "\uD83D\uDCEB", - "mailbox_with_mail" to "\uD83D\uDCEC", - "mailbox_with_no_mail" to "\uD83D\uDCED", - "postbox" to "\uD83D\uDCEE", - "postal_horn" to "\uD83D\uDCEF", - "newspaper" to "\uD83D\uDCF0", - "iphone" to "\uD83D\uDCF1", - "calling" to "\uD83D\uDCF2", - "vibration_mode" to "\uD83D\uDCF3", - "mobile_phone_off" to "\uD83D\uDCF4", - "no_mobile_phones" to "\uD83D\uDCF5", - "signal_strength" to "\uD83D\uDCF6", - "camera" to "\uD83D\uDCF7", - "camera_with_flash" to "\uD83D\uDCF8", - "video_camera" to "\uD83D\uDCF9", - "tv" to "\uD83D\uDCFA", - "radio" to "\uD83D\uDCFB", - "vhs" to "\uD83D\uDCFC", - "film_projector" to "\uD83D\uDCFD\uFE0F", - "prayer_beads" to "\uD83D\uDCFF", - "twisted_rightwards_arrows" to "\uD83D\uDD00", - "repeat" to "\uD83D\uDD01", - "repeat_one" to "\uD83D\uDD02", - "arrows_clockwise" to "\uD83D\uDD03", - "arrows_counterclockwise" to "\uD83D\uDD04", - "low_brightness" to "\uD83D\uDD05", - "high_brightness" to "\uD83D\uDD06", - "mute" to "\uD83D\uDD07", - "speaker" to "\uD83D\uDD08", - "sound" to "\uD83D\uDD09", - "loud_sound" to "\uD83D\uDD0A", - "battery" to "\uD83D\uDD0B", - "electric_plug" to "\uD83D\uDD0C", - "mag" to "\uD83D\uDD0D", - "mag_right" to "\uD83D\uDD0E", - "lock_with_ink_pen" to "\uD83D\uDD0F", - "closed_lock_with_key" to "\uD83D\uDD10", - "key" to "\uD83D\uDD11", - "lock" to "\uD83D\uDD12", - "unlock" to "\uD83D\uDD13", - "bell" to "\uD83D\uDD14", - "no_bell" to "\uD83D\uDD15", - "bookmark" to "\uD83D\uDD16", - "link" to "\uD83D\uDD17", - "radio_button" to "\uD83D\uDD18", - "back" to "\uD83D\uDD19", - "end" to "\uD83D\uDD1A", - "on" to "\uD83D\uDD1B", - "soon" to "\uD83D\uDD1C", - "top" to "\uD83D\uDD1D", - "underage" to "\uD83D\uDD1E", - "keycap_ten" to "\uD83D\uDD1F", - "capital_abcd" to "\uD83D\uDD20", - "abcd" to "\uD83D\uDD21", - "1234" to "\uD83D\uDD22", - "symbols" to "\uD83D\uDD23", - "abc" to "\uD83D\uDD24", - "fire" to "\uD83D\uDD25", - "flashlight" to "\uD83D\uDD26", - "wrench" to "\uD83D\uDD27", - "hammer" to "\uD83D\uDD28", - "nut_and_bolt" to "\uD83D\uDD29", - "hocho" to "\uD83D\uDD2A", - "knife" to "\uD83D\uDD2A", - "gun" to "\uD83D\uDD2B", - "microscope" to "\uD83D\uDD2C", - "telescope" to "\uD83D\uDD2D", - "crystal_ball" to "\uD83D\uDD2E", - "six_pointed_star" to "\uD83D\uDD2F", - "beginner" to "\uD83D\uDD30", - "trident" to "\uD83D\uDD31", - "black_square_button" to "\uD83D\uDD32", - "white_square_button" to "\uD83D\uDD33", - "red_circle" to "\uD83D\uDD34", - "large_blue_circle" to "\uD83D\uDD35", - "large_orange_diamond" to "\uD83D\uDD36", - "large_blue_diamond" to "\uD83D\uDD37", - "small_orange_diamond" to "\uD83D\uDD38", - "small_blue_diamond" to "\uD83D\uDD39", - "small_red_triangle" to "\uD83D\uDD3A", - "small_red_triangle_down" to "\uD83D\uDD3B", - "arrow_up_small" to "\uD83D\uDD3C", - "arrow_down_small" to "\uD83D\uDD3D", - "om_symbol" to "\uD83D\uDD49\uFE0F", - "dove_of_peace" to "\uD83D\uDD4A\uFE0F", - "kaaba" to "\uD83D\uDD4B", - "mosque" to "\uD83D\uDD4C", - "synagogue" to "\uD83D\uDD4D", - "menorah_with_nine_branches" to "\uD83D\uDD4E", - "clock1" to "\uD83D\uDD50", - "clock2" to "\uD83D\uDD51", - "clock3" to "\uD83D\uDD52", - "clock4" to "\uD83D\uDD53", - "clock5" to "\uD83D\uDD54", - "clock6" to "\uD83D\uDD55", - "clock7" to "\uD83D\uDD56", - "clock8" to "\uD83D\uDD57", - "clock9" to "\uD83D\uDD58", - "clock10" to "\uD83D\uDD59", - "clock11" to "\uD83D\uDD5A", - "clock12" to "\uD83D\uDD5B", - "clock130" to "\uD83D\uDD5C", - "clock230" to "\uD83D\uDD5D", - "clock330" to "\uD83D\uDD5E", - "clock430" to "\uD83D\uDD5F", - "clock530" to "\uD83D\uDD60", - "clock630" to "\uD83D\uDD61", - "clock730" to "\uD83D\uDD62", - "clock830" to "\uD83D\uDD63", - "clock930" to "\uD83D\uDD64", - "clock1030" to "\uD83D\uDD65", - "clock1130" to "\uD83D\uDD66", - "clock1230" to "\uD83D\uDD67", - "candle" to "\uD83D\uDD6F\uFE0F", - "mantelpiece_clock" to "\uD83D\uDD70\uFE0F", - "hole" to "\uD83D\uDD73\uFE0F", - "man_in_business_suit_levitating" to "\uD83D\uDD74\uFE0F", - "female-detective" to "\uD83D\uDD75\uFE0F\u200D\u2640\uFE0F", - "male-detective" to "\uD83D\uDD75\uFE0F\u200D\u2642\uFE0F", - "sleuth_or_spy" to "\uD83D\uDD75\uFE0F\u200D\u2642\uFE0F", - "dark_sunglasses" to "\uD83D\uDD76\uFE0F", - "spider" to "\uD83D\uDD77\uFE0F", - "spider_web" to "\uD83D\uDD78\uFE0F", - "joystick" to "\uD83D\uDD79\uFE0F", - "man_dancing" to "\uD83D\uDD7A", - "linked_paperclips" to "\uD83D\uDD87\uFE0F", - "lower_left_ballpoint_pen" to "\uD83D\uDD8A\uFE0F", - "lower_left_fountain_pen" to "\uD83D\uDD8B\uFE0F", - "lower_left_paintbrush" to "\uD83D\uDD8C\uFE0F", - "lower_left_crayon" to "\uD83D\uDD8D\uFE0F", - "raised_hand_with_fingers_splayed" to "\uD83D\uDD90\uFE0F", - "middle_finger" to "\uD83D\uDD95", - "reversed_hand_with_middle_finger_extended" to "\uD83D\uDD95", - "spock-hand" to "\uD83D\uDD96", - "black_heart" to "\uD83D\uDDA4", - "desktop_computer" to "\uD83D\uDDA5\uFE0F", - "printer" to "\uD83D\uDDA8\uFE0F", - "three_button_mouse" to "\uD83D\uDDB1\uFE0F", - "trackball" to "\uD83D\uDDB2\uFE0F", - "frame_with_picture" to "\uD83D\uDDBC\uFE0F", - "card_index_dividers" to "\uD83D\uDDC2\uFE0F", - "card_file_box" to "\uD83D\uDDC3\uFE0F", - "file_cabinet" to "\uD83D\uDDC4\uFE0F", - "wastebasket" to "\uD83D\uDDD1\uFE0F", - "spiral_note_pad" to "\uD83D\uDDD2\uFE0F", - "spiral_calendar_pad" to "\uD83D\uDDD3\uFE0F", - "compression" to "\uD83D\uDDDC\uFE0F", - "old_key" to "\uD83D\uDDDD\uFE0F", - "rolled_up_newspaper" to "\uD83D\uDDDE\uFE0F", - "dagger_knife" to "\uD83D\uDDE1\uFE0F", - "speaking_head_in_silhouette" to "\uD83D\uDDE3\uFE0F", - "left_speech_bubble" to "\uD83D\uDDE8\uFE0F", - "right_anger_bubble" to "\uD83D\uDDEF\uFE0F", - "ballot_box_with_ballot" to "\uD83D\uDDF3\uFE0F", - "world_map" to "\uD83D\uDDFA\uFE0F", - "mount_fuji" to "\uD83D\uDDFB", - "tokyo_tower" to "\uD83D\uDDFC", - "statue_of_liberty" to "\uD83D\uDDFD", - "japan" to "\uD83D\uDDFE", - "moyai" to "\uD83D\uDDFF", - "grinning" to "\uD83D\uDE00", - "grin" to "\uD83D\uDE01", - "joy" to "\uD83D\uDE02", - "smiley" to "\uD83D\uDE03", - "smile" to "\uD83D\uDE04", - "sweat_smile" to "\uD83D\uDE05", - "laughing" to "\uD83D\uDE06", - "satisfied" to "\uD83D\uDE06", - "innocent" to "\uD83D\uDE07", - "smiling_imp" to "\uD83D\uDE08", - "wink" to "\uD83D\uDE09", - "blush" to "\uD83D\uDE0A", - "yum" to "\uD83D\uDE0B", - "relieved" to "\uD83D\uDE0C", - "heart_eyes" to "\uD83D\uDE0D", - "sunglasses" to "\uD83D\uDE0E", - "smirk" to "\uD83D\uDE0F", - "neutral_face" to "\uD83D\uDE10", - "expressionless" to "\uD83D\uDE11", - "unamused" to "\uD83D\uDE12", - "sweat" to "\uD83D\uDE13", - "pensive" to "\uD83D\uDE14", - "confused" to "\uD83D\uDE15", - "confounded" to "\uD83D\uDE16", - "kissing" to "\uD83D\uDE17", - "kissing_heart" to "\uD83D\uDE18", - "kissing_smiling_eyes" to "\uD83D\uDE19", - "kissing_closed_eyes" to "\uD83D\uDE1A", - "stuck_out_tongue" to "\uD83D\uDE1B", - "stuck_out_tongue_winking_eye" to "\uD83D\uDE1C", - "stuck_out_tongue_closed_eyes" to "\uD83D\uDE1D", - "disappointed" to "\uD83D\uDE1E", - "worried" to "\uD83D\uDE1F", - "angry" to "\uD83D\uDE20", - "rage" to "\uD83D\uDE21", - "cry" to "\uD83D\uDE22", - "persevere" to "\uD83D\uDE23", - "triumph" to "\uD83D\uDE24", - "disappointed_relieved" to "\uD83D\uDE25", - "frowning" to "\uD83D\uDE26", - "anguished" to "\uD83D\uDE27", - "fearful" to "\uD83D\uDE28", - "weary" to "\uD83D\uDE29", - "sleepy" to "\uD83D\uDE2A", - "tired_face" to "\uD83D\uDE2B", - "grimacing" to "\uD83D\uDE2C", - "sob" to "\uD83D\uDE2D", - "open_mouth" to "\uD83D\uDE2E", - "hushed" to "\uD83D\uDE2F", - "cold_sweat" to "\uD83D\uDE30", - "scream" to "\uD83D\uDE31", - "astonished" to "\uD83D\uDE32", - "flushed" to "\uD83D\uDE33", - "sleeping" to "\uD83D\uDE34", - "dizzy_face" to "\uD83D\uDE35", - "no_mouth" to "\uD83D\uDE36", - "mask" to "\uD83D\uDE37", - "smile_cat" to "\uD83D\uDE38", - "joy_cat" to "\uD83D\uDE39", - "smiley_cat" to "\uD83D\uDE3A", - "heart_eyes_cat" to "\uD83D\uDE3B", - "smirk_cat" to "\uD83D\uDE3C", - "kissing_cat" to "\uD83D\uDE3D", - "pouting_cat" to "\uD83D\uDE3E", - "crying_cat_face" to "\uD83D\uDE3F", - "scream_cat" to "\uD83D\uDE40", - "slightly_frowning_face" to "\uD83D\uDE41", - "slightly_smiling_face" to "\uD83D\uDE42", - "upside_down_face" to "\uD83D\uDE43", - "face_with_rolling_eyes" to "\uD83D\uDE44", - "woman-gesturing-no" to "\uD83D\uDE45\u200D\u2640\uFE0F", - "no_good" to "\uD83D\uDE45\u200D\u2640\uFE0F", - "man-gesturing-no" to "\uD83D\uDE45\u200D\u2642\uFE0F", - "woman-gesturing-ok" to "\uD83D\uDE46\u200D\u2640\uFE0F", - "ok_woman" to "\uD83D\uDE46\u200D\u2640\uFE0F", - "man-gesturing-ok" to "\uD83D\uDE46\u200D\u2642\uFE0F", - "woman-bowing" to "\uD83D\uDE47\u200D\u2640\uFE0F", - "man-bowing" to "\uD83D\uDE47\u200D\u2642\uFE0F", - "bow" to "\uD83D\uDE47\u200D\u2642\uFE0F", - "see_no_evil" to "\uD83D\uDE48", - "hear_no_evil" to "\uD83D\uDE49", - "speak_no_evil" to "\uD83D\uDE4A", - "woman-raising-hand" to "\uD83D\uDE4B\u200D\u2640\uFE0F", - "raising_hand" to "\uD83D\uDE4B\u200D\u2640\uFE0F", - "man-raising-hand" to "\uD83D\uDE4B\u200D\u2642\uFE0F", - "raised_hands" to "\uD83D\uDE4C", - "woman-frowning" to "\uD83D\uDE4D\u200D\u2640\uFE0F", - "person_frowning" to "\uD83D\uDE4D\u200D\u2640\uFE0F", - "man-frowning" to "\uD83D\uDE4D\u200D\u2642\uFE0F", - "woman-pouting" to "\uD83D\uDE4E\u200D\u2640\uFE0F", - "person_with_pouting_face" to "\uD83D\uDE4E\u200D\u2640\uFE0F", - "man-pouting" to "\uD83D\uDE4E\u200D\u2642\uFE0F", - "pray" to "\uD83D\uDE4F", - "rocket" to "\uD83D\uDE80", - "helicopter" to "\uD83D\uDE81", - "steam_locomotive" to "\uD83D\uDE82", - "railway_car" to "\uD83D\uDE83", - "bullettrain_side" to "\uD83D\uDE84", - "bullettrain_front" to "\uD83D\uDE85", - "train2" to "\uD83D\uDE86", - "metro" to "\uD83D\uDE87", - "light_rail" to "\uD83D\uDE88", - "station" to "\uD83D\uDE89", - "tram" to "\uD83D\uDE8A", - "train" to "\uD83D\uDE8B", - "bus" to "\uD83D\uDE8C", - "oncoming_bus" to "\uD83D\uDE8D", - "trolleybus" to "\uD83D\uDE8E", - "busstop" to "\uD83D\uDE8F", - "minibus" to "\uD83D\uDE90", - "ambulance" to "\uD83D\uDE91", - "fire_engine" to "\uD83D\uDE92", - "police_car" to "\uD83D\uDE93", - "oncoming_police_car" to "\uD83D\uDE94", - "taxi" to "\uD83D\uDE95", - "oncoming_taxi" to "\uD83D\uDE96", - "car" to "\uD83D\uDE97", - "red_car" to "\uD83D\uDE97", - "oncoming_automobile" to "\uD83D\uDE98", - "blue_car" to "\uD83D\uDE99", - "truck" to "\uD83D\uDE9A", - "articulated_lorry" to "\uD83D\uDE9B", - "tractor" to "\uD83D\uDE9C", - "monorail" to "\uD83D\uDE9D", - "mountain_railway" to "\uD83D\uDE9E", - "suspension_railway" to "\uD83D\uDE9F", - "mountain_cableway" to "\uD83D\uDEA0", - "aerial_tramway" to "\uD83D\uDEA1", - "ship" to "\uD83D\uDEA2", - "woman-rowing-boat" to "\uD83D\uDEA3\u200D\u2640\uFE0F", - "man-rowing-boat" to "\uD83D\uDEA3\u200D\u2642\uFE0F", - "rowboat" to "\uD83D\uDEA3\u200D\u2642\uFE0F", - "speedboat" to "\uD83D\uDEA4", - "traffic_light" to "\uD83D\uDEA5", - "vertical_traffic_light" to "\uD83D\uDEA6", - "construction" to "\uD83D\uDEA7", - "rotating_light" to "\uD83D\uDEA8", - "triangular_flag_on_post" to "\uD83D\uDEA9", - "door" to "\uD83D\uDEAA", - "no_entry_sign" to "\uD83D\uDEAB", - "smoking" to "\uD83D\uDEAC", - "no_smoking" to "\uD83D\uDEAD", - "put_litter_in_its_place" to "\uD83D\uDEAE", - "do_not_litter" to "\uD83D\uDEAF", - "potable_water" to "\uD83D\uDEB0", - "non-potable_water" to "\uD83D\uDEB1", - "bike" to "\uD83D\uDEB2", - "no_bicycles" to "\uD83D\uDEB3", - "woman-biking" to "\uD83D\uDEB4\u200D\u2640\uFE0F", - "man-biking" to "\uD83D\uDEB4\u200D\u2642\uFE0F", - "bicyclist" to "\uD83D\uDEB4\u200D\u2642\uFE0F", - "woman-mountain-biking" to "\uD83D\uDEB5\u200D\u2640\uFE0F", - "man-mountain-biking" to "\uD83D\uDEB5\u200D\u2642\uFE0F", - "mountain_bicyclist" to "\uD83D\uDEB5\u200D\u2642\uFE0F", - "woman-walking" to "\uD83D\uDEB6\u200D\u2640\uFE0F", - "man-walking" to "\uD83D\uDEB6\u200D\u2642\uFE0F", - "walking" to "\uD83D\uDEB6\u200D\u2642\uFE0F", - "no_pedestrians" to "\uD83D\uDEB7", - "children_crossing" to "\uD83D\uDEB8", - "mens" to "\uD83D\uDEB9", - "womens" to "\uD83D\uDEBA", - "restroom" to "\uD83D\uDEBB", - "baby_symbol" to "\uD83D\uDEBC", - "toilet" to "\uD83D\uDEBD", - "wc" to "\uD83D\uDEBE", - "shower" to "\uD83D\uDEBF", - "bath" to "\uD83D\uDEC0", - "bathtub" to "\uD83D\uDEC1", - "passport_control" to "\uD83D\uDEC2", - "customs" to "\uD83D\uDEC3", - "baggage_claim" to "\uD83D\uDEC4", - "left_luggage" to "\uD83D\uDEC5", - "couch_and_lamp" to "\uD83D\uDECB\uFE0F", - "sleeping_accommodation" to "\uD83D\uDECC", - "shopping_bags" to "\uD83D\uDECD\uFE0F", - "bellhop_bell" to "\uD83D\uDECE\uFE0F", - "bed" to "\uD83D\uDECF\uFE0F", - "place_of_worship" to "\uD83D\uDED0", - "octagonal_sign" to "\uD83D\uDED1", - "shopping_trolley" to "\uD83D\uDED2", - "hammer_and_wrench" to "\uD83D\uDEE0\uFE0F", - "shield" to "\uD83D\uDEE1\uFE0F", - "oil_drum" to "\uD83D\uDEE2\uFE0F", - "motorway" to "\uD83D\uDEE3\uFE0F", - "railway_track" to "\uD83D\uDEE4\uFE0F", - "motor_boat" to "\uD83D\uDEE5\uFE0F", - "small_airplane" to "\uD83D\uDEE9\uFE0F", - "airplane_departure" to "\uD83D\uDEEB", - "airplane_arriving" to "\uD83D\uDEEC", - "satellite" to "\uD83D\uDEF0\uFE0F", - "passenger_ship" to "\uD83D\uDEF3\uFE0F", - "scooter" to "\uD83D\uDEF4", - "motor_scooter" to "\uD83D\uDEF5", - "canoe" to "\uD83D\uDEF6", - "sled" to "\uD83D\uDEF7", - "flying_saucer" to "\uD83D\uDEF8", - "zipper_mouth_face" to "\uD83E\uDD10", - "money_mouth_face" to "\uD83E\uDD11", - "face_with_thermometer" to "\uD83E\uDD12", - "nerd_face" to "\uD83E\uDD13", - "thinking_face" to "\uD83E\uDD14", - "face_with_head_bandage" to "\uD83E\uDD15", - "robot_face" to "\uD83E\uDD16", - "hugging_face" to "\uD83E\uDD17", - "the_horns" to "\uD83E\uDD18", - "sign_of_the_horns" to "\uD83E\uDD18", - "call_me_hand" to "\uD83E\uDD19", - "raised_back_of_hand" to "\uD83E\uDD1A", - "left-facing_fist" to "\uD83E\uDD1B", - "right-facing_fist" to "\uD83E\uDD1C", - "handshake" to "\uD83E\uDD1D", - "hand_with_index_and_middle_fingers_crossed" to "\uD83E\uDD1E", - "i_love_you_hand_sign" to "\uD83E\uDD1F", - "face_with_cowboy_hat" to "\uD83E\uDD20", - "clown_face" to "\uD83E\uDD21", - "nauseated_face" to "\uD83E\uDD22", - "rolling_on_the_floor_laughing" to "\uD83E\uDD23", - "drooling_face" to "\uD83E\uDD24", - "lying_face" to "\uD83E\uDD25", - "woman-facepalming" to "\uD83E\uDD26\u200D\u2640\uFE0F", - "man-facepalming" to "\uD83E\uDD26\u200D\u2642\uFE0F", - "face_palm" to "\uD83E\uDD26", - "sneezing_face" to "\uD83E\uDD27", - "face_with_one_eyebrow_raised" to "\uD83E\uDD28", - "grinning_face_with_star_eyes" to "\uD83E\uDD29", - "grinning_face_with_one_large_and_one_small_eye" to "\uD83E\uDD2A", - "face_with_finger_covering_closed_lips" to "\uD83E\uDD2B", - "serious_face_with_symbols_covering_mouth" to "\uD83E\uDD2C", - "smiling_face_with_smiling_eyes_and_hand_covering_mouth" to "\uD83E\uDD2D", - "face_with_open_mouth_vomiting" to "\uD83E\uDD2E", - "shocked_face_with_exploding_head" to "\uD83E\uDD2F", - "pregnant_woman" to "\uD83E\uDD30", - "breast-feeding" to "\uD83E\uDD31", - "palms_up_together" to "\uD83E\uDD32", - "selfie" to "\uD83E\uDD33", - "prince" to "\uD83E\uDD34", - "man_in_tuxedo" to "\uD83E\uDD35", - "mother_christmas" to "\uD83E\uDD36", - "woman-shrugging" to "\uD83E\uDD37\u200D\u2640\uFE0F", - "man-shrugging" to "\uD83E\uDD37\u200D\u2642\uFE0F", - "shrug" to "\uD83E\uDD37", - "woman-cartwheeling" to "\uD83E\uDD38\u200D\u2640\uFE0F", - "man-cartwheeling" to "\uD83E\uDD38\u200D\u2642\uFE0F", - "person_doing_cartwheel" to "\uD83E\uDD38", - "woman-juggling" to "\uD83E\uDD39\u200D\u2640\uFE0F", - "man-juggling" to "\uD83E\uDD39\u200D\u2642\uFE0F", - "juggling" to "\uD83E\uDD39", - "fencer" to "\uD83E\uDD3A", - "woman-wrestling" to "\uD83E\uDD3C\u200D\u2640\uFE0F", - "man-wrestling" to "\uD83E\uDD3C\u200D\u2642\uFE0F", - "wrestlers" to "\uD83E\uDD3C", - "woman-playing-water-polo" to "\uD83E\uDD3D\u200D\u2640\uFE0F", - "man-playing-water-polo" to "\uD83E\uDD3D\u200D\u2642\uFE0F", - "water_polo" to "\uD83E\uDD3D", - "woman-playing-handball" to "\uD83E\uDD3E\u200D\u2640\uFE0F", - "man-playing-handball" to "\uD83E\uDD3E\u200D\u2642\uFE0F", - "handball" to "\uD83E\uDD3E", - "wilted_flower" to "\uD83E\uDD40", - "drum_with_drumsticks" to "\uD83E\uDD41", - "clinking_glasses" to "\uD83E\uDD42", - "tumbler_glass" to "\uD83E\uDD43", - "spoon" to "\uD83E\uDD44", - "goal_net" to "\uD83E\uDD45", - "first_place_medal" to "\uD83E\uDD47", - "second_place_medal" to "\uD83E\uDD48", - "third_place_medal" to "\uD83E\uDD49", - "boxing_glove" to "\uD83E\uDD4A", - "martial_arts_uniform" to "\uD83E\uDD4B", - "curling_stone" to "\uD83E\uDD4C", - "croissant" to "\uD83E\uDD50", - "avocado" to "\uD83E\uDD51", - "cucumber" to "\uD83E\uDD52", - "bacon" to "\uD83E\uDD53", - "potato" to "\uD83E\uDD54", - "carrot" to "\uD83E\uDD55", - "baguette_bread" to "\uD83E\uDD56", - "green_salad" to "\uD83E\uDD57", - "shallow_pan_of_food" to "\uD83E\uDD58", - "stuffed_flatbread" to "\uD83E\uDD59", - "egg" to "\uD83E\uDD5A", - "glass_of_milk" to "\uD83E\uDD5B", - "peanuts" to "\uD83E\uDD5C", - "kiwifruit" to "\uD83E\uDD5D", - "pancakes" to "\uD83E\uDD5E", - "dumpling" to "\uD83E\uDD5F", - "fortune_cookie" to "\uD83E\uDD60", - "takeout_box" to "\uD83E\uDD61", - "chopsticks" to "\uD83E\uDD62", - "bowl_with_spoon" to "\uD83E\uDD63", - "cup_with_straw" to "\uD83E\uDD64", - "coconut" to "\uD83E\uDD65", - "broccoli" to "\uD83E\uDD66", - "pie" to "\uD83E\uDD67", - "pretzel" to "\uD83E\uDD68", - "cut_of_meat" to "\uD83E\uDD69", - "sandwich" to "\uD83E\uDD6A", - "canned_food" to "\uD83E\uDD6B", - "crab" to "\uD83E\uDD80", - "lion_face" to "\uD83E\uDD81", - "scorpion" to "\uD83E\uDD82", - "turkey" to "\uD83E\uDD83", - "unicorn_face" to "\uD83E\uDD84", - "eagle" to "\uD83E\uDD85", - "duck" to "\uD83E\uDD86", - "bat" to "\uD83E\uDD87", - "shark" to "\uD83E\uDD88", - "owl" to "\uD83E\uDD89", - "fox_face" to "\uD83E\uDD8A", - "butterfly" to "\uD83E\uDD8B", - "deer" to "\uD83E\uDD8C", - "gorilla" to "\uD83E\uDD8D", - "lizard" to "\uD83E\uDD8E", - "rhinoceros" to "\uD83E\uDD8F", - "shrimp" to "\uD83E\uDD90", - "squid" to "\uD83E\uDD91", - "giraffe_face" to "\uD83E\uDD92", - "zebra_face" to "\uD83E\uDD93", - "hedgehog" to "\uD83E\uDD94", - "sauropod" to "\uD83E\uDD95", - "t-rex" to "\uD83E\uDD96", - "cricket" to "\uD83E\uDD97", - "cheese_wedge" to "\uD83E\uDDC0", - "face_with_monocle" to "\uD83E\uDDD0", - "adult" to "\uD83E\uDDD1", - "child" to "\uD83E\uDDD2", - "older_adult" to "\uD83E\uDDD3", - "bearded_person" to "\uD83E\uDDD4", - "person_with_headscarf" to "\uD83E\uDDD5", - "woman_in_steamy_room" to "\uD83E\uDDD6\u200D\u2640\uFE0F", - "man_in_steamy_room" to "\uD83E\uDDD6\u200D\u2642\uFE0F", - "person_in_steamy_room" to "\uD83E\uDDD6\u200D\u2642\uFE0F", - "woman_climbing" to "\uD83E\uDDD7\u200D\u2640\uFE0F", - "person_climbing" to "\uD83E\uDDD7\u200D\u2640\uFE0F", - "man_climbing" to "\uD83E\uDDD7\u200D\u2642\uFE0F", - "woman_in_lotus_position" to "\uD83E\uDDD8\u200D\u2640\uFE0F", - "person_in_lotus_position" to "\uD83E\uDDD8\u200D\u2640\uFE0F", - "man_in_lotus_position" to "\uD83E\uDDD8\u200D\u2642\uFE0F", - "female_mage" to "\uD83E\uDDD9\u200D\u2640\uFE0F", - "mage" to "\uD83E\uDDD9\u200D\u2640\uFE0F", - "male_mage" to "\uD83E\uDDD9\u200D\u2642\uFE0F", - "female_fairy" to "\uD83E\uDDDA\u200D\u2640\uFE0F", - "fairy" to "\uD83E\uDDDA\u200D\u2640\uFE0F", - "male_fairy" to "\uD83E\uDDDA\u200D\u2642\uFE0F", - "female_vampire" to "\uD83E\uDDDB\u200D\u2640\uFE0F", - "vampire" to "\uD83E\uDDDB\u200D\u2640\uFE0F", - "male_vampire" to "\uD83E\uDDDB\u200D\u2642\uFE0F", - "mermaid" to "\uD83E\uDDDC\u200D\u2640\uFE0F", - "merman" to "\uD83E\uDDDC\u200D\u2642\uFE0F", - "merperson" to "\uD83E\uDDDC\u200D\u2642\uFE0F", - "female_elf" to "\uD83E\uDDDD\u200D\u2640\uFE0F", - "male_elf" to "\uD83E\uDDDD\u200D\u2642\uFE0F", - "elf" to "\uD83E\uDDDD\u200D\u2642\uFE0F", - "female_genie" to "\uD83E\uDDDE\u200D\u2640\uFE0F", - "male_genie" to "\uD83E\uDDDE\u200D\u2642\uFE0F", - "genie" to "\uD83E\uDDDE\u200D\u2642\uFE0F", - "female_zombie" to "\uD83E\uDDDF\u200D\u2640\uFE0F", - "male_zombie" to "\uD83E\uDDDF\u200D\u2642\uFE0F", - "zombie" to "\uD83E\uDDDF\u200D\u2642\uFE0F", - "brain" to "\uD83E\uDDE0", - "orange_heart" to "\uD83E\uDDE1", - "billed_cap" to "\uD83E\uDDE2", - "scarf" to "\uD83E\uDDE3", - "gloves" to "\uD83E\uDDE4", - "coat" to "\uD83E\uDDE5", - "socks" to "\uD83E\uDDE6", - "bangbang" to "\u203C\uFE0F", - "interrobang" to "\u2049\uFE0F", - "tm" to "\u2122\uFE0F", - "information_source" to "\u2139\uFE0F", - "left_right_arrow" to "\u2194\uFE0F", - "arrow_up_down" to "\u2195\uFE0F", - "arrow_upper_left" to "\u2196\uFE0F", - "arrow_upper_right" to "\u2197\uFE0F", - "arrow_lower_right" to "\u2198\uFE0F", - "arrow_lower_left" to "\u2199\uFE0F", - "leftwards_arrow_with_hook" to "\u21A9\uFE0F", - "arrow_right_hook" to "\u21AA\uFE0F", - "watch" to "\u231A", - "hourglass" to "\u231B", - "keyboard" to "\u2328\uFE0F", - "eject" to "\u23CF\uFE0F", - "fast_forward" to "\u23E9", - "rewind" to "\u23EA", - "arrow_double_up" to "\u23EB", - "arrow_double_down" to "\u23EC", - "black_right_pointing_double_triangle_with_vertical_bar" to "\u23ED\uFE0F", - "black_left_pointing_double_triangle_with_vertical_bar" to "\u23EE\uFE0F", - "black_right_pointing_triangle_with_double_vertical_bar" to "\u23EF\uFE0F", - "alarm_clock" to "\u23F0", - "stopwatch" to "\u23F1\uFE0F", - "timer_clock" to "\u23F2\uFE0F", - "hourglass_flowing_sand" to "\u23F3", - "double_vertical_bar" to "\u23F8\uFE0F", - "black_square_for_stop" to "\u23F9\uFE0F", - "black_circle_for_record" to "\u23FA\uFE0F", - "m" to "\u24C2\uFE0F", - "black_small_square" to "\u25AA\uFE0F", - "white_small_square" to "\u25AB\uFE0F", - "arrow_forward" to "\u25B6\uFE0F", - "arrow_backward" to "\u25C0\uFE0F", - "white_medium_square" to "\u25FB\uFE0F", - "black_medium_square" to "\u25FC\uFE0F", - "white_medium_small_square" to "\u25FD", - "black_medium_small_square" to "\u25FE", - "sunny" to "\u2600\uFE0F", - "cloud" to "\u2601\uFE0F", - "umbrella" to "\u2602\uFE0F", - "snowman" to "\u2603\uFE0F", - "comet" to "\u2604\uFE0F", - "phone" to "\u260E\uFE0F", - "telephone" to "\u260E\uFE0F", - "ballot_box_with_check" to "\u2611\uFE0F", - "shamrock" to "\u2618\uFE0F", - "point_up" to "\u261D\uFE0F", - "skull_and_crossbones" to "\u2620\uFE0F", - "radioactive_sign" to "\u2622\uFE0F", - "biohazard_sign" to "\u2623\uFE0F", - "orthodox_cross" to "\u2626\uFE0F", - "star_and_crescent" to "\u262A\uFE0F", - "peace_symbol" to "\u262E\uFE0F", - "yin_yang" to "\u262F\uFE0F", - "wheel_of_dharma" to "\u2638\uFE0F", - "white_frowning_face" to "\u2639\uFE0F", - "relaxed" to "\u263A\uFE0F", - "female_sign" to "\u2640\uFE0F", - "male_sign" to "\u2642\uFE0F", - "gemini" to "\u264A", - "cancer" to "\u264B", - "leo" to "\u264C", - "virgo" to "\u264D", - "libra" to "\u264E", - "scorpius" to "\u264F", - "spades" to "\u2660\uFE0F", - "clubs" to "\u2663\uFE0F", - "hearts" to "\u2665\uFE0F", - "diamonds" to "\u2666\uFE0F", - "hotsprings" to "\u2668\uFE0F", - "recycle" to "\u267B\uFE0F", - "wheelchair" to "\u267F", - "hammer_and_pick" to "\u2692\uFE0F", - "crossed_swords" to "\u2694\uFE0F", - "staff_of_aesculapius" to "\u2695\uFE0F", - "scales" to "\u2696\uFE0F", - "alembic" to "\u2697\uFE0F", - "gear" to "\u2699\uFE0F", - "atom_symbol" to "\u269B\uFE0F", - "fleur_de_lis" to "\u269C\uFE0F", - "warning" to "\u26A0\uFE0F", - "zap" to "\u26A1", - "white_circle" to "\u26AA", - "black_circle" to "\u26AB", - "coffin" to "\u26B0\uFE0F", - "funeral_urn" to "\u26B1\uFE0F", - "soccer" to "\u26BD", - "baseball" to "\u26BE", - "snowman_without_snow" to "\u26C4", - "partly_sunny" to "\u26C5", - "thunder_cloud_and_rain" to "\u26C8\uFE0F", - "ophiuchus" to "\u26CE", - "pick" to "\u26CF\uFE0F", - "helmet_with_white_cross" to "\u26D1\uFE0F", - "chains" to "\u26D3\uFE0F", - "no_entry" to "\u26D4", - "shinto_shrine" to "\u26E9\uFE0F", - "church" to "\u26EA", - "mountain" to "\u26F0\uFE0F", - "umbrella_on_ground" to "\u26F1\uFE0F", - "fountain" to "\u26F2", - "golf" to "\u26F3", - "ferry" to "\u26F4\uFE0F", - "boat" to "\u26F5", - "sailboat" to "\u26F5", - "skier" to "\u26F7\uFE0F", - "ice_skate" to "\u26F8\uFE0F", - "woman-bouncing-ball" to "\u26F9\uFE0F\u200D\u2640\uFE0F", - "man-bouncing-ball" to "\u26F9\uFE0F\u200D\u2642\uFE0F", - "person_with_ball" to "\u26F9\uFE0F\u200D\u2642\uFE0F", - "tent" to "\u26FA", - "fuelpump" to "\u26FD", - "scissors" to "\u2702\uFE0F", - "airplane" to "\u2708\uFE0F", - "email" to "\u2709\uFE0F", - "envelope" to "\u2709\uFE0F", - "fist" to "\u270A", - "hand" to "\u270B", - "raised_hand" to "\u270B", - "v" to "\u270C\uFE0F", - "writing_hand" to "\u270D\uFE0F", - "pencil2" to "\u270F\uFE0F", - "black_nib" to "\u2712\uFE0F", - "heavy_check_mark" to "\u2714\uFE0F", - "heavy_multiplication_x" to "\u2716\uFE0F", - "latin_cross" to "\u271D\uFE0F", - "star_of_david" to "\u2721\uFE0F", - "eight_spoked_asterisk" to "\u2733\uFE0F", - "eight_pointed_black_star" to "\u2734\uFE0F", - "snowflake" to "\u2744\uFE0F", - "sparkle" to "\u2747\uFE0F", - "x" to "\u274C", - "negative_squared_cross_mark" to "\u274E", - "heavy_heart_exclamation_mark_ornament" to "\u2763\uFE0F", - "heart" to "\u2764\uFE0F", - "arrow_right" to "\u27A1\uFE0F", - "curly_loop" to "\u27B0", - "loop" to "\u27BF", - "arrow_heading_up" to "\u2934\uFE0F", - "arrow_heading_down" to "\u2935\uFE0F", - "arrow_left" to "\u2B05\uFE0F", - "arrow_up" to "\u2B06\uFE0F", - "arrow_down" to "\u2B07\uFE0F", - "black_large_square" to "\u2B1B", - "white_large_square" to "\u2B1C", - "star" to "\u2B50", - "o" to "\u2B55", - "wavy_dash" to "\u3030\uFE0F", - "part_alternation_mark" to "\u303D\uFE0F", - "congratulations" to "\u3297\uFE0F", - "secret" to "\u3299\uFE0F" - ) - - val emojiReplacementMap = mapOf( - // Aliases imported from IRCCloud and Slack - "like" to rawEmojiMap["+1"], - "doge" to rawEmojiMap["dog"], - "aubergine" to rawEmojiMap["eggplant"], - "gust_of_wind" to rawEmojiMap["dash"], - "party_popper" to rawEmojiMap["tada"], - "shock" to rawEmojiMap["scream"], - "atom" to rawEmojiMap["atom_symbol"], - "loudly_crying_face" to rawEmojiMap["sob"], - "sad_tears" to rawEmojiMap["sob"], - "bawl" to rawEmojiMap["sob"], - "ufo" to rawEmojiMap["flying_saucer"], - "throwing_up" to rawEmojiMap["face_with_open_mouth_vomiting"], - "being_sick" to rawEmojiMap["face_with_open_mouth_vomiting"], - "sh" to rawEmojiMap["face_with_finger_covering_closed_lips"], - "oops" to rawEmojiMap["smiling_face_with_smiling_eyes_and_hand_covering_mouth"], - "female_wizard" to rawEmojiMap["female_mage"], - "male_wizard" to rawEmojiMap["male_mage"], - "brontosaurus" to rawEmojiMap["sauropod"], - "diplodocus" to rawEmojiMap["sauropod"], - "tyrannosaurus" to rawEmojiMap["t-rex"], - "steak" to rawEmojiMap["cut_of_meat"], - "soup_tin" to rawEmojiMap["canned_food"], - "baseball_cap" to rawEmojiMap["billed_cap"], - "female_yoga" to rawEmojiMap["woman_in_lotus_position"], - "male_yoga" to rawEmojiMap["man_in_lotus_position"], - "female_sauna" to rawEmojiMap["woman_in_steamy_room"], - "male_sauna" to rawEmojiMap["man_in_steamy_room"], - "hijab" to rawEmojiMap["person_with_headscarf"], - "crazy_face" to rawEmojiMap["grinning_face_with_one_large_and_one_small_eye"], - "diamond" to rawEmojiMap["gem"], - "ladybird" to rawEmojiMap["beetle"], - "ladybug" to rawEmojiMap["beetle"], - "ladybeetle" to rawEmojiMap["beetle"], - "coccinellid" to rawEmojiMap["beetle"], - "cursing" to rawEmojiMap["serious_face_with_symbols_covering_mouth"], - "swearing" to rawEmojiMap["serious_face_with_symbols_covering_mouth"], - "fuck" to rawEmojiMap["serious_face_with_symbols_covering_mouth"], - "angry_swearing" to rawEmojiMap["serious_face_with_symbols_covering_mouth"], - "mad_swearing" to rawEmojiMap["serious_face_with_symbols_covering_mouth"], - "pissed_off" to rawEmojiMap["serious_face_with_symbols_covering_mouth"], - "angel_face" to rawEmojiMap["innocent"], - "smiling_devil" to rawEmojiMap["smiling_imp"], - "frowning_devil" to rawEmojiMap["imp"], - "mad_rage" to rawEmojiMap["rage"], - "angry_rage" to rawEmojiMap["rage"], - "mad" to rawEmojiMap["angry"], - "steam_train" to rawEmojiMap["steam_locomotive"] - ) - - val emojiAsciiMap = mapOf( - "<3" to rawEmojiMap["heart"], - "</3" to rawEmojiMap["broken_heart"], - ")" to rawEmojiMap["smiley"], - "')" to rawEmojiMap["smiley"], - "-)" to rawEmojiMap["disappointed"], - "(" to rawEmojiMap["cry"], - "_(" to rawEmojiMap["sob"], - ";)" to rawEmojiMap["wink"], - ";p" to rawEmojiMap["stuck_out_tongue_winking_eye"] - ) - - val processedEmojiMap = (rawEmojiMap + emojiReplacementMap).toList() - .groupBy(Pair<String, String?>::second, Pair<String, String?>::first) - .map { (replacement, shortCodes) -> - AutoCompleteItem.EmojiItem(shortCodes.sorted(), replacement ?: "") - } - - val conversionMap = mapOf( - "\u0030\u20E3" to "\uDBBA\uDC37", // ZERO - "\u0031\u20E3" to "\uDBBA\uDC2E", // ONE - "\u0032\u20E3" to "\uDBBA\uDC2F", // TWO - "\u0033\u20E3" to "\uDBBA\uDC30", // THREE - "\u0034\u20E3" to "\uDBBA\uDC31", // FOUR - "\u0035\u20E3" to "\uDBBA\uDC32", // FIVE - "\u0036\u20E3" to "\uDBBA\uDC33", // SIX - "\u0037\u20E3" to "\uDBBA\uDC34", // SEVEN - "\u0038\u20E3" to "\uDBBA\uDC35", // EIGHT - "\u0039\u20E3" to "\uDBBA\uDC36", // NINE - "\u0023\u20E3" to "\uDBBA\uDC2C", // HASH - "\u0030\uFE0F\u20E3" to "\uDBBA\uDC37", // ZERO - "\u0031\uFE0F\u20E3" to "\uDBBA\uDC2E", // ONE - "\u0032\uFE0F\u20E3" to "\uDBBA\uDC2F", // TWO - "\u0033\uFE0F\u20E3" to "\uDBBA\uDC30", // THREE - "\u0034\uFE0F\u20E3" to "\uDBBA\uDC31", // FOUR - "\u0035\uFE0F\u20E3" to "\uDBBA\uDC32", // FIVE - "\u0036\uFE0F\u20E3" to "\uDBBA\uDC33", // SIX - "\u0037\uFE0F\u20E3" to "\uDBBA\uDC34", // SEVEN - "\u0038\uFE0F\u20E3" to "\uDBBA\uDC35", // EIGHT - "\u0039\uFE0F\u20E3" to "\uDBBA\uDC36", // NINE - "\u0023\uFE0F\u20E3" to "\uDBBA\uDC2C", // HASH - "\u24C2\uFE0F" to "\u24c2", // M - "\u2139\uFE0F" to "\u2139", // INFORMATION_SOURCE - "\u3297\uFE0F" to "\u3297", // CONGRATULATIONS - "\u3299\uFE0F" to "\u3299" // SECRET - ) - - val emojis = conversionMap.values.toSet() + rawEmojiMap.values.toSet() + "\u200d" + "\ufe0f" - - fun replaceShortCodes(source: Editable): Editable { - var result = source - for (emoji in processedEmojiMap) { - for (rawShortCode in emoji.shortCodes) { - val shortCode = ":$rawShortCode:" - var index: Int - while (true) { - index = result.indexOf(shortCode) - if (index == -1) break - - result = result.replace(index, index + shortCode.length, emoji.replacement) - } - } - } - return result - } -} diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiHandler.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiHandler.kt new file mode 100644 index 0000000000000000000000000000000000000000..8aeab33820ad5a2dd9dd28dd199f02b8939a5a95 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiHandler.kt @@ -0,0 +1,81 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2023 Janne Mareike Koschinski + * Copyright (c) 2023 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.util.emoji + +import android.text.Editable +import java.util.* +import javax.inject.Inject + +class EmojiHandler @Inject constructor(private val emojiProvider: EmojiProvider) { + data class Emoji( + val label: String, + val tags: List<String>, + val shortcodes: List<String>, + val replacement: String + ) + + fun replaceShortcodes(source: Editable): Editable { + var result = source + + val matches = shortcodeRegex.findAll(source) + .map(MatchResult::value) + .distinct() + .toList() + + for (match in matches) { + val emoji = shortcodeLookup(normalizeShortcode(match)) + if (emoji != null) { + println("replacing $match with ${emoji.replacement}") + println("before: $result") + result = result.replaceAll(match, emoji.replacement) + println("after: $result") + } + } + + return result + } + + fun normalizeShortcode(pattern: String): String = + pattern.lowercase(Locale.ROOT).trim(':') + + fun fuzzyLookup(pattern: String): List<Emoji> = emojiProvider.emoji.filter { emoji -> + emoji.shortcodes.any { it.contains(pattern) } + || emoji.tags.any { it.contains(pattern) } + || emoji.label.contains(pattern) + } + + fun shortcodeLookup(pattern: String): Emoji? = emojiProvider.shortcodes[pattern] + + companion object { + val shortcodeRegex = Regex(":[\\d+_a-zA-Z-]+:") + + private fun Editable.replaceAll(original: String, replacement: String): Editable { + var result = this + var index: Int + while (true) { + index = result.indexOf(original) + if (index == -1) break + + result = result.replace(index, index + original.length, replacement) + } + return result + } + } +} diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiProvider.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiProvider.kt new file mode 100644 index 0000000000000000000000000000000000000000..8172ca36d42a3d90f621729239d4d2d8344cfde1 --- /dev/null +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/util/emoji/EmojiProvider.kt @@ -0,0 +1,25 @@ +/* + * Quasseldroid - Quassel client for Android + * + * Copyright (c) 2023 Janne Mareike Koschinski + * Copyright (c) 2023 The Quassel Project + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3 as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +package de.kuschku.quasseldroid.util.emoji + +interface EmojiProvider { + val emoji: List<EmojiHandler.Emoji> + val shortcodes: Map<String, EmojiHandler.Emoji> +} diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/AutoCompleteItem.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/AutoCompleteItem.kt index 825debb9a93d7a1fde7b109ed62c8f302db73779..3f6c1ed0367cde38bdcdfb8eb91509b2cacf54c0 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/AutoCompleteItem.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/data/AutoCompleteItem.kt @@ -22,6 +22,7 @@ package de.kuschku.quasseldroid.viewmodel.data import android.graphics.drawable.Drawable import de.kuschku.libquassel.quassel.BufferInfo import de.kuschku.libquassel.quassel.syncables.interfaces.INetwork +import de.kuschku.quasseldroid.util.emoji.EmojiHandler sealed class AutoCompleteItem(open val name: String, val suffix: String, private val type: Int) : Comparable<AutoCompleteItem> { @@ -133,25 +134,22 @@ sealed class AutoCompleteItem(open val name: String, val suffix: String, private } data class EmojiItem( - val shortCodes: List<String>, - val replacement: String - ) : AutoCompleteItem(replacement, " ", 3) { + val emoji: EmojiHandler.Emoji, + ) : AutoCompleteItem(emoji.replacement, " ", 3) { + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false other as EmojiItem - if (shortCodes != other.shortCodes) return false - if (replacement != other.replacement) return false + if (emoji != other.emoji) return false return true } override fun hashCode(): Int { - var result = shortCodes.hashCode() - result = 31 * result + replacement.hashCode() - return result + return emoji.hashCode() } } } diff --git a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt index 28c8eb5028cd9d2e9ca3eff03c5b3bb17518b29c..b1bb689bd24560d5a5233876aae87547b318438e 100644 --- a/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt +++ b/viewmodel/src/main/java/de/kuschku/quasseldroid/viewmodel/helper/EditorViewModelHelper.kt @@ -32,7 +32,7 @@ import de.kuschku.libquassel.util.helper.combineLatest import de.kuschku.libquassel.util.helper.mapNullable import de.kuschku.libquassel.util.helper.nullIf import de.kuschku.libquassel.util.helper.safeSwitchMap -import de.kuschku.quasseldroid.util.emoji.EmojiData +import de.kuschku.quasseldroid.util.emoji.EmojiHandler import de.kuschku.quasseldroid.util.safety.DeceptiveNetworkManager import de.kuschku.quasseldroid.viewmodel.ChatViewModel import de.kuschku.quasseldroid.viewmodel.EditorViewModel @@ -45,6 +45,7 @@ import javax.inject.Inject open class EditorViewModelHelper @Inject constructor( val editor: EditorViewModel, + emojiHandler: EmojiHandler, deceptiveNetworkManager: DeceptiveNetworkManager, chat: ChatViewModel, quassel: QuasselViewModel @@ -166,21 +167,17 @@ open class EditorViewModelHelper @Inject constructor( } } - fun getEmojis() = EmojiData.processedEmojiMap.filter { - it.shortCodes.any { - it.contains(lastWord.first.trim(':')) - } - }.map { - Observable.just(it) - } + fun getEmoji() = emojiHandler.fuzzyLookup( + emojiHandler.normalizeShortcode(lastWord.first) + ).map { Observable.just(AutoCompleteItem.EmojiItem(it)) } processResults( when (lastWord.first.firstOrNull()) { '/' -> getAliases() '@' -> getNicks() '#' -> getBuffers() - ':' -> getEmojis() - else -> getAliases() + getNicks() + getBuffers() + getEmojis() + ':' -> getEmoji() + else -> getAliases() + getNicks() + getBuffers() + getEmoji() } ) }