diff --git a/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs b/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs index 7566989..90a842b 100644 --- a/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs +++ b/DiscordChatExporter.Cli.Tests/Fixtures/ExportWrapperFixture.cs @@ -14,119 +14,118 @@ using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Exporting; using JsonExtensions; -namespace DiscordChatExporter.Cli.Tests.Fixtures +namespace DiscordChatExporter.Cli.Tests.Fixtures; + +public class ExportWrapperFixture : IDisposable { - public class ExportWrapperFixture : IDisposable - { - private string DirPath { get; } = Path.Combine( - Path.GetDirectoryName(typeof(ExportWrapperFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(), - "ExportCache", - Guid.NewGuid().ToString() - ); + private string DirPath { get; } = Path.Combine( + Path.GetDirectoryName(typeof(ExportWrapperFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(), + "ExportCache", + Guid.NewGuid().ToString() + ); - public ExportWrapperFixture() => DirectoryEx.Reset(DirPath); + public ExportWrapperFixture() => DirectoryEx.Reset(DirPath); - private async ValueTask ExportAsync(Snowflake channelId, ExportFormat format) - { - var fileName = channelId.ToString() + '.' + format.GetFileExtension(); - var filePath = Path.Combine(DirPath, fileName); + private async ValueTask ExportAsync(Snowflake channelId, ExportFormat format) + { + var fileName = channelId.ToString() + '.' + format.GetFileExtension(); + var filePath = Path.Combine(DirPath, fileName); - // Perform export only if it hasn't been done before - if (!File.Exists(filePath)) + // Perform export only if it hasn't been done before + if (!File.Exists(filePath)) + { + await new ExportChannelsCommand { - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { channelId }, - ExportFormat = format, - OutputPath = filePath - }.ExecuteAsync(new FakeConsole()); - } - - return await File.ReadAllTextAsync(filePath); + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { channelId }, + ExportFormat = format, + OutputPath = filePath + }.ExecuteAsync(new FakeConsole()); } - public async ValueTask ExportAsHtmlAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.HtmlDark); - return Html.Parse(data); - } + return await File.ReadAllTextAsync(filePath); + } - public async ValueTask ExportAsJsonAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.Json); - return Json.Parse(data); - } + public async ValueTask ExportAsHtmlAsync(Snowflake channelId) + { + var data = await ExportAsync(channelId, ExportFormat.HtmlDark); + return Html.Parse(data); + } - public async ValueTask ExportAsPlainTextAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.PlainText); - return data; - } + public async ValueTask ExportAsJsonAsync(Snowflake channelId) + { + var data = await ExportAsync(channelId, ExportFormat.Json); + return Json.Parse(data); + } - public async ValueTask ExportAsCsvAsync(Snowflake channelId) - { - var data = await ExportAsync(channelId, ExportFormat.Csv); - return data; - } + public async ValueTask ExportAsPlainTextAsync(Snowflake channelId) + { + var data = await ExportAsync(channelId, ExportFormat.PlainText); + return data; + } - public async ValueTask> GetMessagesAsHtmlAsync(Snowflake channelId) - { - var document = await ExportAsHtmlAsync(channelId); - return document.QuerySelectorAll("[data-message-id]").ToArray(); - } + public async ValueTask ExportAsCsvAsync(Snowflake channelId) + { + var data = await ExportAsync(channelId, ExportFormat.Csv); + return data; + } - public async ValueTask> GetMessagesAsJsonAsync(Snowflake channelId) - { - var document = await ExportAsJsonAsync(channelId); - return document.GetProperty("messages").EnumerateArray().ToArray(); - } + public async ValueTask> GetMessagesAsHtmlAsync(Snowflake channelId) + { + var document = await ExportAsHtmlAsync(channelId); + return document.QuerySelectorAll("[data-message-id]").ToArray(); + } + + public async ValueTask> GetMessagesAsJsonAsync(Snowflake channelId) + { + var document = await ExportAsJsonAsync(channelId); + return document.GetProperty("messages").EnumerateArray().ToArray(); + } + + public async ValueTask GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId) + { + var messages = await GetMessagesAsHtmlAsync(channelId); + + var message = messages.SingleOrDefault(e => + string.Equals( + e.GetAttribute("data-message-id"), + messageId.ToString(), + StringComparison.OrdinalIgnoreCase + ) + ); - public async ValueTask GetMessageAsHtmlAsync(Snowflake channelId, Snowflake messageId) + if (message is null) { - var messages = await GetMessagesAsHtmlAsync(channelId); - - var message = messages.SingleOrDefault(e => - string.Equals( - e.GetAttribute("data-message-id"), - messageId.ToString(), - StringComparison.OrdinalIgnoreCase - ) + throw new InvalidOperationException( + $"Message '{messageId}' does not exist in export of channel '{channelId}'." ); + } - if (message is null) - { - throw new InvalidOperationException( - $"Message '{messageId}' does not exist in export of channel '{channelId}'." - ); - } + return message; + } - return message; - } + public async ValueTask GetMessageAsJsonAsync(Snowflake channelId, Snowflake messageId) + { + var messages = await GetMessagesAsJsonAsync(channelId); + + var message = messages.FirstOrDefault(j => + string.Equals( + j.GetProperty("id").GetString(), + messageId.ToString(), + StringComparison.OrdinalIgnoreCase + ) + ); - public async ValueTask GetMessageAsJsonAsync(Snowflake channelId, Snowflake messageId) + if (message.ValueKind == JsonValueKind.Undefined) { - var messages = await GetMessagesAsJsonAsync(channelId); - - var message = messages.FirstOrDefault(j => - string.Equals( - j.GetProperty("id").GetString(), - messageId.ToString(), - StringComparison.OrdinalIgnoreCase - ) + throw new InvalidOperationException( + $"Message '{messageId}' does not exist in export of channel '{channelId}'." ); - - if (message.ValueKind == JsonValueKind.Undefined) - { - throw new InvalidOperationException( - $"Message '{messageId}' does not exist in export of channel '{channelId}'." - ); - } - - return message; } - public void Dispose() => DirectoryEx.DeleteIfExists(DirPath); + return message; } + + public void Dispose() => DirectoryEx.DeleteIfExists(DirPath); } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs b/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs index 75e6e16..1f2114b 100644 --- a/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs +++ b/DiscordChatExporter.Cli.Tests/Fixtures/TempOutputFixture.cs @@ -2,22 +2,21 @@ using System.IO; using DiscordChatExporter.Cli.Tests.Utils; -namespace DiscordChatExporter.Cli.Tests.Fixtures +namespace DiscordChatExporter.Cli.Tests.Fixtures; + +public class TempOutputFixture : IDisposable { - public class TempOutputFixture : IDisposable - { - public string DirPath { get; } = Path.Combine( - Path.GetDirectoryName(typeof(TempOutputFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(), - "Temp", - Guid.NewGuid().ToString() - ); + public string DirPath { get; } = Path.Combine( + Path.GetDirectoryName(typeof(TempOutputFixture).Assembly.Location) ?? Directory.GetCurrentDirectory(), + "Temp", + Guid.NewGuid().ToString() + ); - public TempOutputFixture() => DirectoryEx.Reset(DirPath); + public TempOutputFixture() => DirectoryEx.Reset(DirPath); - public string GetTempFilePath(string fileName) => Path.Combine(DirPath, fileName); + public string GetTempFilePath(string fileName) => Path.Combine(DirPath, fileName); - public string GetTempFilePath() => GetTempFilePath(Guid.NewGuid() + ".tmp"); + public string GetTempFilePath() => GetTempFilePath(Guid.NewGuid() + ".tmp"); - public void Dispose() => DirectoryEx.DeleteIfExists(DirPath); - } + public void Dispose() => DirectoryEx.DeleteIfExists(DirPath); } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Infra/Secrets.cs b/DiscordChatExporter.Cli.Tests/Infra/Secrets.cs index ba6c788..6e2bd46 100644 --- a/DiscordChatExporter.Cli.Tests/Infra/Secrets.cs +++ b/DiscordChatExporter.Cli.Tests/Infra/Secrets.cs @@ -1,46 +1,45 @@ using System; using System.IO; -namespace DiscordChatExporter.Cli.Tests.Infra +namespace DiscordChatExporter.Cli.Tests.Infra; + +internal static class Secrets { - internal static class Secrets + private static readonly Lazy DiscordTokenLazy = new(() => { - private static readonly Lazy DiscordTokenLazy = new(() => - { - var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); - if (!string.IsNullOrWhiteSpace(fromEnvironment)) - return fromEnvironment; + var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN"); + if (!string.IsNullOrWhiteSpace(fromEnvironment)) + return fromEnvironment; - var secretFilePath = Path.Combine( - Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(), - "DiscordToken.secret" - ); + var secretFilePath = Path.Combine( + Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(), + "DiscordToken.secret" + ); - if (File.Exists(secretFilePath)) - return File.ReadAllText(secretFilePath); + if (File.Exists(secretFilePath)) + return File.ReadAllText(secretFilePath); - throw new InvalidOperationException("Discord token not provided for tests."); - }); + throw new InvalidOperationException("Discord token not provided for tests."); + }); - private static readonly Lazy IsDiscordTokenBotLazy = new(() => - { - var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN_BOT"); - if (!string.IsNullOrWhiteSpace(fromEnvironment)) - return string.Equals(fromEnvironment, "true", StringComparison.OrdinalIgnoreCase); + private static readonly Lazy IsDiscordTokenBotLazy = new(() => + { + var fromEnvironment = Environment.GetEnvironmentVariable("DISCORD_TOKEN_BOT"); + if (!string.IsNullOrWhiteSpace(fromEnvironment)) + return string.Equals(fromEnvironment, "true", StringComparison.OrdinalIgnoreCase); - var secretFilePath = Path.Combine( - Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(), - "DiscordTokenBot.secret" - ); + var secretFilePath = Path.Combine( + Path.GetDirectoryName(typeof(Secrets).Assembly.Location) ?? Directory.GetCurrentDirectory(), + "DiscordTokenBot.secret" + ); - if (File.Exists(secretFilePath)) - return true; + if (File.Exists(secretFilePath)) + return true; - return false; - }); + return false; + }); - public static string DiscordToken => DiscordTokenLazy.Value; + public static string DiscordToken => DiscordTokenLazy.Value; - public static bool IsDiscordTokenBot => IsDiscordTokenBotLazy.Value; - } + public static bool IsDiscordTokenBot => IsDiscordTokenBotLazy.Value; } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/CsvWriting/ContentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/CsvWriting/ContentSpecs.cs index d7e6b6f..d0fa0a1 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/CsvWriting/ContentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/CsvWriting/ContentSpecs.cs @@ -4,28 +4,27 @@ using DiscordChatExporter.Cli.Tests.TestData; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.CsvWriting +namespace DiscordChatExporter.Cli.Tests.Specs.CsvWriting; + +public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Messages_are_exported_correctly() { - [Fact] - public async Task Messages_are_exported_correctly() - { - // Act - var document = await ExportWrapper.ExportAsCsvAsync(ChannelIds.DateRangeTestCases); + // Act + var document = await ExportWrapper.ExportAsCsvAsync(ChannelIds.DateRangeTestCases); - // Assert - document.Should().ContainAll( - "Tyrrrz#5447", - "Hello world", - "Goodbye world", - "Foo bar", - "Hurdle Durdle", - "One", - "Two", - "Three", - "Yeet" - ); - } + // Assert + document.Should().ContainAll( + "Tyrrrz#5447", + "Hello world", + "Goodbye world", + "Foo bar", + "Hurdle Durdle", + "One", + "Two", + "Three", + "Yeet" + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/DateRangeSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/DateRangeSpecs.cs index 4545bb0..23af76d 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/DateRangeSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/DateRangeSpecs.cs @@ -13,148 +13,147 @@ using FluentAssertions; using JsonExtensions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs +namespace DiscordChatExporter.Cli.Tests.Specs; + +public record DateRangeSpecs(TempOutputFixture TempOutput) : IClassFixture { - public record DateRangeSpecs(TempOutputFixture TempOutput) : IClassFixture + [Fact] + public async Task Messages_filtered_after_specific_date_only_include_messages_sent_after_that_date() + { + // Arrange + var after = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero); + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand + { + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.DateRangeTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + After = Snowflake.FromDate(after) + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + var timestamps = document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("timestamp").GetDateTimeOffset()) + .ToArray(); + + // Assert + timestamps.All(t => t > after).Should().BeTrue(); + + timestamps.Should().BeEquivalentTo(new[] + { + new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero), + new DateTimeOffset(2021, 09, 08, 14, 26, 35, TimeSpan.Zero) + }, o => + { + return o + .Using(ctx => + ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1)) + ) + .WhenTypeIs(); + }); + } + + [Fact] + public async Task Messages_filtered_before_specific_date_only_include_messages_sent_before_that_date() { - [Fact] - public async Task Messages_filtered_after_specific_date_only_include_messages_sent_after_that_date() + // Arrange + var before = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero); + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand + { + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.DateRangeTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + Before = Snowflake.FromDate(before) + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + var timestamps = document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("timestamp").GetDateTimeOffset()) + .ToArray(); + + // Assert + timestamps.All(t => t < before).Should().BeTrue(); + + timestamps.Should().BeEquivalentTo(new[] + { + new DateTimeOffset(2021, 07, 19, 13, 34, 18, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 19, 15, 58, 48, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 19, 17, 23, 58, TimeSpan.Zero) + }, o => + { + return o + .Using(ctx => + ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1)) + ) + .WhenTypeIs(); + }); + } + + [Fact] + public async Task Messages_filtered_between_specific_dates_only_include_messages_sent_between_those_dates() + { + // Arrange + var after = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero); + var before = new DateTimeOffset(2021, 08, 01, 0, 0, 0, TimeSpan.Zero); + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand { - // Arrange - var after = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero); - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.DateRangeTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - After = Snowflake.FromDate(after) - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - var timestamps = document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("timestamp").GetDateTimeOffset()) - .ToArray(); - - // Assert - timestamps.All(t => t > after).Should().BeTrue(); - - timestamps.Should().BeEquivalentTo(new[] - { - new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero), - new DateTimeOffset(2021, 09, 08, 14, 26, 35, TimeSpan.Zero) - }, o => - { - return o - .Using(ctx => - ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1)) - ) - .WhenTypeIs(); - }); - } - - [Fact] - public async Task Messages_filtered_before_specific_date_only_include_messages_sent_before_that_date() + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.DateRangeTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + Before = Snowflake.FromDate(before), + After = Snowflake.FromDate(after) + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + var timestamps = document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("timestamp").GetDateTimeOffset()) + .ToArray(); + + // Assert + timestamps.All(t => t < before && t > after).Should().BeTrue(); + + timestamps.Should().BeEquivalentTo(new[] { - // Arrange - var before = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero); - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.DateRangeTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - Before = Snowflake.FromDate(before) - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - var timestamps = document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("timestamp").GetDateTimeOffset()) - .ToArray(); - - // Assert - timestamps.All(t => t < before).Should().BeTrue(); - - timestamps.Should().BeEquivalentTo(new[] - { - new DateTimeOffset(2021, 07, 19, 13, 34, 18, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 19, 15, 58, 48, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 19, 17, 23, 58, TimeSpan.Zero) - }, o => - { - return o - .Using(ctx => - ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1)) - ) - .WhenTypeIs(); - }); - } - - [Fact] - public async Task Messages_filtered_between_specific_dates_only_include_messages_sent_between_those_dates() + new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero), + new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero) + }, o => { - // Arrange - var after = new DateTimeOffset(2021, 07, 24, 0, 0, 0, TimeSpan.Zero); - var before = new DateTimeOffset(2021, 08, 01, 0, 0, 0, TimeSpan.Zero); - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.DateRangeTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - Before = Snowflake.FromDate(before), - After = Snowflake.FromDate(after) - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - var timestamps = document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("timestamp").GetDateTimeOffset()) - .ToArray(); - - // Assert - timestamps.All(t => t < before && t > after).Should().BeTrue(); - - timestamps.Should().BeEquivalentTo(new[] - { - new DateTimeOffset(2021, 07, 24, 13, 49, 13, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 24, 14, 52, 38, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 24, 14, 52, 39, TimeSpan.Zero), - new DateTimeOffset(2021, 07, 24, 14, 52, 40, TimeSpan.Zero) - }, o => - { - return o - .Using(ctx => - ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1)) - ) - .WhenTypeIs(); - }); - } + return o + .Using(ctx => + ctx.Subject.Should().BeCloseTo(ctx.Expectation, TimeSpan.FromSeconds(1)) + ) + .WhenTypeIs(); + }); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/FilterSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/FilterSpecs.cs index a0aa6d6..e2b0b6d 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/FilterSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/FilterSpecs.cs @@ -12,124 +12,123 @@ using FluentAssertions; using JsonExtensions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs +namespace DiscordChatExporter.Cli.Tests.Specs; + +public record FilterSpecs(TempOutputFixture TempOutput) : IClassFixture { - public record FilterSpecs(TempOutputFixture TempOutput) : IClassFixture + [Fact] + public async Task Messages_filtered_by_text_only_include_messages_that_contain_that_text() { - [Fact] - public async Task Messages_filtered_by_text_only_include_messages_that_contain_that_text() + // Arrange + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.FilterTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - MessageFilter = MessageFilter.Parse("some text") - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - // Assert - document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("content").GetString()) - .Should() - .ContainSingle("Some random text"); - } - - [Fact] - public async Task Messages_filtered_by_author_only_include_messages_sent_by_that_author() + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.FilterTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + MessageFilter = MessageFilter.Parse("some text") + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + // Assert + document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("content").GetString()) + .Should() + .ContainSingle("Some random text"); + } + + [Fact] + public async Task Messages_filtered_by_author_only_include_messages_sent_by_that_author() + { + // Arrange + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.FilterTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - MessageFilter = MessageFilter.Parse("from:Tyrrrz") - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - // Assert - document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("author").GetProperty("name").GetString()) - .Should() - .AllBe("Tyrrrz"); - } - - [Fact] - public async Task Messages_filtered_by_content_only_include_messages_that_have_that_content() + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.FilterTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + MessageFilter = MessageFilter.Parse("from:Tyrrrz") + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + // Assert + document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("author").GetProperty("name").GetString()) + .Should() + .AllBe("Tyrrrz"); + } + + [Fact] + public async Task Messages_filtered_by_content_only_include_messages_that_have_that_content() + { + // Arrange + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.FilterTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - MessageFilter = MessageFilter.Parse("has:image") - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - // Assert - document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("content").GetString()) - .Should() - .ContainSingle("This has image"); - } - - [Fact] - public async Task Messages_filtered_by_mention_only_include_messages_that_have_that_mention() + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.FilterTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + MessageFilter = MessageFilter.Parse("has:image") + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + // Assert + document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("content").GetString()) + .Should() + .ContainSingle("This has image"); + } + + [Fact] + public async Task Messages_filtered_by_mention_only_include_messages_that_have_that_mention() + { + // Arrange + var filePath = TempOutput.GetTempFilePath(); + + // Act + await new ExportChannelsCommand { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.FilterTestCases }, - ExportFormat = ExportFormat.Json, - OutputPath = filePath, - MessageFilter = MessageFilter.Parse("mentions:Tyrrrz") - }.ExecuteAsync(new FakeConsole()); - - var data = await File.ReadAllTextAsync(filePath); - var document = Json.Parse(data); - - // Assert - document - .GetProperty("messages") - .EnumerateArray() - .Select(j => j.GetProperty("content").GetString()) - .Should() - .ContainSingle("This has mention"); - } + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.FilterTestCases }, + ExportFormat = ExportFormat.Json, + OutputPath = filePath, + MessageFilter = MessageFilter.Parse("mentions:Tyrrrz") + }.ExecuteAsync(new FakeConsole()); + + var data = await File.ReadAllTextAsync(filePath); + var document = Json.Parse(data); + + // Assert + document + .GetProperty("messages") + .EnumerateArray() + .Select(j => j.GetProperty("content").GetString()) + .Should() + .ContainSingle("This has mention"); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs index d04b9bc..6002e56 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/AttachmentSpecs.cs @@ -6,88 +6,87 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting +namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting; + +public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Message_with_a_generic_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885587844989612074") + ); + + var fileUrl = message.QuerySelector("a")?.GetAttribute("href"); + + // Assert + message.Text().Should().ContainAll( + "Generic file attachment", + "Test.txt", + "11 bytes" + ); + + fileUrl.Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt" + ); + } + + [Fact] + public async Task Message_with_an_image_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885654862656843786") + ); + + var imageUrl = message.QuerySelector("img")?.GetAttribute("src"); + + // Assert + message.Text().Should().Contain("Image attachment"); + + imageUrl.Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png" + ); + } + + [Fact] + public async Task Message_with_a_video_attachment_is_rendered_correctly() { - [Fact] - public async Task Message_with_a_generic_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885587844989612074") - ); - - var fileUrl = message.QuerySelector("a")?.GetAttribute("href"); - - // Assert - message.Text().Should().ContainAll( - "Generic file attachment", - "Test.txt", - "11 bytes" - ); - - fileUrl.Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt" - ); - } - - [Fact] - public async Task Message_with_an_image_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885654862656843786") - ); - - var imageUrl = message.QuerySelector("img")?.GetAttribute("src"); - - // Assert - message.Text().Should().Contain("Image attachment"); - - imageUrl.Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png" - ); - } - - [Fact] - public async Task Message_with_a_video_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885655761919836171") - ); - - var videoUrl = message.QuerySelector("video source")?.GetAttribute("src"); - - // Assert - message.Text().Should().Contain("Video attachment"); - - videoUrl.Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4" - ); - } - - [Fact] - public async Task Message_with_an_audio_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885656175620808734") - ); - - var audioUrl = message.QuerySelector("audio source")?.GetAttribute("src"); - - // Assert - message.Text().Should().Contain("Audio attachment"); - - audioUrl.Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3" - ); - } + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885655761919836171") + ); + + var videoUrl = message.QuerySelector("video source")?.GetAttribute("src"); + + // Assert + message.Text().Should().Contain("Video attachment"); + + videoUrl.Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4" + ); + } + + [Fact] + public async Task Message_with_an_audio_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885656175620808734") + ); + + var audioUrl = message.QuerySelector("audio source")?.GetAttribute("src"); + + // Assert + message.Text().Should().Contain("Audio attachment"); + + audioUrl.Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3" + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ContentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ContentSpecs.cs index 829cc58..6d9e6a9 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ContentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ContentSpecs.cs @@ -6,38 +6,37 @@ using DiscordChatExporter.Cli.Tests.TestData; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting +namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting; + +public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Messages_are_exported_correctly() { - [Fact] - public async Task Messages_are_exported_correctly() - { - // Act - var messages = await ExportWrapper.GetMessagesAsHtmlAsync(ChannelIds.DateRangeTestCases); + // Act + var messages = await ExportWrapper.GetMessagesAsHtmlAsync(ChannelIds.DateRangeTestCases); - // Assert - messages.Select(e => e.GetAttribute("data-message-id")).Should().Equal( - "866674314627121232", - "866710679758045195", - "866732113319428096", - "868490009366396958", - "868505966528835604", - "868505969821364245", - "868505973294268457", - "885169254029213696" - ); + // Assert + messages.Select(e => e.GetAttribute("data-message-id")).Should().Equal( + "866674314627121232", + "866710679758045195", + "866732113319428096", + "868490009366396958", + "868505966528835604", + "868505969821364245", + "868505973294268457", + "885169254029213696" + ); - messages.Select(e => e.QuerySelector(".chatlog__content")?.Text().Trim()).Should().Equal( - "Hello world", - "Goodbye world", - "Foo bar", - "Hurdle Durdle", - "One", - "Two", - "Three", - "Yeet" - ); - } + messages.Select(e => e.QuerySelector(".chatlog__content")?.Text().Trim()).Should().Equal( + "Hello world", + "Goodbye world", + "Foo bar", + "Hurdle Durdle", + "One", + "Two", + "Three", + "Yeet" + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs index 670368e..7a448fe 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/EmbedSpecs.cs @@ -6,59 +6,58 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting +namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting; + +public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Message_with_an_embed_is_rendered_correctly() { - [Fact] - public async Task Message_with_an_embed_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.EmbedTestCases, - Snowflake.Parse("866769910729146400") - ); - - // Assert - message.Text().Should().ContainAll( - "Embed author", - "Embed title", - "Embed description", - "Field 1", "Value 1", - "Field 2", "Value 2", - "Field 3", "Value 3", - "Embed footer" - ); - } + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.EmbedTestCases, + Snowflake.Parse("866769910729146400") + ); + + // Assert + message.Text().Should().ContainAll( + "Embed author", + "Embed title", + "Embed description", + "Field 1", "Value 1", + "Field 2", "Value 2", + "Field 3", "Value 3", + "Embed footer" + ); + } - [Fact] - public async Task Message_with_a_Spotify_track_is_rendered_using_an_iframe() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.EmbedTestCases, - Snowflake.Parse("867886632203976775") - ); + [Fact] + public async Task Message_with_a_Spotify_track_is_rendered_using_an_iframe() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.EmbedTestCases, + Snowflake.Parse("867886632203976775") + ); - var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src"); + var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src"); - // Assert - iframeSrc.Should().StartWithEquivalentOf("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP"); - } + // Assert + iframeSrc.Should().StartWithEquivalentOf("https://open.spotify.com/embed/track/1LHZMWefF9502NPfArRfvP"); + } - [Fact] - public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.EmbedTestCases, - Snowflake.Parse("866472508588294165") - ); + [Fact] + public async Task Message_with_a_YouTube_video_is_rendered_using_an_iframe() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.EmbedTestCases, + Snowflake.Parse("866472508588294165") + ); - var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src"); + var iframeSrc = message.QuerySelector("iframe")?.GetAttribute("src"); - // Assert - iframeSrc.Should().StartWithEquivalentOf("https://www.youtube.com/embed/qOWW4OlgbvE"); - } + // Assert + iframeSrc.Should().StartWithEquivalentOf("https://www.youtube.com/embed/qOWW4OlgbvE"); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/MentionSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/MentionSpecs.cs index 0335da8..336dc4f 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/MentionSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/MentionSpecs.cs @@ -6,61 +6,60 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting +namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting; + +public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task User_mention_is_rendered_correctly() { - [Fact] - public async Task User_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866458840245076028") - ); + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866458840245076028") + ); - // Assert - message.Text().Trim().Should().Be("User mention: @Tyrrrz"); - message.InnerHtml.Should().Contain("Tyrrrz#5447"); - } + // Assert + message.Text().Trim().Should().Be("User mention: @Tyrrrz"); + message.InnerHtml.Should().Contain("Tyrrrz#5447"); + } - [Fact] - public async Task Text_channel_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866459040480624680") - ); + [Fact] + public async Task Text_channel_mention_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866459040480624680") + ); - // Assert - message.Text().Trim().Should().Be("Text channel mention: #mention-tests"); - } + // Assert + message.Text().Trim().Should().Be("Text channel mention: #mention-tests"); + } - [Fact] - public async Task Voice_channel_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866459175462633503") - ); + [Fact] + public async Task Voice_channel_mention_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866459175462633503") + ); - // Assert - message.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc"); - } + // Assert + message.Text().Trim().Should().Be("Voice channel mention: 🔊chaos-vc"); + } - [Fact] - public async Task Role_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866459254693429258") - ); + [Fact] + public async Task Role_mention_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866459254693429258") + ); - // Assert - message.Text().Trim().Should().Be("Role mention: @Role 1"); - } + // Assert + message.Text().Trim().Should().Be("Role mention: @Role 1"); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs index 6a3c702..73984a2 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/HtmlWriting/ReplySpecs.cs @@ -6,52 +6,51 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting +namespace DiscordChatExporter.Cli.Tests.Specs.HtmlWriting; + +public record ReplySpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record ReplySpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Reply_to_a_normal_message_is_rendered_correctly() { - [Fact] - public async Task Reply_to_a_normal_message_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.ReplyTestCases, - Snowflake.Parse("866460738239725598") - ); + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.ReplyTestCases, + Snowflake.Parse("866460738239725598") + ); - // Assert - message.Text().Trim().Should().Be("reply to original"); - message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original"); - } + // Assert + message.Text().Trim().Should().Be("reply to original"); + message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should().Be("original"); + } - [Fact] - public async Task Reply_to_a_deleted_message_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.ReplyTestCases, - Snowflake.Parse("866460975388819486") - ); + [Fact] + public async Task Reply_to_a_deleted_message_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.ReplyTestCases, + Snowflake.Parse("866460975388819486") + ); - // Assert - message.Text().Trim().Should().Be("reply to deleted"); - message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should() - .Be("Original message was deleted or could not be loaded."); - } + // Assert + message.Text().Trim().Should().Be("reply to deleted"); + message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should() + .Be("Original message was deleted or could not be loaded."); + } - [Fact] - public async Task Reply_to_a_empty_message_with_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsHtmlAsync( - ChannelIds.ReplyTestCases, - Snowflake.Parse("866462470335627294") - ); + [Fact] + public async Task Reply_to_a_empty_message_with_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsHtmlAsync( + ChannelIds.ReplyTestCases, + Snowflake.Parse("866462470335627294") + ); - // Assert - message.Text().Trim().Should().Be("reply to attachment"); - message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should() - .Be("Click to see attachment 🖼️"); - } + // Assert + message.Text().Trim().Should().Be("reply to attachment"); + message.QuerySelector(".chatlog__reference-link")?.Text().Trim().Should() + .Be("Click to see attachment 🖼️"); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs index 9bd9b12..8dcfda5 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/AttachmentSpecs.cs @@ -6,96 +6,95 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting +namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting; + +public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record AttachmentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Message_with_a_generic_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885587844989612074") + ); + + var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); + + // Assert + message.GetProperty("content").GetString().Should().Be("Generic file attachment"); + + attachments.Should().HaveCount(1); + attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt" + ); + attachments.Single().GetProperty("fileName").GetString().Should().Be("Test.txt"); + attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(11); + } + + [Fact] + public async Task Message_with_an_image_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885654862656843786") + ); + + var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); + + // Assert + message.GetProperty("content").GetString().Should().Be("Image attachment"); + + attachments.Should().HaveCount(1); + attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png" + ); + attachments.Single().GetProperty("fileName").GetString().Should().Be("bird-thumbnail.png"); + attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(466335); + } + + [Fact] + public async Task Message_with_a_video_attachment_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885655761919836171") + ); + + var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); + + // Assert + message.GetProperty("content").GetString().Should().Be("Video attachment"); + + attachments.Should().HaveCount(1); + attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4" + ); + attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP4_640_3MG.mp4"); + attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(3114374); + } + + [Fact] + public async Task Message_with_an_audio_attachment_is_rendered_correctly() { - [Fact] - public async Task Message_with_a_generic_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885587844989612074") - ); - - var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); - - // Assert - message.GetProperty("content").GetString().Should().Be("Generic file attachment"); - - attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885587844964417596/Test.txt" - ); - attachments.Single().GetProperty("fileName").GetString().Should().Be("Test.txt"); - attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(11); - } - - [Fact] - public async Task Message_with_an_image_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885654862656843786") - ); - - var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); - - // Assert - message.GetProperty("content").GetString().Should().Be("Image attachment"); - - attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885654862430359613/bird-thumbnail.png" - ); - attachments.Single().GetProperty("fileName").GetString().Should().Be("bird-thumbnail.png"); - attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(466335); - } - - [Fact] - public async Task Message_with_a_video_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885655761919836171") - ); - - var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); - - // Assert - message.GetProperty("content").GetString().Should().Be("Video attachment"); - - attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885655761512968233/file_example_MP4_640_3MG.mp4" - ); - attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP4_640_3MG.mp4"); - attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(3114374); - } - - [Fact] - public async Task Message_with_an_audio_attachment_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.AttachmentTestCases, - Snowflake.Parse("885656175620808734") - ); - - var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); - - // Assert - message.GetProperty("content").GetString().Should().Be("Audio attachment"); - - attachments.Should().HaveCount(1); - attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( - "https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3" - ); - attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP3_1MG.mp3"); - attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(1087849); - } + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.AttachmentTestCases, + Snowflake.Parse("885656175620808734") + ); + + var attachments = message.GetProperty("attachments").EnumerateArray().ToArray(); + + // Assert + message.GetProperty("content").GetString().Should().Be("Audio attachment"); + + attachments.Should().HaveCount(1); + attachments.Single().GetProperty("url").GetString().Should().StartWithEquivalentOf( + "https://cdn.discordapp.com/attachments/885587741654536192/885656175348187146/file_example_MP3_1MG.mp3" + ); + attachments.Single().GetProperty("fileName").GetString().Should().Be("file_example_MP3_1MG.mp3"); + attachments.Single().GetProperty("fileSizeBytes").GetInt64().Should().Be(1087849); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/ContentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/ContentSpecs.cs index 7b98023..efce33c 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/ContentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/ContentSpecs.cs @@ -5,38 +5,37 @@ using DiscordChatExporter.Cli.Tests.TestData; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting +namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting; + +public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Messages_are_exported_correctly() { - [Fact] - public async Task Messages_are_exported_correctly() - { - // Act - var messages = await ExportWrapper.GetMessagesAsJsonAsync(ChannelIds.DateRangeTestCases); + // Act + var messages = await ExportWrapper.GetMessagesAsJsonAsync(ChannelIds.DateRangeTestCases); - // Assert - messages.Select(j => j.GetProperty("id").GetString()).Should().Equal( - "866674314627121232", - "866710679758045195", - "866732113319428096", - "868490009366396958", - "868505966528835604", - "868505969821364245", - "868505973294268457", - "885169254029213696" - ); + // Assert + messages.Select(j => j.GetProperty("id").GetString()).Should().Equal( + "866674314627121232", + "866710679758045195", + "866732113319428096", + "868490009366396958", + "868505966528835604", + "868505969821364245", + "868505973294268457", + "885169254029213696" + ); - messages.Select(j => j.GetProperty("content").GetString()).Should().Equal( - "Hello world", - "Goodbye world", - "Foo bar", - "Hurdle Durdle", - "One", - "Two", - "Three", - "Yeet" - ); - } + messages.Select(j => j.GetProperty("content").GetString()).Should().Equal( + "Hello world", + "Goodbye world", + "Foo bar", + "Hurdle Durdle", + "One", + "Two", + "Three", + "Yeet" + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/EmbedSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/EmbedSpecs.cs index 83e7d95..0192703 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/EmbedSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/EmbedSpecs.cs @@ -6,53 +6,52 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting +namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting; + +public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record EmbedSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Message_with_an_embed_is_rendered_correctly() { - [Fact] - public async Task Message_with_an_embed_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.EmbedTestCases, - Snowflake.Parse("866769910729146400") - ); + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.EmbedTestCases, + Snowflake.Parse("866769910729146400") + ); - var embed = message - .GetProperty("embeds") - .EnumerateArray() - .Single(); + var embed = message + .GetProperty("embeds") + .EnumerateArray() + .Single(); - var embedAuthor = embed.GetProperty("author"); - var embedThumbnail = embed.GetProperty("thumbnail"); - var embedFooter = embed.GetProperty("footer"); - var embedFields = embed.GetProperty("fields").EnumerateArray().ToArray(); + var embedAuthor = embed.GetProperty("author"); + var embedThumbnail = embed.GetProperty("thumbnail"); + var embedFooter = embed.GetProperty("footer"); + var embedFields = embed.GetProperty("fields").EnumerateArray().ToArray(); - // Assert - embed.GetProperty("title").GetString().Should().Be("Embed title"); - embed.GetProperty("url").GetString().Should().Be("https://example.com"); - embed.GetProperty("timestamp").GetString().Should().Be("2021-07-14T21:00:00+00:00"); - embed.GetProperty("description").GetString().Should().Be("**Embed** _description_"); - embed.GetProperty("color").GetString().Should().Be("#58B9FF"); - embedAuthor.GetProperty("name").GetString().Should().Be("Embed author"); - embedAuthor.GetProperty("url").GetString().Should().Be("https://example.com/author"); - embedAuthor.GetProperty("iconUrl").GetString().Should().NotBeNullOrWhiteSpace(); - embedThumbnail.GetProperty("url").GetString().Should().NotBeNullOrWhiteSpace(); - embedThumbnail.GetProperty("width").GetInt32().Should().Be(120); - embedThumbnail.GetProperty("height").GetInt32().Should().Be(120); - embedFooter.GetProperty("text").GetString().Should().Be("Embed footer"); - embedFooter.GetProperty("iconUrl").GetString().Should().NotBeNullOrWhiteSpace(); - embedFields.Should().HaveCount(3); - embedFields[0].GetProperty("name").GetString().Should().Be("Field 1"); - embedFields[0].GetProperty("value").GetString().Should().Be("Value 1"); - embedFields[0].GetProperty("isInline").GetBoolean().Should().BeTrue(); - embedFields[1].GetProperty("name").GetString().Should().Be("Field 2"); - embedFields[1].GetProperty("value").GetString().Should().Be("Value 2"); - embedFields[1].GetProperty("isInline").GetBoolean().Should().BeTrue(); - embedFields[2].GetProperty("name").GetString().Should().Be("Field 3"); - embedFields[2].GetProperty("value").GetString().Should().Be("Value 3"); - embedFields[2].GetProperty("isInline").GetBoolean().Should().BeTrue(); - } + // Assert + embed.GetProperty("title").GetString().Should().Be("Embed title"); + embed.GetProperty("url").GetString().Should().Be("https://example.com"); + embed.GetProperty("timestamp").GetString().Should().Be("2021-07-14T21:00:00+00:00"); + embed.GetProperty("description").GetString().Should().Be("**Embed** _description_"); + embed.GetProperty("color").GetString().Should().Be("#58B9FF"); + embedAuthor.GetProperty("name").GetString().Should().Be("Embed author"); + embedAuthor.GetProperty("url").GetString().Should().Be("https://example.com/author"); + embedAuthor.GetProperty("iconUrl").GetString().Should().NotBeNullOrWhiteSpace(); + embedThumbnail.GetProperty("url").GetString().Should().NotBeNullOrWhiteSpace(); + embedThumbnail.GetProperty("width").GetInt32().Should().Be(120); + embedThumbnail.GetProperty("height").GetInt32().Should().Be(120); + embedFooter.GetProperty("text").GetString().Should().Be("Embed footer"); + embedFooter.GetProperty("iconUrl").GetString().Should().NotBeNullOrWhiteSpace(); + embedFields.Should().HaveCount(3); + embedFields[0].GetProperty("name").GetString().Should().Be("Field 1"); + embedFields[0].GetProperty("value").GetString().Should().Be("Value 1"); + embedFields[0].GetProperty("isInline").GetBoolean().Should().BeTrue(); + embedFields[1].GetProperty("name").GetString().Should().Be("Field 2"); + embedFields[1].GetProperty("value").GetString().Should().Be("Value 2"); + embedFields[1].GetProperty("isInline").GetBoolean().Should().BeTrue(); + embedFields[2].GetProperty("name").GetString().Should().Be("Field 3"); + embedFields[2].GetProperty("value").GetString().Should().Be("Value 3"); + embedFields[2].GetProperty("isInline").GetBoolean().Should().BeTrue(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs index e2d5cf0..dcd2443 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/JsonWriting/MentionSpecs.cs @@ -6,66 +6,65 @@ using DiscordChatExporter.Core.Discord; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting +namespace DiscordChatExporter.Cli.Tests.Specs.JsonWriting; + +public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record MentionSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task User_mention_is_rendered_correctly() { - [Fact] - public async Task User_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866458840245076028") - ); + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866458840245076028") + ); - // Assert - message.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz"); + // Assert + message.GetProperty("content").GetString().Should().Be("User mention: @Tyrrrz"); - message - .GetProperty("mentions") - .EnumerateArray() - .Select(j => j.GetProperty("id").GetString()) - .Should().Contain("128178626683338752"); - } + message + .GetProperty("mentions") + .EnumerateArray() + .Select(j => j.GetProperty("id").GetString()) + .Should().Contain("128178626683338752"); + } - [Fact] - public async Task Text_channel_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866459040480624680") - ); + [Fact] + public async Task Text_channel_mention_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866459040480624680") + ); - // Assert - message.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests"); - } + // Assert + message.GetProperty("content").GetString().Should().Be("Text channel mention: #mention-tests"); + } - [Fact] - public async Task Voice_channel_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866459175462633503") - ); + [Fact] + public async Task Voice_channel_mention_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866459175462633503") + ); - // Assert - message.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]"); - } + // Assert + message.GetProperty("content").GetString().Should().Be("Voice channel mention: #chaos-vc [voice]"); + } - [Fact] - public async Task Role_mention_is_rendered_correctly() - { - // Act - var message = await ExportWrapper.GetMessageAsJsonAsync( - ChannelIds.MentionTestCases, - Snowflake.Parse("866459254693429258") - ); + [Fact] + public async Task Role_mention_is_rendered_correctly() + { + // Act + var message = await ExportWrapper.GetMessageAsJsonAsync( + ChannelIds.MentionTestCases, + Snowflake.Parse("866459254693429258") + ); - // Assert - message.GetProperty("content").GetString().Should().Be("Role mention: @Role 1"); - } + // Assert + message.GetProperty("content").GetString().Should().Be("Role mention: @Role 1"); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs index 4fc363a..f18eccf 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/PartitioningSpecs.cs @@ -10,58 +10,57 @@ using DiscordChatExporter.Core.Exporting.Partitioning; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs +namespace DiscordChatExporter.Cli.Tests.Specs; + +public record PartitioningSpecs(TempOutputFixture TempOutput) : IClassFixture { - public record PartitioningSpecs(TempOutputFixture TempOutput) : IClassFixture + [Fact] + public async Task Messages_partitioned_by_count_are_split_into_multiple_files_correctly() { - [Fact] - public async Task Messages_partitioned_by_count_are_split_into_multiple_files_correctly() + // Arrange + var filePath = TempOutput.GetTempFilePath(); + var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath); + var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory(); + + // Act + await new ExportChannelsCommand { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath); - var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory(); + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.DateRangeTestCases }, + ExportFormat = ExportFormat.HtmlDark, + OutputPath = filePath, + PartitionLimit = PartitionLimit.Parse("3") + }.ExecuteAsync(new FakeConsole()); - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.DateRangeTestCases }, - ExportFormat = ExportFormat.HtmlDark, - OutputPath = filePath, - PartitionLimit = PartitionLimit.Parse("3") - }.ExecuteAsync(new FakeConsole()); + // Assert + Directory.EnumerateFiles(dirPath, fileNameWithoutExt + "*") + .Should() + .HaveCount(3); + } - // Assert - Directory.EnumerateFiles(dirPath, fileNameWithoutExt + "*") - .Should() - .HaveCount(3); - } + [Fact] + public async Task Messages_partitioned_by_file_size_are_split_into_multiple_files_correctly() + { + // Arrange + var filePath = TempOutput.GetTempFilePath(); + var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath); + var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory(); - [Fact] - public async Task Messages_partitioned_by_file_size_are_split_into_multiple_files_correctly() + // Act + await new ExportChannelsCommand { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - var fileNameWithoutExt = Path.GetFileNameWithoutExtension(filePath); - var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory(); - - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.DateRangeTestCases }, - ExportFormat = ExportFormat.HtmlDark, - OutputPath = filePath, - PartitionLimit = PartitionLimit.Parse("20kb") - }.ExecuteAsync(new FakeConsole()); + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.DateRangeTestCases }, + ExportFormat = ExportFormat.HtmlDark, + OutputPath = filePath, + PartitionLimit = PartitionLimit.Parse("20kb") + }.ExecuteAsync(new FakeConsole()); - // Assert - Directory.EnumerateFiles(dirPath, fileNameWithoutExt + "*") - .Should() - .HaveCount(2); - } + // Assert + Directory.EnumerateFiles(dirPath, fileNameWithoutExt + "*") + .Should() + .HaveCount(2); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/PlainTextWriting/ContentSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/PlainTextWriting/ContentSpecs.cs index 3c18e6a..8a03e1a 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/PlainTextWriting/ContentSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/PlainTextWriting/ContentSpecs.cs @@ -4,28 +4,27 @@ using DiscordChatExporter.Cli.Tests.TestData; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs.PlainTextWriting +namespace DiscordChatExporter.Cli.Tests.Specs.PlainTextWriting; + +public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture { - public record ContentSpecs(ExportWrapperFixture ExportWrapper) : IClassFixture + [Fact] + public async Task Messages_are_exported_correctly() { - [Fact] - public async Task Messages_are_exported_correctly() - { - // Act - var document = await ExportWrapper.ExportAsPlainTextAsync(ChannelIds.DateRangeTestCases); + // Act + var document = await ExportWrapper.ExportAsPlainTextAsync(ChannelIds.DateRangeTestCases); - // Assert - document.Should().ContainAll( - "Tyrrrz#5447", - "Hello world", - "Goodbye world", - "Foo bar", - "Hurdle Durdle", - "One", - "Two", - "Three", - "Yeet" - ); - } + // Assert + document.Should().ContainAll( + "Tyrrrz#5447", + "Hello world", + "Goodbye world", + "Foo bar", + "Hurdle Durdle", + "One", + "Two", + "Three", + "Yeet" + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Specs/SelfContainedSpecs.cs b/DiscordChatExporter.Cli.Tests/Specs/SelfContainedSpecs.cs index 568d6b6..21f0454 100644 --- a/DiscordChatExporter.Cli.Tests/Specs/SelfContainedSpecs.cs +++ b/DiscordChatExporter.Cli.Tests/Specs/SelfContainedSpecs.cs @@ -11,39 +11,38 @@ using DiscordChatExporter.Core.Exporting; using FluentAssertions; using Xunit; -namespace DiscordChatExporter.Cli.Tests.Specs +namespace DiscordChatExporter.Cli.Tests.Specs; + +public record SelfContainedSpecs(TempOutputFixture TempOutput) : IClassFixture { - public record SelfContainedSpecs(TempOutputFixture TempOutput) : IClassFixture + [Fact] + public async Task Messages_in_self_contained_export_only_reference_local_file_resources() { - [Fact] - public async Task Messages_in_self_contained_export_only_reference_local_file_resources() - { - // Arrange - var filePath = TempOutput.GetTempFilePath(); - var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory(); + // Arrange + var filePath = TempOutput.GetTempFilePath(); + var dirPath = Path.GetDirectoryName(filePath) ?? Directory.GetCurrentDirectory(); - // Act - await new ExportChannelsCommand - { - TokenValue = Secrets.DiscordToken, - IsBotToken = Secrets.IsDiscordTokenBot, - ChannelIds = new[] { ChannelIds.SelfContainedTestCases }, - ExportFormat = ExportFormat.HtmlDark, - OutputPath = filePath, - ShouldDownloadMedia = true - }.ExecuteAsync(new FakeConsole()); + // Act + await new ExportChannelsCommand + { + TokenValue = Secrets.DiscordToken, + IsBotToken = Secrets.IsDiscordTokenBot, + ChannelIds = new[] { ChannelIds.SelfContainedTestCases }, + ExportFormat = ExportFormat.HtmlDark, + OutputPath = filePath, + ShouldDownloadMedia = true + }.ExecuteAsync(new FakeConsole()); - var data = await File.ReadAllTextAsync(filePath); - var document = Html.Parse(data); + var data = await File.ReadAllTextAsync(filePath); + var document = Html.Parse(data); - // Assert - document - .QuerySelectorAll("body [src]") - .Select(e => e.GetAttribute("src")!) - .Select(f => Path.GetFullPath(f, dirPath)) - .All(File.Exists) - .Should() - .BeTrue(); - } + // Assert + document + .QuerySelectorAll("body [src]") + .Select(e => e.GetAttribute("src")!) + .Select(f => Path.GetFullPath(f, dirPath)) + .All(File.Exists) + .Should() + .BeTrue(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs b/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs index f071c1c..21dcfae 100644 --- a/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs +++ b/DiscordChatExporter.Cli.Tests/TestData/ChannelIds.cs @@ -1,21 +1,20 @@ using DiscordChatExporter.Core.Discord; -namespace DiscordChatExporter.Cli.Tests.TestData +namespace DiscordChatExporter.Cli.Tests.TestData; + +public static class ChannelIds { - public static class ChannelIds - { - public static Snowflake AttachmentTestCases { get; } = Snowflake.Parse("885587741654536192"); + public static Snowflake AttachmentTestCases { get; } = Snowflake.Parse("885587741654536192"); - public static Snowflake DateRangeTestCases { get; } = Snowflake.Parse("866674248747319326"); + public static Snowflake DateRangeTestCases { get; } = Snowflake.Parse("866674248747319326"); - public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687"); + public static Snowflake EmbedTestCases { get; } = Snowflake.Parse("866472452459462687"); - public static Snowflake FilterTestCases { get; } = Snowflake.Parse("866744075033641020"); + public static Snowflake FilterTestCases { get; } = Snowflake.Parse("866744075033641020"); - public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794"); + public static Snowflake MentionTestCases { get; } = Snowflake.Parse("866458801389174794"); - public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052"); + public static Snowflake ReplyTestCases { get; } = Snowflake.Parse("866459871934677052"); - public static Snowflake SelfContainedTestCases { get; } = Snowflake.Parse("887441432678379560"); - } + public static Snowflake SelfContainedTestCases { get; } = Snowflake.Parse("887441432678379560"); } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Utils/DirectoryEx.cs b/DiscordChatExporter.Cli.Tests/Utils/DirectoryEx.cs index f525143..42cd899 100644 --- a/DiscordChatExporter.Cli.Tests/Utils/DirectoryEx.cs +++ b/DiscordChatExporter.Cli.Tests/Utils/DirectoryEx.cs @@ -1,24 +1,23 @@ using System.IO; -namespace DiscordChatExporter.Cli.Tests.Utils +namespace DiscordChatExporter.Cli.Tests.Utils; + +internal static class DirectoryEx { - internal static class DirectoryEx + public static void DeleteIfExists(string dirPath, bool recursive = true) { - public static void DeleteIfExists(string dirPath, bool recursive = true) + try { - try - { - Directory.Delete(dirPath, recursive); - } - catch (DirectoryNotFoundException) - { - } + Directory.Delete(dirPath, recursive); } - - public static void Reset(string dirPath) + catch (DirectoryNotFoundException) { - DeleteIfExists(dirPath); - Directory.CreateDirectory(dirPath); } } + + public static void Reset(string dirPath) + { + DeleteIfExists(dirPath); + Directory.CreateDirectory(dirPath); + } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli.Tests/Utils/Html.cs b/DiscordChatExporter.Cli.Tests/Utils/Html.cs index 4f9ca13..1d620f4 100644 --- a/DiscordChatExporter.Cli.Tests/Utils/Html.cs +++ b/DiscordChatExporter.Cli.Tests/Utils/Html.cs @@ -1,12 +1,11 @@ using AngleSharp.Html.Dom; using AngleSharp.Html.Parser; -namespace DiscordChatExporter.Cli.Tests.Utils +namespace DiscordChatExporter.Cli.Tests.Utils; + +internal static class Html { - internal static class Html - { - private static readonly IHtmlParser Parser = new HtmlParser(); + private static readonly IHtmlParser Parser = new HtmlParser(); - public static IHtmlDocument Parse(string source) => Parser.ParseDocument(source); - } + public static IHtmlDocument Parse(string source) => Parser.ParseDocument(source); } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs index 95c8647..f0e68bb 100644 --- a/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs +++ b/DiscordChatExporter.Cli/Commands/Base/ExportCommandBase.cs @@ -16,141 +16,140 @@ using DiscordChatExporter.Core.Exporting.Filtering; using DiscordChatExporter.Core.Exporting.Partitioning; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Cli.Commands.Base +namespace DiscordChatExporter.Cli.Commands.Base; + +public abstract class ExportCommandBase : TokenCommandBase { - public abstract class ExportCommandBase : TokenCommandBase - { - [CommandOption("output", 'o', Description = "Output file or directory path.")] - public string OutputPath { get; init; } = Directory.GetCurrentDirectory(); + [CommandOption("output", 'o', Description = "Output file or directory path.")] + public string OutputPath { get; init; } = Directory.GetCurrentDirectory(); - [CommandOption("format", 'f', Description = "Export format.")] - public ExportFormat ExportFormat { get; init; } = ExportFormat.HtmlDark; + [CommandOption("format", 'f', Description = "Export format.")] + public ExportFormat ExportFormat { get; init; } = ExportFormat.HtmlDark; - [CommandOption("after", Description = "Only include messages sent after this date or message ID.")] - public Snowflake? After { get; init; } + [CommandOption("after", Description = "Only include messages sent after this date or message ID.")] + public Snowflake? After { get; init; } - [CommandOption("before", Description = "Only include messages sent before this date or message ID.")] - public Snowflake? Before { get; init; } + [CommandOption("before", Description = "Only include messages sent before this date or message ID.")] + public Snowflake? Before { get; init; } - [CommandOption("partition", 'p', Description = "Split output into partitions, each limited to this number of messages (e.g. '100') or file size (e.g. '10mb').")] - public PartitionLimit PartitionLimit { get; init; } = PartitionLimit.Null; + [CommandOption("partition", 'p', Description = "Split output into partitions, each limited to this number of messages (e.g. '100') or file size (e.g. '10mb').")] + public PartitionLimit PartitionLimit { get; init; } = PartitionLimit.Null; - [CommandOption("filter", Description = "Only include messages that satisfy this filter (e.g. 'from:foo#1234' or 'has:image').")] - public MessageFilter MessageFilter { get; init; } = MessageFilter.Null; + [CommandOption("filter", Description = "Only include messages that satisfy this filter (e.g. 'from:foo#1234' or 'has:image').")] + public MessageFilter MessageFilter { get; init; } = MessageFilter.Null; - [CommandOption("parallel", Description = "Limits how many channels can be exported in parallel.")] - public int ParallelLimit { get; init; } = 1; + [CommandOption("parallel", Description = "Limits how many channels can be exported in parallel.")] + public int ParallelLimit { get; init; } = 1; - [CommandOption("media", Description = "Download referenced media content.")] - public bool ShouldDownloadMedia { get; init; } + [CommandOption("media", Description = "Download referenced media content.")] + public bool ShouldDownloadMedia { get; init; } - [CommandOption("reuse-media", Description = "Reuse already existing media content to skip redundant downloads.")] - public bool ShouldReuseMedia { get; init; } + [CommandOption("reuse-media", Description = "Reuse already existing media content to skip redundant downloads.")] + public bool ShouldReuseMedia { get; init; } - [CommandOption("dateformat", Description = "Format used when writing dates.")] - public string DateFormat { get; init; } = "dd-MMM-yy hh:mm tt"; + [CommandOption("dateformat", Description = "Format used when writing dates.")] + public string DateFormat { get; init; } = "dd-MMM-yy hh:mm tt"; - private ChannelExporter? _channelExporter; - protected ChannelExporter Exporter => _channelExporter ??= new ChannelExporter(Discord); + private ChannelExporter? _channelExporter; + protected ChannelExporter Exporter => _channelExporter ??= new ChannelExporter(Discord); - protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList channels) - { - var cancellationToken = console.RegisterCancellationHandler(); + protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList channels) + { + var cancellationToken = console.RegisterCancellationHandler(); - if (ShouldReuseMedia && !ShouldDownloadMedia) - { - throw new CommandException("Option --reuse-media cannot be used without --media."); - } + if (ShouldReuseMedia && !ShouldDownloadMedia) + { + throw new CommandException("Option --reuse-media cannot be used without --media."); + } - var errors = new ConcurrentDictionary(); + var errors = new ConcurrentDictionary(); - // Export - await console.Output.WriteLineAsync($"Exporting {channels.Count} channel(s)..."); - await console.CreateProgressTicker().StartAsync(async progressContext => + // Export + await console.Output.WriteLineAsync($"Exporting {channels.Count} channel(s)..."); + await console.CreateProgressTicker().StartAsync(async progressContext => + { + await channels.ParallelForEachAsync(async channel => { - await channels.ParallelForEachAsync(async channel => + try { - try + await progressContext.StartTaskAsync($"{channel.Category.Name} / {channel.Name}", async progress => { - await progressContext.StartTaskAsync($"{channel.Category.Name} / {channel.Name}", async progress => - { - var guild = await Discord.GetGuildAsync(channel.GuildId, cancellationToken); - - var request = new ExportRequest( - guild, - channel, - OutputPath, - ExportFormat, - After, - Before, - PartitionLimit, - MessageFilter, - ShouldDownloadMedia, - ShouldReuseMedia, - DateFormat - ); - - await Exporter.ExportChannelAsync(request, progress, cancellationToken); - }); - } - catch (DiscordChatExporterException ex) when (!ex.IsFatal) - { - errors[channel] = ex.Message; - } - }, Math.Max(ParallelLimit, 1), cancellationToken); - }); + var guild = await Discord.GetGuildAsync(channel.GuildId, cancellationToken); + + var request = new ExportRequest( + guild, + channel, + OutputPath, + ExportFormat, + After, + Before, + PartitionLimit, + MessageFilter, + ShouldDownloadMedia, + ShouldReuseMedia, + DateFormat + ); + + await Exporter.ExportChannelAsync(request, progress, cancellationToken); + }); + } + catch (DiscordChatExporterException ex) when (!ex.IsFatal) + { + errors[channel] = ex.Message; + } + }, Math.Max(ParallelLimit, 1), cancellationToken); + }); + + // Print result + using (console.WithForegroundColor(ConsoleColor.White)) + { + await console.Output.WriteLineAsync( + $"Successfully exported {channels.Count - errors.Count} channel(s)." + ); + } + + // Print errors + if (errors.Any()) + { + await console.Output.WriteLineAsync(); - // Print result - using (console.WithForegroundColor(ConsoleColor.White)) + using (console.WithForegroundColor(ConsoleColor.Red)) { await console.Output.WriteLineAsync( - $"Successfully exported {channels.Count - errors.Count} channel(s)." + $"Failed to export {errors.Count} channel(s):" ); } - // Print errors - if (errors.Any()) + foreach (var (channel, error) in errors) { - await console.Output.WriteLineAsync(); + await console.Output.WriteAsync($"{channel.Category.Name} / {channel.Name}: "); using (console.WithForegroundColor(ConsoleColor.Red)) - { - await console.Output.WriteLineAsync( - $"Failed to export {errors.Count} channel(s):" - ); - } - - foreach (var (channel, error) in errors) - { - await console.Output.WriteAsync($"{channel.Category.Name} / {channel.Name}: "); - - using (console.WithForegroundColor(ConsoleColor.Red)) - await console.Output.WriteLineAsync(error); - } - - await console.Output.WriteLineAsync(); + await console.Output.WriteLineAsync(error); } - // Fail the command only if ALL channels failed to export. - // Having some of the channels fail to export is expected. - if (errors.Count >= channels.Count) - { - throw new CommandException("Export failed."); - } + await console.Output.WriteLineAsync(); } - protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList channelIds) + // Fail the command only if ALL channels failed to export. + // Having some of the channels fail to export is expected. + if (errors.Count >= channels.Count) { - var cancellationToken = console.RegisterCancellationHandler(); - var channels = new List(); + throw new CommandException("Export failed."); + } + } - foreach (var channelId in channelIds) - { - var channel = await Discord.GetChannelAsync(channelId, cancellationToken); - channels.Add(channel); - } + protected async ValueTask ExecuteAsync(IConsole console, IReadOnlyList channelIds) + { + var cancellationToken = console.RegisterCancellationHandler(); + var channels = new List(); - await ExecuteAsync(console, channels); + foreach (var channelId in channelIds) + { + var channel = await Discord.GetChannelAsync(channelId, cancellationToken); + channels.Add(channel); } + + await ExecuteAsync(console, channels); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/Base/TokenCommandBase.cs b/DiscordChatExporter.Cli/Commands/Base/TokenCommandBase.cs index b68808e..baa3305 100644 --- a/DiscordChatExporter.Cli/Commands/Base/TokenCommandBase.cs +++ b/DiscordChatExporter.Cli/Commands/Base/TokenCommandBase.cs @@ -4,27 +4,26 @@ using CliFx.Attributes; using CliFx.Infrastructure; using DiscordChatExporter.Core.Discord; -namespace DiscordChatExporter.Cli.Commands.Base +namespace DiscordChatExporter.Cli.Commands.Base; + +public abstract class TokenCommandBase : ICommand { - public abstract class TokenCommandBase : ICommand - { - [CommandOption("token", 't', IsRequired = true, EnvironmentVariable = "DISCORD_TOKEN", Description = "Authentication token.")] - public string TokenValue { get; init; } = ""; + [CommandOption("token", 't', IsRequired = true, EnvironmentVariable = "DISCORD_TOKEN", Description = "Authentication token.")] + public string TokenValue { get; init; } = ""; - [CommandOption("bot", 'b', EnvironmentVariable = "DISCORD_TOKEN_BOT", Description = "Authenticate as a bot.")] - public bool IsBotToken { get; init; } + [CommandOption("bot", 'b', EnvironmentVariable = "DISCORD_TOKEN_BOT", Description = "Authenticate as a bot.")] + public bool IsBotToken { get; init; } - private AuthToken? _authToken; - private AuthToken AuthToken => _authToken ??= new AuthToken( - IsBotToken - ? AuthTokenKind.Bot - : AuthTokenKind.User, - TokenValue - ); + private AuthToken? _authToken; + private AuthToken AuthToken => _authToken ??= new AuthToken( + IsBotToken + ? AuthTokenKind.Bot + : AuthTokenKind.User, + TokenValue + ); - private DiscordClient? _discordClient; - protected DiscordClient Discord => _discordClient ??= new DiscordClient(AuthToken); + private DiscordClient? _discordClient; + protected DiscordClient Discord => _discordClient ??= new DiscordClient(AuthToken); - public abstract ValueTask ExecuteAsync(IConsole console); - } + public abstract ValueTask ExecuteAsync(IConsole console); } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs b/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs index 842e12b..4ec6343 100644 --- a/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs +++ b/DiscordChatExporter.Cli/Commands/ExportAllCommand.cs @@ -5,37 +5,36 @@ using CliFx.Infrastructure; using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("exportall", Description = "Export all accessible channels.")] +public class ExportAllCommand : ExportCommandBase { - [Command("exportall", Description = "Export all accessible channels.")] - public class ExportAllCommand : ExportCommandBase + [CommandOption("include-dm", Description = "Include direct message channels.")] + public bool IncludeDirectMessages { get; init; } = true; + + public override async ValueTask ExecuteAsync(IConsole console) { - [CommandOption("include-dm", Description = "Include direct message channels.")] - public bool IncludeDirectMessages { get; init; } = true; + var cancellationToken = console.RegisterCancellationHandler(); + var channels = new List(); - public override async ValueTask ExecuteAsync(IConsole console) + await console.Output.WriteLineAsync("Fetching channels..."); + await foreach (var guild in Discord.GetUserGuildsAsync(cancellationToken)) { - var cancellationToken = console.RegisterCancellationHandler(); - var channels = new List(); + // Skip DMs if instructed to + if (!IncludeDirectMessages && guild.Id == Guild.DirectMessages.Id) + continue; - await console.Output.WriteLineAsync("Fetching channels..."); - await foreach (var guild in Discord.GetUserGuildsAsync(cancellationToken)) + await foreach (var channel in Discord.GetGuildChannelsAsync(guild.Id, cancellationToken)) { - // Skip DMs if instructed to - if (!IncludeDirectMessages && guild.Id == Guild.DirectMessages.Id) + // Skip non-text channels + if (!channel.IsTextChannel) continue; - await foreach (var channel in Discord.GetGuildChannelsAsync(guild.Id, cancellationToken)) - { - // Skip non-text channels - if (!channel.IsTextChannel) - continue; - - channels.Add(channel); - } + channels.Add(channel); } - - await base.ExecuteAsync(console, channels); } + + await base.ExecuteAsync(console, channels); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs index 3fe02b2..17c12d1 100644 --- a/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs +++ b/DiscordChatExporter.Cli/Commands/ExportChannelsCommand.cs @@ -6,16 +6,15 @@ using CliFx.Infrastructure; using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Discord; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("export", Description = "Export one or multiple channels.")] +public class ExportChannelsCommand : ExportCommandBase { - [Command("export", Description = "Export one or multiple channels.")] - public class ExportChannelsCommand : ExportCommandBase - { - // TODO: change this to plural (breaking change) - [CommandOption("channel", 'c', IsRequired = true, Description = "Channel ID(s).")] - public IReadOnlyList ChannelIds { get; init; } = Array.Empty(); + // TODO: change this to plural (breaking change) + [CommandOption("channel", 'c', IsRequired = true, Description = "Channel ID(s).")] + public IReadOnlyList ChannelIds { get; init; } = Array.Empty(); - public override async ValueTask ExecuteAsync(IConsole console) => - await base.ExecuteAsync(console, ChannelIds); - } + public override async ValueTask ExecuteAsync(IConsole console) => + await base.ExecuteAsync(console, ChannelIds); } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs b/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs index 2ff6cd6..4d4b408 100644 --- a/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs +++ b/DiscordChatExporter.Cli/Commands/ExportDirectMessagesCommand.cs @@ -6,20 +6,19 @@ using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("exportdm", Description = "Export all direct message channels.")] +public class ExportDirectMessagesCommand : ExportCommandBase { - [Command("exportdm", Description = "Export all direct message channels.")] - public class ExportDirectMessagesCommand : ExportCommandBase + public override async ValueTask ExecuteAsync(IConsole console) { - public override async ValueTask ExecuteAsync(IConsole console) - { - var cancellationToken = console.RegisterCancellationHandler(); + var cancellationToken = console.RegisterCancellationHandler(); - await console.Output.WriteLineAsync("Fetching channels..."); - var channels = await Discord.GetGuildChannelsAsync(Guild.DirectMessages.Id, cancellationToken); - var textChannels = channels.Where(c => c.IsTextChannel).ToArray(); + await console.Output.WriteLineAsync("Fetching channels..."); + var channels = await Discord.GetGuildChannelsAsync(Guild.DirectMessages.Id, cancellationToken); + var textChannels = channels.Where(c => c.IsTextChannel).ToArray(); - await base.ExecuteAsync(console, textChannels); - } + await base.ExecuteAsync(console, textChannels); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs b/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs index 2f14cb0..edcb65d 100644 --- a/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs +++ b/DiscordChatExporter.Cli/Commands/ExportGuildCommand.cs @@ -6,23 +6,22 @@ using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("exportguild", Description = "Export all channels within specified guild.")] +public class ExportGuildCommand : ExportCommandBase { - [Command("exportguild", Description = "Export all channels within specified guild.")] - public class ExportGuildCommand : ExportCommandBase - { - [CommandOption("guild", 'g', IsRequired = true, Description = "Guild ID.")] - public Snowflake GuildId { get; init; } + [CommandOption("guild", 'g', IsRequired = true, Description = "Guild ID.")] + public Snowflake GuildId { get; init; } - public override async ValueTask ExecuteAsync(IConsole console) - { - var cancellationToken = console.RegisterCancellationHandler(); + public override async ValueTask ExecuteAsync(IConsole console) + { + var cancellationToken = console.RegisterCancellationHandler(); - await console.Output.WriteLineAsync("Fetching channels..."); - var channels = await Discord.GetGuildChannelsAsync(GuildId, cancellationToken); - var textChannels = channels.Where(c => c.IsTextChannel).ToArray(); + await console.Output.WriteLineAsync("Fetching channels..."); + var channels = await Discord.GetGuildChannelsAsync(GuildId, cancellationToken); + var textChannels = channels.Where(c => c.IsTextChannel).ToArray(); - await base.ExecuteAsync(console, textChannels); - } + await base.ExecuteAsync(console, textChannels); } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs index df5e573..75fb62c 100644 --- a/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs +++ b/DiscordChatExporter.Cli/Commands/GetChannelsCommand.cs @@ -7,39 +7,38 @@ using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("channels", Description = "Get the list of channels in a guild.")] +public class GetChannelsCommand : TokenCommandBase { - [Command("channels", Description = "Get the list of channels in a guild.")] - public class GetChannelsCommand : TokenCommandBase - { - [CommandOption("guild", 'g', IsRequired = true, Description = "Guild ID.")] - public Snowflake GuildId { get; init; } + [CommandOption("guild", 'g', IsRequired = true, Description = "Guild ID.")] + public Snowflake GuildId { get; init; } - public override async ValueTask ExecuteAsync(IConsole console) - { - var cancellationToken = console.RegisterCancellationHandler(); + public override async ValueTask ExecuteAsync(IConsole console) + { + var cancellationToken = console.RegisterCancellationHandler(); - var channels = await Discord.GetGuildChannelsAsync(GuildId, cancellationToken); + var channels = await Discord.GetGuildChannelsAsync(GuildId, cancellationToken); - var textChannels = channels - .Where(c => c.IsTextChannel) - .OrderBy(c => c.Category.Position) - .ThenBy(c => c.Name) - .ToArray(); + var textChannels = channels + .Where(c => c.IsTextChannel) + .OrderBy(c => c.Category.Position) + .ThenBy(c => c.Name) + .ToArray(); - foreach (var channel in textChannels) - { - // Channel ID - await console.Output.WriteAsync(channel.Id.ToString()); + foreach (var channel in textChannels) + { + // Channel ID + await console.Output.WriteAsync(channel.Id.ToString()); - // Separator - using (console.WithForegroundColor(ConsoleColor.DarkGray)) - await console.Output.WriteAsync(" | "); + // Separator + using (console.WithForegroundColor(ConsoleColor.DarkGray)) + await console.Output.WriteAsync(" | "); - // Channel category / name - using (console.WithForegroundColor(ConsoleColor.White)) - await console.Output.WriteLineAsync($"{channel.Category.Name} / {channel.Name}"); - } + // Channel category / name + using (console.WithForegroundColor(ConsoleColor.White)) + await console.Output.WriteLineAsync($"{channel.Category.Name} / {channel.Name}"); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/GetDirectMessageChannelsCommand.cs b/DiscordChatExporter.Cli/Commands/GetDirectMessageChannelsCommand.cs index b802685..e50a825 100644 --- a/DiscordChatExporter.Cli/Commands/GetDirectMessageChannelsCommand.cs +++ b/DiscordChatExporter.Cli/Commands/GetDirectMessageChannelsCommand.cs @@ -7,36 +7,35 @@ using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("dm", Description = "Get the list of direct message channels.")] +public class GetDirectMessageChannelsCommand : TokenCommandBase { - [Command("dm", Description = "Get the list of direct message channels.")] - public class GetDirectMessageChannelsCommand : TokenCommandBase + public override async ValueTask ExecuteAsync(IConsole console) { - public override async ValueTask ExecuteAsync(IConsole console) - { - var cancellationToken = console.RegisterCancellationHandler(); + var cancellationToken = console.RegisterCancellationHandler(); - var channels = await Discord.GetGuildChannelsAsync(Guild.DirectMessages.Id, cancellationToken); + var channels = await Discord.GetGuildChannelsAsync(Guild.DirectMessages.Id, cancellationToken); - var textChannels = channels - .Where(c => c.IsTextChannel) - .OrderBy(c => c.Category.Position) - .ThenBy(c => c.Name) - .ToArray(); + var textChannels = channels + .Where(c => c.IsTextChannel) + .OrderBy(c => c.Category.Position) + .ThenBy(c => c.Name) + .ToArray(); - foreach (var channel in textChannels) - { - // Channel ID - await console.Output.WriteAsync(channel.Id.ToString()); + foreach (var channel in textChannels) + { + // Channel ID + await console.Output.WriteAsync(channel.Id.ToString()); - // Separator - using (console.WithForegroundColor(ConsoleColor.DarkGray)) - await console.Output.WriteAsync(" | "); + // Separator + using (console.WithForegroundColor(ConsoleColor.DarkGray)) + await console.Output.WriteAsync(" | "); - // Channel category / name - using (console.WithForegroundColor(ConsoleColor.White)) - await console.Output.WriteLineAsync($"{channel.Category.Name} / {channel.Name}"); - } + // Channel category / name + using (console.WithForegroundColor(ConsoleColor.White)) + await console.Output.WriteLineAsync($"{channel.Category.Name} / {channel.Name}"); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs b/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs index fd65ecc..92fa041 100644 --- a/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs +++ b/DiscordChatExporter.Cli/Commands/GetGuildsCommand.cs @@ -6,30 +6,29 @@ using CliFx.Infrastructure; using DiscordChatExporter.Cli.Commands.Base; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("guilds", Description = "Get the list of accessible guilds.")] +public class GetGuildsCommand : TokenCommandBase { - [Command("guilds", Description = "Get the list of accessible guilds.")] - public class GetGuildsCommand : TokenCommandBase + public override async ValueTask ExecuteAsync(IConsole console) { - public override async ValueTask ExecuteAsync(IConsole console) - { - var cancellationToken = console.RegisterCancellationHandler(); + var cancellationToken = console.RegisterCancellationHandler(); - var guilds = await Discord.GetUserGuildsAsync(cancellationToken); + var guilds = await Discord.GetUserGuildsAsync(cancellationToken); - foreach (var guild in guilds.OrderBy(g => g.Name)) - { - // Guild ID - await console.Output.WriteAsync(guild.Id.ToString()); + foreach (var guild in guilds.OrderBy(g => g.Name)) + { + // Guild ID + await console.Output.WriteAsync(guild.Id.ToString()); - // Separator - using (console.WithForegroundColor(ConsoleColor.DarkGray)) - await console.Output.WriteAsync(" | "); + // Separator + using (console.WithForegroundColor(ConsoleColor.DarkGray)) + await console.Output.WriteAsync(" | "); - // Guild name - using (console.WithForegroundColor(ConsoleColor.White)) - await console.Output.WriteLineAsync(guild.Name); - } + // Guild name + using (console.WithForegroundColor(ConsoleColor.White)) + await console.Output.WriteLineAsync(guild.Name); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Commands/GuideCommand.cs b/DiscordChatExporter.Cli/Commands/GuideCommand.cs index 5b49359..ead49b5 100644 --- a/DiscordChatExporter.Cli/Commands/GuideCommand.cs +++ b/DiscordChatExporter.Cli/Commands/GuideCommand.cs @@ -4,68 +4,67 @@ using CliFx; using CliFx.Attributes; using CliFx.Infrastructure; -namespace DiscordChatExporter.Cli.Commands +namespace DiscordChatExporter.Cli.Commands; + +[Command("guide", Description = "Explains how to obtain token, guild or channel ID.")] +public class GuideCommand : ICommand { - [Command("guide", Description = "Explains how to obtain token, guild or channel ID.")] - public class GuideCommand : ICommand + public ValueTask ExecuteAsync(IConsole console) { - public ValueTask ExecuteAsync(IConsole console) - { - // User token - using (console.WithForegroundColor(ConsoleColor.White)) - console.Output.WriteLine("To get user token:"); + // User token + using (console.WithForegroundColor(ConsoleColor.White)) + console.Output.WriteLine("To get user token:"); - console.Output.WriteLine(" 1. Open Discord"); - console.Output.WriteLine(" 2. Press Ctrl+Shift+I to show developer tools"); - console.Output.WriteLine(" 3. Press Ctrl+Shift+M to toggle device toolbar"); - console.Output.WriteLine(" 4. Navigate to the Application tab"); - console.Output.WriteLine(" 5. On the left, expand Local Storage and select https://discord.com"); - console.Output.WriteLine(" 6. Type \"token\" into the Filter box"); - console.Output.WriteLine(" 7. If the token key does not appear, press Ctrl+R to reload"); - console.Output.WriteLine(" 8. Copy the value of the token key"); - console.Output.WriteLine(" * Automating user accounts is technically against TOS, use at your own risk."); - console.Output.WriteLine(); + console.Output.WriteLine(" 1. Open Discord"); + console.Output.WriteLine(" 2. Press Ctrl+Shift+I to show developer tools"); + console.Output.WriteLine(" 3. Press Ctrl+Shift+M to toggle device toolbar"); + console.Output.WriteLine(" 4. Navigate to the Application tab"); + console.Output.WriteLine(" 5. On the left, expand Local Storage and select https://discord.com"); + console.Output.WriteLine(" 6. Type \"token\" into the Filter box"); + console.Output.WriteLine(" 7. If the token key does not appear, press Ctrl+R to reload"); + console.Output.WriteLine(" 8. Copy the value of the token key"); + console.Output.WriteLine(" * Automating user accounts is technically against TOS, use at your own risk."); + console.Output.WriteLine(); - // Bot token - using (console.WithForegroundColor(ConsoleColor.White)) - console.Output.WriteLine("To get bot token:"); + // Bot token + using (console.WithForegroundColor(ConsoleColor.White)) + console.Output.WriteLine("To get bot token:"); - console.Output.WriteLine(" 1. Go to Discord developer portal"); - console.Output.WriteLine(" 2. Open your application's settings"); - console.Output.WriteLine(" 3. Navigate to the Bot section on the left"); - console.Output.WriteLine(" 4. Under Token click Copy"); - console.Output.WriteLine(); + console.Output.WriteLine(" 1. Go to Discord developer portal"); + console.Output.WriteLine(" 2. Open your application's settings"); + console.Output.WriteLine(" 3. Navigate to the Bot section on the left"); + console.Output.WriteLine(" 4. Under Token click Copy"); + console.Output.WriteLine(); - // Guild or channel ID - using (console.WithForegroundColor(ConsoleColor.White)) - console.Output.WriteLine("To get guild ID or guild channel ID:"); + // Guild or channel ID + using (console.WithForegroundColor(ConsoleColor.White)) + console.Output.WriteLine("To get guild ID or guild channel ID:"); - console.Output.WriteLine(" 1. Open Discord"); - console.Output.WriteLine(" 2. Open Settings"); - console.Output.WriteLine(" 3. Go to Appearance section"); - console.Output.WriteLine(" 4. Enable Developer Mode"); - console.Output.WriteLine(" 5. Right click on the desired guild or channel and click Copy ID"); - console.Output.WriteLine(); + console.Output.WriteLine(" 1. Open Discord"); + console.Output.WriteLine(" 2. Open Settings"); + console.Output.WriteLine(" 3. Go to Appearance section"); + console.Output.WriteLine(" 4. Enable Developer Mode"); + console.Output.WriteLine(" 5. Right click on the desired guild or channel and click Copy ID"); + console.Output.WriteLine(); - // Direct message channel ID - using (console.WithForegroundColor(ConsoleColor.White)) - console.Output.WriteLine("To get direct message channel ID:"); + // Direct message channel ID + using (console.WithForegroundColor(ConsoleColor.White)) + console.Output.WriteLine("To get direct message channel ID:"); - console.Output.WriteLine(" 1. Open Discord"); - console.Output.WriteLine(" 2. Open the desired direct message channel"); - console.Output.WriteLine(" 3. Press Ctrl+Shift+I to show developer tools"); - console.Output.WriteLine(" 4. Navigate to the Console tab"); - console.Output.WriteLine(" 5. Type \"window.location.href\" and press Enter"); - console.Output.WriteLine(" 6. Copy the first long sequence of numbers inside the URL"); - console.Output.WriteLine(); + console.Output.WriteLine(" 1. Open Discord"); + console.Output.WriteLine(" 2. Open the desired direct message channel"); + console.Output.WriteLine(" 3. Press Ctrl+Shift+I to show developer tools"); + console.Output.WriteLine(" 4. Navigate to the Console tab"); + console.Output.WriteLine(" 5. Type \"window.location.href\" and press Enter"); + console.Output.WriteLine(" 6. Copy the first long sequence of numbers inside the URL"); + console.Output.WriteLine(); - // Wiki link - using (console.WithForegroundColor(ConsoleColor.White)) - console.Output.WriteLine("For more information, check out the wiki:"); - using (console.WithForegroundColor(ConsoleColor.DarkCyan)) - console.Output.WriteLine("https://github.com/Tyrrrz/DiscordChatExporter/wiki"); + // Wiki link + using (console.WithForegroundColor(ConsoleColor.White)) + console.Output.WriteLine("For more information, check out the wiki:"); + using (console.WithForegroundColor(ConsoleColor.DarkCyan)) + console.Output.WriteLine("https://github.com/Tyrrrz/DiscordChatExporter/wiki"); - return default; - } + return default; } } \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Program.cs b/DiscordChatExporter.Cli/Program.cs index 5dbbdee..b26d622 100644 --- a/DiscordChatExporter.Cli/Program.cs +++ b/DiscordChatExporter.Cli/Program.cs @@ -1,14 +1,6 @@ -using System.Threading.Tasks; -using CliFx; +using CliFx; -namespace DiscordChatExporter.Cli -{ - public static class Program - { - public static async Task Main(string[] args) => - await new CliApplicationBuilder() - .AddCommandsFromThisAssembly() - .Build() - .RunAsync(args); - } -} \ No newline at end of file +return await new CliApplicationBuilder() + .AddCommandsFromThisAssembly() + .Build() + .RunAsync(args); \ No newline at end of file diff --git a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs index 9a336b5..0d4963b 100644 --- a/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs +++ b/DiscordChatExporter.Cli/Utils/Extensions/ConsoleExtensions.cs @@ -3,49 +3,48 @@ using System.Threading.Tasks; using CliFx.Infrastructure; using Spectre.Console; -namespace DiscordChatExporter.Cli.Utils.Extensions +namespace DiscordChatExporter.Cli.Utils.Extensions; + +internal static class ConsoleExtensions { - internal static class ConsoleExtensions - { - public static IAnsiConsole CreateAnsiConsole(this IConsole console) => - AnsiConsole.Create(new AnsiConsoleSettings - { - Ansi = AnsiSupport.Detect, - ColorSystem = ColorSystemSupport.Detect, - Out = new AnsiConsoleOutput(console.Output) - }); + public static IAnsiConsole CreateAnsiConsole(this IConsole console) => + AnsiConsole.Create(new AnsiConsoleSettings + { + Ansi = AnsiSupport.Detect, + ColorSystem = ColorSystemSupport.Detect, + Out = new AnsiConsoleOutput(console.Output) + }); - public static Progress CreateProgressTicker(this IConsole console) => console - .CreateAnsiConsole() - .Progress() - .AutoClear(false) - .AutoRefresh(true) - .HideCompleted(false) - .Columns( - new TaskDescriptionColumn {Alignment = Justify.Left}, - new ProgressBarColumn(), - new PercentageColumn() - ); + public static Progress CreateProgressTicker(this IConsole console) => console + .CreateAnsiConsole() + .Progress() + .AutoClear(false) + .AutoRefresh(true) + .HideCompleted(false) + .Columns( + new TaskDescriptionColumn {Alignment = Justify.Left}, + new ProgressBarColumn(), + new PercentageColumn() + ); - public static async ValueTask StartTaskAsync( - this ProgressContext progressContext, - string description, - Func performOperationAsync) - { - var progressTask = progressContext.AddTask( - // Don't recognize random square brackets as style tags - Markup.Escape(description), - new ProgressTaskSettings {MaxValue = 1} - ); + public static async ValueTask StartTaskAsync( + this ProgressContext progressContext, + string description, + Func performOperationAsync) + { + var progressTask = progressContext.AddTask( + // Don't recognize random square brackets as style tags + Markup.Escape(description), + new ProgressTaskSettings {MaxValue = 1} + ); - try - { - await performOperationAsync(progressTask); - } - finally - { - progressTask.StopTask(); - } + try + { + await performOperationAsync(progressTask); + } + finally + { + progressTask.StopTask(); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/AuthToken.cs b/DiscordChatExporter.Core/Discord/AuthToken.cs index eea45db..6d10c6b 100644 --- a/DiscordChatExporter.Core/Discord/AuthToken.cs +++ b/DiscordChatExporter.Core/Discord/AuthToken.cs @@ -1,13 +1,12 @@ using System.Net.Http.Headers; -namespace DiscordChatExporter.Core.Discord +namespace DiscordChatExporter.Core.Discord; + +public record AuthToken(AuthTokenKind Kind, string Value) { - public record AuthToken(AuthTokenKind Kind, string Value) + public AuthenticationHeaderValue GetAuthenticationHeader() => Kind switch { - public AuthenticationHeaderValue GetAuthenticationHeader() => Kind switch - { - AuthTokenKind.Bot => new AuthenticationHeaderValue("Bot", Value), - _ => new AuthenticationHeaderValue(Value) - }; - } + AuthTokenKind.Bot => new AuthenticationHeaderValue("Bot", Value), + _ => new AuthenticationHeaderValue(Value) + }; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/AuthTokenKind.cs b/DiscordChatExporter.Core/Discord/AuthTokenKind.cs index 301692b..4aa841a 100644 --- a/DiscordChatExporter.Core/Discord/AuthTokenKind.cs +++ b/DiscordChatExporter.Core/Discord/AuthTokenKind.cs @@ -1,8 +1,7 @@ -namespace DiscordChatExporter.Core.Discord +namespace DiscordChatExporter.Core.Discord; + +public enum AuthTokenKind { - public enum AuthTokenKind - { - User, - Bot - } + User, + Bot } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Attachment.cs b/DiscordChatExporter.Core/Discord/Data/Attachment.cs index 9d13896..82d3456 100644 --- a/DiscordChatExporter.Core/Discord/Data/Attachment.cs +++ b/DiscordChatExporter.Core/Discord/Data/Attachment.cs @@ -6,40 +6,39 @@ using DiscordChatExporter.Core.Utils; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/channel#attachment-object +public partial record Attachment( + Snowflake Id, + string Url, + string FileName, + int? Width, + int? Height, + FileSize FileSize) : IHasId { - // https://discord.com/developers/docs/resources/channel#attachment-object - public partial record Attachment( - Snowflake Id, - string Url, - string FileName, - int? Width, - int? Height, - FileSize FileSize) : IHasId - { - public string FileExtension => Path.GetExtension(FileName); + public string FileExtension => Path.GetExtension(FileName); - public bool IsImage => FileFormat.IsImage(FileExtension); + public bool IsImage => FileFormat.IsImage(FileExtension); - public bool IsVideo => FileFormat.IsVideo(FileExtension); + public bool IsVideo => FileFormat.IsVideo(FileExtension); - public bool IsAudio => FileFormat.IsAudio(FileExtension); + public bool IsAudio => FileFormat.IsAudio(FileExtension); - public bool IsSpoiler => FileName.StartsWith("SPOILER_", StringComparison.Ordinal); - } + public bool IsSpoiler => FileName.StartsWith("SPOILER_", StringComparison.Ordinal); +} - public partial record Attachment +public partial record Attachment +{ + public static Attachment Parse(JsonElement json) { - public static Attachment Parse(JsonElement json) - { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var url = json.GetProperty("url").GetNonWhiteSpaceString(); - var width = json.GetPropertyOrNull("width")?.GetInt32(); - var height = json.GetPropertyOrNull("height")?.GetInt32(); - var fileName = json.GetProperty("filename").GetNonWhiteSpaceString(); - var fileSize = json.GetProperty("size").GetInt64().Pipe(FileSize.FromBytes); - - return new Attachment(id, url, fileName, width, height, fileSize); - } + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var url = json.GetProperty("url").GetNonWhiteSpaceString(); + var width = json.GetPropertyOrNull("width")?.GetInt32(); + var height = json.GetPropertyOrNull("height")?.GetInt32(); + var fileName = json.GetProperty("filename").GetNonWhiteSpaceString(); + var fileSize = json.GetProperty("size").GetInt64().Pipe(FileSize.FromBytes); + + return new Attachment(id, url, fileName, width, height, fileSize); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Channel.cs b/DiscordChatExporter.Core/Discord/Data/Channel.cs index bc525a1..3c8c2d1 100644 --- a/DiscordChatExporter.Core/Discord/Data/Channel.cs +++ b/DiscordChatExporter.Core/Discord/Data/Channel.cs @@ -4,69 +4,68 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data -{ - // https://discord.com/developers/docs/resources/channel#channel-object - public partial record Channel( - Snowflake Id, - ChannelKind Kind, - Snowflake GuildId, - ChannelCategory Category, - string Name, - int? Position, - string? Topic) : IHasId - { - public bool IsTextChannel => Kind is - ChannelKind.GuildTextChat or - ChannelKind.DirectTextChat or - ChannelKind.DirectGroupTextChat or - ChannelKind.GuildNews or - ChannelKind.GuildStore; +namespace DiscordChatExporter.Core.Discord.Data; - public bool IsVoiceChannel => !IsTextChannel; - } +// https://discord.com/developers/docs/resources/channel#channel-object +public partial record Channel( + Snowflake Id, + ChannelKind Kind, + Snowflake GuildId, + ChannelCategory Category, + string Name, + int? Position, + string? Topic) : IHasId +{ + public bool IsTextChannel => Kind is + ChannelKind.GuildTextChat or + ChannelKind.DirectTextChat or + ChannelKind.DirectGroupTextChat or + ChannelKind.GuildNews or + ChannelKind.GuildStore; - public partial record Channel - { - private static ChannelCategory GetFallbackCategory(ChannelKind channelKind) => new( - Snowflake.Zero, - channelKind switch - { - ChannelKind.GuildTextChat => "Text", - ChannelKind.DirectTextChat => "Private", - ChannelKind.DirectGroupTextChat => "Group", - ChannelKind.GuildNews => "News", - ChannelKind.GuildStore => "Store", - _ => "Default" - }, - null - ); + public bool IsVoiceChannel => !IsTextChannel; +} - public static Channel Parse(JsonElement json, ChannelCategory? category = null, int? position = null) +public partial record Channel +{ + private static ChannelCategory GetFallbackCategory(ChannelKind channelKind) => new( + Snowflake.Zero, + channelKind switch { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var guildId = json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var topic = json.GetPropertyOrNull("topic")?.GetStringOrNull(); - var kind = (ChannelKind)json.GetProperty("type").GetInt32(); + ChannelKind.GuildTextChat => "Text", + ChannelKind.DirectTextChat => "Private", + ChannelKind.DirectGroupTextChat => "Group", + ChannelKind.GuildNews => "News", + ChannelKind.GuildStore => "Store", + _ => "Default" + }, + null + ); - var name = - // Guild channel - json.GetPropertyOrNull("name")?.GetStringOrNull() ?? - // DM channel - json.GetPropertyOrNull("recipients")?.EnumerateArray().Select(User.Parse).Select(u => u.Name) - .Pipe(s => string.Join(", ", s)) ?? - // Fallback - id.ToString(); + public static Channel Parse(JsonElement json, ChannelCategory? category = null, int? position = null) + { + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var guildId = json.GetPropertyOrNull("guild_id")?.GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var topic = json.GetPropertyOrNull("topic")?.GetStringOrNull(); + var kind = (ChannelKind)json.GetProperty("type").GetInt32(); - return new Channel( - id, - kind, - guildId ?? Guild.DirectMessages.Id, - category ?? GetFallbackCategory(kind), - name, - position ?? json.GetPropertyOrNull("position")?.GetInt32(), - topic - ); - } + var name = + // Guild channel + json.GetPropertyOrNull("name")?.GetStringOrNull() ?? + // DM channel + json.GetPropertyOrNull("recipients")?.EnumerateArray().Select(User.Parse).Select(u => u.Name) + .Pipe(s => string.Join(", ", s)) ?? + // Fallback + id.ToString(); + + return new Channel( + id, + kind, + guildId ?? Guild.DirectMessages.Id, + category ?? GetFallbackCategory(kind), + name, + position ?? json.GetPropertyOrNull("position")?.GetInt32(), + topic + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs b/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs index d576f80..a76a561 100644 --- a/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs +++ b/DiscordChatExporter.Core/Discord/Data/ChannelCategory.cs @@ -3,25 +3,24 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +public record ChannelCategory(Snowflake Id, string Name, int? Position) : IHasId { - public record ChannelCategory(Snowflake Id, string Name, int? Position) : IHasId - { - public static ChannelCategory Unknown { get; } = new(Snowflake.Zero, "", 0); + public static ChannelCategory Unknown { get; } = new(Snowflake.Zero, "", 0); - public static ChannelCategory Parse(JsonElement json, int? position = null) - { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + public static ChannelCategory Parse(JsonElement json, int? position = null) + { + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var name = - json.GetPropertyOrNull("name")?.GetStringOrNull() ?? - id.ToString(); + var name = + json.GetPropertyOrNull("name")?.GetStringOrNull() ?? + id.ToString(); - return new ChannelCategory( - id, - name, - position ?? json.GetPropertyOrNull("position")?.GetInt32() - ); - } + return new ChannelCategory( + id, + name, + position ?? json.GetPropertyOrNull("position")?.GetInt32() + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/ChannelKind.cs b/DiscordChatExporter.Core/Discord/Data/ChannelKind.cs index 38d6fbc..6862ca2 100644 --- a/DiscordChatExporter.Core/Discord/Data/ChannelKind.cs +++ b/DiscordChatExporter.Core/Discord/Data/ChannelKind.cs @@ -1,15 +1,14 @@ -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/channel#channel-object-channel-types +// Order of enum fields needs to match the order in the docs. +public enum ChannelKind { - // https://discord.com/developers/docs/resources/channel#channel-object-channel-types - // Order of enum fields needs to match the order in the docs. - public enum ChannelKind - { - GuildTextChat = 0, - DirectTextChat, - GuildVoiceChat, - DirectGroupTextChat, - GuildCategory, - GuildNews, - GuildStore - } + GuildTextChat = 0, + DirectTextChat, + GuildVoiceChat, + DirectGroupTextChat, + GuildCategory, + GuildNews, + GuildStore } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs b/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs index 5cb1362..8fad6fd 100644 --- a/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs +++ b/DiscordChatExporter.Core/Discord/Data/Common/FileSize.cs @@ -1,49 +1,48 @@ using System; using System.Diagnostics.CodeAnalysis; -namespace DiscordChatExporter.Core.Discord.Data.Common -{ - // Loosely based on https://github.com/omar/ByteSize (MIT license) - public readonly partial record struct FileSize(long TotalBytes) - { - public double TotalKiloBytes => TotalBytes / 1024.0; - public double TotalMegaBytes => TotalKiloBytes / 1024.0; - public double TotalGigaBytes => TotalMegaBytes / 1024.0; +namespace DiscordChatExporter.Core.Discord.Data.Common; - private double GetLargestWholeNumberValue() - { - if (Math.Abs(TotalGigaBytes) >= 1) - return TotalGigaBytes; +// Loosely based on https://github.com/omar/ByteSize (MIT license) +public readonly partial record struct FileSize(long TotalBytes) +{ + public double TotalKiloBytes => TotalBytes / 1024.0; + public double TotalMegaBytes => TotalKiloBytes / 1024.0; + public double TotalGigaBytes => TotalMegaBytes / 1024.0; - if (Math.Abs(TotalMegaBytes) >= 1) - return TotalMegaBytes; + private double GetLargestWholeNumberValue() + { + if (Math.Abs(TotalGigaBytes) >= 1) + return TotalGigaBytes; - if (Math.Abs(TotalKiloBytes) >= 1) - return TotalKiloBytes; + if (Math.Abs(TotalMegaBytes) >= 1) + return TotalMegaBytes; - return TotalBytes; - } + if (Math.Abs(TotalKiloBytes) >= 1) + return TotalKiloBytes; - private string GetLargestWholeNumberSymbol() - { - if (Math.Abs(TotalGigaBytes) >= 1) - return "GB"; + return TotalBytes; + } - if (Math.Abs(TotalMegaBytes) >= 1) - return "MB"; + private string GetLargestWholeNumberSymbol() + { + if (Math.Abs(TotalGigaBytes) >= 1) + return "GB"; - if (Math.Abs(TotalKiloBytes) >= 1) - return "KB"; + if (Math.Abs(TotalMegaBytes) >= 1) + return "MB"; - return "bytes"; - } + if (Math.Abs(TotalKiloBytes) >= 1) + return "KB"; - [ExcludeFromCodeCoverage] - public override string ToString() => $"{GetLargestWholeNumberValue():0.##} {GetLargestWholeNumberSymbol()}"; + return "bytes"; } - public partial record struct FileSize - { - public static FileSize FromBytes(long bytes) => new(bytes); - } + [ExcludeFromCodeCoverage] + public override string ToString() => $"{GetLargestWholeNumberValue():0.##} {GetLargestWholeNumberSymbol()}"; +} + +public partial record struct FileSize +{ + public static FileSize FromBytes(long bytes) => new(bytes); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Common/IHasId.cs b/DiscordChatExporter.Core/Discord/Data/Common/IHasId.cs index d32dab2..3354e80 100644 --- a/DiscordChatExporter.Core/Discord/Data/Common/IHasId.cs +++ b/DiscordChatExporter.Core/Discord/Data/Common/IHasId.cs @@ -1,7 +1,6 @@ -namespace DiscordChatExporter.Core.Discord.Data.Common +namespace DiscordChatExporter.Core.Discord.Data.Common; + +public interface IHasId { - public interface IHasId - { - Snowflake Id { get; } - } + Snowflake Id { get; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs b/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs index 04e63da..42468ae 100644 --- a/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs +++ b/DiscordChatExporter.Core/Discord/Data/Common/IdBasedEqualityComparer.cs @@ -1,13 +1,12 @@ using System.Collections.Generic; -namespace DiscordChatExporter.Core.Discord.Data.Common +namespace DiscordChatExporter.Core.Discord.Data.Common; + +public class IdBasedEqualityComparer : IEqualityComparer { - public class IdBasedEqualityComparer : IEqualityComparer - { - public static IdBasedEqualityComparer Instance { get; } = new(); + public static IdBasedEqualityComparer Instance { get; } = new(); - public bool Equals(IHasId? x, IHasId? y) => x?.Id == y?.Id; + public bool Equals(IHasId? x, IHasId? y) => x?.Id == y?.Id; - public int GetHashCode(IHasId obj) => obj.Id.GetHashCode(); - } + public int GetHashCode(IHasId obj) => obj.Id.GetHashCode(); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs index dea5c5d..7b72f92 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/Embed.cs @@ -6,62 +6,61 @@ using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +// https://discord.com/developers/docs/resources/channel#embed-object +public partial record Embed( + string? Title, + string? Url, + DateTimeOffset? Timestamp, + Color? Color, + EmbedAuthor? Author, + string? Description, + IReadOnlyList Fields, + EmbedImage? Thumbnail, + EmbedImage? Image, + EmbedFooter? Footer) { - // https://discord.com/developers/docs/resources/channel#embed-object - public partial record Embed( - string? Title, - string? Url, - DateTimeOffset? Timestamp, - Color? Color, - EmbedAuthor? Author, - string? Description, - IReadOnlyList Fields, - EmbedImage? Thumbnail, - EmbedImage? Image, - EmbedFooter? Footer) - { - public PlainImageEmbedProjection? TryGetPlainImage() => - PlainImageEmbedProjection.TryResolve(this); + public PlainImageEmbedProjection? TryGetPlainImage() => + PlainImageEmbedProjection.TryResolve(this); - public SpotifyTrackEmbedProjection? TryGetSpotifyTrack() => - SpotifyTrackEmbedProjection.TryResolve(this); + public SpotifyTrackEmbedProjection? TryGetSpotifyTrack() => + SpotifyTrackEmbedProjection.TryResolve(this); - public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() => - YouTubeVideoEmbedProjection.TryResolve(this); - } + public YouTubeVideoEmbedProjection? TryGetYouTubeVideo() => + YouTubeVideoEmbedProjection.TryResolve(this); +} - public partial record Embed +public partial record Embed +{ + public static Embed Parse(JsonElement json) { - public static Embed Parse(JsonElement json) - { - var title = json.GetPropertyOrNull("title")?.GetStringOrNull(); - var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); - var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset(); - var color = json.GetPropertyOrNull("color")?.GetInt32().Pipe(System.Drawing.Color.FromArgb).ResetAlpha(); - var description = json.GetPropertyOrNull("description")?.GetStringOrNull(); + var title = json.GetPropertyOrNull("title")?.GetStringOrNull(); + var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); + var timestamp = json.GetPropertyOrNull("timestamp")?.GetDateTimeOffset(); + var color = json.GetPropertyOrNull("color")?.GetInt32().Pipe(System.Drawing.Color.FromArgb).ResetAlpha(); + var description = json.GetPropertyOrNull("description")?.GetStringOrNull(); - var author = json.GetPropertyOrNull("author")?.Pipe(EmbedAuthor.Parse); - var thumbnail = json.GetPropertyOrNull("thumbnail")?.Pipe(EmbedImage.Parse); - var image = json.GetPropertyOrNull("image")?.Pipe(EmbedImage.Parse); - var footer = json.GetPropertyOrNull("footer")?.Pipe(EmbedFooter.Parse); + var author = json.GetPropertyOrNull("author")?.Pipe(EmbedAuthor.Parse); + var thumbnail = json.GetPropertyOrNull("thumbnail")?.Pipe(EmbedImage.Parse); + var image = json.GetPropertyOrNull("image")?.Pipe(EmbedImage.Parse); + var footer = json.GetPropertyOrNull("footer")?.Pipe(EmbedFooter.Parse); - var fields = - json.GetPropertyOrNull("fields")?.EnumerateArray().Select(EmbedField.Parse).ToArray() ?? - Array.Empty(); + var fields = + json.GetPropertyOrNull("fields")?.EnumerateArray().Select(EmbedField.Parse).ToArray() ?? + Array.Empty(); - return new Embed( - title, - url, - timestamp, - color, - author, - description, - fields, - thumbnail, - image, - footer - ); - } + return new Embed( + title, + url, + timestamp, + color, + author, + description, + fields, + thumbnail, + image, + footer + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs index 4526c09..9a8ddc2 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedAuthor.cs @@ -1,23 +1,22 @@ using System.Text.Json; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +// https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure +public record EmbedAuthor( + string? Name, + string? Url, + string? IconUrl, + string? IconProxyUrl) { - // https://discord.com/developers/docs/resources/channel#embed-object-embed-author-structure - public record EmbedAuthor( - string? Name, - string? Url, - string? IconUrl, - string? IconProxyUrl) + public static EmbedAuthor Parse(JsonElement json) { - public static EmbedAuthor Parse(JsonElement json) - { - var name = json.GetPropertyOrNull("name")?.GetStringOrNull(); - var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); - var iconUrl = json.GetPropertyOrNull("icon_url")?.GetStringOrNull(); - var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetStringOrNull(); + var name = json.GetPropertyOrNull("name")?.GetStringOrNull(); + var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); + var iconUrl = json.GetPropertyOrNull("icon_url")?.GetStringOrNull(); + var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetStringOrNull(); - return new EmbedAuthor(name, url, iconUrl, iconProxyUrl); - } + return new EmbedAuthor(name, url, iconUrl, iconProxyUrl); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs index 5e632de..0dac0cf 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedField.cs @@ -2,21 +2,20 @@ using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +// https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure +public record EmbedField( + string Name, + string Value, + bool IsInline) { - // https://discord.com/developers/docs/resources/channel#embed-object-embed-field-structure - public record EmbedField( - string Name, - string Value, - bool IsInline) + public static EmbedField Parse(JsonElement json) { - public static EmbedField Parse(JsonElement json) - { - var name = json.GetProperty("name").GetNonWhiteSpaceString(); - var value = json.GetProperty("value").GetNonWhiteSpaceString(); - var isInline = json.GetPropertyOrNull("inline")?.GetBoolean() ?? false; + var name = json.GetProperty("name").GetNonWhiteSpaceString(); + var value = json.GetProperty("value").GetNonWhiteSpaceString(); + var isInline = json.GetPropertyOrNull("inline")?.GetBoolean() ?? false; - return new EmbedField(name, value, isInline); - } + return new EmbedField(name, value, isInline); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs index b5763ec..5cdd094 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedFooter.cs @@ -2,21 +2,20 @@ using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +// https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure +public record EmbedFooter( + string Text, + string? IconUrl, + string? IconProxyUrl) { - // https://discord.com/developers/docs/resources/channel#embed-object-embed-footer-structure - public record EmbedFooter( - string Text, - string? IconUrl, - string? IconProxyUrl) + public static EmbedFooter Parse(JsonElement json) { - public static EmbedFooter Parse(JsonElement json) - { - var text = json.GetProperty("text").GetNonWhiteSpaceString(); - var iconUrl = json.GetPropertyOrNull("icon_url")?.GetStringOrNull(); - var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetStringOrNull(); + var text = json.GetProperty("text").GetNonWhiteSpaceString(); + var iconUrl = json.GetPropertyOrNull("icon_url")?.GetStringOrNull(); + var iconProxyUrl = json.GetPropertyOrNull("proxy_icon_url")?.GetStringOrNull(); - return new EmbedFooter(text, iconUrl, iconProxyUrl); - } + return new EmbedFooter(text, iconUrl, iconProxyUrl); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs index c2fee1e..2aae835 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/EmbedImage.cs @@ -1,23 +1,22 @@ using System.Text.Json; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +// https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure +public record EmbedImage( + string? Url, + string? ProxyUrl, + int? Width, + int? Height) { - // https://discord.com/developers/docs/resources/channel#embed-object-embed-image-structure - public record EmbedImage( - string? Url, - string? ProxyUrl, - int? Width, - int? Height) + public static EmbedImage Parse(JsonElement json) { - public static EmbedImage Parse(JsonElement json) - { - var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); - var proxyUrl = json.GetPropertyOrNull("proxy_url")?.GetStringOrNull(); - var width = json.GetPropertyOrNull("width")?.GetInt32(); - var height = json.GetPropertyOrNull("height")?.GetInt32(); + var url = json.GetPropertyOrNull("url")?.GetStringOrNull(); + var proxyUrl = json.GetPropertyOrNull("proxy_url")?.GetStringOrNull(); + var width = json.GetPropertyOrNull("width")?.GetInt32(); + var height = json.GetPropertyOrNull("height")?.GetInt32(); - return new EmbedImage(url, proxyUrl, width, height); - } + return new EmbedImage(url, proxyUrl, width, height); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs index 04bfb0b..5fcfd66 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/PlainImageEmbedProjection.cs @@ -3,32 +3,31 @@ using System.Linq; using System.Text.RegularExpressions; using DiscordChatExporter.Core.Utils; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +public record PlainImageEmbedProjection(string Url) { - public record PlainImageEmbedProjection(string Url) + public static PlainImageEmbedProjection? TryResolve(Embed embed) { - public static PlainImageEmbedProjection? TryResolve(Embed embed) - { - if (string.IsNullOrWhiteSpace(embed.Url)) - return null; + if (string.IsNullOrWhiteSpace(embed.Url)) + return null; - // Has to be an embed without any data (except URL and image) - if (!string.IsNullOrWhiteSpace(embed.Title) || - embed.Timestamp is not null || - embed.Author is not null || - !string.IsNullOrWhiteSpace(embed.Description) || - embed.Fields.Any() || - embed.Footer is not null) - { - return null; - } + // Has to be an embed without any data (except URL and image) + if (!string.IsNullOrWhiteSpace(embed.Title) || + embed.Timestamp is not null || + embed.Author is not null || + !string.IsNullOrWhiteSpace(embed.Description) || + embed.Fields.Any() || + embed.Footer is not null) + { + return null; + } - // Has to be an image file - var fileName = Regex.Match(embed.Url, @".+/([^?]*)").Groups[1].Value; - if (string.IsNullOrWhiteSpace(fileName) || !FileFormat.IsImage(Path.GetExtension(fileName))) - return null; + // Has to be an image file + var fileName = Regex.Match(embed.Url, @".+/([^?]*)").Groups[1].Value; + if (string.IsNullOrWhiteSpace(fileName) || !FileFormat.IsImage(Path.GetExtension(fileName))) + return null; - return new PlainImageEmbedProjection(embed.Url); - } + return new PlainImageEmbedProjection(embed.Url); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs index 0bbe08d..2d5c6fa 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/SpotifyTrackEmbedProjection.cs @@ -1,34 +1,33 @@ using System.Text.RegularExpressions; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +public partial record SpotifyTrackEmbedProjection(string TrackId) +{ + public string Url => $"https://open.spotify.com/embed/track/{TrackId}"; +} + +public partial record SpotifyTrackEmbedProjection { - public partial record SpotifyTrackEmbedProjection(string TrackId) + private static string? TryParseTrackId(string embedUrl) { - public string Url => $"https://open.spotify.com/embed/track/{TrackId}"; + // https://open.spotify.com/track/1LHZMWefF9502NPfArRfvP?si=3efac6ce9be04f0a + var trackId = Regex.Match(embedUrl, @"spotify\.com/track/(.*?)(?:\?|&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(trackId)) + return trackId; + + return null; } - public partial record SpotifyTrackEmbedProjection + public static SpotifyTrackEmbedProjection? TryResolve(Embed embed) { - private static string? TryParseTrackId(string embedUrl) - { - // https://open.spotify.com/track/1LHZMWefF9502NPfArRfvP?si=3efac6ce9be04f0a - var trackId = Regex.Match(embedUrl, @"spotify\.com/track/(.*?)(?:\?|&|/|$)").Groups[1].Value; - if (!string.IsNullOrWhiteSpace(trackId)) - return trackId; - + if (string.IsNullOrWhiteSpace(embed.Url)) return null; - } - - public static SpotifyTrackEmbedProjection? TryResolve(Embed embed) - { - if (string.IsNullOrWhiteSpace(embed.Url)) - return null; - var trackId = TryParseTrackId(embed.Url); - if (string.IsNullOrWhiteSpace(trackId)) - return null; + var trackId = TryParseTrackId(embed.Url); + if (string.IsNullOrWhiteSpace(trackId)) + return null; - return new SpotifyTrackEmbedProjection(trackId); - } + return new SpotifyTrackEmbedProjection(trackId); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs b/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs index 1f41862..704fdae 100644 --- a/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs +++ b/DiscordChatExporter.Core/Discord/Data/Embeds/YouTubeVideoEmbedProjection.cs @@ -1,49 +1,48 @@ using System.Text.RegularExpressions; -namespace DiscordChatExporter.Core.Discord.Data.Embeds +namespace DiscordChatExporter.Core.Discord.Data.Embeds; + +public partial record YouTubeVideoEmbedProjection(string VideoId) +{ + public string Url => $"https://www.youtube.com/embed/{VideoId}"; +} + +public partial record YouTubeVideoEmbedProjection { - public partial record YouTubeVideoEmbedProjection(string VideoId) + // Adapted from YoutubeExplode + // https://github.com/Tyrrrz/YoutubeExplode/blob/5be164be20019783913f76fcc98f18c65aebe9f0/YoutubeExplode/Videos/VideoId.cs#L34-L64 + private static string? TryParseVideoId(string embedUrl) { - public string Url => $"https://www.youtube.com/embed/{VideoId}"; + // Regular URL + // https://www.youtube.com/watch?v=yIVRs6YSbOM + var regularMatch = Regex.Match(embedUrl, @"youtube\..+?/watch.*?v=(.*?)(?:&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(regularMatch)) + return regularMatch; + + // Short URL + // https://youtu.be/yIVRs6YSbOM + var shortMatch = Regex.Match(embedUrl, @"youtu\.be/(.*?)(?:\?|&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(shortMatch)) + return shortMatch; + + // Embed URL + // https://www.youtube.com/embed/yIVRs6YSbOM + var embedMatch = Regex.Match(embedUrl, @"youtube\..+?/embed/(.*?)(?:\?|&|/|$)").Groups[1].Value; + if (!string.IsNullOrWhiteSpace(embedMatch)) + return embedMatch; + + return null; } - public partial record YouTubeVideoEmbedProjection + public static YouTubeVideoEmbedProjection? TryResolve(Embed embed) { - // Adapted from YoutubeExplode - // https://github.com/Tyrrrz/YoutubeExplode/blob/5be164be20019783913f76fcc98f18c65aebe9f0/YoutubeExplode/Videos/VideoId.cs#L34-L64 - private static string? TryParseVideoId(string embedUrl) - { - // Regular URL - // https://www.youtube.com/watch?v=yIVRs6YSbOM - var regularMatch = Regex.Match(embedUrl, @"youtube\..+?/watch.*?v=(.*?)(?:&|/|$)").Groups[1].Value; - if (!string.IsNullOrWhiteSpace(regularMatch)) - return regularMatch; - - // Short URL - // https://youtu.be/yIVRs6YSbOM - var shortMatch = Regex.Match(embedUrl, @"youtu\.be/(.*?)(?:\?|&|/|$)").Groups[1].Value; - if (!string.IsNullOrWhiteSpace(shortMatch)) - return shortMatch; - - // Embed URL - // https://www.youtube.com/embed/yIVRs6YSbOM - var embedMatch = Regex.Match(embedUrl, @"youtube\..+?/embed/(.*?)(?:\?|&|/|$)").Groups[1].Value; - if (!string.IsNullOrWhiteSpace(embedMatch)) - return embedMatch; - + if (string.IsNullOrWhiteSpace(embed.Url)) return null; - } - - public static YouTubeVideoEmbedProjection? TryResolve(Embed embed) - { - if (string.IsNullOrWhiteSpace(embed.Url)) - return null; - var videoId = TryParseVideoId(embed.Url); - if (string.IsNullOrWhiteSpace(videoId)) - return null; + var videoId = TryParseVideoId(embed.Url); + if (string.IsNullOrWhiteSpace(videoId)) + return null; - return new YouTubeVideoEmbedProjection(videoId); - } + return new YouTubeVideoEmbedProjection(videoId); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Emoji.cs b/DiscordChatExporter.Core/Discord/Data/Emoji.cs index adf8bcd..ba8bb53 100644 --- a/DiscordChatExporter.Core/Discord/Data/Emoji.cs +++ b/DiscordChatExporter.Core/Discord/Data/Emoji.cs @@ -4,57 +4,56 @@ using DiscordChatExporter.Core.Utils; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/emoji#emoji-object +public partial record Emoji( + // Only present on custom emoji + string? Id, + // Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂) + string Name, + bool IsAnimated, + string ImageUrl) { - // https://discord.com/developers/docs/resources/emoji#emoji-object - public partial record Emoji( - // Only present on custom emoji - string? Id, - // Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂) - string Name, - bool IsAnimated, - string ImageUrl) - { - // Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile) - public string Code => !string.IsNullOrWhiteSpace(Id) - ? Name - : EmojiIndex.TryGetCode(Name) ?? Name; - } + // Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile) + public string Code => !string.IsNullOrWhiteSpace(Id) + ? Name + : EmojiIndex.TryGetCode(Name) ?? Name; +} + +public partial record Emoji +{ + private static string GetTwemojiName(string name) => string.Join("-", + name + .GetRunes() + // Variant selector rune is skipped in Twemoji names + .Where(r => r.Value != 0xfe0f) + .Select(r => r.Value.ToString("x")) + ); - public partial record Emoji + public static string GetImageUrl(string? id, string name, bool isAnimated) { - private static string GetTwemojiName(string name) => string.Join("-", - name - .GetRunes() - // Variant selector rune is skipped in Twemoji names - .Where(r => r.Value != 0xfe0f) - .Select(r => r.Value.ToString("x")) - ); - - public static string GetImageUrl(string? id, string name, bool isAnimated) + // Custom emoji + if (!string.IsNullOrWhiteSpace(id)) { - // Custom emoji - if (!string.IsNullOrWhiteSpace(id)) - { - return isAnimated - ? $"https://cdn.discordapp.com/emojis/{id}.gif" - : $"https://cdn.discordapp.com/emojis/{id}.png"; - } - - // Standard emoji - var twemojiName = GetTwemojiName(name); - return $"https://twemoji.maxcdn.com/2/svg/{twemojiName}.svg"; + return isAnimated + ? $"https://cdn.discordapp.com/emojis/{id}.gif" + : $"https://cdn.discordapp.com/emojis/{id}.png"; } - public static Emoji Parse(JsonElement json) - { - var id = json.GetPropertyOrNull("id")?.GetNonWhiteSpaceString(); - var name = json.GetProperty("name").GetNonWhiteSpaceString(); - var isAnimated = json.GetPropertyOrNull("animated")?.GetBoolean() ?? false; + // Standard emoji + var twemojiName = GetTwemojiName(name); + return $"https://twemoji.maxcdn.com/2/svg/{twemojiName}.svg"; + } - var imageUrl = GetImageUrl(id, name, isAnimated); + public static Emoji Parse(JsonElement json) + { + var id = json.GetPropertyOrNull("id")?.GetNonWhiteSpaceString(); + var name = json.GetProperty("name").GetNonWhiteSpaceString(); + var isAnimated = json.GetPropertyOrNull("animated")?.GetBoolean() ?? false; - return new Emoji(id, name, isAnimated, imageUrl); - } + var imageUrl = GetImageUrl(id, name, isAnimated); + + return new Emoji(id, name, isAnimated, imageUrl); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Guild.cs b/DiscordChatExporter.Core/Discord/Data/Guild.cs index 4cd833c..1b4faf9 100644 --- a/DiscordChatExporter.Core/Discord/Data/Guild.cs +++ b/DiscordChatExporter.Core/Discord/Data/Guild.cs @@ -3,34 +3,33 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/guild#guild-object +public record Guild(Snowflake Id, string Name, string IconUrl) : IHasId { - // https://discord.com/developers/docs/resources/guild#guild-object - public record Guild(Snowflake Id, string Name, string IconUrl) : IHasId - { - public static Guild DirectMessages { get; } = new( - Snowflake.Zero, - "Direct Messages", - GetDefaultIconUrl() - ); + public static Guild DirectMessages { get; } = new( + Snowflake.Zero, + "Direct Messages", + GetDefaultIconUrl() + ); - private static string GetDefaultIconUrl() => - "https://cdn.discordapp.com/embed/avatars/0.png"; + private static string GetDefaultIconUrl() => + "https://cdn.discordapp.com/embed/avatars/0.png"; - private static string GetIconUrl(Snowflake id, string iconHash) => - $"https://cdn.discordapp.com/icons/{id}/{iconHash}.png"; + private static string GetIconUrl(Snowflake id, string iconHash) => + $"https://cdn.discordapp.com/icons/{id}/{iconHash}.png"; - public static Guild Parse(JsonElement json) - { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var name = json.GetProperty("name").GetNonWhiteSpaceString(); - var iconHash = json.GetPropertyOrNull("icon")?.GetStringOrNull(); + public static Guild Parse(JsonElement json) + { + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var name = json.GetProperty("name").GetNonWhiteSpaceString(); + var iconHash = json.GetPropertyOrNull("icon")?.GetStringOrNull(); - var iconUrl = !string.IsNullOrWhiteSpace(iconHash) - ? GetIconUrl(id, iconHash) - : GetDefaultIconUrl(); + var iconUrl = !string.IsNullOrWhiteSpace(iconHash) + ? GetIconUrl(id, iconHash) + : GetDefaultIconUrl(); - return new Guild(id, name, iconUrl); - } + return new Guild(id, name, iconUrl); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Member.cs b/DiscordChatExporter.Core/Discord/Data/Member.cs index cdae4c1..e36f341 100644 --- a/DiscordChatExporter.Core/Discord/Data/Member.cs +++ b/DiscordChatExporter.Core/Discord/Data/Member.cs @@ -6,42 +6,41 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/guild#guild-member-object +public partial record Member( + User User, + string Nick, + IReadOnlyList RoleIds) : IHasId { - // https://discord.com/developers/docs/resources/guild#guild-member-object - public partial record Member( - User User, - string Nick, - IReadOnlyList RoleIds) : IHasId - { - public Snowflake Id => User.Id; - } + public Snowflake Id => User.Id; +} - public partial record Member - { - public static Member CreateForUser(User user) => new( - user, - user.Name, - Array.Empty() - ); +public partial record Member +{ + public static Member CreateForUser(User user) => new( + user, + user.Name, + Array.Empty() + ); - public static Member Parse(JsonElement json) - { - var user = json.GetProperty("user").Pipe(User.Parse); - var nick = json.GetPropertyOrNull("nick")?.GetStringOrNull(); + public static Member Parse(JsonElement json) + { + var user = json.GetProperty("user").Pipe(User.Parse); + var nick = json.GetPropertyOrNull("nick")?.GetStringOrNull(); - var roleIds = json - .GetPropertyOrNull("roles")? - .EnumerateArray() - .Select(j => j.GetNonWhiteSpaceString()) - .Select(Snowflake.Parse) - .ToArray() ?? Array.Empty(); + var roleIds = json + .GetPropertyOrNull("roles")? + .EnumerateArray() + .Select(j => j.GetNonWhiteSpaceString()) + .Select(Snowflake.Parse) + .ToArray() ?? Array.Empty(); - return new Member( - user, - nick ?? user.Name, - roleIds - ); - } + return new Member( + user, + nick ?? user.Name, + roleIds + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Message.cs b/DiscordChatExporter.Core/Discord/Data/Message.cs index e888eea..1a379b9 100644 --- a/DiscordChatExporter.Core/Discord/Data/Message.cs +++ b/DiscordChatExporter.Core/Discord/Data/Message.cs @@ -7,83 +7,82 @@ using DiscordChatExporter.Core.Discord.Data.Embeds; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/channel#message-object +public record Message( + Snowflake Id, + MessageKind Kind, + User Author, + DateTimeOffset Timestamp, + DateTimeOffset? EditedTimestamp, + DateTimeOffset? CallEndedTimestamp, + bool IsPinned, + string Content, + IReadOnlyList Attachments, + IReadOnlyList Embeds, + IReadOnlyList Reactions, + IReadOnlyList MentionedUsers, + MessageReference? Reference, + Message? ReferencedMessage) : IHasId { - // https://discord.com/developers/docs/resources/channel#message-object - public record Message( - Snowflake Id, - MessageKind Kind, - User Author, - DateTimeOffset Timestamp, - DateTimeOffset? EditedTimestamp, - DateTimeOffset? CallEndedTimestamp, - bool IsPinned, - string Content, - IReadOnlyList Attachments, - IReadOnlyList Embeds, - IReadOnlyList Reactions, - IReadOnlyList MentionedUsers, - MessageReference? Reference, - Message? ReferencedMessage) : IHasId + public static Message Parse(JsonElement json) { - public static Message Parse(JsonElement json) - { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var author = json.GetProperty("author").Pipe(User.Parse); - var timestamp = json.GetProperty("timestamp").GetDateTimeOffset(); - var editedTimestamp = json.GetPropertyOrNull("edited_timestamp")?.GetDateTimeOffset(); - var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp") - ?.GetDateTimeOffset(); - var kind = (MessageKind)json.GetProperty("type").GetInt32(); - var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false; - var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse); - var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse); + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var author = json.GetProperty("author").Pipe(User.Parse); + var timestamp = json.GetProperty("timestamp").GetDateTimeOffset(); + var editedTimestamp = json.GetPropertyOrNull("edited_timestamp")?.GetDateTimeOffset(); + var callEndedTimestamp = json.GetPropertyOrNull("call")?.GetPropertyOrNull("ended_timestamp") + ?.GetDateTimeOffset(); + var kind = (MessageKind)json.GetProperty("type").GetInt32(); + var isPinned = json.GetPropertyOrNull("pinned")?.GetBoolean() ?? false; + var messageReference = json.GetPropertyOrNull("message_reference")?.Pipe(MessageReference.Parse); + var referencedMessage = json.GetPropertyOrNull("referenced_message")?.Pipe(Parse); - var content = kind switch - { - MessageKind.RecipientAdd => "Added a recipient.", - MessageKind.RecipientRemove => "Removed a recipient.", - MessageKind.Call => - $"Started a call that lasted {callEndedTimestamp?.Pipe(t => t - timestamp).Pipe(t => (int)t.TotalMinutes) ?? 0} minutes.", - MessageKind.ChannelNameChange => "Changed the channel name.", - MessageKind.ChannelIconChange => "Changed the channel icon.", - MessageKind.ChannelPinnedMessage => "Pinned a message.", - MessageKind.GuildMemberJoin => "Joined the server.", - _ => json.GetPropertyOrNull("content")?.GetStringOrNull() ?? "" - }; + var content = kind switch + { + MessageKind.RecipientAdd => "Added a recipient.", + MessageKind.RecipientRemove => "Removed a recipient.", + MessageKind.Call => + $"Started a call that lasted {callEndedTimestamp?.Pipe(t => t - timestamp).Pipe(t => (int)t.TotalMinutes) ?? 0} minutes.", + MessageKind.ChannelNameChange => "Changed the channel name.", + MessageKind.ChannelIconChange => "Changed the channel icon.", + MessageKind.ChannelPinnedMessage => "Pinned a message.", + MessageKind.GuildMemberJoin => "Joined the server.", + _ => json.GetPropertyOrNull("content")?.GetStringOrNull() ?? "" + }; - var attachments = - json.GetPropertyOrNull("attachments")?.EnumerateArray().Select(Attachment.Parse).ToArray() ?? - Array.Empty(); + var attachments = + json.GetPropertyOrNull("attachments")?.EnumerateArray().Select(Attachment.Parse).ToArray() ?? + Array.Empty(); - var embeds = - json.GetPropertyOrNull("embeds")?.EnumerateArray().Select(Embed.Parse).ToArray() ?? - Array.Empty(); + var embeds = + json.GetPropertyOrNull("embeds")?.EnumerateArray().Select(Embed.Parse).ToArray() ?? + Array.Empty(); - var reactions = - json.GetPropertyOrNull("reactions")?.EnumerateArray().Select(Reaction.Parse).ToArray() ?? - Array.Empty(); + var reactions = + json.GetPropertyOrNull("reactions")?.EnumerateArray().Select(Reaction.Parse).ToArray() ?? + Array.Empty(); - var mentionedUsers = - json.GetPropertyOrNull("mentions")?.EnumerateArray().Select(User.Parse).ToArray() ?? - Array.Empty(); + var mentionedUsers = + json.GetPropertyOrNull("mentions")?.EnumerateArray().Select(User.Parse).ToArray() ?? + Array.Empty(); - return new Message( - id, - kind, - author, - timestamp, - editedTimestamp, - callEndedTimestamp, - isPinned, - content, - attachments, - embeds, - reactions, - mentionedUsers, - messageReference, - referencedMessage - ); - } + return new Message( + id, + kind, + author, + timestamp, + editedTimestamp, + callEndedTimestamp, + isPinned, + content, + attachments, + embeds, + reactions, + mentionedUsers, + messageReference, + referencedMessage + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/MessageKind.cs b/DiscordChatExporter.Core/Discord/Data/MessageKind.cs index 78e632c..c64fdac 100644 --- a/DiscordChatExporter.Core/Discord/Data/MessageKind.cs +++ b/DiscordChatExporter.Core/Discord/Data/MessageKind.cs @@ -1,16 +1,15 @@ -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/channel#message-object-message-types +public enum MessageKind { - // https://discord.com/developers/docs/resources/channel#message-object-message-types - public enum MessageKind - { - Default = 0, - RecipientAdd = 1, - RecipientRemove = 2, - Call = 3, - ChannelNameChange = 4, - ChannelIconChange = 5, - ChannelPinnedMessage = 6, - GuildMemberJoin = 7, - Reply = 19 - } + Default = 0, + RecipientAdd = 1, + RecipientRemove = 2, + Call = 3, + ChannelNameChange = 4, + ChannelIconChange = 5, + ChannelPinnedMessage = 6, + GuildMemberJoin = 7, + Reply = 19 } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/MessageReference.cs b/DiscordChatExporter.Core/Discord/Data/MessageReference.cs index 2fa4b25..f392050 100644 --- a/DiscordChatExporter.Core/Discord/Data/MessageReference.cs +++ b/DiscordChatExporter.Core/Discord/Data/MessageReference.cs @@ -2,18 +2,17 @@ using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure +public record MessageReference(Snowflake? MessageId, Snowflake? ChannelId, Snowflake? GuildId) { - // https://discord.com/developers/docs/resources/channel#message-object-message-reference-structure - public record MessageReference(Snowflake? MessageId, Snowflake? ChannelId, Snowflake? GuildId) + public static MessageReference Parse(JsonElement json) { - public static MessageReference Parse(JsonElement json) - { - var messageId = json.GetPropertyOrNull("message_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); - var channelId = json.GetPropertyOrNull("channel_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); - var guildId = json.GetPropertyOrNull("guild_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); + var messageId = json.GetPropertyOrNull("message_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); + var channelId = json.GetPropertyOrNull("channel_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); + var guildId = json.GetPropertyOrNull("guild_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); - return new MessageReference(messageId, channelId, guildId); - } + return new MessageReference(messageId, channelId, guildId); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Reaction.cs b/DiscordChatExporter.Core/Discord/Data/Reaction.cs index 90abae9..f271c04 100644 --- a/DiscordChatExporter.Core/Discord/Data/Reaction.cs +++ b/DiscordChatExporter.Core/Discord/Data/Reaction.cs @@ -1,17 +1,16 @@ using System.Text.Json; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/channel#reaction-object +public record Reaction(Emoji Emoji, int Count) { - // https://discord.com/developers/docs/resources/channel#reaction-object - public record Reaction(Emoji Emoji, int Count) + public static Reaction Parse(JsonElement json) { - public static Reaction Parse(JsonElement json) - { - var emoji = json.GetProperty("emoji").Pipe(Emoji.Parse); - var count = json.GetProperty("count").GetInt32(); + var emoji = json.GetProperty("emoji").Pipe(Emoji.Parse); + var count = json.GetProperty("count").GetInt32(); - return new Reaction(emoji, count); - } + return new Reaction(emoji, count); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/Role.cs b/DiscordChatExporter.Core/Discord/Data/Role.cs index 860a339..b29b1db 100644 --- a/DiscordChatExporter.Core/Discord/Data/Role.cs +++ b/DiscordChatExporter.Core/Discord/Data/Role.cs @@ -4,25 +4,24 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/topics/permissions#role-object +public record Role(Snowflake Id, string Name, int Position, Color? Color) : IHasId { - // https://discord.com/developers/docs/topics/permissions#role-object - public record Role(Snowflake Id, string Name, int Position, Color? Color) : IHasId + public static Role Parse(JsonElement json) { - public static Role Parse(JsonElement json) - { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var name = json.GetProperty("name").GetNonWhiteSpaceString(); - var position = json.GetProperty("position").GetInt32(); + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var name = json.GetProperty("name").GetNonWhiteSpaceString(); + var position = json.GetProperty("position").GetInt32(); - var color = json - .GetPropertyOrNull("color")? - .GetInt32() - .Pipe(System.Drawing.Color.FromArgb) - .ResetAlpha() - .NullIf(c => c.ToRgb() <= 0); + var color = json + .GetPropertyOrNull("color")? + .GetInt32() + .Pipe(System.Drawing.Color.FromArgb) + .ResetAlpha() + .NullIf(c => c.ToRgb() <= 0); - return new Role(id, name, position, color); - } + return new Role(id, name, position, color); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/Data/User.cs b/DiscordChatExporter.Core/Discord/Data/User.cs index 7180c86..32b8aa2 100644 --- a/DiscordChatExporter.Core/Discord/Data/User.cs +++ b/DiscordChatExporter.Core/Discord/Data/User.cs @@ -4,48 +4,47 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord.Data +namespace DiscordChatExporter.Core.Discord.Data; + +// https://discord.com/developers/docs/resources/user#user-object +public partial record User( + Snowflake Id, + bool IsBot, + int Discriminator, + string Name, + string AvatarUrl) : IHasId { - // https://discord.com/developers/docs/resources/user#user-object - public partial record User( - Snowflake Id, - bool IsBot, - int Discriminator, - string Name, - string AvatarUrl) : IHasId + public string DiscriminatorFormatted => $"{Discriminator:0000}"; + + public string FullName => $"{Name}#{DiscriminatorFormatted}"; +} + +public partial record User +{ + private static string GetDefaultAvatarUrl(int discriminator) => + $"https://cdn.discordapp.com/embed/avatars/{discriminator % 5}.png"; + + private static string GetAvatarUrl(Snowflake id, string avatarHash) { - public string DiscriminatorFormatted => $"{Discriminator:0000}"; + var extension = avatarHash.StartsWith("a_", StringComparison.Ordinal) + ? "gif" + : "png"; - public string FullName => $"{Name}#{DiscriminatorFormatted}"; + return $"https://cdn.discordapp.com/avatars/{id}/{avatarHash}.{extension}?size=128"; } - public partial record User + public static User Parse(JsonElement json) { - private static string GetDefaultAvatarUrl(int discriminator) => - $"https://cdn.discordapp.com/embed/avatars/{discriminator % 5}.png"; - - private static string GetAvatarUrl(Snowflake id, string avatarHash) - { - var extension = avatarHash.StartsWith("a_", StringComparison.Ordinal) - ? "gif" - : "png"; - - return $"https://cdn.discordapp.com/avatars/{id}/{avatarHash}.{extension}?size=128"; - } - - public static User Parse(JsonElement json) - { - var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); - var isBot = json.GetPropertyOrNull("bot")?.GetBoolean() ?? false; - var discriminator = json.GetProperty("discriminator").GetNonWhiteSpaceString().Pipe(int.Parse); - var name = json.GetProperty("username").GetNonWhiteSpaceString(); - var avatarHash = json.GetPropertyOrNull("avatar")?.GetStringOrNull(); - - var avatarUrl = !string.IsNullOrWhiteSpace(avatarHash) - ? GetAvatarUrl(id, avatarHash) - : GetDefaultAvatarUrl(discriminator); - - return new User(id, isBot, discriminator, name, avatarUrl); - } + var id = json.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse); + var isBot = json.GetPropertyOrNull("bot")?.GetBoolean() ?? false; + var discriminator = json.GetProperty("discriminator").GetNonWhiteSpaceString().Pipe(int.Parse); + var name = json.GetProperty("username").GetNonWhiteSpaceString(); + var avatarHash = json.GetPropertyOrNull("avatar")?.GetStringOrNull(); + + var avatarUrl = !string.IsNullOrWhiteSpace(avatarHash) + ? GetAvatarUrl(id, avatarHash) + : GetDefaultAvatarUrl(discriminator); + + return new User(id, isBot, discriminator, name, avatarUrl); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Discord/DiscordClient.cs b/DiscordChatExporter.Core/Discord/DiscordClient.cs index 87e3c1e..1f4bd15 100644 --- a/DiscordChatExporter.Core/Discord/DiscordClient.cs +++ b/DiscordChatExporter.Core/Discord/DiscordClient.cs @@ -14,289 +14,288 @@ using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Http; using JsonExtensions.Reading; -namespace DiscordChatExporter.Core.Discord +namespace DiscordChatExporter.Core.Discord; + +public class DiscordClient { - public class DiscordClient + private readonly AuthToken _token; + private readonly Uri _baseUri = new("https://discord.com/api/v8/", UriKind.Absolute); + + public DiscordClient(AuthToken token) => _token = token; + + private async ValueTask GetResponseAsync( + string url, + CancellationToken cancellationToken = default) { - private readonly AuthToken _token; - private readonly Uri _baseUri = new("https://discord.com/api/v8/", UriKind.Absolute); + return await Http.ResponsePolicy.ExecuteAsync(async innerCancellationToken => + { + using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url)); + request.Headers.Authorization = _token.GetAuthenticationHeader(); + + return await Http.Client.SendAsync( + request, + HttpCompletionOption.ResponseHeadersRead, + innerCancellationToken + ); + }, cancellationToken); + } - public DiscordClient(AuthToken token) => _token = token; + private async ValueTask GetJsonResponseAsync( + string url, + CancellationToken cancellationToken = default) + { + using var response = await GetResponseAsync(url, cancellationToken); - private async ValueTask GetResponseAsync( - string url, - CancellationToken cancellationToken = default) + if (!response.IsSuccessStatusCode) { - return await Http.ResponsePolicy.ExecuteAsync(async innerCancellationToken => + throw response.StatusCode switch { - using var request = new HttpRequestMessage(HttpMethod.Get, new Uri(_baseUri, url)); - request.Headers.Authorization = _token.GetAuthenticationHeader(); - - return await Http.Client.SendAsync( - request, - HttpCompletionOption.ResponseHeadersRead, - innerCancellationToken - ); - }, cancellationToken); + HttpStatusCode.Unauthorized => DiscordChatExporterException.Unauthorized(), + HttpStatusCode.Forbidden => DiscordChatExporterException.Forbidden(), + HttpStatusCode.NotFound => DiscordChatExporterException.NotFound(url), + _ => DiscordChatExporterException.FailedHttpRequest(response) + }; } - private async ValueTask GetJsonResponseAsync( - string url, - CancellationToken cancellationToken = default) - { - using var response = await GetResponseAsync(url, cancellationToken); + return await response.Content.ReadAsJsonAsync(cancellationToken); + } - if (!response.IsSuccessStatusCode) - { - throw response.StatusCode switch - { - HttpStatusCode.Unauthorized => DiscordChatExporterException.Unauthorized(), - HttpStatusCode.Forbidden => DiscordChatExporterException.Forbidden(), - HttpStatusCode.NotFound => DiscordChatExporterException.NotFound(url), - _ => DiscordChatExporterException.FailedHttpRequest(response) - }; - } + private async ValueTask TryGetJsonResponseAsync( + string url, + CancellationToken cancellationToken = default) + { + using var response = await GetResponseAsync(url, cancellationToken); - return await response.Content.ReadAsJsonAsync(cancellationToken); - } + return response.IsSuccessStatusCode + ? await response.Content.ReadAsJsonAsync(cancellationToken) + : null; + } - private async ValueTask TryGetJsonResponseAsync( - string url, - CancellationToken cancellationToken = default) - { - using var response = await GetResponseAsync(url, cancellationToken); + public async IAsyncEnumerable GetUserGuildsAsync( + [EnumeratorCancellation] CancellationToken cancellationToken = default) + { + yield return Guild.DirectMessages; - return response.IsSuccessStatusCode - ? await response.Content.ReadAsJsonAsync(cancellationToken) - : null; - } + var currentAfter = Snowflake.Zero; - public async IAsyncEnumerable GetUserGuildsAsync( - [EnumeratorCancellation] CancellationToken cancellationToken = default) + while (true) { - yield return Guild.DirectMessages; + var url = new UrlBuilder() + .SetPath("users/@me/guilds") + .SetQueryParameter("limit", "100") + .SetQueryParameter("after", currentAfter.ToString()) + .Build(); - var currentAfter = Snowflake.Zero; + var response = await GetJsonResponseAsync(url, cancellationToken); - while (true) + var isEmpty = true; + foreach (var guild in response.EnumerateArray().Select(Guild.Parse)) { - var url = new UrlBuilder() - .SetPath("users/@me/guilds") - .SetQueryParameter("limit", "100") - .SetQueryParameter("after", currentAfter.ToString()) - .Build(); + yield return guild; - var response = await GetJsonResponseAsync(url, cancellationToken); + currentAfter = guild.Id; + isEmpty = false; + } - var isEmpty = true; - foreach (var guild in response.EnumerateArray().Select(Guild.Parse)) - { - yield return guild; + if (isEmpty) + yield break; + } + } - currentAfter = guild.Id; - isEmpty = false; - } + public async ValueTask GetGuildAsync( + Snowflake guildId, + CancellationToken cancellationToken = default) + { + if (guildId == Guild.DirectMessages.Id) + return Guild.DirectMessages; - if (isEmpty) - yield break; - } - } + var response = await GetJsonResponseAsync($"guilds/{guildId}", cancellationToken); + return Guild.Parse(response); + } - public async ValueTask GetGuildAsync( - Snowflake guildId, - CancellationToken cancellationToken = default) + public async IAsyncEnumerable GetGuildChannelsAsync( + Snowflake guildId, + [EnumeratorCancellation] CancellationToken cancellationToken = default) + { + if (guildId == Guild.DirectMessages.Id) { - if (guildId == Guild.DirectMessages.Id) - return Guild.DirectMessages; - - var response = await GetJsonResponseAsync($"guilds/{guildId}", cancellationToken); - return Guild.Parse(response); + var response = await GetJsonResponseAsync("users/@me/channels", cancellationToken); + foreach (var channelJson in response.EnumerateArray()) + yield return Channel.Parse(channelJson); } - - public async IAsyncEnumerable GetGuildChannelsAsync( - Snowflake guildId, - [EnumeratorCancellation] CancellationToken cancellationToken = default) + else { - if (guildId == Guild.DirectMessages.Id) - { - var response = await GetJsonResponseAsync("users/@me/channels", cancellationToken); - foreach (var channelJson in response.EnumerateArray()) - yield return Channel.Parse(channelJson); - } - else - { - var response = await GetJsonResponseAsync($"guilds/{guildId}/channels", cancellationToken); + var response = await GetJsonResponseAsync($"guilds/{guildId}/channels", cancellationToken); - var responseOrdered = response - .EnumerateArray() - .OrderBy(j => j.GetProperty("position").GetInt32()) - .ThenBy(j => j.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse)) - .ToArray(); + var responseOrdered = response + .EnumerateArray() + .OrderBy(j => j.GetProperty("position").GetInt32()) + .ThenBy(j => j.GetProperty("id").GetNonWhiteSpaceString().Pipe(Snowflake.Parse)) + .ToArray(); - var categories = responseOrdered - .Where(j => j.GetProperty("type").GetInt32() == (int) ChannelKind.GuildCategory) - .Select((j, index) => ChannelCategory.Parse(j, index + 1)) - .ToDictionary(j => j.Id.ToString(), StringComparer.Ordinal); + var categories = responseOrdered + .Where(j => j.GetProperty("type").GetInt32() == (int) ChannelKind.GuildCategory) + .Select((j, index) => ChannelCategory.Parse(j, index + 1)) + .ToDictionary(j => j.Id.ToString(), StringComparer.Ordinal); - var position = 0; + var position = 0; - foreach (var channelJson in responseOrdered) - { - var parentId = channelJson.GetPropertyOrNull("parent_id")?.GetStringOrNull(); + foreach (var channelJson in responseOrdered) + { + var parentId = channelJson.GetPropertyOrNull("parent_id")?.GetStringOrNull(); - var category = !string.IsNullOrWhiteSpace(parentId) - ? categories.GetValueOrDefault(parentId) - : null; + var category = !string.IsNullOrWhiteSpace(parentId) + ? categories.GetValueOrDefault(parentId) + : null; - var channel = Channel.Parse(channelJson, category, position); + var channel = Channel.Parse(channelJson, category, position); - position++; + position++; - yield return channel; - } + yield return channel; } } + } - public async IAsyncEnumerable GetGuildRolesAsync( - Snowflake guildId, - [EnumeratorCancellation] CancellationToken cancellationToken = default) - { - if (guildId == Guild.DirectMessages.Id) - yield break; + public async IAsyncEnumerable GetGuildRolesAsync( + Snowflake guildId, + [EnumeratorCancellation] CancellationToken cancellationToken = default) + { + if (guildId == Guild.DirectMessages.Id) + yield break; - var response = await GetJsonResponseAsync($"guilds/{guildId}/roles", cancellationToken); + var response = await GetJsonResponseAsync($"guilds/{guildId}/roles", cancellationToken); - foreach (var roleJson in response.EnumerateArray()) - yield return Role.Parse(roleJson); - } + foreach (var roleJson in response.EnumerateArray()) + yield return Role.Parse(roleJson); + } - public async ValueTask GetGuildMemberAsync( - Snowflake guildId, - User user, - CancellationToken cancellationToken = default) - { - if (guildId == Guild.DirectMessages.Id) - return Member.CreateForUser(user); + public async ValueTask GetGuildMemberAsync( + Snowflake guildId, + User user, + CancellationToken cancellationToken = default) + { + if (guildId == Guild.DirectMessages.Id) + return Member.CreateForUser(user); - var response = await TryGetJsonResponseAsync($"guilds/{guildId}/members/{user.Id}", cancellationToken); - return response?.Pipe(Member.Parse) ?? Member.CreateForUser(user); - } + var response = await TryGetJsonResponseAsync($"guilds/{guildId}/members/{user.Id}", cancellationToken); + return response?.Pipe(Member.Parse) ?? Member.CreateForUser(user); + } - public async ValueTask GetChannelCategoryAsync( - Snowflake channelId, - CancellationToken cancellationToken = default) + public async ValueTask GetChannelCategoryAsync( + Snowflake channelId, + CancellationToken cancellationToken = default) + { + try { - try - { - var response = await GetJsonResponseAsync($"channels/{channelId}", cancellationToken); - return ChannelCategory.Parse(response); - } - // In some cases, the Discord API returns an empty body when requesting channel category. - // Instead, we use an empty channel category as a fallback. - catch (DiscordChatExporterException) - { - return ChannelCategory.Unknown; - } + var response = await GetJsonResponseAsync($"channels/{channelId}", cancellationToken); + return ChannelCategory.Parse(response); } - - public async ValueTask GetChannelAsync( - Snowflake channelId, - CancellationToken cancellationToken = default) + // In some cases, the Discord API returns an empty body when requesting channel category. + // Instead, we use an empty channel category as a fallback. + catch (DiscordChatExporterException) { - var response = await GetJsonResponseAsync($"channels/{channelId}", cancellationToken); + return ChannelCategory.Unknown; + } + } - var parentId = response.GetPropertyOrNull("parent_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); + public async ValueTask GetChannelAsync( + Snowflake channelId, + CancellationToken cancellationToken = default) + { + var response = await GetJsonResponseAsync($"channels/{channelId}", cancellationToken); - var category = parentId is not null - ? await GetChannelCategoryAsync(parentId.Value, cancellationToken) - : null; + var parentId = response.GetPropertyOrNull("parent_id")?.GetStringOrNull()?.Pipe(Snowflake.Parse); - return Channel.Parse(response, category); - } + var category = parentId is not null + ? await GetChannelCategoryAsync(parentId.Value, cancellationToken) + : null; + + return Channel.Parse(response, category); + } - private async ValueTask TryGetLastMessageAsync( - Snowflake channelId, - Snowflake? before = null, - CancellationToken cancellationToken = default) + private async ValueTask TryGetLastMessageAsync( + Snowflake channelId, + Snowflake? before = null, + CancellationToken cancellationToken = default) + { + var url = new UrlBuilder() + .SetPath($"channels/{channelId}/messages") + .SetQueryParameter("limit", "1") + .SetQueryParameter("before", before?.ToString()) + .Build(); + + var response = await GetJsonResponseAsync(url, cancellationToken); + return response.EnumerateArray().Select(Message.Parse).LastOrDefault(); + } + + public async IAsyncEnumerable GetMessagesAsync( + Snowflake channelId, + Snowflake? after = null, + Snowflake? before = null, + IProgress? progress = null, + [EnumeratorCancellation] CancellationToken cancellationToken = default) + { + // Get the last message in the specified range. + // This snapshots the boundaries, which means that messages posted after the export started + // will not appear in the output. + // Additionally, it provides the date of the last message, which is used to calculate progress. + var lastMessage = await TryGetLastMessageAsync(channelId, before, cancellationToken); + if (lastMessage is null || lastMessage.Timestamp < after?.ToDate()) + yield break; + + // Keep track of first message in range in order to calculate progress + var firstMessage = default(Message); + var currentAfter = after ?? Snowflake.Zero; + + while (true) { var url = new UrlBuilder() .SetPath($"channels/{channelId}/messages") - .SetQueryParameter("limit", "1") - .SetQueryParameter("before", before?.ToString()) + .SetQueryParameter("limit", "100") + .SetQueryParameter("after", currentAfter.ToString()) .Build(); var response = await GetJsonResponseAsync(url, cancellationToken); - return response.EnumerateArray().Select(Message.Parse).LastOrDefault(); - } - public async IAsyncEnumerable GetMessagesAsync( - Snowflake channelId, - Snowflake? after = null, - Snowflake? before = null, - IProgress? progress = null, - [EnumeratorCancellation] CancellationToken cancellationToken = default) - { - // Get the last message in the specified range. - // This snapshots the boundaries, which means that messages posted after the export started - // will not appear in the output. - // Additionally, it provides the date of the last message, which is used to calculate progress. - var lastMessage = await TryGetLastMessageAsync(channelId, before, cancellationToken); - if (lastMessage is null || lastMessage.Timestamp < after?.ToDate()) - yield break; + var messages = response + .EnumerateArray() + .Select(Message.Parse) + .Reverse() // reverse because messages appear newest first + .ToArray(); - // Keep track of first message in range in order to calculate progress - var firstMessage = default(Message); - var currentAfter = after ?? Snowflake.Zero; + // Break if there are no messages (can happen if messages are deleted during execution) + if (!messages.Any()) + yield break; - while (true) + foreach (var message in messages) { - var url = new UrlBuilder() - .SetPath($"channels/{channelId}/messages") - .SetQueryParameter("limit", "100") - .SetQueryParameter("after", currentAfter.ToString()) - .Build(); - - var response = await GetJsonResponseAsync(url, cancellationToken); - - var messages = response - .EnumerateArray() - .Select(Message.Parse) - .Reverse() // reverse because messages appear newest first - .ToArray(); - - // Break if there are no messages (can happen if messages are deleted during execution) - if (!messages.Any()) + firstMessage ??= message; + + // Ensure messages are in range (take into account that last message could have been deleted) + if (message.Timestamp > lastMessage.Timestamp) yield break; - foreach (var message in messages) + // Report progress based on the duration of exported messages divided by total + if (progress is not null) { - firstMessage ??= message; - - // Ensure messages are in range (take into account that last message could have been deleted) - if (message.Timestamp > lastMessage.Timestamp) - yield break; + var exportedDuration = (message.Timestamp - firstMessage.Timestamp).Duration(); + var totalDuration = (lastMessage.Timestamp - firstMessage.Timestamp).Duration(); - // Report progress based on the duration of exported messages divided by total - if (progress is not null) + if (totalDuration > TimeSpan.Zero) { - var exportedDuration = (message.Timestamp - firstMessage.Timestamp).Duration(); - var totalDuration = (lastMessage.Timestamp - firstMessage.Timestamp).Duration(); - - if (totalDuration > TimeSpan.Zero) - { - progress.Report(exportedDuration / totalDuration); - } - // Avoid division by zero if all messages have the exact same timestamp - // (which may be the case if there's only one message in the channel) - else - { - progress.Report(1); - } + progress.Report(exportedDuration / totalDuration); + } + // Avoid division by zero if all messages have the exact same timestamp + // (which may be the case if there's only one message in the channel) + else + { + progress.Report(1); } - - yield return message; - currentAfter = message.Id; } + + yield return message; + currentAfter = message.Id; } } } diff --git a/DiscordChatExporter.Core/Discord/Snowflake.cs b/DiscordChatExporter.Core/Discord/Snowflake.cs index e02e169..38c75d2 100644 --- a/DiscordChatExporter.Core/Discord/Snowflake.cs +++ b/DiscordChatExporter.Core/Discord/Snowflake.cs @@ -3,54 +3,53 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text.RegularExpressions; -namespace DiscordChatExporter.Core.Discord -{ - public readonly partial record struct Snowflake(ulong Value) - { - public DateTimeOffset ToDate() => DateTimeOffset.FromUnixTimeMilliseconds( - (long)((Value >> 22) + 1420070400000UL) - ).ToLocalTime(); - - [ExcludeFromCodeCoverage] - public override string ToString() => Value.ToString(CultureInfo.InvariantCulture); - } - - public partial record struct Snowflake - { - public static Snowflake Zero { get; } = new(0); +namespace DiscordChatExporter.Core.Discord; - public static Snowflake FromDate(DateTimeOffset date) => new( - ((ulong)date.ToUnixTimeMilliseconds() - 1420070400000UL) << 22 - ); +public readonly partial record struct Snowflake(ulong Value) +{ + public DateTimeOffset ToDate() => DateTimeOffset.FromUnixTimeMilliseconds( + (long)((Value >> 22) + 1420070400000UL) + ).ToLocalTime(); - public static Snowflake? TryParse(string? str, IFormatProvider? formatProvider = null) - { - if (string.IsNullOrWhiteSpace(str)) - return null; + [ExcludeFromCodeCoverage] + public override string ToString() => Value.ToString(CultureInfo.InvariantCulture); +} - // As number - if (Regex.IsMatch(str, @"^\d+$") && ulong.TryParse(str, NumberStyles.Number, formatProvider, out var value)) - { - return new Snowflake(value); - } +public partial record struct Snowflake +{ + public static Snowflake Zero { get; } = new(0); - // As date - if (DateTimeOffset.TryParse(str, formatProvider, DateTimeStyles.None, out var date)) - { - return FromDate(date); - } + public static Snowflake FromDate(DateTimeOffset date) => new( + ((ulong)date.ToUnixTimeMilliseconds() - 1420070400000UL) << 22 + ); + public static Snowflake? TryParse(string? str, IFormatProvider? formatProvider = null) + { + if (string.IsNullOrWhiteSpace(str)) return null; + + // As number + if (Regex.IsMatch(str, @"^\d+$") && ulong.TryParse(str, NumberStyles.Number, formatProvider, out var value)) + { + return new Snowflake(value); } - public static Snowflake Parse(string str, IFormatProvider? formatProvider) => - TryParse(str, formatProvider) ?? throw new FormatException($"Invalid snowflake '{str}'."); + // As date + if (DateTimeOffset.TryParse(str, formatProvider, DateTimeStyles.None, out var date)) + { + return FromDate(date); + } - public static Snowflake Parse(string str) => Parse(str, null); + return null; } - public partial record struct Snowflake : IComparable - { - public int CompareTo(Snowflake other) => Value.CompareTo(other.Value); - } + public static Snowflake Parse(string str, IFormatProvider? formatProvider) => + TryParse(str, formatProvider) ?? throw new FormatException($"Invalid snowflake '{str}'."); + + public static Snowflake Parse(string str) => Parse(str, null); +} + +public partial record struct Snowflake : IComparable +{ + public int CompareTo(Snowflake other) => Value.CompareTo(other.Value); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exceptions/DiscordChatExporterException.cs b/DiscordChatExporter.Core/Exceptions/DiscordChatExporterException.cs index 530da2f..7543c5f 100644 --- a/DiscordChatExporter.Core/Exceptions/DiscordChatExporterException.cs +++ b/DiscordChatExporter.Core/Exceptions/DiscordChatExporterException.cs @@ -1,24 +1,24 @@ using System; using System.Net.Http; -namespace DiscordChatExporter.Core.Exceptions +namespace DiscordChatExporter.Core.Exceptions; + +public partial class DiscordChatExporterException : Exception { - public partial class DiscordChatExporterException : Exception - { - public bool IsFatal { get; } + public bool IsFatal { get; } - public DiscordChatExporterException(string message, bool isFatal = false) - : base(message) - { - IsFatal = isFatal; - } + public DiscordChatExporterException(string message, bool isFatal = false) + : base(message) + { + IsFatal = isFatal; } +} - public partial class DiscordChatExporterException +public partial class DiscordChatExporterException +{ + internal static DiscordChatExporterException FailedHttpRequest(HttpResponseMessage response) { - internal static DiscordChatExporterException FailedHttpRequest(HttpResponseMessage response) - { - var message = $@" + var message = $@" Failed to perform an HTTP request. [Request] @@ -27,19 +27,18 @@ Failed to perform an HTTP request. [Response] {response}"; - return new DiscordChatExporterException(message.Trim(), true); - } + return new DiscordChatExporterException(message.Trim(), true); + } - internal static DiscordChatExporterException Unauthorized() => - new("Authentication token is invalid.", true); + internal static DiscordChatExporterException Unauthorized() => + new("Authentication token is invalid.", true); - internal static DiscordChatExporterException Forbidden() => - new("Access is forbidden."); + internal static DiscordChatExporterException Forbidden() => + new("Access is forbidden."); - internal static DiscordChatExporterException NotFound(string resourceId) => - new($"Requested resource ({resourceId}) does not exist."); + internal static DiscordChatExporterException NotFound(string resourceId) => + new($"Requested resource ({resourceId}) does not exist."); - internal static DiscordChatExporterException ChannelIsEmpty() => - new("No messages found for the specified period."); - } + internal static DiscordChatExporterException ChannelIsEmpty() => + new("No messages found for the specified period."); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs index 47ca98a..165b610 100644 --- a/DiscordChatExporter.Core/Exporting/ChannelExporter.cs +++ b/DiscordChatExporter.Core/Exporting/ChannelExporter.cs @@ -9,75 +9,74 @@ using DiscordChatExporter.Core.Discord.Data.Common; using DiscordChatExporter.Core.Exceptions; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Exporting -{ - public class ChannelExporter - { - private readonly DiscordClient _discord; +namespace DiscordChatExporter.Core.Exporting; - public ChannelExporter(DiscordClient discord) => _discord = discord; +public class ChannelExporter +{ + private readonly DiscordClient _discord; - public ChannelExporter(AuthToken token) : this(new DiscordClient(token)) {} + public ChannelExporter(DiscordClient discord) => _discord = discord; - public async ValueTask ExportChannelAsync( - ExportRequest request, - IProgress? progress = null, - CancellationToken cancellationToken = default) - { - // Build context - var contextMembers = new HashSet(IdBasedEqualityComparer.Instance); - var contextChannels = await _discord.GetGuildChannelsAsync(request.Guild.Id, cancellationToken); - var contextRoles = await _discord.GetGuildRolesAsync(request.Guild.Id, cancellationToken); + public ChannelExporter(AuthToken token) : this(new DiscordClient(token)) {} - var context = new ExportContext( - request, - contextMembers, - contextChannels, - contextRoles - ); + public async ValueTask ExportChannelAsync( + ExportRequest request, + IProgress? progress = null, + CancellationToken cancellationToken = default) + { + // Build context + var contextMembers = new HashSet(IdBasedEqualityComparer.Instance); + var contextChannels = await _discord.GetGuildChannelsAsync(request.Guild.Id, cancellationToken); + var contextRoles = await _discord.GetGuildRolesAsync(request.Guild.Id, cancellationToken); - // Export messages - await using var messageExporter = new MessageExporter(context); + var context = new ExportContext( + request, + contextMembers, + contextChannels, + contextRoles + ); - var exportedAnything = false; - var encounteredUsers = new HashSet(IdBasedEqualityComparer.Instance); + // Export messages + await using var messageExporter = new MessageExporter(context); - await foreach (var message in _discord.GetMessagesAsync( - request.Channel.Id, - request.After, - request.Before, - progress, - cancellationToken)) - { - cancellationToken.ThrowIfCancellationRequested(); + var exportedAnything = false; + var encounteredUsers = new HashSet(IdBasedEqualityComparer.Instance); - // Skips any messages that fail to pass the supplied filter - if (!request.MessageFilter.IsMatch(message)) - continue; + await foreach (var message in _discord.GetMessagesAsync( + request.Channel.Id, + request.After, + request.Before, + progress, + cancellationToken)) + { + cancellationToken.ThrowIfCancellationRequested(); - // Resolve members for referenced users - foreach (var referencedUser in message.MentionedUsers.Prepend(message.Author)) - { - if (!encounteredUsers.Add(referencedUser)) - continue; + // Skips any messages that fail to pass the supplied filter + if (!request.MessageFilter.IsMatch(message)) + continue; - var member = await _discord.GetGuildMemberAsync( - request.Guild.Id, - referencedUser, - cancellationToken - ); + // Resolve members for referenced users + foreach (var referencedUser in message.MentionedUsers.Prepend(message.Author)) + { + if (!encounteredUsers.Add(referencedUser)) + continue; - contextMembers.Add(member); - } + var member = await _discord.GetGuildMemberAsync( + request.Guild.Id, + referencedUser, + cancellationToken + ); - // Export message - await messageExporter.ExportMessageAsync(message, cancellationToken); - exportedAnything = true; + contextMembers.Add(member); } - // Throw if no messages were exported - if (!exportedAnything) - throw DiscordChatExporterException.ChannelIsEmpty(); + // Export message + await messageExporter.ExportMessageAsync(message, cancellationToken); + exportedAnything = true; } + + // Throw if no messages were exported + if (!exportedAnything) + throw DiscordChatExporterException.ChannelIsEmpty(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/ExportContext.cs b/DiscordChatExporter.Core/Exporting/ExportContext.cs index 96d5bfa..70ede4e 100644 --- a/DiscordChatExporter.Core/Exporting/ExportContext.cs +++ b/DiscordChatExporter.Core/Exporting/ExportContext.cs @@ -10,97 +10,96 @@ using DiscordChatExporter.Core.Discord; using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Exporting +namespace DiscordChatExporter.Core.Exporting; + +internal class ExportContext { - internal class ExportContext - { - private readonly MediaDownloader _mediaDownloader; + private readonly MediaDownloader _mediaDownloader; - public ExportRequest Request { get; } + public ExportRequest Request { get; } - public IReadOnlyCollection Members { get; } + public IReadOnlyCollection Members { get; } - public IReadOnlyCollection Channels { get; } + public IReadOnlyCollection Channels { get; } - public IReadOnlyCollection Roles { get; } + public IReadOnlyCollection Roles { get; } - public ExportContext( - ExportRequest request, - IReadOnlyCollection members, - IReadOnlyCollection channels, - IReadOnlyCollection roles) - { - Request = request; - Members = members; - Channels = channels; - Roles = roles; + public ExportContext( + ExportRequest request, + IReadOnlyCollection members, + IReadOnlyCollection channels, + IReadOnlyCollection roles) + { + Request = request; + Members = members; + Channels = channels; + Roles = roles; - _mediaDownloader = new MediaDownloader(request.OutputMediaDirPath, request.ShouldReuseMedia); - } + _mediaDownloader = new MediaDownloader(request.OutputMediaDirPath, request.ShouldReuseMedia); + } - public string FormatDate(DateTimeOffset date) => Request.DateFormat switch - { - "unix" => date.ToUnixTimeSeconds().ToString(), - "unixms" => date.ToUnixTimeMilliseconds().ToString(), - var dateFormat => date.ToLocalString(dateFormat) - }; + public string FormatDate(DateTimeOffset date) => Request.DateFormat switch + { + "unix" => date.ToUnixTimeSeconds().ToString(), + "unixms" => date.ToUnixTimeMilliseconds().ToString(), + var dateFormat => date.ToLocalString(dateFormat) + }; - public Member? TryGetMember(Snowflake id) => Members.FirstOrDefault(m => m.Id == id); + public Member? TryGetMember(Snowflake id) => Members.FirstOrDefault(m => m.Id == id); - public Channel? TryGetChannel(Snowflake id) => Channels.FirstOrDefault(c => c.Id == id); + public Channel? TryGetChannel(Snowflake id) => Channels.FirstOrDefault(c => c.Id == id); - public Role? TryGetRole(Snowflake id) => Roles.FirstOrDefault(r => r.Id == id); + public Role? TryGetRole(Snowflake id) => Roles.FirstOrDefault(r => r.Id == id); - public Color? TryGetUserColor(Snowflake id) - { - var member = TryGetMember(id); - var roles = member?.RoleIds.Join(Roles, i => i, r => r.Id, (_, role) => role); - - return roles? - .Where(r => r.Color is not null) - .OrderByDescending(r => r.Position) - .Select(r => r.Color) - .FirstOrDefault(); - } + public Color? TryGetUserColor(Snowflake id) + { + var member = TryGetMember(id); + var roles = member?.RoleIds.Join(Roles, i => i, r => r.Id, (_, role) => role); + + return roles? + .Where(r => r.Color is not null) + .OrderByDescending(r => r.Position) + .Select(r => r.Color) + .FirstOrDefault(); + } - public async ValueTask ResolveMediaUrlAsync(string url, CancellationToken cancellationToken = default) + public async ValueTask ResolveMediaUrlAsync(string url, CancellationToken cancellationToken = default) + { + if (!Request.ShouldDownloadMedia) + return url; + + try { - if (!Request.ShouldDownloadMedia) - return url; + var filePath = await _mediaDownloader.DownloadAsync(url, cancellationToken); - try - { - var filePath = await _mediaDownloader.DownloadAsync(url, cancellationToken); - - // We want relative path so that the output files can be copied around without breaking. - // Base directory path may be null if the file is stored at the root or relative to working directory. - var relativeFilePath = !string.IsNullOrWhiteSpace(Request.OutputBaseDirPath) - ? Path.GetRelativePath(Request.OutputBaseDirPath, filePath) - : filePath; - - // HACK: for HTML, we need to format the URL properly - if (Request.Format is ExportFormat.HtmlDark or ExportFormat.HtmlLight) - { - // Need to escape each path segment while keeping the directory separators intact - return string.Join( - Path.AltDirectorySeparatorChar, - relativeFilePath - .Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) - .Select(Uri.EscapeDataString) - ); - } - - return relativeFilePath; - } - // Try to catch only exceptions related to failed HTTP requests - // https://github.com/Tyrrrz/DiscordChatExporter/issues/332 - // https://github.com/Tyrrrz/DiscordChatExporter/issues/372 - catch (Exception ex) when (ex is HttpRequestException or OperationCanceledException) + // We want relative path so that the output files can be copied around without breaking. + // Base directory path may be null if the file is stored at the root or relative to working directory. + var relativeFilePath = !string.IsNullOrWhiteSpace(Request.OutputBaseDirPath) + ? Path.GetRelativePath(Request.OutputBaseDirPath, filePath) + : filePath; + + // HACK: for HTML, we need to format the URL properly + if (Request.Format is ExportFormat.HtmlDark or ExportFormat.HtmlLight) { - // TODO: add logging so we can be more liberal with catching exceptions - // We don't want this to crash the exporting process in case of failure - return url; + // Need to escape each path segment while keeping the directory separators intact + return string.Join( + Path.AltDirectorySeparatorChar, + relativeFilePath + .Split(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + .Select(Uri.EscapeDataString) + ); } + + return relativeFilePath; + } + // Try to catch only exceptions related to failed HTTP requests + // https://github.com/Tyrrrz/DiscordChatExporter/issues/332 + // https://github.com/Tyrrrz/DiscordChatExporter/issues/372 + catch (Exception ex) when (ex is HttpRequestException or OperationCanceledException) + { + // TODO: add logging so we can be more liberal with catching exceptions + // We don't want this to crash the exporting process in case of failure + return url; } } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/ExportFormat.cs b/DiscordChatExporter.Core/Exporting/ExportFormat.cs index 5119347..41a06b7 100644 --- a/DiscordChatExporter.Core/Exporting/ExportFormat.cs +++ b/DiscordChatExporter.Core/Exporting/ExportFormat.cs @@ -1,36 +1,35 @@ using System; -namespace DiscordChatExporter.Core.Exporting +namespace DiscordChatExporter.Core.Exporting; + +public enum ExportFormat { - public enum ExportFormat - { - PlainText, - HtmlDark, - HtmlLight, - Csv, - Json - } + PlainText, + HtmlDark, + HtmlLight, + Csv, + Json +} - public static class ExportFormatExtensions +public static class ExportFormatExtensions +{ + public static string GetFileExtension(this ExportFormat format) => format switch { - public static string GetFileExtension(this ExportFormat format) => format switch - { - ExportFormat.PlainText => "txt", - ExportFormat.HtmlDark => "html", - ExportFormat.HtmlLight => "html", - ExportFormat.Csv => "csv", - ExportFormat.Json => "json", - _ => throw new ArgumentOutOfRangeException(nameof(format)) - }; + ExportFormat.PlainText => "txt", + ExportFormat.HtmlDark => "html", + ExportFormat.HtmlLight => "html", + ExportFormat.Csv => "csv", + ExportFormat.Json => "json", + _ => throw new ArgumentOutOfRangeException(nameof(format)) + }; - public static string GetDisplayName(this ExportFormat format) => format switch - { - ExportFormat.PlainText => "TXT", - ExportFormat.HtmlDark => "HTML (Dark)", - ExportFormat.HtmlLight => "HTML (Light)", - ExportFormat.Csv => "CSV", - ExportFormat.Json => "JSON", - _ => throw new ArgumentOutOfRangeException(nameof(format)) - }; - } + public static string GetDisplayName(this ExportFormat format) => format switch + { + ExportFormat.PlainText => "TXT", + ExportFormat.HtmlDark => "HTML (Dark)", + ExportFormat.HtmlLight => "HTML (Light)", + ExportFormat.Csv => "CSV", + ExportFormat.Json => "JSON", + _ => throw new ArgumentOutOfRangeException(nameof(format)) + }; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/ExportRequest.cs b/DiscordChatExporter.Core/Exporting/ExportRequest.cs index e73d461..db61514 100644 --- a/DiscordChatExporter.Core/Exporting/ExportRequest.cs +++ b/DiscordChatExporter.Core/Exporting/ExportRequest.cs @@ -8,120 +8,119 @@ using DiscordChatExporter.Core.Exporting.Filtering; using DiscordChatExporter.Core.Exporting.Partitioning; using DiscordChatExporter.Core.Utils; -namespace DiscordChatExporter.Core.Exporting +namespace DiscordChatExporter.Core.Exporting; + +public partial record ExportRequest( + Guild Guild, + Channel Channel, + string OutputPath, + ExportFormat Format, + Snowflake? After, + Snowflake? Before, + PartitionLimit PartitionLimit, + MessageFilter MessageFilter, + bool ShouldDownloadMedia, + bool ShouldReuseMedia, + string DateFormat) { - public partial record ExportRequest( - Guild Guild, - Channel Channel, - string OutputPath, - ExportFormat Format, - Snowflake? After, - Snowflake? Before, - PartitionLimit PartitionLimit, - MessageFilter MessageFilter, - bool ShouldDownloadMedia, - bool ShouldReuseMedia, - string DateFormat) - { - private string? _outputBaseFilePath; - public string OutputBaseFilePath => _outputBaseFilePath ??= GetOutputBaseFilePath( - Guild, - Channel, - OutputPath, - Format, - After, - Before - ); + private string? _outputBaseFilePath; + public string OutputBaseFilePath => _outputBaseFilePath ??= GetOutputBaseFilePath( + Guild, + Channel, + OutputPath, + Format, + After, + Before + ); - public string OutputBaseDirPath => Path.GetDirectoryName(OutputBaseFilePath) ?? OutputPath; + public string OutputBaseDirPath => Path.GetDirectoryName(OutputBaseFilePath) ?? OutputPath; - public string OutputMediaDirPath => $"{OutputBaseFilePath}_Files{Path.DirectorySeparatorChar}"; - } + public string OutputMediaDirPath => $"{OutputBaseFilePath}_Files{Path.DirectorySeparatorChar}"; +} - public partial record ExportRequest +public partial record ExportRequest +{ + private static string GetOutputBaseFilePath( + Guild guild, + Channel channel, + string outputPath, + ExportFormat format, + Snowflake? after = null, + Snowflake? before = null) { - private static string GetOutputBaseFilePath( - Guild guild, - Channel channel, - string outputPath, - ExportFormat format, - Snowflake? after = null, - Snowflake? before = null) - { - // Formats path - outputPath = Regex.Replace(outputPath, "%.", m => - PathEx.EscapePath(m.Value switch - { - "%g" => guild.Id.ToString(), - "%G" => guild.Name, - "%t" => channel.Category.Id.ToString(), - "%T" => channel.Category.Name, - "%c" => channel.Id.ToString(), - "%C" => channel.Name, - "%p" => channel.Position?.ToString() ?? "0", - "%P" => channel.Category.Position?.ToString() ?? "0", - "%a" => (after ?? Snowflake.Zero).ToDate().ToString("yyyy-MM-dd"), - "%b" => (before?.ToDate() ?? DateTime.Now).ToString("yyyy-MM-dd"), - "%%" => "%", - _ => m.Value - }) - ); - - // Output is a directory - if (Directory.Exists(outputPath) || string.IsNullOrWhiteSpace(Path.GetExtension(outputPath))) + // Formats path + outputPath = Regex.Replace(outputPath, "%.", m => + PathEx.EscapePath(m.Value switch { - var fileName = GetDefaultOutputFileName(guild, channel, format, after, before); - return Path.Combine(outputPath, fileName); - } + "%g" => guild.Id.ToString(), + "%G" => guild.Name, + "%t" => channel.Category.Id.ToString(), + "%T" => channel.Category.Name, + "%c" => channel.Id.ToString(), + "%C" => channel.Name, + "%p" => channel.Position?.ToString() ?? "0", + "%P" => channel.Category.Position?.ToString() ?? "0", + "%a" => (after ?? Snowflake.Zero).ToDate().ToString("yyyy-MM-dd"), + "%b" => (before?.ToDate() ?? DateTime.Now).ToString("yyyy-MM-dd"), + "%%" => "%", + _ => m.Value + }) + ); - // Output is a file - return outputPath; + // Output is a directory + if (Directory.Exists(outputPath) || string.IsNullOrWhiteSpace(Path.GetExtension(outputPath))) + { + var fileName = GetDefaultOutputFileName(guild, channel, format, after, before); + return Path.Combine(outputPath, fileName); } - public static string GetDefaultOutputFileName( - Guild guild, - Channel channel, - ExportFormat format, - Snowflake? after = null, - Snowflake? before = null) - { - var buffer = new StringBuilder(); + // Output is a file + return outputPath; + } - // Guild and channel names - buffer.Append($"{guild.Name} - {channel.Category.Name} - {channel.Name} [{channel.Id}]"); + public static string GetDefaultOutputFileName( + Guild guild, + Channel channel, + ExportFormat format, + Snowflake? after = null, + Snowflake? before = null) + { + var buffer = new StringBuilder(); + + // Guild and channel names + buffer.Append($"{guild.Name} - {channel.Category.Name} - {channel.Name} [{channel.Id}]"); + + // Date range + if (after is not null || before is not null) + { + buffer.Append(" ("); - // Date range - if (after is not null || before is not null) + // Both 'after' and 'before' are set + if (after is not null && before is not null) + { + buffer.Append($"{after.Value.ToDate():yyyy-MM-dd} to {before.Value.ToDate():yyyy-MM-dd}"); + } + // Only 'after' is set + else if (after is not null) { - buffer.Append(" ("); - - // Both 'after' and 'before' are set - if (after is not null && before is not null) - { - buffer.Append($"{after.Value.ToDate():yyyy-MM-dd} to {before.Value.ToDate():yyyy-MM-dd}"); - } - // Only 'after' is set - else if (after is not null) - { - buffer.Append($"after {after.Value.ToDate():yyyy-MM-dd}"); - } - // Only 'before' is set - else if (before is not null) - { - buffer.Append($"before {before.Value.ToDate():yyyy-MM-dd}"); - } - - buffer.Append(")"); + buffer.Append($"after {after.Value.ToDate():yyyy-MM-dd}"); + } + // Only 'before' is set + else if (before is not null) + { + buffer.Append($"before {before.Value.ToDate():yyyy-MM-dd}"); } - // File extension - buffer.Append($".{format.GetFileExtension()}"); + buffer.Append(")"); + } - // Replace invalid chars - PathEx.EscapePath(buffer); + // File extension + buffer.Append($".{format.GetFileExtension()}"); - return buffer.ToString(); - } + // Replace invalid chars + PathEx.EscapePath(buffer); + + return buffer.ToString(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionKind.cs b/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionKind.cs index 16bd5d7..4387d26 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionKind.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionKind.cs @@ -1,8 +1,7 @@ -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal enum BinaryExpressionKind { - internal enum BinaryExpressionKind - { - Or, - And - } + Or, + And } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionMessageFilter.cs index 013bd0e..386932d 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/BinaryExpressionMessageFilter.cs @@ -1,26 +1,25 @@ using System; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering -{ - internal class BinaryExpressionMessageFilter : MessageFilter - { - private readonly MessageFilter _first; - private readonly MessageFilter _second; - private readonly BinaryExpressionKind _kind; +namespace DiscordChatExporter.Core.Exporting.Filtering; - public BinaryExpressionMessageFilter(MessageFilter first, MessageFilter second, BinaryExpressionKind kind) - { - _first = first; - _second = second; - _kind = kind; - } +internal class BinaryExpressionMessageFilter : MessageFilter +{ + private readonly MessageFilter _first; + private readonly MessageFilter _second; + private readonly BinaryExpressionKind _kind; - public override bool IsMatch(Message message) => _kind switch - { - BinaryExpressionKind.Or => _first.IsMatch(message) || _second.IsMatch(message), - BinaryExpressionKind.And => _first.IsMatch(message) && _second.IsMatch(message), - _ => throw new InvalidOperationException($"Unknown binary expression kind '{_kind}'.") - }; + public BinaryExpressionMessageFilter(MessageFilter first, MessageFilter second, BinaryExpressionKind kind) + { + _first = first; + _second = second; + _kind = kind; } + + public override bool IsMatch(Message message) => _kind switch + { + BinaryExpressionKind.Or => _first.IsMatch(message) || _second.IsMatch(message), + BinaryExpressionKind.And => _first.IsMatch(message) && _second.IsMatch(message), + _ => throw new InvalidOperationException($"Unknown binary expression kind '{_kind}'.") + }; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/ContainsMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/ContainsMessageFilter.cs index 2e0999d..ad47119 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/ContainsMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/ContainsMessageFilter.cs @@ -2,33 +2,32 @@ using System.Text.RegularExpressions; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal class ContainsMessageFilter : MessageFilter { - internal class ContainsMessageFilter : MessageFilter - { - private readonly string _text; + private readonly string _text; - public ContainsMessageFilter(string text) => _text = text; + public ContainsMessageFilter(string text) => _text = text; - private bool IsMatch(string? content) => - !string.IsNullOrWhiteSpace(content) && - Regex.IsMatch( - content, - "\\b" + Regex.Escape(_text) + "\\b", - RegexOptions.IgnoreCase | RegexOptions.CultureInvariant - ); + private bool IsMatch(string? content) => + !string.IsNullOrWhiteSpace(content) && + Regex.IsMatch( + content, + "\\b" + Regex.Escape(_text) + "\\b", + RegexOptions.IgnoreCase | RegexOptions.CultureInvariant + ); - public override bool IsMatch(Message message) => - IsMatch(message.Content) || - message.Embeds.Any(e => - IsMatch(e.Title) || - IsMatch(e.Author?.Name) || - IsMatch(e.Description) || - IsMatch(e.Footer?.Text) || - e.Fields.Any(f => - IsMatch(f.Name) || - IsMatch(f.Value) - ) - ); - } + public override bool IsMatch(Message message) => + IsMatch(message.Content) || + message.Embeds.Any(e => + IsMatch(e.Title) || + IsMatch(e.Author?.Name) || + IsMatch(e.Description) || + IsMatch(e.Footer?.Text) || + e.Fields.Any(f => + IsMatch(f.Name) || + IsMatch(f.Value) + ) + ); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/FromMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/FromMessageFilter.cs index a328fc5..3ea91ee 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/FromMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/FromMessageFilter.cs @@ -1,17 +1,16 @@ using System; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal class FromMessageFilter : MessageFilter { - internal class FromMessageFilter : MessageFilter - { - private readonly string _value; + private readonly string _value; - public FromMessageFilter(string value) => _value = value; + public FromMessageFilter(string value) => _value = value; - public override bool IsMatch(Message message) => - string.Equals(_value, message.Author.Name, StringComparison.OrdinalIgnoreCase) || - string.Equals(_value, message.Author.FullName, StringComparison.OrdinalIgnoreCase) || - string.Equals(_value, message.Author.Id.ToString(), StringComparison.OrdinalIgnoreCase); - } + public override bool IsMatch(Message message) => + string.Equals(_value, message.Author.Name, StringComparison.OrdinalIgnoreCase) || + string.Equals(_value, message.Author.FullName, StringComparison.OrdinalIgnoreCase) || + string.Equals(_value, message.Author.Id.ToString(), StringComparison.OrdinalIgnoreCase); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/HasMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/HasMessageFilter.cs index 2188522..451869f 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/HasMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/HasMessageFilter.cs @@ -3,23 +3,22 @@ using System.Linq; using System.Text.RegularExpressions; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal class HasMessageFilter : MessageFilter { - internal class HasMessageFilter : MessageFilter - { - private readonly MessageContentMatchKind _kind; + private readonly MessageContentMatchKind _kind; - public HasMessageFilter(MessageContentMatchKind kind) => _kind = kind; + public HasMessageFilter(MessageContentMatchKind kind) => _kind = kind; - public override bool IsMatch(Message message) => _kind switch - { - MessageContentMatchKind.Link => Regex.IsMatch(message.Content, "https?://\\S*[^\\.,:;\"\'\\s]"), - MessageContentMatchKind.Embed => message.Embeds.Any(), - MessageContentMatchKind.File => message.Attachments.Any(), - MessageContentMatchKind.Video => message.Attachments.Any(file => file.IsVideo), - MessageContentMatchKind.Image => message.Attachments.Any(file => file.IsImage), - MessageContentMatchKind.Sound => message.Attachments.Any(file => file.IsAudio), - _ => throw new InvalidOperationException($"Unknown message content match kind '{_kind}'.") - }; - } + public override bool IsMatch(Message message) => _kind switch + { + MessageContentMatchKind.Link => Regex.IsMatch(message.Content, "https?://\\S*[^\\.,:;\"\'\\s]"), + MessageContentMatchKind.Embed => message.Embeds.Any(), + MessageContentMatchKind.File => message.Attachments.Any(), + MessageContentMatchKind.Video => message.Attachments.Any(file => file.IsVideo), + MessageContentMatchKind.Image => message.Attachments.Any(file => file.IsImage), + MessageContentMatchKind.Sound => message.Attachments.Any(file => file.IsAudio), + _ => throw new InvalidOperationException($"Unknown message content match kind '{_kind}'.") + }; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/MentionsMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/MentionsMessageFilter.cs index 2cfe77d..5cccd52 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/MentionsMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/MentionsMessageFilter.cs @@ -2,18 +2,17 @@ using System.Linq; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal class MentionsMessageFilter : MessageFilter { - internal class MentionsMessageFilter : MessageFilter - { - private readonly string _value; + private readonly string _value; - public MentionsMessageFilter(string value) => _value = value; + public MentionsMessageFilter(string value) => _value = value; - public override bool IsMatch(Message message) => message.MentionedUsers.Any(user => - string.Equals(_value, user.Name, StringComparison.OrdinalIgnoreCase) || - string.Equals(_value, user.FullName, StringComparison.OrdinalIgnoreCase) || - string.Equals(_value, user.Id.ToString(), StringComparison.OrdinalIgnoreCase) - ); - } + public override bool IsMatch(Message message) => message.MentionedUsers.Any(user => + string.Equals(_value, user.Name, StringComparison.OrdinalIgnoreCase) || + string.Equals(_value, user.FullName, StringComparison.OrdinalIgnoreCase) || + string.Equals(_value, user.Id.ToString(), StringComparison.OrdinalIgnoreCase) + ); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/MessageContentMatchKind.cs b/DiscordChatExporter.Core/Exporting/Filtering/MessageContentMatchKind.cs index 549a38f..d38287e 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/MessageContentMatchKind.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/MessageContentMatchKind.cs @@ -1,12 +1,11 @@ -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal enum MessageContentMatchKind { - internal enum MessageContentMatchKind - { - Link, - Embed, - File, - Video, - Image, - Sound - } + Link, + Embed, + File, + Video, + Image, + Sound } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/MessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/MessageFilter.cs index 45fb75d..4004fef 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/MessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/MessageFilter.cs @@ -2,17 +2,16 @@ using DiscordChatExporter.Core.Exporting.Filtering.Parsing; using Superpower; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +public abstract partial class MessageFilter { - public abstract partial class MessageFilter - { - public abstract bool IsMatch(Message message); - } + public abstract bool IsMatch(Message message); +} - public partial class MessageFilter - { - public static MessageFilter Null { get; } = new NullMessageFilter(); +public partial class MessageFilter +{ + public static MessageFilter Null { get; } = new NullMessageFilter(); - public static MessageFilter Parse(string value) => FilterGrammar.Filter.Parse(value); - } + public static MessageFilter Parse(string value) => FilterGrammar.Filter.Parse(value); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/NegatedMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/NegatedMessageFilter.cs index 2d9b8ad..1e74775 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/NegatedMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/NegatedMessageFilter.cs @@ -1,13 +1,12 @@ using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal class NegatedMessageFilter : MessageFilter { - internal class NegatedMessageFilter : MessageFilter - { - private readonly MessageFilter _filter; + private readonly MessageFilter _filter; - public NegatedMessageFilter(MessageFilter filter) => _filter = filter; + public NegatedMessageFilter(MessageFilter filter) => _filter = filter; - public override bool IsMatch(Message message) => !_filter.IsMatch(message); - } + public override bool IsMatch(Message message) => !_filter.IsMatch(message); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/NullMessageFilter.cs b/DiscordChatExporter.Core/Exporting/Filtering/NullMessageFilter.cs index be81ab6..419ce79 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/NullMessageFilter.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/NullMessageFilter.cs @@ -1,9 +1,8 @@ using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Filtering +namespace DiscordChatExporter.Core.Exporting.Filtering; + +internal class NullMessageFilter : MessageFilter { - internal class NullMessageFilter : MessageFilter - { - public override bool IsMatch(Message message) => true; - } + public override bool IsMatch(Message message) => true; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Filtering/Parsing/FilterGrammar.cs b/DiscordChatExporter.Core/Exporting/Filtering/Parsing/FilterGrammar.cs index ab44296..d17c823 100644 --- a/DiscordChatExporter.Core/Exporting/Filtering/Parsing/FilterGrammar.cs +++ b/DiscordChatExporter.Core/Exporting/Filtering/Parsing/FilterGrammar.cs @@ -2,101 +2,100 @@ using Superpower; using Superpower.Parsers; -namespace DiscordChatExporter.Core.Exporting.Filtering.Parsing +namespace DiscordChatExporter.Core.Exporting.Filtering.Parsing; + +internal static class FilterGrammar { - internal static class FilterGrammar - { - private static readonly TextParser EscapedCharacter = - Character.EqualTo('\\').IgnoreThen(Character.AnyChar); - - private static readonly TextParser QuotedString = - from open in Character.In('"', '\'') - from value in Parse.OneOf(EscapedCharacter, Character.Except(open)).Many().Text() - from close in Character.EqualTo(open) - select value; - - private static readonly TextParser FreeCharacter = - Character.Matching(c => - !char.IsWhiteSpace(c) && - // Avoid all special tokens used by the grammar - c is not ('(' or ')' or '"' or '\'' or '-' or '|' or '&'), - "any character except whitespace or `(`, `)`, `\"`, `'`, `-`, `|`, `&`" - ); - - private static readonly TextParser UnquotedString = - Parse.OneOf(EscapedCharacter, FreeCharacter).AtLeastOnce().Text(); - - private static readonly TextParser String = - Parse.OneOf(QuotedString, UnquotedString).Named("text string"); - - private static readonly TextParser ContainsFilter = - String.Select(v => (MessageFilter) new ContainsMessageFilter(v)); - - private static readonly TextParser FromFilter = Span - .EqualToIgnoreCase("from:") - .IgnoreThen(String) - .Select(v => (MessageFilter) new FromMessageFilter(v)) - .Named("from:"); - - private static readonly TextParser MentionsFilter = Span - .EqualToIgnoreCase("mentions:") - .IgnoreThen(String) - .Select(v => (MessageFilter) new MentionsMessageFilter(v)) - .Named("mentions:"); - - private static readonly TextParser HasFilter = Span - .EqualToIgnoreCase("has:") - .IgnoreThen(Parse.OneOf( - Span.EqualToIgnoreCase("link").IgnoreThen(Parse.Return(MessageContentMatchKind.Link)), - Span.EqualToIgnoreCase("embed").IgnoreThen(Parse.Return(MessageContentMatchKind.Embed)), - Span.EqualToIgnoreCase("file").IgnoreThen(Parse.Return(MessageContentMatchKind.File)), - Span.EqualToIgnoreCase("video").IgnoreThen(Parse.Return(MessageContentMatchKind.Video)), - Span.EqualToIgnoreCase("image").IgnoreThen(Parse.Return(MessageContentMatchKind.Image)), - Span.EqualToIgnoreCase("sound").IgnoreThen(Parse.Return(MessageContentMatchKind.Sound)) - )) - .Select(k => (MessageFilter) new HasMessageFilter(k)) - .Named("has:"); - - private static readonly TextParser NegatedFilter = Character - .EqualTo('-') - .IgnoreThen(Parse.Ref(() => StandaloneFilter!)) - .Select(f => (MessageFilter) new NegatedMessageFilter(f)); - - private static readonly TextParser GroupedFilter = - from open in Character.EqualTo('(') - from content in Parse.Ref(() => BinaryExpressionFilter!).Token() - from close in Character.EqualTo(')') - select content; - - private static readonly TextParser StandaloneFilter = Parse.OneOf( - GroupedFilter, - FromFilter, - MentionsFilter, - HasFilter, - ContainsFilter - ); + private static readonly TextParser EscapedCharacter = + Character.EqualTo('\\').IgnoreThen(Character.AnyChar); - private static readonly TextParser UnaryExpressionFilter = Parse.OneOf( - NegatedFilter, - StandaloneFilter - ); + private static readonly TextParser QuotedString = + from open in Character.In('"', '\'') + from value in Parse.OneOf(EscapedCharacter, Character.Except(open)).Many().Text() + from close in Character.EqualTo(open) + select value; - private static readonly TextParser BinaryExpressionFilter = Parse.Chain( - Parse.OneOf( - // Explicit operator - Character.In('|', '&').Token().Try(), - // Implicit operator (resolves to 'and') - Character.WhiteSpace.AtLeastOnce().IgnoreThen(Parse.Return(' ')) - ), - UnaryExpressionFilter, - (op, left, right) => op switch - { - '|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or), - _ => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.And) - } + private static readonly TextParser FreeCharacter = + Character.Matching(c => + !char.IsWhiteSpace(c) && + // Avoid all special tokens used by the grammar + c is not ('(' or ')' or '"' or '\'' or '-' or '|' or '&'), + "any character except whitespace or `(`, `)`, `\"`, `'`, `-`, `|`, `&`" ); - public static readonly TextParser Filter = - BinaryExpressionFilter.Token().AtEnd(); - } + private static readonly TextParser UnquotedString = + Parse.OneOf(EscapedCharacter, FreeCharacter).AtLeastOnce().Text(); + + private static readonly TextParser String = + Parse.OneOf(QuotedString, UnquotedString).Named("text string"); + + private static readonly TextParser ContainsFilter = + String.Select(v => (MessageFilter) new ContainsMessageFilter(v)); + + private static readonly TextParser FromFilter = Span + .EqualToIgnoreCase("from:") + .IgnoreThen(String) + .Select(v => (MessageFilter) new FromMessageFilter(v)) + .Named("from:"); + + private static readonly TextParser MentionsFilter = Span + .EqualToIgnoreCase("mentions:") + .IgnoreThen(String) + .Select(v => (MessageFilter) new MentionsMessageFilter(v)) + .Named("mentions:"); + + private static readonly TextParser HasFilter = Span + .EqualToIgnoreCase("has:") + .IgnoreThen(Parse.OneOf( + Span.EqualToIgnoreCase("link").IgnoreThen(Parse.Return(MessageContentMatchKind.Link)), + Span.EqualToIgnoreCase("embed").IgnoreThen(Parse.Return(MessageContentMatchKind.Embed)), + Span.EqualToIgnoreCase("file").IgnoreThen(Parse.Return(MessageContentMatchKind.File)), + Span.EqualToIgnoreCase("video").IgnoreThen(Parse.Return(MessageContentMatchKind.Video)), + Span.EqualToIgnoreCase("image").IgnoreThen(Parse.Return(MessageContentMatchKind.Image)), + Span.EqualToIgnoreCase("sound").IgnoreThen(Parse.Return(MessageContentMatchKind.Sound)) + )) + .Select(k => (MessageFilter) new HasMessageFilter(k)) + .Named("has:"); + + private static readonly TextParser NegatedFilter = Character + .EqualTo('-') + .IgnoreThen(Parse.Ref(() => StandaloneFilter!)) + .Select(f => (MessageFilter) new NegatedMessageFilter(f)); + + private static readonly TextParser GroupedFilter = + from open in Character.EqualTo('(') + from content in Parse.Ref(() => BinaryExpressionFilter!).Token() + from close in Character.EqualTo(')') + select content; + + private static readonly TextParser StandaloneFilter = Parse.OneOf( + GroupedFilter, + FromFilter, + MentionsFilter, + HasFilter, + ContainsFilter + ); + + private static readonly TextParser UnaryExpressionFilter = Parse.OneOf( + NegatedFilter, + StandaloneFilter + ); + + private static readonly TextParser BinaryExpressionFilter = Parse.Chain( + Parse.OneOf( + // Explicit operator + Character.In('|', '&').Token().Try(), + // Implicit operator (resolves to 'and') + Character.WhiteSpace.AtLeastOnce().IgnoreThen(Parse.Return(' ')) + ), + UnaryExpressionFilter, + (op, left, right) => op switch + { + '|' => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.Or), + _ => new BinaryExpressionMessageFilter(left, right, BinaryExpressionKind.And) + } + ); + + public static readonly TextParser Filter = + BinaryExpressionFilter.Token().AtEnd(); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/MediaDownloader.cs b/DiscordChatExporter.Core/Exporting/MediaDownloader.cs index 38fca29..38a5b0b 100644 --- a/DiscordChatExporter.Core/Exporting/MediaDownloader.cs +++ b/DiscordChatExporter.Core/Exporting/MediaDownloader.cs @@ -10,101 +10,100 @@ using System.Threading.Tasks; using DiscordChatExporter.Core.Utils; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Exporting +namespace DiscordChatExporter.Core.Exporting; + +internal partial class MediaDownloader { - internal partial class MediaDownloader - { - private readonly string _workingDirPath; - private readonly bool _reuseMedia; + private readonly string _workingDirPath; + private readonly bool _reuseMedia; - // File paths of already downloaded media - private readonly Dictionary _pathCache = new(StringComparer.Ordinal); + // File paths of already downloaded media + private readonly Dictionary _pathCache = new(StringComparer.Ordinal); - public MediaDownloader(string workingDirPath, bool reuseMedia) - { - _workingDirPath = workingDirPath; - _reuseMedia = reuseMedia; - } + public MediaDownloader(string workingDirPath, bool reuseMedia) + { + _workingDirPath = workingDirPath; + _reuseMedia = reuseMedia; + } - public async ValueTask DownloadAsync(string url, CancellationToken cancellationToken = default) - { - if (_pathCache.TryGetValue(url, out var cachedFilePath)) - return cachedFilePath; + public async ValueTask DownloadAsync(string url, CancellationToken cancellationToken = default) + { + if (_pathCache.TryGetValue(url, out var cachedFilePath)) + return cachedFilePath; - var fileName = GetFileNameFromUrl(url); - var filePath = Path.Combine(_workingDirPath, fileName); + var fileName = GetFileNameFromUrl(url); + var filePath = Path.Combine(_workingDirPath, fileName); - // Reuse existing files if we're allowed to - if (_reuseMedia && File.Exists(filePath)) - return _pathCache[url] = filePath; + // Reuse existing files if we're allowed to + if (_reuseMedia && File.Exists(filePath)) + return _pathCache[url] = filePath; - Directory.CreateDirectory(_workingDirPath); + Directory.CreateDirectory(_workingDirPath); - // This retries on IOExceptions which is dangerous as we're also working with files - await Http.ExceptionPolicy.ExecuteAsync(async () => + // This retries on IOExceptions which is dangerous as we're also working with files + await Http.ExceptionPolicy.ExecuteAsync(async () => + { + // Download the file + using var response = await Http.Client.GetAsync(url, cancellationToken); + await using (var output = File.Create(filePath)) { - // Download the file - using var response = await Http.Client.GetAsync(url, cancellationToken); - await using (var output = File.Create(filePath)) - { - await response.Content.CopyToAsync(output); - } + await response.Content.CopyToAsync(output, cancellationToken); + } - // Try to set the file date according to the last-modified header - try - { - var lastModified = response.Content.Headers.TryGetValue("Last-Modified")?.Pipe(s => - DateTimeOffset.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) - ? date - : (DateTimeOffset?) null - ); - - if (lastModified is not null) - { - File.SetCreationTimeUtc(filePath, lastModified.Value.UtcDateTime); - File.SetLastWriteTimeUtc(filePath, lastModified.Value.UtcDateTime); - File.SetLastAccessTimeUtc(filePath, lastModified.Value.UtcDateTime); - } - } - catch + // Try to set the file date according to the last-modified header + try + { + var lastModified = response.Content.Headers.TryGetValue("Last-Modified")?.Pipe(s => + DateTimeOffset.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.None, out var date) + ? date + : (DateTimeOffset?) null + ); + + if (lastModified is not null) { - // This can apparently fail for some reason. - // https://github.com/Tyrrrz/DiscordChatExporter/issues/585 - // Updating file dates is not a critical task, so we'll just - // ignore exceptions thrown here. + File.SetCreationTimeUtc(filePath, lastModified.Value.UtcDateTime); + File.SetLastWriteTimeUtc(filePath, lastModified.Value.UtcDateTime); + File.SetLastAccessTimeUtc(filePath, lastModified.Value.UtcDateTime); } - }); - - return _pathCache[url] = filePath; - } + } + catch + { + // This can apparently fail for some reason. + // https://github.com/Tyrrrz/DiscordChatExporter/issues/585 + // Updating file dates is not a critical task, so we'll just + // ignore exceptions thrown here. + } + }); + + return _pathCache[url] = filePath; } +} - internal partial class MediaDownloader +internal partial class MediaDownloader +{ + private static string GetUrlHash(string url) { - private static string GetUrlHash(string url) - { - using var hash = SHA256.Create(); + using var hash = SHA256.Create(); - var data = hash.ComputeHash(Encoding.UTF8.GetBytes(url)); - return data.ToHex().Truncate(5); // 5 chars ought to be enough for anybody - } + var data = hash.ComputeHash(Encoding.UTF8.GetBytes(url)); + return data.ToHex().Truncate(5); // 5 chars ought to be enough for anybody + } - private static string GetFileNameFromUrl(string url) - { - var urlHash = GetUrlHash(url); + private static string GetFileNameFromUrl(string url) + { + var urlHash = GetUrlHash(url); - // Try to extract file name from URL - var fileName = Regex.Match(url, @".+/([^?]*)").Groups[1].Value; + // Try to extract file name from URL + var fileName = Regex.Match(url, @".+/([^?]*)").Groups[1].Value; - // If it's not there, just use the URL hash as the file name - if (string.IsNullOrWhiteSpace(fileName)) - return urlHash; + // If it's not there, just use the URL hash as the file name + if (string.IsNullOrWhiteSpace(fileName)) + return urlHash; - // Otherwise, use the original file name but inject the hash in the middle - var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); - var fileExtension = Path.GetExtension(fileName); + // Otherwise, use the original file name but inject the hash in the middle + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); + var fileExtension = Path.GetExtension(fileName); - return PathEx.EscapePath(fileNameWithoutExtension.Truncate(42) + '-' + urlHash + fileExtension); - } + return PathEx.EscapePath(fileNameWithoutExtension.Truncate(42) + '-' + urlHash + fileExtension); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/MessageExporter.cs b/DiscordChatExporter.Core/Exporting/MessageExporter.cs index 8eddacb..75d8e5c 100644 --- a/DiscordChatExporter.Core/Exporting/MessageExporter.cs +++ b/DiscordChatExporter.Core/Exporting/MessageExporter.cs @@ -5,101 +5,100 @@ using System.Threading.Tasks; using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Exporting.Writers; -namespace DiscordChatExporter.Core.Exporting +namespace DiscordChatExporter.Core.Exporting; + +internal partial class MessageExporter : IAsyncDisposable { - internal partial class MessageExporter : IAsyncDisposable - { - private readonly ExportContext _context; + private readonly ExportContext _context; + + private int _partitionIndex; + private MessageWriter? _writer; - private int _partitionIndex; - private MessageWriter? _writer; + public MessageExporter(ExportContext context) + { + _context = context; + } - public MessageExporter(ExportContext context) + private async ValueTask ResetWriterAsync(CancellationToken cancellationToken = default) + { + if (_writer is not null) { - _context = context; + await _writer.WritePostambleAsync(cancellationToken); + await _writer.DisposeAsync(); + _writer = null; } + } - private async ValueTask ResetWriterAsync(CancellationToken cancellationToken = default) + private async ValueTask GetWriterAsync(CancellationToken cancellationToken = default) + { + // Ensure partition limit has not been reached + if (_writer is not null && + _context.Request.PartitionLimit.IsReached(_writer.MessagesWritten, _writer.BytesWritten)) { - if (_writer is not null) - { - await _writer.WritePostambleAsync(cancellationToken); - await _writer.DisposeAsync(); - _writer = null; - } + await ResetWriterAsync(cancellationToken); + _partitionIndex++; } - private async ValueTask GetWriterAsync(CancellationToken cancellationToken = default) - { - // Ensure partition limit has not been reached - if (_writer is not null && - _context.Request.PartitionLimit.IsReached(_writer.MessagesWritten, _writer.BytesWritten)) - { - await ResetWriterAsync(cancellationToken); - _partitionIndex++; - } + // Writer is still valid - return + if (_writer is not null) + return _writer; - // Writer is still valid - return - if (_writer is not null) - return _writer; + var filePath = GetPartitionFilePath(_context.Request.OutputBaseFilePath, _partitionIndex); - var filePath = GetPartitionFilePath(_context.Request.OutputBaseFilePath, _partitionIndex); + var dirPath = Path.GetDirectoryName(_context.Request.OutputBaseFilePath); + if (!string.IsNullOrWhiteSpace(dirPath)) + Directory.CreateDirectory(dirPath); - var dirPath = Path.GetDirectoryName(_context.Request.OutputBaseFilePath); - if (!string.IsNullOrWhiteSpace(dirPath)) - Directory.CreateDirectory(dirPath); + var writer = CreateMessageWriter(filePath, _context.Request.Format, _context); + await writer.WritePreambleAsync(cancellationToken); - var writer = CreateMessageWriter(filePath, _context.Request.Format, _context); - await writer.WritePreambleAsync(cancellationToken); + return _writer = writer; + } - return _writer = writer; - } + public async ValueTask ExportMessageAsync(Message message, CancellationToken cancellationToken = default) + { + var writer = await GetWriterAsync(cancellationToken); + await writer.WriteMessageAsync(message, cancellationToken); + } - public async ValueTask ExportMessageAsync(Message message, CancellationToken cancellationToken = default) - { - var writer = await GetWriterAsync(cancellationToken); - await writer.WriteMessageAsync(message, cancellationToken); - } + public async ValueTask DisposeAsync() => await ResetWriterAsync(); +} - public async ValueTask DisposeAsync() => await ResetWriterAsync(); +internal partial class MessageExporter +{ + private static string GetPartitionFilePath(string baseFilePath, int partitionIndex) + { + // First partition - don't change file name + if (partitionIndex <= 0) + return baseFilePath; + + // Inject partition index into file name + var fileNameWithoutExt = Path.GetFileNameWithoutExtension(baseFilePath); + var fileExt = Path.GetExtension(baseFilePath); + var fileName = $"{fileNameWithoutExt} [part {partitionIndex + 1}]{fileExt}"; + var dirPath = Path.GetDirectoryName(baseFilePath); + + return !string.IsNullOrWhiteSpace(dirPath) + ? Path.Combine(dirPath, fileName) + : fileName; } - internal partial class MessageExporter + private static MessageWriter CreateMessageWriter( + string filePath, + ExportFormat format, + ExportContext context) { - private static string GetPartitionFilePath(string baseFilePath, int partitionIndex) - { - // First partition - don't change file name - if (partitionIndex <= 0) - return baseFilePath; - - // Inject partition index into file name - var fileNameWithoutExt = Path.GetFileNameWithoutExtension(baseFilePath); - var fileExt = Path.GetExtension(baseFilePath); - var fileName = $"{fileNameWithoutExt} [part {partitionIndex + 1}]{fileExt}"; - var dirPath = Path.GetDirectoryName(baseFilePath); - - return !string.IsNullOrWhiteSpace(dirPath) - ? Path.Combine(dirPath, fileName) - : fileName; - } + // Stream will be disposed by the underlying writer + var stream = File.Create(filePath); - private static MessageWriter CreateMessageWriter( - string filePath, - ExportFormat format, - ExportContext context) + return format switch { - // Stream will be disposed by the underlying writer - var stream = File.Create(filePath); - - return format switch - { - ExportFormat.PlainText => new PlainTextMessageWriter(stream, context), - ExportFormat.Csv => new CsvMessageWriter(stream, context), - ExportFormat.HtmlDark => new HtmlMessageWriter(stream, context, "Dark"), - ExportFormat.HtmlLight => new HtmlMessageWriter(stream, context, "Light"), - ExportFormat.Json => new JsonMessageWriter(stream, context), - _ => throw new ArgumentOutOfRangeException(nameof(format), $"Unknown export format '{format}'.") - }; - } + ExportFormat.PlainText => new PlainTextMessageWriter(stream, context), + ExportFormat.Csv => new CsvMessageWriter(stream, context), + ExportFormat.HtmlDark => new HtmlMessageWriter(stream, context, "Dark"), + ExportFormat.HtmlLight => new HtmlMessageWriter(stream, context, "Light"), + ExportFormat.Json => new JsonMessageWriter(stream, context), + _ => throw new ArgumentOutOfRangeException(nameof(format), $"Unknown export format '{format}'.") + }; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Partitioning/FileSizePartitionLimit.cs b/DiscordChatExporter.Core/Exporting/Partitioning/FileSizePartitionLimit.cs index a2e6bac..c38318f 100644 --- a/DiscordChatExporter.Core/Exporting/Partitioning/FileSizePartitionLimit.cs +++ b/DiscordChatExporter.Core/Exporting/Partitioning/FileSizePartitionLimit.cs @@ -1,12 +1,11 @@ -namespace DiscordChatExporter.Core.Exporting.Partitioning +namespace DiscordChatExporter.Core.Exporting.Partitioning; + +internal class FileSizePartitionLimit : PartitionLimit { - internal class FileSizePartitionLimit : PartitionLimit - { - private readonly long _limit; + private readonly long _limit; - public FileSizePartitionLimit(long limit) => _limit = limit; + public FileSizePartitionLimit(long limit) => _limit = limit; - public override bool IsReached(long messagesWritten, long bytesWritten) => - bytesWritten >= _limit; - } + public override bool IsReached(long messagesWritten, long bytesWritten) => + bytesWritten >= _limit; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Partitioning/MessageCountPartitionLimit.cs b/DiscordChatExporter.Core/Exporting/Partitioning/MessageCountPartitionLimit.cs index 83f3379..2326b34 100644 --- a/DiscordChatExporter.Core/Exporting/Partitioning/MessageCountPartitionLimit.cs +++ b/DiscordChatExporter.Core/Exporting/Partitioning/MessageCountPartitionLimit.cs @@ -1,12 +1,11 @@ -namespace DiscordChatExporter.Core.Exporting.Partitioning +namespace DiscordChatExporter.Core.Exporting.Partitioning; + +internal class MessageCountPartitionLimit : PartitionLimit { - internal class MessageCountPartitionLimit : PartitionLimit - { - private readonly long _limit; + private readonly long _limit; - public MessageCountPartitionLimit(long limit) => _limit = limit; + public MessageCountPartitionLimit(long limit) => _limit = limit; - public override bool IsReached(long messagesWritten, long bytesWritten) => - messagesWritten >= _limit; - } + public override bool IsReached(long messagesWritten, long bytesWritten) => + messagesWritten >= _limit; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Partitioning/NullPartitionLimit.cs b/DiscordChatExporter.Core/Exporting/Partitioning/NullPartitionLimit.cs index 4017a37..ffd248c 100644 --- a/DiscordChatExporter.Core/Exporting/Partitioning/NullPartitionLimit.cs +++ b/DiscordChatExporter.Core/Exporting/Partitioning/NullPartitionLimit.cs @@ -1,7 +1,6 @@ -namespace DiscordChatExporter.Core.Exporting.Partitioning +namespace DiscordChatExporter.Core.Exporting.Partitioning; + +internal class NullPartitionLimit : PartitionLimit { - internal class NullPartitionLimit : PartitionLimit - { - public override bool IsReached(long messagesWritten, long bytesWritten) => false; - } + public override bool IsReached(long messagesWritten, long bytesWritten) => false; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Partitioning/PartitionLimit.cs b/DiscordChatExporter.Core/Exporting/Partitioning/PartitionLimit.cs index f1336d6..e4fd965 100644 --- a/DiscordChatExporter.Core/Exporting/Partitioning/PartitionLimit.cs +++ b/DiscordChatExporter.Core/Exporting/Partitioning/PartitionLimit.cs @@ -2,62 +2,61 @@ using System.Globalization; using System.Text.RegularExpressions; -namespace DiscordChatExporter.Core.Exporting.Partitioning +namespace DiscordChatExporter.Core.Exporting.Partitioning; + +public abstract partial class PartitionLimit { - public abstract partial class PartitionLimit - { - public abstract bool IsReached(long messagesWritten, long bytesWritten); - } + public abstract bool IsReached(long messagesWritten, long bytesWritten); +} - public partial class PartitionLimit - { - public static PartitionLimit Null { get; } = new NullPartitionLimit(); +public partial class PartitionLimit +{ + public static PartitionLimit Null { get; } = new NullPartitionLimit(); - private static long? TryParseFileSizeBytes(string value, IFormatProvider? formatProvider = null) - { - var match = Regex.Match(value, @"^\s*(\d+[\.,]?\d*)\s*(\w)?b\s*$", RegexOptions.IgnoreCase); + private static long? TryParseFileSizeBytes(string value, IFormatProvider? formatProvider = null) + { + var match = Regex.Match(value, @"^\s*(\d+[\.,]?\d*)\s*(\w)?b\s*$", RegexOptions.IgnoreCase); - // Number part - if (!double.TryParse( + // Number part + if (!double.TryParse( match.Groups[1].Value, NumberStyles.Float, formatProvider, out var number)) - { - return null; - } - - // Magnitude part - var magnitude = match.Groups[2].Value.ToUpperInvariant() switch - { - "G" => 1_000_000_000, - "M" => 1_000_000, - "K" => 1_000, - "" => 1, - _ => -1 - }; - - if (magnitude < 0) - { - return null; - } - - return (long) (number * magnitude); + { + return null; } - public static PartitionLimit? TryParse(string value, IFormatProvider? formatProvider = null) + // Magnitude part + var magnitude = match.Groups[2].Value.ToUpperInvariant() switch + { + "G" => 1_000_000_000, + "M" => 1_000_000, + "K" => 1_000, + "" => 1, + _ => -1 + }; + + if (magnitude < 0) { - var fileSizeLimit = TryParseFileSizeBytes(value, formatProvider); - if (fileSizeLimit is not null) - return new FileSizePartitionLimit(fileSizeLimit.Value); - - if (int.TryParse(value, NumberStyles.Integer, formatProvider, out var messageCountLimit)) - return new MessageCountPartitionLimit(messageCountLimit); - return null; } - public static PartitionLimit Parse(string value, IFormatProvider? formatProvider = null) => - TryParse(value, formatProvider) ?? throw new FormatException($"Invalid partition limit '{value}'."); + return (long) (number * magnitude); } + + public static PartitionLimit? TryParse(string value, IFormatProvider? formatProvider = null) + { + var fileSizeLimit = TryParseFileSizeBytes(value, formatProvider); + if (fileSizeLimit is not null) + return new FileSizePartitionLimit(fileSizeLimit.Value); + + if (int.TryParse(value, NumberStyles.Integer, formatProvider, out var messageCountLimit)) + return new MessageCountPartitionLimit(messageCountLimit); + + return null; + } + + public static PartitionLimit Parse(string value, IFormatProvider? formatProvider = null) => + TryParse(value, formatProvider) ?? throw new FormatException($"Invalid partition limit '{value}'."); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/CsvMessageWriter.cs b/DiscordChatExporter.Core/Exporting/Writers/CsvMessageWriter.cs index bda01cb..58c4422 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/CsvMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/CsvMessageWriter.cs @@ -7,110 +7,109 @@ using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Exporting.Writers +namespace DiscordChatExporter.Core.Exporting.Writers; + +internal partial class CsvMessageWriter : MessageWriter { - internal partial class CsvMessageWriter : MessageWriter + private readonly TextWriter _writer; + + public CsvMessageWriter(Stream stream, ExportContext context) + : base(stream, context) { - private readonly TextWriter _writer; + _writer = new StreamWriter(stream); + } - public CsvMessageWriter(Stream stream, ExportContext context) - : base(stream, context) - { - _writer = new StreamWriter(stream); - } + private string FormatMarkdown(string? markdown) => + PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); - private string FormatMarkdown(string? markdown) => - PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); + public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) => + await _writer.WriteLineAsync("AuthorID,Author,Date,Content,Attachments,Reactions"); - public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) => - await _writer.WriteLineAsync("AuthorID,Author,Date,Content,Attachments,Reactions"); + private async ValueTask WriteAttachmentsAsync( + IReadOnlyList attachments, + CancellationToken cancellationToken = default) + { + var buffer = new StringBuilder(); - private async ValueTask WriteAttachmentsAsync( - IReadOnlyList attachments, - CancellationToken cancellationToken = default) + foreach (var attachment in attachments) { - var buffer = new StringBuilder(); + cancellationToken.ThrowIfCancellationRequested(); - foreach (var attachment in attachments) - { - cancellationToken.ThrowIfCancellationRequested(); + buffer + .AppendIfNotEmpty(',') + .Append(await Context.ResolveMediaUrlAsync(attachment.Url, cancellationToken)); + } - buffer - .AppendIfNotEmpty(',') - .Append(await Context.ResolveMediaUrlAsync(attachment.Url, cancellationToken)); - } + await _writer.WriteAsync(CsvEncode(buffer.ToString())); + } - await _writer.WriteAsync(CsvEncode(buffer.ToString())); - } + private async ValueTask WriteReactionsAsync( + IReadOnlyList reactions, + CancellationToken cancellationToken = default) + { + var buffer = new StringBuilder(); - private async ValueTask WriteReactionsAsync( - IReadOnlyList reactions, - CancellationToken cancellationToken = default) + foreach (var reaction in reactions) { - var buffer = new StringBuilder(); - - foreach (var reaction in reactions) - { - cancellationToken.ThrowIfCancellationRequested(); - - buffer - .AppendIfNotEmpty(',') - .Append(reaction.Emoji.Name) - .Append(' ') - .Append('(') - .Append(reaction.Count) - .Append(')'); - } - - await _writer.WriteAsync(CsvEncode(buffer.ToString())); + cancellationToken.ThrowIfCancellationRequested(); + + buffer + .AppendIfNotEmpty(',') + .Append(reaction.Emoji.Name) + .Append(' ') + .Append('(') + .Append(reaction.Count) + .Append(')'); } - public override async ValueTask WriteMessageAsync( - Message message, - CancellationToken cancellationToken = default) - { - await base.WriteMessageAsync(message, cancellationToken); + await _writer.WriteAsync(CsvEncode(buffer.ToString())); + } - // Author ID - await _writer.WriteAsync(CsvEncode(message.Author.Id.ToString())); - await _writer.WriteAsync(','); + public override async ValueTask WriteMessageAsync( + Message message, + CancellationToken cancellationToken = default) + { + await base.WriteMessageAsync(message, cancellationToken); - // Author name - await _writer.WriteAsync(CsvEncode(message.Author.FullName)); - await _writer.WriteAsync(','); + // Author ID + await _writer.WriteAsync(CsvEncode(message.Author.Id.ToString())); + await _writer.WriteAsync(','); - // Message timestamp - await _writer.WriteAsync(CsvEncode(Context.FormatDate(message.Timestamp))); - await _writer.WriteAsync(','); + // Author name + await _writer.WriteAsync(CsvEncode(message.Author.FullName)); + await _writer.WriteAsync(','); - // Message content - await _writer.WriteAsync(CsvEncode(FormatMarkdown(message.Content))); - await _writer.WriteAsync(','); + // Message timestamp + await _writer.WriteAsync(CsvEncode(Context.FormatDate(message.Timestamp))); + await _writer.WriteAsync(','); - // Attachments - await WriteAttachmentsAsync(message.Attachments, cancellationToken); - await _writer.WriteAsync(','); + // Message content + await _writer.WriteAsync(CsvEncode(FormatMarkdown(message.Content))); + await _writer.WriteAsync(','); - // Reactions - await WriteReactionsAsync(message.Reactions, cancellationToken); + // Attachments + await WriteAttachmentsAsync(message.Attachments, cancellationToken); + await _writer.WriteAsync(','); - // Finish row - await _writer.WriteLineAsync(); - } + // Reactions + await WriteReactionsAsync(message.Reactions, cancellationToken); - public override async ValueTask DisposeAsync() - { - await _writer.DisposeAsync(); - await base.DisposeAsync(); - } + // Finish row + await _writer.WriteLineAsync(); } - internal partial class CsvMessageWriter + public override async ValueTask DisposeAsync() { - private static string CsvEncode(string value) - { - value = value.Replace("\"", "\"\""); - return $"\"{value}\""; - } + await _writer.DisposeAsync(); + await base.DisposeAsync(); + } +} + +internal partial class CsvMessageWriter +{ + private static string CsvEncode(string value) + { + value = value.Replace("\"", "\"\""); + return $"\"{value}\""; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroup.cs b/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroup.cs index b9c90f1..3762d42 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroup.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroup.cs @@ -3,59 +3,58 @@ using System.Collections.Generic; using System.Linq; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Writers.Html +namespace DiscordChatExporter.Core.Exporting.Writers.Html; + +// Used for grouping contiguous messages in HTML export +internal partial class MessageGroup { - // Used for grouping contiguous messages in HTML export - internal partial class MessageGroup - { - public User Author { get; } + public User Author { get; } - public DateTimeOffset Timestamp { get; } + public DateTimeOffset Timestamp { get; } - public IReadOnlyList Messages { get; } + public IReadOnlyList Messages { get; } - public MessageReference? Reference { get; } + public MessageReference? Reference { get; } - public Message? ReferencedMessage {get; } + public Message? ReferencedMessage {get; } - public MessageGroup( - User author, - DateTimeOffset timestamp, - MessageReference? reference, - Message? referencedMessage, - IReadOnlyList messages) - { - Author = author; - Timestamp = timestamp; - Reference = reference; - ReferencedMessage = referencedMessage; - Messages = messages; - } + public MessageGroup( + User author, + DateTimeOffset timestamp, + MessageReference? reference, + Message? referencedMessage, + IReadOnlyList messages) + { + Author = author; + Timestamp = timestamp; + Reference = reference; + ReferencedMessage = referencedMessage; + Messages = messages; } +} - internal partial class MessageGroup +internal partial class MessageGroup +{ + public static bool CanJoin(Message message1, Message message2) => + // Must be from the same author + message1.Author.Id == message2.Author.Id && + // Author's name must not have changed between messages + string.Equals(message1.Author.FullName, message2.Author.FullName, StringComparison.Ordinal) && + // Duration between messages must be 7 minutes or less + (message2.Timestamp - message1.Timestamp).Duration().TotalMinutes <= 7 && + // Other message must not be a reply + message2.Reference is null; + + public static MessageGroup Join(IReadOnlyList messages) { - public static bool CanJoin(Message message1, Message message2) => - // Must be from the same author - message1.Author.Id == message2.Author.Id && - // Author's name must not have changed between messages - string.Equals(message1.Author.FullName, message2.Author.FullName, StringComparison.Ordinal) && - // Duration between messages must be 7 minutes or less - (message2.Timestamp - message1.Timestamp).Duration().TotalMinutes <= 7 && - // Other message must not be a reply - message2.Reference is null; - - public static MessageGroup Join(IReadOnlyList messages) - { - var first = messages.First(); - - return new MessageGroup( - first.Author, - first.Timestamp, - first.Reference, - first.ReferencedMessage, - messages - ); - } + var first = messages.First(); + + return new MessageGroup( + first.Author, + first.Timestamp, + first.Reference, + first.ReferencedMessage, + messages + ); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplateContext.cs b/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplateContext.cs index 8049d8f..8c3eadb 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplateContext.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/MessageGroupTemplateContext.cs @@ -1,20 +1,19 @@ using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; -namespace DiscordChatExporter.Core.Exporting.Writers.Html -{ - internal class MessageGroupTemplateContext - { - public ExportContext ExportContext { get; } +namespace DiscordChatExporter.Core.Exporting.Writers.Html; - public MessageGroup MessageGroup { get; } +internal class MessageGroupTemplateContext +{ + public ExportContext ExportContext { get; } - public MessageGroupTemplateContext(ExportContext exportContext, MessageGroup messageGroup) - { - ExportContext = exportContext; - MessageGroup = messageGroup; - } + public MessageGroup MessageGroup { get; } - public string FormatMarkdown(string? markdown, bool isJumboAllowed = true) => - HtmlMarkdownVisitor.Format(ExportContext, markdown ?? "", isJumboAllowed); + public MessageGroupTemplateContext(ExportContext exportContext, MessageGroup messageGroup) + { + ExportContext = exportContext; + MessageGroup = messageGroup; } + + public string FormatMarkdown(string? markdown, bool isJumboAllowed = true) => + HtmlMarkdownVisitor.Format(ExportContext, markdown ?? "", isJumboAllowed); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/PostambleTemplateContext.cs b/DiscordChatExporter.Core/Exporting/Writers/Html/PostambleTemplateContext.cs index 79b3b02..897fd99 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/PostambleTemplateContext.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/PostambleTemplateContext.cs @@ -1,15 +1,14 @@ -namespace DiscordChatExporter.Core.Exporting.Writers.Html +namespace DiscordChatExporter.Core.Exporting.Writers.Html; + +internal class PostambleTemplateContext { - internal class PostambleTemplateContext - { - public ExportContext ExportContext { get; } + public ExportContext ExportContext { get; } - public long MessagesWritten { get; } + public long MessagesWritten { get; } - public PostambleTemplateContext(ExportContext exportContext, long messagesWritten) - { - ExportContext = exportContext; - MessagesWritten = messagesWritten; - } + public PostambleTemplateContext(ExportContext exportContext, long messagesWritten) + { + ExportContext = exportContext; + MessagesWritten = messagesWritten; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplateContext.cs b/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplateContext.cs index 18b0d51..df6a729 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplateContext.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/Html/PreambleTemplateContext.cs @@ -1,20 +1,19 @@ using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; -namespace DiscordChatExporter.Core.Exporting.Writers.Html -{ - internal class PreambleTemplateContext - { - public ExportContext ExportContext { get; } +namespace DiscordChatExporter.Core.Exporting.Writers.Html; - public string ThemeName { get; } +internal class PreambleTemplateContext +{ + public ExportContext ExportContext { get; } - public PreambleTemplateContext(ExportContext exportContext, string themeName) - { - ExportContext = exportContext; - ThemeName = themeName; - } + public string ThemeName { get; } - public string FormatMarkdown(string? markdown, bool isJumboAllowed = true) => - HtmlMarkdownVisitor.Format(ExportContext, markdown ?? "", isJumboAllowed); + public PreambleTemplateContext(ExportContext exportContext, string themeName) + { + ExportContext = exportContext; + ThemeName = themeName; } + + public string FormatMarkdown(string? markdown, bool isJumboAllowed = true) => + HtmlMarkdownVisitor.Format(ExportContext, markdown ?? "", isJumboAllowed); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs b/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs index 5594d36..02dc277 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/HtmlMessageWriter.cs @@ -6,91 +6,90 @@ using System.Threading.Tasks; using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Exporting.Writers.Html; -namespace DiscordChatExporter.Core.Exporting.Writers +namespace DiscordChatExporter.Core.Exporting.Writers; + +internal class HtmlMessageWriter : MessageWriter { - internal class HtmlMessageWriter : MessageWriter + private readonly TextWriter _writer; + private readonly string _themeName; + + private readonly List _messageGroupBuffer = new(); + + public HtmlMessageWriter(Stream stream, ExportContext context, string themeName) + : base(stream, context) { - private readonly TextWriter _writer; - private readonly string _themeName; + _writer = new StreamWriter(stream); + _themeName = themeName; + } - private readonly List _messageGroupBuffer = new(); + public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) + { + var templateContext = new PreambleTemplateContext(Context, _themeName); - public HtmlMessageWriter(Stream stream, ExportContext context, string themeName) - : base(stream, context) - { - _writer = new StreamWriter(stream); - _themeName = themeName; - } + // We are not writing directly to output because Razor + // does not actually do asynchronous writes to stream. + await _writer.WriteLineAsync( + await PreambleTemplate.RenderAsync(templateContext, cancellationToken) + ); + } - public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) - { - var templateContext = new PreambleTemplateContext(Context, _themeName); + private async ValueTask WriteMessageGroupAsync( + MessageGroup messageGroup, + CancellationToken cancellationToken = default) + { + var templateContext = new MessageGroupTemplateContext(Context, messageGroup); - // We are not writing directly to output because Razor - // does not actually do asynchronous writes to stream. - await _writer.WriteLineAsync( - await PreambleTemplate.RenderAsync(templateContext, cancellationToken) - ); - } + // We are not writing directly to output because Razor + // does not actually do asynchronous writes to stream. + await _writer.WriteLineAsync( + await MessageGroupTemplate.RenderAsync(templateContext, cancellationToken) + ); + } - private async ValueTask WriteMessageGroupAsync( - MessageGroup messageGroup, - CancellationToken cancellationToken = default) - { - var templateContext = new MessageGroupTemplateContext(Context, messageGroup); + public override async ValueTask WriteMessageAsync( + Message message, + CancellationToken cancellationToken = default) + { + await base.WriteMessageAsync(message, cancellationToken); - // We are not writing directly to output because Razor - // does not actually do asynchronous writes to stream. - await _writer.WriteLineAsync( - await MessageGroupTemplate.RenderAsync(templateContext, cancellationToken) - ); + // If message group is empty or the given message can be grouped, buffer the given message + if (!_messageGroupBuffer.Any() || MessageGroup.CanJoin(_messageGroupBuffer.Last(), message)) + { + _messageGroupBuffer.Add(message); } - - public override async ValueTask WriteMessageAsync( - Message message, - CancellationToken cancellationToken = default) + // Otherwise, flush the group and render messages + else { - await base.WriteMessageAsync(message, cancellationToken); - - // If message group is empty or the given message can be grouped, buffer the given message - if (!_messageGroupBuffer.Any() || MessageGroup.CanJoin(_messageGroupBuffer.Last(), message)) - { - _messageGroupBuffer.Add(message); - } - // Otherwise, flush the group and render messages - else - { - await WriteMessageGroupAsync(MessageGroup.Join(_messageGroupBuffer), cancellationToken); + await WriteMessageGroupAsync(MessageGroup.Join(_messageGroupBuffer), cancellationToken); - _messageGroupBuffer.Clear(); - _messageGroupBuffer.Add(message); - } + _messageGroupBuffer.Clear(); + _messageGroupBuffer.Add(message); } + } - public override async ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) + public override async ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) + { + // Flush current message group + if (_messageGroupBuffer.Any()) { - // Flush current message group - if (_messageGroupBuffer.Any()) - { - await WriteMessageGroupAsync( - MessageGroup.Join(_messageGroupBuffer), - cancellationToken - ); - } - - var templateContext = new PostambleTemplateContext(Context, MessagesWritten); - - // We are not writing directly to output because Razor - // does not actually do asynchronous writes to stream. - await _writer.WriteLineAsync( - await PostambleTemplate.RenderAsync(templateContext, cancellationToken) + await WriteMessageGroupAsync( + MessageGroup.Join(_messageGroupBuffer), + cancellationToken ); } - public override async ValueTask DisposeAsync() - { - await _writer.DisposeAsync(); - await base.DisposeAsync(); - } + var templateContext = new PostambleTemplateContext(Context, MessagesWritten); + + // We are not writing directly to output because Razor + // does not actually do asynchronous writes to stream. + await _writer.WriteLineAsync( + await PostambleTemplate.RenderAsync(templateContext, cancellationToken) + ); + } + + public override async ValueTask DisposeAsync() + { + await _writer.DisposeAsync(); + await base.DisposeAsync(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/JsonMessageWriter.cs b/DiscordChatExporter.Core/Exporting/Writers/JsonMessageWriter.cs index df5856b..69aff4f 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/JsonMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/JsonMessageWriter.cs @@ -9,319 +9,318 @@ using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; using DiscordChatExporter.Core.Utils.Extensions; using JsonExtensions.Writing; -namespace DiscordChatExporter.Core.Exporting.Writers +namespace DiscordChatExporter.Core.Exporting.Writers; + +internal class JsonMessageWriter : MessageWriter { - internal class JsonMessageWriter : MessageWriter - { - private readonly Utf8JsonWriter _writer; + private readonly Utf8JsonWriter _writer; - public JsonMessageWriter(Stream stream, ExportContext context) - : base(stream, context) + public JsonMessageWriter(Stream stream, ExportContext context) + : base(stream, context) + { + _writer = new Utf8JsonWriter(stream, new JsonWriterOptions { - _writer = new Utf8JsonWriter(stream, new JsonWriterOptions - { - Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, - Indented = true, - // Validation errors may mask actual failures - // https://github.com/Tyrrrz/DiscordChatExporter/issues/413 - SkipValidation = true - }); - } + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + Indented = true, + // Validation errors may mask actual failures + // https://github.com/Tyrrrz/DiscordChatExporter/issues/413 + SkipValidation = true + }); + } - private string FormatMarkdown(string? markdown) => - PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); + private string FormatMarkdown(string? markdown) => + PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); - private async ValueTask WriteAttachmentAsync( - Attachment attachment, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject(); + private async ValueTask WriteAttachmentAsync( + Attachment attachment, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject(); - _writer.WriteString("id", attachment.Id.ToString()); - _writer.WriteString("url", await Context.ResolveMediaUrlAsync(attachment.Url, cancellationToken)); - _writer.WriteString("fileName", attachment.FileName); - _writer.WriteNumber("fileSizeBytes", attachment.FileSize.TotalBytes); + _writer.WriteString("id", attachment.Id.ToString()); + _writer.WriteString("url", await Context.ResolveMediaUrlAsync(attachment.Url, cancellationToken)); + _writer.WriteString("fileName", attachment.FileName); + _writer.WriteNumber("fileSizeBytes", attachment.FileSize.TotalBytes); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteEmbedAuthorAsync( - EmbedAuthor embedAuthor, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject("author"); + private async ValueTask WriteEmbedAuthorAsync( + EmbedAuthor embedAuthor, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject("author"); - _writer.WriteString("name", embedAuthor.Name); - _writer.WriteString("url", embedAuthor.Url); + _writer.WriteString("name", embedAuthor.Name); + _writer.WriteString("url", embedAuthor.Url); - if (!string.IsNullOrWhiteSpace(embedAuthor.IconUrl)) - _writer.WriteString("iconUrl", await Context.ResolveMediaUrlAsync(embedAuthor.IconProxyUrl ?? embedAuthor.IconUrl, cancellationToken)); + if (!string.IsNullOrWhiteSpace(embedAuthor.IconUrl)) + _writer.WriteString("iconUrl", await Context.ResolveMediaUrlAsync(embedAuthor.IconProxyUrl ?? embedAuthor.IconUrl, cancellationToken)); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteEmbedThumbnailAsync( - EmbedImage embedThumbnail, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject("thumbnail"); + private async ValueTask WriteEmbedThumbnailAsync( + EmbedImage embedThumbnail, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject("thumbnail"); - if (!string.IsNullOrWhiteSpace(embedThumbnail.Url)) - _writer.WriteString("url", await Context.ResolveMediaUrlAsync(embedThumbnail.ProxyUrl ?? embedThumbnail.Url, cancellationToken)); + if (!string.IsNullOrWhiteSpace(embedThumbnail.Url)) + _writer.WriteString("url", await Context.ResolveMediaUrlAsync(embedThumbnail.ProxyUrl ?? embedThumbnail.Url, cancellationToken)); - _writer.WriteNumber("width", embedThumbnail.Width); - _writer.WriteNumber("height", embedThumbnail.Height); + _writer.WriteNumber("width", embedThumbnail.Width); + _writer.WriteNumber("height", embedThumbnail.Height); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteEmbedImageAsync( - EmbedImage embedImage, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject("image"); + private async ValueTask WriteEmbedImageAsync( + EmbedImage embedImage, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject("image"); - if (!string.IsNullOrWhiteSpace(embedImage.Url)) - _writer.WriteString("url", await Context.ResolveMediaUrlAsync(embedImage.ProxyUrl ?? embedImage.Url, cancellationToken)); + if (!string.IsNullOrWhiteSpace(embedImage.Url)) + _writer.WriteString("url", await Context.ResolveMediaUrlAsync(embedImage.ProxyUrl ?? embedImage.Url, cancellationToken)); - _writer.WriteNumber("width", embedImage.Width); - _writer.WriteNumber("height", embedImage.Height); + _writer.WriteNumber("width", embedImage.Width); + _writer.WriteNumber("height", embedImage.Height); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteEmbedFooterAsync( - EmbedFooter embedFooter, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject("footer"); + private async ValueTask WriteEmbedFooterAsync( + EmbedFooter embedFooter, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject("footer"); - _writer.WriteString("text", embedFooter.Text); + _writer.WriteString("text", embedFooter.Text); - if (!string.IsNullOrWhiteSpace(embedFooter.IconUrl)) - _writer.WriteString("iconUrl", await Context.ResolveMediaUrlAsync(embedFooter.IconProxyUrl ?? embedFooter.IconUrl, cancellationToken)); + if (!string.IsNullOrWhiteSpace(embedFooter.IconUrl)) + _writer.WriteString("iconUrl", await Context.ResolveMediaUrlAsync(embedFooter.IconProxyUrl ?? embedFooter.IconUrl, cancellationToken)); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteEmbedFieldAsync( - EmbedField embedField, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject(); + private async ValueTask WriteEmbedFieldAsync( + EmbedField embedField, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject(); - _writer.WriteString("name", FormatMarkdown(embedField.Name)); - _writer.WriteString("value", FormatMarkdown(embedField.Value)); - _writer.WriteBoolean("isInline", embedField.IsInline); + _writer.WriteString("name", FormatMarkdown(embedField.Name)); + _writer.WriteString("value", FormatMarkdown(embedField.Value)); + _writer.WriteBoolean("isInline", embedField.IsInline); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteEmbedAsync( - Embed embed, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject(); + private async ValueTask WriteEmbedAsync( + Embed embed, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject(); - _writer.WriteString("title", FormatMarkdown(embed.Title)); - _writer.WriteString("url", embed.Url); - _writer.WriteString("timestamp", embed.Timestamp); - _writer.WriteString("description", FormatMarkdown(embed.Description)); + _writer.WriteString("title", FormatMarkdown(embed.Title)); + _writer.WriteString("url", embed.Url); + _writer.WriteString("timestamp", embed.Timestamp); + _writer.WriteString("description", FormatMarkdown(embed.Description)); - if (embed.Color is not null) - _writer.WriteString("color", embed.Color.Value.ToHex()); + if (embed.Color is not null) + _writer.WriteString("color", embed.Color.Value.ToHex()); - if (embed.Author is not null) - await WriteEmbedAuthorAsync(embed.Author, cancellationToken); + if (embed.Author is not null) + await WriteEmbedAuthorAsync(embed.Author, cancellationToken); - if (embed.Thumbnail is not null) - await WriteEmbedThumbnailAsync(embed.Thumbnail, cancellationToken); + if (embed.Thumbnail is not null) + await WriteEmbedThumbnailAsync(embed.Thumbnail, cancellationToken); - if (embed.Image is not null) - await WriteEmbedImageAsync(embed.Image, cancellationToken); + if (embed.Image is not null) + await WriteEmbedImageAsync(embed.Image, cancellationToken); - if (embed.Footer is not null) - await WriteEmbedFooterAsync(embed.Footer, cancellationToken); + if (embed.Footer is not null) + await WriteEmbedFooterAsync(embed.Footer, cancellationToken); - // Fields - _writer.WriteStartArray("fields"); + // Fields + _writer.WriteStartArray("fields"); - foreach (var field in embed.Fields) - await WriteEmbedFieldAsync(field, cancellationToken); + foreach (var field in embed.Fields) + await WriteEmbedFieldAsync(field, cancellationToken); - _writer.WriteEndArray(); + _writer.WriteEndArray(); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - private async ValueTask WriteReactionAsync( - Reaction reaction, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject(); - - // Emoji - _writer.WriteStartObject("emoji"); - _writer.WriteString("id", reaction.Emoji.Id); - _writer.WriteString("name", reaction.Emoji.Name); - _writer.WriteBoolean("isAnimated", reaction.Emoji.IsAnimated); - _writer.WriteString("imageUrl", await Context.ResolveMediaUrlAsync(reaction.Emoji.ImageUrl, cancellationToken)); - _writer.WriteEndObject(); + private async ValueTask WriteReactionAsync( + Reaction reaction, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject(); - _writer.WriteNumber("count", reaction.Count); + // Emoji + _writer.WriteStartObject("emoji"); + _writer.WriteString("id", reaction.Emoji.Id); + _writer.WriteString("name", reaction.Emoji.Name); + _writer.WriteBoolean("isAnimated", reaction.Emoji.IsAnimated); + _writer.WriteString("imageUrl", await Context.ResolveMediaUrlAsync(reaction.Emoji.ImageUrl, cancellationToken)); + _writer.WriteEndObject(); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteNumber("count", reaction.Count); - private async ValueTask WriteMentionAsync( - User mentionedUser, - CancellationToken cancellationToken = default) - { - _writer.WriteStartObject(); + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - _writer.WriteString("id", mentionedUser.Id.ToString()); - _writer.WriteString("name", mentionedUser.Name); - _writer.WriteString("discriminator", mentionedUser.DiscriminatorFormatted); - _writer.WriteString("nickname", Context.TryGetMember(mentionedUser.Id)?.Nick ?? mentionedUser.Name); - _writer.WriteBoolean("isBot", mentionedUser.IsBot); + private async ValueTask WriteMentionAsync( + User mentionedUser, + CancellationToken cancellationToken = default) + { + _writer.WriteStartObject(); - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteString("id", mentionedUser.Id.ToString()); + _writer.WriteString("name", mentionedUser.Name); + _writer.WriteString("discriminator", mentionedUser.DiscriminatorFormatted); + _writer.WriteString("nickname", Context.TryGetMember(mentionedUser.Id)?.Nick ?? mentionedUser.Name); + _writer.WriteBoolean("isBot", mentionedUser.IsBot); - public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) - { - // Root object (start) - _writer.WriteStartObject(); - - // Guild - _writer.WriteStartObject("guild"); - _writer.WriteString("id", Context.Request.Guild.Id.ToString()); - _writer.WriteString("name", Context.Request.Guild.Name); - _writer.WriteString("iconUrl", await Context.ResolveMediaUrlAsync(Context.Request.Guild.IconUrl, cancellationToken)); - _writer.WriteEndObject(); + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - // Channel - _writer.WriteStartObject("channel"); - _writer.WriteString("id", Context.Request.Channel.Id.ToString()); - _writer.WriteString("type", Context.Request.Channel.Kind.ToString()); - _writer.WriteString("categoryId", Context.Request.Channel.Category.Id.ToString()); - _writer.WriteString("category", Context.Request.Channel.Category.Name); - _writer.WriteString("name", Context.Request.Channel.Name); - _writer.WriteString("topic", Context.Request.Channel.Topic); - _writer.WriteEndObject(); + public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) + { + // Root object (start) + _writer.WriteStartObject(); + + // Guild + _writer.WriteStartObject("guild"); + _writer.WriteString("id", Context.Request.Guild.Id.ToString()); + _writer.WriteString("name", Context.Request.Guild.Name); + _writer.WriteString("iconUrl", await Context.ResolveMediaUrlAsync(Context.Request.Guild.IconUrl, cancellationToken)); + _writer.WriteEndObject(); + + // Channel + _writer.WriteStartObject("channel"); + _writer.WriteString("id", Context.Request.Channel.Id.ToString()); + _writer.WriteString("type", Context.Request.Channel.Kind.ToString()); + _writer.WriteString("categoryId", Context.Request.Channel.Category.Id.ToString()); + _writer.WriteString("category", Context.Request.Channel.Category.Name); + _writer.WriteString("name", Context.Request.Channel.Name); + _writer.WriteString("topic", Context.Request.Channel.Topic); + _writer.WriteEndObject(); + + // Date range + _writer.WriteStartObject("dateRange"); + _writer.WriteString("after", Context.Request.After?.ToDate()); + _writer.WriteString("before", Context.Request.Before?.ToDate()); + _writer.WriteEndObject(); + + // Message array (start) + _writer.WriteStartArray("messages"); + await _writer.FlushAsync(cancellationToken); + } - // Date range - _writer.WriteStartObject("dateRange"); - _writer.WriteString("after", Context.Request.After?.ToDate()); - _writer.WriteString("before", Context.Request.Before?.ToDate()); - _writer.WriteEndObject(); + public override async ValueTask WriteMessageAsync( + Message message, + CancellationToken cancellationToken = default) + { + await base.WriteMessageAsync(message, cancellationToken); - // Message array (start) - _writer.WriteStartArray("messages"); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteStartObject(); - public override async ValueTask WriteMessageAsync( - Message message, - CancellationToken cancellationToken = default) - { - await base.WriteMessageAsync(message, cancellationToken); - - _writer.WriteStartObject(); - - // Metadata - _writer.WriteString("id", message.Id.ToString()); - _writer.WriteString("type", message.Kind.ToString()); - _writer.WriteString("timestamp", message.Timestamp); - _writer.WriteString("timestampEdited", message.EditedTimestamp); - _writer.WriteString("callEndedTimestamp", message.CallEndedTimestamp); - _writer.WriteBoolean("isPinned", message.IsPinned); - - // Content - _writer.WriteString("content", FormatMarkdown(message.Content)); - - // Author - _writer.WriteStartObject("author"); - _writer.WriteString("id", message.Author.Id.ToString()); - _writer.WriteString("name", message.Author.Name); - _writer.WriteString("discriminator", message.Author.DiscriminatorFormatted); - _writer.WriteString("nickname", Context.TryGetMember(message.Author.Id)?.Nick ?? message.Author.Name); - _writer.WriteString("color", Context.TryGetUserColor(message.Author.Id)?.ToHex()); - _writer.WriteBoolean("isBot", message.Author.IsBot); - _writer.WriteString("avatarUrl", await Context.ResolveMediaUrlAsync(message.Author.AvatarUrl, cancellationToken)); - _writer.WriteEndObject(); + // Metadata + _writer.WriteString("id", message.Id.ToString()); + _writer.WriteString("type", message.Kind.ToString()); + _writer.WriteString("timestamp", message.Timestamp); + _writer.WriteString("timestampEdited", message.EditedTimestamp); + _writer.WriteString("callEndedTimestamp", message.CallEndedTimestamp); + _writer.WriteBoolean("isPinned", message.IsPinned); + + // Content + _writer.WriteString("content", FormatMarkdown(message.Content)); - // Attachments - _writer.WriteStartArray("attachments"); + // Author + _writer.WriteStartObject("author"); + _writer.WriteString("id", message.Author.Id.ToString()); + _writer.WriteString("name", message.Author.Name); + _writer.WriteString("discriminator", message.Author.DiscriminatorFormatted); + _writer.WriteString("nickname", Context.TryGetMember(message.Author.Id)?.Nick ?? message.Author.Name); + _writer.WriteString("color", Context.TryGetUserColor(message.Author.Id)?.ToHex()); + _writer.WriteBoolean("isBot", message.Author.IsBot); + _writer.WriteString("avatarUrl", await Context.ResolveMediaUrlAsync(message.Author.AvatarUrl, cancellationToken)); + _writer.WriteEndObject(); - foreach (var attachment in message.Attachments) - await WriteAttachmentAsync(attachment, cancellationToken); + // Attachments + _writer.WriteStartArray("attachments"); - _writer.WriteEndArray(); + foreach (var attachment in message.Attachments) + await WriteAttachmentAsync(attachment, cancellationToken); - // Embeds - _writer.WriteStartArray("embeds"); + _writer.WriteEndArray(); - foreach (var embed in message.Embeds) - await WriteEmbedAsync(embed, cancellationToken); + // Embeds + _writer.WriteStartArray("embeds"); - _writer.WriteEndArray(); + foreach (var embed in message.Embeds) + await WriteEmbedAsync(embed, cancellationToken); - // Reactions - _writer.WriteStartArray("reactions"); + _writer.WriteEndArray(); - foreach (var reaction in message.Reactions) - await WriteReactionAsync(reaction, cancellationToken); + // Reactions + _writer.WriteStartArray("reactions"); - _writer.WriteEndArray(); + foreach (var reaction in message.Reactions) + await WriteReactionAsync(reaction, cancellationToken); - // Mentions - _writer.WriteStartArray("mentions"); + _writer.WriteEndArray(); - foreach (var mention in message.MentionedUsers) - await WriteMentionAsync(mention, cancellationToken); + // Mentions + _writer.WriteStartArray("mentions"); - _writer.WriteEndArray(); + foreach (var mention in message.MentionedUsers) + await WriteMentionAsync(mention, cancellationToken); - // Message reference - if (message.Reference is not null) - { - _writer.WriteStartObject("reference"); - _writer.WriteString("messageId", message.Reference.MessageId?.ToString()); - _writer.WriteString("channelId", message.Reference.ChannelId?.ToString()); - _writer.WriteString("guildId", message.Reference.GuildId?.ToString()); - _writer.WriteEndObject(); - } + _writer.WriteEndArray(); + // Message reference + if (message.Reference is not null) + { + _writer.WriteStartObject("reference"); + _writer.WriteString("messageId", message.Reference.MessageId?.ToString()); + _writer.WriteString("channelId", message.Reference.ChannelId?.ToString()); + _writer.WriteString("guildId", message.Reference.GuildId?.ToString()); _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); } - public override async ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) - { - // Message array (end) - _writer.WriteEndArray(); + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } - _writer.WriteNumber("messageCount", MessagesWritten); + public override async ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) + { + // Message array (end) + _writer.WriteEndArray(); - // Root object (end) - _writer.WriteEndObject(); - await _writer.FlushAsync(cancellationToken); - } + _writer.WriteNumber("messageCount", MessagesWritten); - public override async ValueTask DisposeAsync() - { - await _writer.DisposeAsync(); - await base.DisposeAsync(); - } + // Root object (end) + _writer.WriteEndObject(); + await _writer.FlushAsync(cancellationToken); + } + + public override async ValueTask DisposeAsync() + { + await _writer.DisposeAsync(); + await base.DisposeAsync(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs index ed999b9..10e393e 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/HtmlMarkdownVisitor.cs @@ -9,185 +9,184 @@ using DiscordChatExporter.Core.Markdown; using DiscordChatExporter.Core.Markdown.Parsing; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors +namespace DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; + +internal partial class HtmlMarkdownVisitor : MarkdownVisitor { - internal partial class HtmlMarkdownVisitor : MarkdownVisitor + private readonly ExportContext _context; + private readonly StringBuilder _buffer; + private readonly bool _isJumbo; + + public HtmlMarkdownVisitor(ExportContext context, StringBuilder buffer, bool isJumbo) { - private readonly ExportContext _context; - private readonly StringBuilder _buffer; - private readonly bool _isJumbo; + _context = context; + _buffer = buffer; + _isJumbo = isJumbo; + } - public HtmlMarkdownVisitor(ExportContext context, StringBuilder buffer, bool isJumbo) - { - _context = context; - _buffer = buffer; - _isJumbo = isJumbo; - } + protected override MarkdownNode VisitText(TextNode text) + { + _buffer.Append(HtmlEncode(text.Text)); + return base.VisitText(text); + } - protected override MarkdownNode VisitText(TextNode text) + protected override MarkdownNode VisitFormatting(FormattingNode formatting) + { + var (tagOpen, tagClose) = formatting.Kind switch { - _buffer.Append(HtmlEncode(text.Text)); - return base.VisitText(text); - } + FormattingKind.Bold => ("", ""), + FormattingKind.Italic => ("", ""), + FormattingKind.Underline => ("", ""), + FormattingKind.Strikethrough => ("", ""), + FormattingKind.Spoiler => ( + "", ""), + FormattingKind.Quote => ("
", "
"), + _ => throw new ArgumentOutOfRangeException(nameof(formatting.Kind)) + }; + + _buffer.Append(tagOpen); + var result = base.VisitFormatting(formatting); + _buffer.Append(tagClose); + + return result; + } - protected override MarkdownNode VisitFormatting(FormattingNode formatting) - { - var (tagOpen, tagClose) = formatting.Kind switch - { - FormattingKind.Bold => ("", ""), - FormattingKind.Italic => ("", ""), - FormattingKind.Underline => ("", ""), - FormattingKind.Strikethrough => ("", ""), - FormattingKind.Spoiler => ( - "", ""), - FormattingKind.Quote => ("
", "
"), - _ => throw new ArgumentOutOfRangeException(nameof(formatting.Kind)) - }; - - _buffer.Append(tagOpen); - var result = base.VisitFormatting(formatting); - _buffer.Append(tagClose); - - return result; - } + protected override MarkdownNode VisitInlineCodeBlock(InlineCodeBlockNode inlineCodeBlock) + { + _buffer + .Append("") + .Append(HtmlEncode(inlineCodeBlock.Code)) + .Append(""); - protected override MarkdownNode VisitInlineCodeBlock(InlineCodeBlockNode inlineCodeBlock) - { - _buffer - .Append("") - .Append(HtmlEncode(inlineCodeBlock.Code)) - .Append(""); + return base.VisitInlineCodeBlock(inlineCodeBlock); + } - return base.VisitInlineCodeBlock(inlineCodeBlock); - } + protected override MarkdownNode VisitMultiLineCodeBlock(MultiLineCodeBlockNode multiLineCodeBlock) + { + var highlightCssClass = !string.IsNullOrWhiteSpace(multiLineCodeBlock.Language) + ? $"language-{multiLineCodeBlock.Language}" + : "nohighlight"; - protected override MarkdownNode VisitMultiLineCodeBlock(MultiLineCodeBlockNode multiLineCodeBlock) - { - var highlightCssClass = !string.IsNullOrWhiteSpace(multiLineCodeBlock.Language) - ? $"language-{multiLineCodeBlock.Language}" - : "nohighlight"; + _buffer + .Append($"
") + .Append(HtmlEncode(multiLineCodeBlock.Code)) + .Append("
"); - _buffer - .Append($"
") - .Append(HtmlEncode(multiLineCodeBlock.Code)) - .Append("
"); + return base.VisitMultiLineCodeBlock(multiLineCodeBlock); + } - return base.VisitMultiLineCodeBlock(multiLineCodeBlock); - } + protected override MarkdownNode VisitLink(LinkNode link) + { + // Try to extract message ID if the link refers to a Discord message + var linkedMessageId = Regex.Match( + link.Url, + "^https?://(?:discord|discordapp).com/channels/.*?/(\\d+)/?$" + ).Groups[1].Value; + + _buffer.Append( + !string.IsNullOrWhiteSpace(linkedMessageId) + ? $"" + : $"" + ); + + var result = base.VisitLink(link); + _buffer.Append(""); + + return result; + } + + protected override MarkdownNode VisitEmoji(EmojiNode emoji) + { + var emojiImageUrl = Emoji.GetImageUrl(emoji.Id, emoji.Name, emoji.IsAnimated); + var jumboClass = _isJumbo ? "emoji--large" : ""; + + _buffer + .Append($"\"{emoji.Name}\""); + + return base.VisitEmoji(emoji); + } - protected override MarkdownNode VisitLink(LinkNode link) + protected override MarkdownNode VisitMention(MentionNode mention) + { + var mentionId = Snowflake.TryParse(mention.Id); + if (mention.Kind == MentionKind.Meta) { - // Try to extract message ID if the link refers to a Discord message - var linkedMessageId = Regex.Match( - link.Url, - "^https?://(?:discord|discordapp).com/channels/.*?/(\\d+)/?$" - ).Groups[1].Value; - - _buffer.Append( - !string.IsNullOrWhiteSpace(linkedMessageId) - ? $"" - : $"" - ); - - var result = base.VisitLink(link); - _buffer.Append(""); - - return result; + _buffer + .Append("") + .Append("@").Append(HtmlEncode(mention.Id)) + .Append(""); } - - protected override MarkdownNode VisitEmoji(EmojiNode emoji) + else if (mention.Kind == MentionKind.User) { - var emojiImageUrl = Emoji.GetImageUrl(emoji.Id, emoji.Name, emoji.IsAnimated); - var jumboClass = _isJumbo ? "emoji--large" : ""; + var member = mentionId?.Pipe(_context.TryGetMember); + var fullName = member?.User.FullName ?? "Unknown"; + var nick = member?.Nick ?? "Unknown"; _buffer - .Append($"\"{emoji.Name}\""); - - return base.VisitEmoji(emoji); + .Append($"") + .Append("@").Append(HtmlEncode(nick)) + .Append(""); } - - protected override MarkdownNode VisitMention(MentionNode mention) + else if (mention.Kind == MentionKind.Channel) { - var mentionId = Snowflake.TryParse(mention.Id); - if (mention.Kind == MentionKind.Meta) - { - _buffer - .Append("") - .Append("@").Append(HtmlEncode(mention.Id)) - .Append(""); - } - else if (mention.Kind == MentionKind.User) - { - var member = mentionId?.Pipe(_context.TryGetMember); - var fullName = member?.User.FullName ?? "Unknown"; - var nick = member?.Nick ?? "Unknown"; - - _buffer - .Append($"") - .Append("@").Append(HtmlEncode(nick)) - .Append(""); - } - else if (mention.Kind == MentionKind.Channel) - { - var channel = mentionId?.Pipe(_context.TryGetChannel); - var symbol = channel?.IsVoiceChannel == true ? "🔊" : "#"; - var name = channel?.Name ?? "deleted-channel"; - - _buffer - .Append("") - .Append(symbol).Append(HtmlEncode(name)) - .Append(""); - } - else if (mention.Kind == MentionKind.Role) - { - var role = mentionId?.Pipe(_context.TryGetRole); - var name = role?.Name ?? "deleted-role"; - var color = role?.Color; - - var style = color is not null - ? $"color: rgb({color?.R}, {color?.G}, {color?.B}); background-color: rgba({color?.R}, {color?.G}, {color?.B}, 0.1);" - : ""; - - _buffer - .Append($"") - .Append("@").Append(HtmlEncode(name)) - .Append(""); - } - - return base.VisitMention(mention); - } + var channel = mentionId?.Pipe(_context.TryGetChannel); + var symbol = channel?.IsVoiceChannel == true ? "🔊" : "#"; + var name = channel?.Name ?? "deleted-channel"; - protected override MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp) + _buffer + .Append("") + .Append(symbol).Append(HtmlEncode(name)) + .Append(""); + } + else if (mention.Kind == MentionKind.Role) { - // Timestamp tooltips always use full date regardless of the configured format - var longDateString = timestamp.Value.ToLocalString("dddd, MMMM d, yyyy h:mm tt"); + var role = mentionId?.Pipe(_context.TryGetRole); + var name = role?.Name ?? "deleted-role"; + var color = role?.Color; + + var style = color is not null + ? $"color: rgb({color?.R}, {color?.G}, {color?.B}); background-color: rgba({color?.R}, {color?.G}, {color?.B}, 0.1);" + : ""; _buffer - .Append($"") - .Append(HtmlEncode(_context.FormatDate(timestamp.Value))) + .Append($"") + .Append("@").Append(HtmlEncode(name)) .Append(""); - - return base.VisitUnixTimestamp(timestamp); } + + return base.VisitMention(mention); } - internal partial class HtmlMarkdownVisitor + protected override MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp) { - private static string HtmlEncode(string text) => WebUtility.HtmlEncode(text); + // Timestamp tooltips always use full date regardless of the configured format + var longDateString = timestamp.Value.ToLocalString("dddd, MMMM d, yyyy h:mm tt"); - public static string Format(ExportContext context, string markdown, bool isJumboAllowed = true) - { - var nodes = MarkdownParser.Parse(markdown); + _buffer + .Append($"") + .Append(HtmlEncode(_context.FormatDate(timestamp.Value))) + .Append(""); - var isJumbo = - isJumboAllowed && - nodes.All(n => n is EmojiNode || n is TextNode textNode && string.IsNullOrWhiteSpace(textNode.Text)); + return base.VisitUnixTimestamp(timestamp); + } +} - var buffer = new StringBuilder(); +internal partial class HtmlMarkdownVisitor +{ + private static string HtmlEncode(string text) => WebUtility.HtmlEncode(text); - new HtmlMarkdownVisitor(context, buffer, isJumbo).Visit(nodes); + public static string Format(ExportContext context, string markdown, bool isJumboAllowed = true) + { + var nodes = MarkdownParser.Parse(markdown); - return buffer.ToString(); - } + var isJumbo = + isJumboAllowed && + nodes.All(n => n is EmojiNode || n is TextNode textNode && string.IsNullOrWhiteSpace(textNode.Text)); + + var buffer = new StringBuilder(); + + new HtmlMarkdownVisitor(context, buffer, isJumbo).Visit(nodes); + + return buffer.ToString(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs index 128ff77..b165127 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/MarkdownVisitors/PlainTextMarkdownVisitor.cs @@ -4,92 +4,91 @@ using DiscordChatExporter.Core.Markdown; using DiscordChatExporter.Core.Markdown.Parsing; using DiscordChatExporter.Core.Utils.Extensions; -namespace DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors +namespace DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; + +internal partial class PlainTextMarkdownVisitor : MarkdownVisitor { - internal partial class PlainTextMarkdownVisitor : MarkdownVisitor + private readonly ExportContext _context; + private readonly StringBuilder _buffer; + + public PlainTextMarkdownVisitor(ExportContext context, StringBuilder buffer) { - private readonly ExportContext _context; - private readonly StringBuilder _buffer; + _context = context; + _buffer = buffer; + } - public PlainTextMarkdownVisitor(ExportContext context, StringBuilder buffer) - { - _context = context; - _buffer = buffer; - } + protected override MarkdownNode VisitText(TextNode text) + { + _buffer.Append(text.Text); + return base.VisitText(text); + } - protected override MarkdownNode VisitText(TextNode text) + protected override MarkdownNode VisitEmoji(EmojiNode emoji) + { + _buffer.Append( + emoji.IsCustomEmoji + ? $":{emoji.Name}:" + : emoji.Name + ); + + return base.VisitEmoji(emoji); + } + + protected override MarkdownNode VisitMention(MentionNode mention) + { + var mentionId = Snowflake.TryParse(mention.Id); + if (mention.Kind == MentionKind.Meta) { - _buffer.Append(text.Text); - return base.VisitText(text); + _buffer.Append($"@{mention.Id}"); } - - protected override MarkdownNode VisitEmoji(EmojiNode emoji) + else if (mention.Kind == MentionKind.User) { - _buffer.Append( - emoji.IsCustomEmoji - ? $":{emoji.Name}:" - : emoji.Name - ); + var member = mentionId?.Pipe(_context.TryGetMember); + var name = member?.User.Name ?? "Unknown"; - return base.VisitEmoji(emoji); + _buffer.Append($"@{name}"); } - - protected override MarkdownNode VisitMention(MentionNode mention) + else if (mention.Kind == MentionKind.Channel) { - var mentionId = Snowflake.TryParse(mention.Id); - if (mention.Kind == MentionKind.Meta) - { - _buffer.Append($"@{mention.Id}"); - } - else if (mention.Kind == MentionKind.User) - { - var member = mentionId?.Pipe(_context.TryGetMember); - var name = member?.User.Name ?? "Unknown"; - - _buffer.Append($"@{name}"); - } - else if (mention.Kind == MentionKind.Channel) - { - var channel = mentionId?.Pipe(_context.TryGetChannel); - var name = channel?.Name ?? "deleted-channel"; - - _buffer.Append($"#{name}"); - - // Voice channel marker - if (channel?.IsVoiceChannel == true) - _buffer.Append(" [voice]"); - } - else if (mention.Kind == MentionKind.Role) - { - var role = mentionId?.Pipe(_context.TryGetRole); - var name = role?.Name ?? "deleted-role"; - - _buffer.Append($"@{name}"); - } - - return base.VisitMention(mention); - } + var channel = mentionId?.Pipe(_context.TryGetChannel); + var name = channel?.Name ?? "deleted-channel"; + + _buffer.Append($"#{name}"); - protected override MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp) + // Voice channel marker + if (channel?.IsVoiceChannel == true) + _buffer.Append(" [voice]"); + } + else if (mention.Kind == MentionKind.Role) { - _buffer.Append( - _context.FormatDate(timestamp.Value) - ); + var role = mentionId?.Pipe(_context.TryGetRole); + var name = role?.Name ?? "deleted-role"; - return base.VisitUnixTimestamp(timestamp); + _buffer.Append($"@{name}"); } + + return base.VisitMention(mention); } - internal partial class PlainTextMarkdownVisitor + protected override MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp) { - public static string Format(ExportContext context, string markdown) - { - var nodes = MarkdownParser.ParseMinimal(markdown); - var buffer = new StringBuilder(); + _buffer.Append( + _context.FormatDate(timestamp.Value) + ); - new PlainTextMarkdownVisitor(context, buffer).Visit(nodes); + return base.VisitUnixTimestamp(timestamp); + } +} - return buffer.ToString(); - } +internal partial class PlainTextMarkdownVisitor +{ + public static string Format(ExportContext context, string markdown) + { + var nodes = MarkdownParser.ParseMinimal(markdown); + var buffer = new StringBuilder(); + + new PlainTextMarkdownVisitor(context, buffer).Visit(nodes); + + return buffer.ToString(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/MessageWriter.cs b/DiscordChatExporter.Core/Exporting/Writers/MessageWriter.cs index f79135f..5e0b7b5 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/MessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/MessageWriter.cs @@ -4,34 +4,33 @@ using System.Threading; using System.Threading.Tasks; using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Core.Exporting.Writers +namespace DiscordChatExporter.Core.Exporting.Writers; + +internal abstract class MessageWriter : IAsyncDisposable { - internal abstract class MessageWriter : IAsyncDisposable - { - protected Stream Stream { get; } + protected Stream Stream { get; } - protected ExportContext Context { get; } + protected ExportContext Context { get; } - public long MessagesWritten { get; private set; } + public long MessagesWritten { get; private set; } - public long BytesWritten => Stream.Length; + public long BytesWritten => Stream.Length; - protected MessageWriter(Stream stream, ExportContext context) - { - Stream = stream; - Context = context; - } + protected MessageWriter(Stream stream, ExportContext context) + { + Stream = stream; + Context = context; + } - public virtual ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) => default; + public virtual ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) => default; - public virtual ValueTask WriteMessageAsync(Message message, CancellationToken cancellationToken = default) - { - MessagesWritten++; - return default; - } + public virtual ValueTask WriteMessageAsync(Message message, CancellationToken cancellationToken = default) + { + MessagesWritten++; + return default; + } - public virtual ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) => default; + public virtual ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) => default; - public virtual async ValueTask DisposeAsync() => await Stream.DisposeAsync(); - } + public virtual async ValueTask DisposeAsync() => await Stream.DisposeAsync(); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Exporting/Writers/PlainTextMessageWriter.cs b/DiscordChatExporter.Core/Exporting/Writers/PlainTextMessageWriter.cs index b80fedb..6ecf413 100644 --- a/DiscordChatExporter.Core/Exporting/Writers/PlainTextMessageWriter.cs +++ b/DiscordChatExporter.Core/Exporting/Writers/PlainTextMessageWriter.cs @@ -7,174 +7,173 @@ using DiscordChatExporter.Core.Discord.Data; using DiscordChatExporter.Core.Discord.Data.Embeds; using DiscordChatExporter.Core.Exporting.Writers.MarkdownVisitors; -namespace DiscordChatExporter.Core.Exporting.Writers +namespace DiscordChatExporter.Core.Exporting.Writers; + +internal class PlainTextMessageWriter : MessageWriter { - internal class PlainTextMessageWriter : MessageWriter - { - private readonly TextWriter _writer; + private readonly TextWriter _writer; - public PlainTextMessageWriter(Stream stream, ExportContext context) - : base(stream, context) - { - _writer = new StreamWriter(stream); - } + public PlainTextMessageWriter(Stream stream, ExportContext context) + : base(stream, context) + { + _writer = new StreamWriter(stream); + } - private string FormatMarkdown(string? markdown) => - PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); + private string FormatMarkdown(string? markdown) => + PlainTextMarkdownVisitor.Format(Context, markdown ?? ""); - private async ValueTask WriteMessageHeaderAsync(Message message) - { - // Timestamp & author - await _writer.WriteAsync($"[{Context.FormatDate(message.Timestamp)}]"); - await _writer.WriteAsync($" {message.Author.FullName}"); + private async ValueTask WriteMessageHeaderAsync(Message message) + { + // Timestamp & author + await _writer.WriteAsync($"[{Context.FormatDate(message.Timestamp)}]"); + await _writer.WriteAsync($" {message.Author.FullName}"); - // Whether the message is pinned - if (message.IsPinned) - await _writer.WriteAsync(" (pinned)"); + // Whether the message is pinned + if (message.IsPinned) + await _writer.WriteAsync(" (pinned)"); - await _writer.WriteLineAsync(); - } + await _writer.WriteLineAsync(); + } - private async ValueTask WriteAttachmentsAsync( - IReadOnlyList attachments, - CancellationToken cancellationToken = default) - { - if (!attachments.Any()) - return; + private async ValueTask WriteAttachmentsAsync( + IReadOnlyList attachments, + CancellationToken cancellationToken = default) + { + if (!attachments.Any()) + return; - await _writer.WriteLineAsync("{Attachments}"); + await _writer.WriteLineAsync("{Attachments}"); - foreach (var attachment in attachments) - { - cancellationToken.ThrowIfCancellationRequested(); - - await _writer.WriteLineAsync(await Context.ResolveMediaUrlAsync(attachment.Url, cancellationToken)); - } + foreach (var attachment in attachments) + { + cancellationToken.ThrowIfCancellationRequested(); - await _writer.WriteLineAsync(); + await _writer.WriteLineAsync(await Context.ResolveMediaUrlAsync(attachment.Url, cancellationToken)); } - private async ValueTask WriteEmbedsAsync( - IReadOnlyList embeds, - CancellationToken cancellationToken = default) + await _writer.WriteLineAsync(); + } + + private async ValueTask WriteEmbedsAsync( + IReadOnlyList embeds, + CancellationToken cancellationToken = default) + { + foreach (var embed in embeds) { - foreach (var embed in embeds) - { - cancellationToken.ThrowIfCancellationRequested(); + cancellationToken.ThrowIfCancellationRequested(); - await _writer.WriteLineAsync("{Embed}"); + await _writer.WriteLineAsync("{Embed}"); - if (!string.IsNullOrWhiteSpace(embed.Author?.Name)) - await _writer.WriteLineAsync(embed.Author.Name); + if (!string.IsNullOrWhiteSpace(embed.Author?.Name)) + await _writer.WriteLineAsync(embed.Author.Name); - if (!string.IsNullOrWhiteSpace(embed.Url)) - await _writer.WriteLineAsync(embed.Url); + if (!string.IsNullOrWhiteSpace(embed.Url)) + await _writer.WriteLineAsync(embed.Url); - if (!string.IsNullOrWhiteSpace(embed.Title)) - await _writer.WriteLineAsync(FormatMarkdown(embed.Title)); + if (!string.IsNullOrWhiteSpace(embed.Title)) + await _writer.WriteLineAsync(FormatMarkdown(embed.Title)); - if (!string.IsNullOrWhiteSpace(embed.Description)) - await _writer.WriteLineAsync(FormatMarkdown(embed.Description)); + if (!string.IsNullOrWhiteSpace(embed.Description)) + await _writer.WriteLineAsync(FormatMarkdown(embed.Description)); - foreach (var field in embed.Fields) - { - if (!string.IsNullOrWhiteSpace(field.Name)) - await _writer.WriteLineAsync(FormatMarkdown(field.Name)); + foreach (var field in embed.Fields) + { + if (!string.IsNullOrWhiteSpace(field.Name)) + await _writer.WriteLineAsync(FormatMarkdown(field.Name)); - if (!string.IsNullOrWhiteSpace(field.Value)) - await _writer.WriteLineAsync(FormatMarkdown(field.Value)); - } + if (!string.IsNullOrWhiteSpace(field.Value)) + await _writer.WriteLineAsync(FormatMarkdown(field.Value)); + } - if (!string.IsNullOrWhiteSpace(embed.Thumbnail?.Url)) - await _writer.WriteLineAsync(await Context.ResolveMediaUrlAsync(embed.Thumbnail.ProxyUrl ?? embed.Thumbnail.Url, cancellationToken)); + if (!string.IsNullOrWhiteSpace(embed.Thumbnail?.Url)) + await _writer.WriteLineAsync(await Context.ResolveMediaUrlAsync(embed.Thumbnail.ProxyUrl ?? embed.Thumbnail.Url, cancellationToken)); - if (!string.IsNullOrWhiteSpace(embed.Image?.Url)) - await _writer.WriteLineAsync(await Context.ResolveMediaUrlAsync(embed.Image.ProxyUrl ?? embed.Image.Url, cancellationToken)); + if (!string.IsNullOrWhiteSpace(embed.Image?.Url)) + await _writer.WriteLineAsync(await Context.ResolveMediaUrlAsync(embed.Image.ProxyUrl ?? embed.Image.Url, cancellationToken)); - if (!string.IsNullOrWhiteSpace(embed.Footer?.Text)) - await _writer.WriteLineAsync(embed.Footer.Text); + if (!string.IsNullOrWhiteSpace(embed.Footer?.Text)) + await _writer.WriteLineAsync(embed.Footer.Text); - await _writer.WriteLineAsync(); - } + await _writer.WriteLineAsync(); } + } - private async ValueTask WriteReactionsAsync( - IReadOnlyList reactions, - CancellationToken cancellationToken = default) - { - if (!reactions.Any()) - return; - - await _writer.WriteLineAsync("{Reactions}"); + private async ValueTask WriteReactionsAsync( + IReadOnlyList reactions, + CancellationToken cancellationToken = default) + { + if (!reactions.Any()) + return; - foreach (var reaction in reactions) - { - cancellationToken.ThrowIfCancellationRequested(); + await _writer.WriteLineAsync("{Reactions}"); - await _writer.WriteAsync(reaction.Emoji.Name); + foreach (var reaction in reactions) + { + cancellationToken.ThrowIfCancellationRequested(); - if (reaction.Count > 1) - await _writer.WriteAsync($" ({reaction.Count})"); + await _writer.WriteAsync(reaction.Emoji.Name); - await _writer.WriteAsync(' '); - } + if (reaction.Count > 1) + await _writer.WriteAsync($" ({reaction.Count})"); - await _writer.WriteLineAsync(); + await _writer.WriteAsync(' '); } - public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) - { - await _writer.WriteLineAsync(new string('=', 62)); - await _writer.WriteLineAsync($"Guild: {Context.Request.Guild.Name}"); - await _writer.WriteLineAsync($"Channel: {Context.Request.Channel.Category.Name} / {Context.Request.Channel.Name}"); + await _writer.WriteLineAsync(); + } - if (!string.IsNullOrWhiteSpace(Context.Request.Channel.Topic)) - await _writer.WriteLineAsync($"Topic: {Context.Request.Channel.Topic}"); + public override async ValueTask WritePreambleAsync(CancellationToken cancellationToken = default) + { + await _writer.WriteLineAsync(new string('=', 62)); + await _writer.WriteLineAsync($"Guild: {Context.Request.Guild.Name}"); + await _writer.WriteLineAsync($"Channel: {Context.Request.Channel.Category.Name} / {Context.Request.Channel.Name}"); - if (Context.Request.After is not null) - await _writer.WriteLineAsync($"After: {Context.FormatDate(Context.Request.After.Value.ToDate())}"); + if (!string.IsNullOrWhiteSpace(Context.Request.Channel.Topic)) + await _writer.WriteLineAsync($"Topic: {Context.Request.Channel.Topic}"); - if (Context.Request.Before is not null) - await _writer.WriteLineAsync($"Before: {Context.FormatDate(Context.Request.Before.Value.ToDate())}"); + if (Context.Request.After is not null) + await _writer.WriteLineAsync($"After: {Context.FormatDate(Context.Request.After.Value.ToDate())}"); - await _writer.WriteLineAsync(new string('=', 62)); - await _writer.WriteLineAsync(); - } + if (Context.Request.Before is not null) + await _writer.WriteLineAsync($"Before: {Context.FormatDate(Context.Request.Before.Value.ToDate())}"); - public override async ValueTask WriteMessageAsync( - Message message, - CancellationToken cancellationToken = default) - { - await base.WriteMessageAsync(message, cancellationToken); + await _writer.WriteLineAsync(new string('=', 62)); + await _writer.WriteLineAsync(); + } - // Header - await WriteMessageHeaderAsync(message); + public override async ValueTask WriteMessageAsync( + Message message, + CancellationToken cancellationToken = default) + { + await base.WriteMessageAsync(message, cancellationToken); - // Content - if (!string.IsNullOrWhiteSpace(message.Content)) - await _writer.WriteLineAsync(FormatMarkdown(message.Content)); + // Header + await WriteMessageHeaderAsync(message); - await _writer.WriteLineAsync(); + // Content + if (!string.IsNullOrWhiteSpace(message.Content)) + await _writer.WriteLineAsync(FormatMarkdown(message.Content)); - // Attachments, embeds, reactions - await WriteAttachmentsAsync(message.Attachments, cancellationToken); - await WriteEmbedsAsync(message.Embeds, cancellationToken); - await WriteReactionsAsync(message.Reactions, cancellationToken); + await _writer.WriteLineAsync(); - await _writer.WriteLineAsync(); - } + // Attachments, embeds, reactions + await WriteAttachmentsAsync(message.Attachments, cancellationToken); + await WriteEmbedsAsync(message.Embeds, cancellationToken); + await WriteReactionsAsync(message.Reactions, cancellationToken); - public override async ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) - { - await _writer.WriteLineAsync(new string('=', 62)); - await _writer.WriteLineAsync($"Exported {MessagesWritten:N0} message(s)"); - await _writer.WriteLineAsync(new string('=', 62)); - } + await _writer.WriteLineAsync(); + } - public override async ValueTask DisposeAsync() - { - await _writer.DisposeAsync(); - await base.DisposeAsync(); - } + public override async ValueTask WritePostambleAsync(CancellationToken cancellationToken = default) + { + await _writer.WriteLineAsync(new string('=', 62)); + await _writer.WriteLineAsync($"Exported {MessagesWritten:N0} message(s)"); + await _writer.WriteLineAsync(new string('=', 62)); + } + + public override async ValueTask DisposeAsync() + { + await _writer.DisposeAsync(); + await base.DisposeAsync(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/EmojiNode.cs b/DiscordChatExporter.Core/Markdown/EmojiNode.cs index 4ab6d69..22242d1 100644 --- a/DiscordChatExporter.Core/Markdown/EmojiNode.cs +++ b/DiscordChatExporter.Core/Markdown/EmojiNode.cs @@ -1,24 +1,23 @@ using DiscordChatExporter.Core.Utils; -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown; + +internal record EmojiNode( + // Only present on custom emoji + string? Id, + // Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂) + string Name, + bool IsAnimated) : MarkdownNode { - internal record EmojiNode( - // Only present on custom emoji - string? Id, - // Name of custom emoji (e.g. LUL) or actual representation of standard emoji (e.g. 🙂) - string Name, - bool IsAnimated) : MarkdownNode - { - // Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile) - public string Code => !string.IsNullOrWhiteSpace(Id) - ? Name - : EmojiIndex.TryGetCode(Name) ?? Name; + // Name of custom emoji (e.g. LUL) or name of standard emoji (e.g. slight_smile) + public string Code => !string.IsNullOrWhiteSpace(Id) + ? Name + : EmojiIndex.TryGetCode(Name) ?? Name; - public bool IsCustomEmoji => !string.IsNullOrWhiteSpace(Id); + public bool IsCustomEmoji => !string.IsNullOrWhiteSpace(Id); - public EmojiNode(string name) - : this(null, name, false) - { - } + public EmojiNode(string name) + : this(null, name, false) + { } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/FormattingKind.cs b/DiscordChatExporter.Core/Markdown/FormattingKind.cs index 6859b4f..749e312 100644 --- a/DiscordChatExporter.Core/Markdown/FormattingKind.cs +++ b/DiscordChatExporter.Core/Markdown/FormattingKind.cs @@ -1,12 +1,11 @@ -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown; + +internal enum FormattingKind { - internal enum FormattingKind - { - Bold, - Italic, - Underline, - Strikethrough, - Spoiler, - Quote - } + Bold, + Italic, + Underline, + Strikethrough, + Spoiler, + Quote } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/FormattingNode.cs b/DiscordChatExporter.Core/Markdown/FormattingNode.cs index 4c8096d..db1c153 100644 --- a/DiscordChatExporter.Core/Markdown/FormattingNode.cs +++ b/DiscordChatExporter.Core/Markdown/FormattingNode.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; -namespace DiscordChatExporter.Core.Markdown -{ - internal record FormattingNode(FormattingKind Kind, IReadOnlyList Children) : MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal record FormattingNode(FormattingKind Kind, IReadOnlyList Children) : MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs b/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs index 9c1fbcf..cdf0379 100644 --- a/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs +++ b/DiscordChatExporter.Core/Markdown/InlineCodeBlockNode.cs @@ -1,4 +1,3 @@ -namespace DiscordChatExporter.Core.Markdown -{ - internal record InlineCodeBlockNode(string Code) : MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal record InlineCodeBlockNode(string Code) : MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/LinkNode.cs b/DiscordChatExporter.Core/Markdown/LinkNode.cs index 71bd611..e023ec8 100644 --- a/DiscordChatExporter.Core/Markdown/LinkNode.cs +++ b/DiscordChatExporter.Core/Markdown/LinkNode.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown; + +internal record LinkNode( + string Url, + IReadOnlyList Children) : MarkdownNode { - internal record LinkNode( - string Url, - IReadOnlyList Children) : MarkdownNode + public LinkNode(string url) + : this(url, new[] { new TextNode(url) }) { - public LinkNode(string url) - : this(url, new[] { new TextNode(url) }) - { - } } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MarkdownNode.cs b/DiscordChatExporter.Core/Markdown/MarkdownNode.cs index 5bf9e8a..10f661c 100644 --- a/DiscordChatExporter.Core/Markdown/MarkdownNode.cs +++ b/DiscordChatExporter.Core/Markdown/MarkdownNode.cs @@ -1,4 +1,3 @@ -namespace DiscordChatExporter.Core.Markdown -{ - internal abstract record MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal abstract record MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MentionKind.cs b/DiscordChatExporter.Core/Markdown/MentionKind.cs index 824a1cd..5fb66db 100644 --- a/DiscordChatExporter.Core/Markdown/MentionKind.cs +++ b/DiscordChatExporter.Core/Markdown/MentionKind.cs @@ -1,10 +1,9 @@ -namespace DiscordChatExporter.Core.Markdown +namespace DiscordChatExporter.Core.Markdown; + +internal enum MentionKind { - internal enum MentionKind - { - Meta, - User, - Channel, - Role - } + Meta, + User, + Channel, + Role } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MentionNode.cs b/DiscordChatExporter.Core/Markdown/MentionNode.cs index fb317ef..748f7f0 100644 --- a/DiscordChatExporter.Core/Markdown/MentionNode.cs +++ b/DiscordChatExporter.Core/Markdown/MentionNode.cs @@ -1,4 +1,3 @@ -namespace DiscordChatExporter.Core.Markdown -{ - internal record MentionNode(string Id, MentionKind Kind) : MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal record MentionNode(string Id, MentionKind Kind) : MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs b/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs index 1388db9..63a0575 100644 --- a/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs +++ b/DiscordChatExporter.Core/Markdown/MultiLineCodeBlockNode.cs @@ -1,4 +1,3 @@ -namespace DiscordChatExporter.Core.Markdown -{ - internal record MultiLineCodeBlockNode(string Language, string Code) : MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal record MultiLineCodeBlockNode(string Language, string Code) : MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/AggregateMatcher.cs b/DiscordChatExporter.Core/Markdown/Parsing/AggregateMatcher.cs index 07b30bc..450aa83 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/AggregateMatcher.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/AggregateMatcher.cs @@ -1,46 +1,45 @@ using System.Collections.Generic; -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal class AggregateMatcher : IMatcher { - internal class AggregateMatcher : IMatcher + private readonly IReadOnlyList> _matchers; + + public AggregateMatcher(IReadOnlyList> matchers) { - private readonly IReadOnlyList> _matchers; + _matchers = matchers; + } - public AggregateMatcher(IReadOnlyList> matchers) - { - _matchers = matchers; - } + public AggregateMatcher(params IMatcher[] matchers) + : this((IReadOnlyList>) matchers) + { + } - public AggregateMatcher(params IMatcher[] matchers) - : this((IReadOnlyList>) matchers) - { - } + public ParsedMatch? TryMatch(StringPart stringPart) + { + ParsedMatch? earliestMatch = null; - public ParsedMatch? TryMatch(StringPart stringPart) + // Try to match the input with each matcher and get the match with the lowest start index + foreach (var matcher in _matchers) { - ParsedMatch? earliestMatch = null; + // Try to match + var match = matcher.TryMatch(stringPart); - // Try to match the input with each matcher and get the match with the lowest start index - foreach (var matcher in _matchers) - { - // Try to match - var match = matcher.TryMatch(stringPart); + // If there's no match - continue + if (match is null) + continue; - // If there's no match - continue - if (match is null) - continue; + // If this match is earlier than previous earliest - replace + if (earliestMatch is null || match.StringPart.StartIndex < earliestMatch.StringPart.StartIndex) + earliestMatch = match; - // If this match is earlier than previous earliest - replace - if (earliestMatch is null || match.StringPart.StartIndex < earliestMatch.StringPart.StartIndex) - earliestMatch = match; - - // If the earliest match starts at the very beginning - break, - // because it's impossible to find a match earlier than that - if (earliestMatch.StringPart.StartIndex == stringPart.StartIndex) - break; - } - - return earliestMatch; + // If the earliest match starts at the very beginning - break, + // because it's impossible to find a match earlier than that + if (earliestMatch.StringPart.StartIndex == stringPart.StartIndex) + break; } + + return earliestMatch; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/IMatcher.cs b/DiscordChatExporter.Core/Markdown/Parsing/IMatcher.cs index 0e3d1ec..175c312 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/IMatcher.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/IMatcher.cs @@ -1,49 +1,48 @@ using System; using System.Collections.Generic; -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal interface IMatcher { - internal interface IMatcher - { - ParsedMatch? TryMatch(StringPart stringPart); - } + ParsedMatch? TryMatch(StringPart stringPart); +} - internal static class MatcherExtensions +internal static class MatcherExtensions +{ + public static IEnumerable> MatchAll(this IMatcher matcher, + StringPart stringPart, Func transformFallback) { - public static IEnumerable> MatchAll(this IMatcher matcher, - StringPart stringPart, Func transformFallback) + // Loop through segments divided by individual matches + var currentIndex = stringPart.StartIndex; + while (currentIndex < stringPart.EndIndex) { - // Loop through segments divided by individual matches - var currentIndex = stringPart.StartIndex; - while (currentIndex < stringPart.EndIndex) - { - // Find a match within this segment - var match = matcher.TryMatch(stringPart.Slice(currentIndex, stringPart.EndIndex - currentIndex)); - - // If there's no match - break - if (match is null) - break; - - // If this match doesn't start immediately at current index - transform and yield fallback first - if (match.StringPart.StartIndex > currentIndex) - { - var fallbackPart = stringPart.Slice(currentIndex, match.StringPart.StartIndex - currentIndex); - yield return new ParsedMatch(fallbackPart, transformFallback(fallbackPart)); - } + // Find a match within this segment + var match = matcher.TryMatch(stringPart.Slice(currentIndex, stringPart.EndIndex - currentIndex)); - // Yield match - yield return match; + // If there's no match - break + if (match is null) + break; - // Shift current index to the end of the match - currentIndex = match.StringPart.StartIndex + match.StringPart.Length; - } - - // If EOL wasn't reached - transform and yield remaining part as fallback - if (currentIndex < stringPart.EndIndex) + // If this match doesn't start immediately at current index - transform and yield fallback first + if (match.StringPart.StartIndex > currentIndex) { - var fallbackPart = stringPart.Slice(currentIndex); + var fallbackPart = stringPart.Slice(currentIndex, match.StringPart.StartIndex - currentIndex); yield return new ParsedMatch(fallbackPart, transformFallback(fallbackPart)); } + + // Yield match + yield return match; + + // Shift current index to the end of the match + currentIndex = match.StringPart.StartIndex + match.StringPart.Length; + } + + // If EOL wasn't reached - transform and yield remaining part as fallback + if (currentIndex < stringPart.EndIndex) + { + var fallbackPart = stringPart.Slice(currentIndex); + yield return new ParsedMatch(fallbackPart, transformFallback(fallbackPart)); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs b/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs index fe5b064..d82bb74 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/MarkdownParser.cs @@ -5,341 +5,340 @@ using System.Linq; using System.Text.RegularExpressions; using DiscordChatExporter.Core.Utils; -namespace DiscordChatExporter.Core.Markdown.Parsing -{ - // Discord does NOT use a recursive-descent parser for markdown which becomes evident in some - // scenarios, like when multiple formatting nodes are nested together. - // To replicate Discord's behavior, we're employing a special parser that uses a set of regular - // expressions that are executed sequentially in a first-match-first-serve manner. - internal static partial class MarkdownParser - { - private const RegexOptions DefaultRegexOptions = - RegexOptions.Compiled | - RegexOptions.CultureInvariant | - RegexOptions.Multiline; - - /* Formatting */ - - // Capture any character until the earliest double asterisk not followed by an asterisk - private static readonly IMatcher BoldFormattingNodeMatcher = new RegexMatcher( - new Regex("\\*\\*(.+?)\\*\\*(?!\\*)", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Bold, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any character until the earliest single asterisk not preceded or followed by an asterisk - // Opening asterisk must not be followed by whitespace - // Closing asterisk must not be preceded by whitespace - private static readonly IMatcher ItalicFormattingNodeMatcher = new RegexMatcher( - new Regex("\\*(?!\\s)(.+?)(? new FormattingNode(FormattingKind.Italic, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any character until the earliest triple asterisk not followed by an asterisk - private static readonly IMatcher ItalicBoldFormattingNodeMatcher = new RegexMatcher( - new Regex("\\*(\\*\\*.+?\\*\\*)\\*(?!\\*)", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Italic, Parse(p.Slice(m.Groups[1]), BoldFormattingNodeMatcher)) - ); - - // Capture any character except underscore until an underscore - // Closing underscore must not be followed by a word character - private static readonly IMatcher ItalicAltFormattingNodeMatcher = new RegexMatcher( - new Regex("_([^_]+)_(?!\\w)", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Italic, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any character until the earliest double underscore not followed by an underscore - private static readonly IMatcher UnderlineFormattingNodeMatcher = new RegexMatcher( - new Regex("__(.+?)__(?!_)", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Underline, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any character until the earliest triple underscore not followed by an underscore - private static readonly IMatcher ItalicUnderlineFormattingNodeMatcher = - new RegexMatcher( - new Regex("_(__.+?__)_(?!_)", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Italic, - Parse(p.Slice(m.Groups[1]), UnderlineFormattingNodeMatcher)) - ); - - // Capture any character until the earliest double tilde - private static readonly IMatcher StrikethroughFormattingNodeMatcher = - new RegexMatcher( - new Regex("~~(.+?)~~", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Strikethrough, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any character until the earliest double pipe - private static readonly IMatcher SpoilerFormattingNodeMatcher = new RegexMatcher( - new Regex("\\|\\|(.+?)\\|\\|", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Spoiler, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any character until the end of the line - // Opening 'greater than' character must be followed by whitespace - private static readonly IMatcher SingleLineQuoteNodeMatcher = new RegexMatcher( - new Regex("^>\\s(.+\n?)", DefaultRegexOptions), - (p, m) => new FormattingNode(FormattingKind.Quote, Parse(p.Slice(m.Groups[1]))) - ); - - // Repeatedly capture any character until the end of the line - // This one is tricky as it ends up producing multiple separate captures which need to be joined - private static readonly IMatcher RepeatedSingleLineQuoteNodeMatcher = - new RegexMatcher( - new Regex("(?:^>\\s(.+\n?)){2,}", DefaultRegexOptions), - (_, m) => - { - var content = string.Concat(m.Groups[1].Captures.Select(c => c.Value)); - return new FormattingNode(FormattingKind.Quote, Parse(content)); - } - ); - - // Capture any character until the end of the input - // Opening 'greater than' characters must be followed by whitespace - private static readonly IMatcher MultiLineQuoteNodeMatcher = new RegexMatcher( - new Regex("^>>>\\s(.+)", DefaultRegexOptions | RegexOptions.Singleline), - (p, m) => new FormattingNode(FormattingKind.Quote, Parse(p.Slice(m.Groups[1]))) - ); - - /* Code blocks */ +namespace DiscordChatExporter.Core.Markdown.Parsing; - // Capture any character except backtick until a backtick - // Blank lines at the beginning and end of content are trimmed - // There can be either one or two backticks, but equal number on both sides - private static readonly IMatcher InlineCodeBlockNodeMatcher = new RegexMatcher( - new Regex("(`{1,2})([^`]+)\\1", DefaultRegexOptions | RegexOptions.Singleline), - (_, m) => new InlineCodeBlockNode(m.Groups[2].Value.Trim('\r', '\n')) - ); - - // Capture language identifier and then any character until the earliest triple backtick - // Language identifier is one word immediately after opening backticks, followed immediately by newline - // Blank lines at the beginning and end of content are trimmed - private static readonly IMatcher MultiLineCodeBlockNodeMatcher = new RegexMatcher( - new Regex("```(?:(\\w*)\\n)?(.+?)```", DefaultRegexOptions | RegexOptions.Singleline), - (_, m) => new MultiLineCodeBlockNode(m.Groups[1].Value, m.Groups[2].Value.Trim('\r', '\n')) - ); - - /* Mentions */ - - // Capture @everyone - private static readonly IMatcher EveryoneMentionNodeMatcher = new StringMatcher( - "@everyone", - _ => new MentionNode("everyone", MentionKind.Meta) - ); - - // Capture @here - private static readonly IMatcher HereMentionNodeMatcher = new StringMatcher( - "@here", - _ => new MentionNode("here", MentionKind.Meta) - ); - - // Capture <@123456> or <@!123456> - private static readonly IMatcher UserMentionNodeMatcher = new RegexMatcher( - new Regex("<@!?(\\d+)>", DefaultRegexOptions), - (_, m) => new MentionNode(m.Groups[1].Value, MentionKind.User) - ); - - // Capture <#123456> - private static readonly IMatcher ChannelMentionNodeMatcher = new RegexMatcher( - new Regex("<#!?(\\d+)>", DefaultRegexOptions), - (_, m) => new MentionNode(m.Groups[1].Value, MentionKind.Channel) - ); - - // Capture <@&123456> - private static readonly IMatcher RoleMentionNodeMatcher = new RegexMatcher( - new Regex("<@&(\\d+)>", DefaultRegexOptions), - (_, m) => new MentionNode(m.Groups[1].Value, MentionKind.Role) +// Discord does NOT use a recursive-descent parser for markdown which becomes evident in some +// scenarios, like when multiple formatting nodes are nested together. +// To replicate Discord's behavior, we're employing a special parser that uses a set of regular +// expressions that are executed sequentially in a first-match-first-serve manner. +internal static partial class MarkdownParser +{ + private const RegexOptions DefaultRegexOptions = + RegexOptions.Compiled | + RegexOptions.CultureInvariant | + RegexOptions.Multiline; + + /* Formatting */ + + // Capture any character until the earliest double asterisk not followed by an asterisk + private static readonly IMatcher BoldFormattingNodeMatcher = new RegexMatcher( + new Regex("\\*\\*(.+?)\\*\\*(?!\\*)", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Bold, Parse(p.Slice(m.Groups[1]))) + ); + + // Capture any character until the earliest single asterisk not preceded or followed by an asterisk + // Opening asterisk must not be followed by whitespace + // Closing asterisk must not be preceded by whitespace + private static readonly IMatcher ItalicFormattingNodeMatcher = new RegexMatcher( + new Regex("\\*(?!\\s)(.+?)(? new FormattingNode(FormattingKind.Italic, Parse(p.Slice(m.Groups[1]))) + ); + + // Capture any character until the earliest triple asterisk not followed by an asterisk + private static readonly IMatcher ItalicBoldFormattingNodeMatcher = new RegexMatcher( + new Regex("\\*(\\*\\*.+?\\*\\*)\\*(?!\\*)", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Italic, Parse(p.Slice(m.Groups[1]), BoldFormattingNodeMatcher)) + ); + + // Capture any character except underscore until an underscore + // Closing underscore must not be followed by a word character + private static readonly IMatcher ItalicAltFormattingNodeMatcher = new RegexMatcher( + new Regex("_([^_]+)_(?!\\w)", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Italic, Parse(p.Slice(m.Groups[1]))) + ); + + // Capture any character until the earliest double underscore not followed by an underscore + private static readonly IMatcher UnderlineFormattingNodeMatcher = new RegexMatcher( + new Regex("__(.+?)__(?!_)", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Underline, Parse(p.Slice(m.Groups[1]))) + ); + + // Capture any character until the earliest triple underscore not followed by an underscore + private static readonly IMatcher ItalicUnderlineFormattingNodeMatcher = + new RegexMatcher( + new Regex("_(__.+?__)_(?!_)", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Italic, + Parse(p.Slice(m.Groups[1]), UnderlineFormattingNodeMatcher)) ); - /* Emoji */ - - // Capture any country flag emoji (two regional indicator surrogate pairs) - // ... or "miscellaneous symbol" character - // ... or surrogate pair - // ... or digit followed by enclosing mark - // (this does not match all emoji in Discord but it's reasonably accurate enough) - private static readonly IMatcher StandardEmojiNodeMatcher = new RegexMatcher( - new Regex("((?:[\\uD83C][\\uDDE6-\\uDDFF]){2}|[\\u2600-\\u26FF]|\\p{Cs}{2}|\\d\\p{Me})", DefaultRegexOptions), - (_, m) => new EmojiNode(m.Groups[1].Value) + // Capture any character until the earliest double tilde + private static readonly IMatcher StrikethroughFormattingNodeMatcher = + new RegexMatcher( + new Regex("~~(.+?)~~", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Strikethrough, Parse(p.Slice(m.Groups[1]))) ); - // Capture :thinking: (but only for known emoji codes) - private static readonly IMatcher CodedStandardEmojiNodeMatcher = new RegexMatcher( - new Regex(":([\\w_]+):", DefaultRegexOptions), + // Capture any character until the earliest double pipe + private static readonly IMatcher SpoilerFormattingNodeMatcher = new RegexMatcher( + new Regex("\\|\\|(.+?)\\|\\|", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Spoiler, Parse(p.Slice(m.Groups[1]))) + ); + + // Capture any character until the end of the line + // Opening 'greater than' character must be followed by whitespace + private static readonly IMatcher SingleLineQuoteNodeMatcher = new RegexMatcher( + new Regex("^>\\s(.+\n?)", DefaultRegexOptions), + (p, m) => new FormattingNode(FormattingKind.Quote, Parse(p.Slice(m.Groups[1]))) + ); + + // Repeatedly capture any character until the end of the line + // This one is tricky as it ends up producing multiple separate captures which need to be joined + private static readonly IMatcher RepeatedSingleLineQuoteNodeMatcher = + new RegexMatcher( + new Regex("(?:^>\\s(.+\n?)){2,}", DefaultRegexOptions), (_, m) => { - var name = EmojiIndex.TryGetName(m.Groups[1].Value); - return !string.IsNullOrWhiteSpace(name) - ? new EmojiNode(name) - : null; + var content = string.Concat(m.Groups[1].Captures.Select(c => c.Value)); + return new FormattingNode(FormattingKind.Quote, Parse(content)); } ); - // Capture <:lul:123456> or - private static readonly IMatcher CustomEmojiNodeMatcher = new RegexMatcher( - new Regex("<(a)?:(.+?):(\\d+?)>", DefaultRegexOptions), - (_, m) => new EmojiNode(m.Groups[3].Value, m.Groups[2].Value, !string.IsNullOrWhiteSpace(m.Groups[1].Value)) - ); - - /* Links */ - - // Capture [title](link) - private static readonly IMatcher TitledLinkNodeMatcher = new RegexMatcher( - new Regex("\\[(.+?)\\]\\((.+?)\\)", DefaultRegexOptions), - (p, m) => new LinkNode(m.Groups[2].Value, Parse(p.Slice(m.Groups[1]))) - ); - - // Capture any non-whitespace character after http:// or https:// - // until the last punctuation character or whitespace - private static readonly IMatcher AutoLinkNodeMatcher = new RegexMatcher( - new Regex("(https?://\\S*[^\\.,:;\"\'\\s])", DefaultRegexOptions), - (_, m) => new LinkNode(m.Groups[1].Value) - ); - - // Same as auto link but also surrounded by angular brackets - private static readonly IMatcher HiddenLinkNodeMatcher = new RegexMatcher( - new Regex("<(https?://\\S*[^\\.,:;\"\'\\s])>", DefaultRegexOptions), - (_, m) => new LinkNode(m.Groups[1].Value) - ); - - /* Text */ - - // Capture the shrug kaomoji - // This escapes it from matching for formatting - private static readonly IMatcher ShrugTextNodeMatcher = new StringMatcher( - @"¯\_(ツ)_/¯", - p => new TextNode(p.ToString()) - ); - - // Capture some specific emoji that don't get rendered - // This escapes it from matching for emoji - private static readonly IMatcher IgnoredEmojiTextNodeMatcher = new RegexMatcher( - new Regex("(\\u26A7|\\u2640|\\u2642|\\u2695|\\u267E|\\u00A9|\\u00AE|\\u2122)", DefaultRegexOptions), - (_, m) => new TextNode(m.Groups[1].Value) - ); - - // Capture any "symbol/other" character or surrogate pair preceded by a backslash - // This escapes it from matching for emoji - private static readonly IMatcher EscapedSymbolTextNodeMatcher = new RegexMatcher( - new Regex("\\\\(\\p{So}|\\p{Cs}{2})", DefaultRegexOptions), - (_, m) => new TextNode(m.Groups[1].Value) - ); - - // Capture any non-whitespace, non latin alphanumeric character preceded by a backslash - // This escapes it from matching for formatting or other tokens - private static readonly IMatcher EscapedCharacterTextNodeMatcher = new RegexMatcher( - new Regex("\\\\([^a-zA-Z0-9\\s])", DefaultRegexOptions), - (_, m) => new TextNode(m.Groups[1].Value) - ); - - /* Misc */ - - // Capture or - private static readonly IMatcher UnixTimestampNodeMatcher = new RegexMatcher( - new Regex("", DefaultRegexOptions), - (_, m) => - { - // TODO: support formatting parameters - // See: https://github.com/Tyrrrz/DiscordChatExporter/issues/662 - - if (!long.TryParse(m.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, + // Capture any character until the end of the input + // Opening 'greater than' characters must be followed by whitespace + private static readonly IMatcher MultiLineQuoteNodeMatcher = new RegexMatcher( + new Regex("^>>>\\s(.+)", DefaultRegexOptions | RegexOptions.Singleline), + (p, m) => new FormattingNode(FormattingKind.Quote, Parse(p.Slice(m.Groups[1]))) + ); + + /* Code blocks */ + + // Capture any character except backtick until a backtick + // Blank lines at the beginning and end of content are trimmed + // There can be either one or two backticks, but equal number on both sides + private static readonly IMatcher InlineCodeBlockNodeMatcher = new RegexMatcher( + new Regex("(`{1,2})([^`]+)\\1", DefaultRegexOptions | RegexOptions.Singleline), + (_, m) => new InlineCodeBlockNode(m.Groups[2].Value.Trim('\r', '\n')) + ); + + // Capture language identifier and then any character until the earliest triple backtick + // Language identifier is one word immediately after opening backticks, followed immediately by newline + // Blank lines at the beginning and end of content are trimmed + private static readonly IMatcher MultiLineCodeBlockNodeMatcher = new RegexMatcher( + new Regex("```(?:(\\w*)\\n)?(.+?)```", DefaultRegexOptions | RegexOptions.Singleline), + (_, m) => new MultiLineCodeBlockNode(m.Groups[1].Value, m.Groups[2].Value.Trim('\r', '\n')) + ); + + /* Mentions */ + + // Capture @everyone + private static readonly IMatcher EveryoneMentionNodeMatcher = new StringMatcher( + "@everyone", + _ => new MentionNode("everyone", MentionKind.Meta) + ); + + // Capture @here + private static readonly IMatcher HereMentionNodeMatcher = new StringMatcher( + "@here", + _ => new MentionNode("here", MentionKind.Meta) + ); + + // Capture <@123456> or <@!123456> + private static readonly IMatcher UserMentionNodeMatcher = new RegexMatcher( + new Regex("<@!?(\\d+)>", DefaultRegexOptions), + (_, m) => new MentionNode(m.Groups[1].Value, MentionKind.User) + ); + + // Capture <#123456> + private static readonly IMatcher ChannelMentionNodeMatcher = new RegexMatcher( + new Regex("<#!?(\\d+)>", DefaultRegexOptions), + (_, m) => new MentionNode(m.Groups[1].Value, MentionKind.Channel) + ); + + // Capture <@&123456> + private static readonly IMatcher RoleMentionNodeMatcher = new RegexMatcher( + new Regex("<@&(\\d+)>", DefaultRegexOptions), + (_, m) => new MentionNode(m.Groups[1].Value, MentionKind.Role) + ); + + /* Emoji */ + + // Capture any country flag emoji (two regional indicator surrogate pairs) + // ... or "miscellaneous symbol" character + // ... or surrogate pair + // ... or digit followed by enclosing mark + // (this does not match all emoji in Discord but it's reasonably accurate enough) + private static readonly IMatcher StandardEmojiNodeMatcher = new RegexMatcher( + new Regex("((?:[\\uD83C][\\uDDE6-\\uDDFF]){2}|[\\u2600-\\u26FF]|\\p{Cs}{2}|\\d\\p{Me})", DefaultRegexOptions), + (_, m) => new EmojiNode(m.Groups[1].Value) + ); + + // Capture :thinking: (but only for known emoji codes) + private static readonly IMatcher CodedStandardEmojiNodeMatcher = new RegexMatcher( + new Regex(":([\\w_]+):", DefaultRegexOptions), + (_, m) => + { + var name = EmojiIndex.TryGetName(m.Groups[1].Value); + return !string.IsNullOrWhiteSpace(name) + ? new EmojiNode(name) + : null; + } + ); + + // Capture <:lul:123456> or + private static readonly IMatcher CustomEmojiNodeMatcher = new RegexMatcher( + new Regex("<(a)?:(.+?):(\\d+?)>", DefaultRegexOptions), + (_, m) => new EmojiNode(m.Groups[3].Value, m.Groups[2].Value, !string.IsNullOrWhiteSpace(m.Groups[1].Value)) + ); + + /* Links */ + + // Capture [title](link) + private static readonly IMatcher TitledLinkNodeMatcher = new RegexMatcher( + new Regex("\\[(.+?)\\]\\((.+?)\\)", DefaultRegexOptions), + (p, m) => new LinkNode(m.Groups[2].Value, Parse(p.Slice(m.Groups[1]))) + ); + + // Capture any non-whitespace character after http:// or https:// + // until the last punctuation character or whitespace + private static readonly IMatcher AutoLinkNodeMatcher = new RegexMatcher( + new Regex("(https?://\\S*[^\\.,:;\"\'\\s])", DefaultRegexOptions), + (_, m) => new LinkNode(m.Groups[1].Value) + ); + + // Same as auto link but also surrounded by angular brackets + private static readonly IMatcher HiddenLinkNodeMatcher = new RegexMatcher( + new Regex("<(https?://\\S*[^\\.,:;\"\'\\s])>", DefaultRegexOptions), + (_, m) => new LinkNode(m.Groups[1].Value) + ); + + /* Text */ + + // Capture the shrug kaomoji + // This escapes it from matching for formatting + private static readonly IMatcher ShrugTextNodeMatcher = new StringMatcher( + @"¯\_(ツ)_/¯", + p => new TextNode(p.ToString()) + ); + + // Capture some specific emoji that don't get rendered + // This escapes it from matching for emoji + private static readonly IMatcher IgnoredEmojiTextNodeMatcher = new RegexMatcher( + new Regex("(\\u26A7|\\u2640|\\u2642|\\u2695|\\u267E|\\u00A9|\\u00AE|\\u2122)", DefaultRegexOptions), + (_, m) => new TextNode(m.Groups[1].Value) + ); + + // Capture any "symbol/other" character or surrogate pair preceded by a backslash + // This escapes it from matching for emoji + private static readonly IMatcher EscapedSymbolTextNodeMatcher = new RegexMatcher( + new Regex("\\\\(\\p{So}|\\p{Cs}{2})", DefaultRegexOptions), + (_, m) => new TextNode(m.Groups[1].Value) + ); + + // Capture any non-whitespace, non latin alphanumeric character preceded by a backslash + // This escapes it from matching for formatting or other tokens + private static readonly IMatcher EscapedCharacterTextNodeMatcher = new RegexMatcher( + new Regex("\\\\([^a-zA-Z0-9\\s])", DefaultRegexOptions), + (_, m) => new TextNode(m.Groups[1].Value) + ); + + /* Misc */ + + // Capture or + private static readonly IMatcher UnixTimestampNodeMatcher = new RegexMatcher( + new Regex("", DefaultRegexOptions), + (_, m) => + { + // TODO: support formatting parameters + // See: https://github.com/Tyrrrz/DiscordChatExporter/issues/662 + + if (!long.TryParse(m.Groups[1].Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out var offset)) - { - return null; - } - - // Bound check - // https://github.com/Tyrrrz/DiscordChatExporter/issues/681 - if (offset < TimeSpan.MinValue.TotalSeconds || offset > TimeSpan.MaxValue.TotalSeconds) - { - return null; - } - - return new UnixTimestampNode(DateTimeOffset.UnixEpoch + TimeSpan.FromSeconds(offset)); + { + return null; } - ); - - // Combine all matchers into one - // Matchers that have similar patterns are ordered from most specific to least specific - private static readonly IMatcher AggregateNodeMatcher = new AggregateMatcher( - // Escaped text - ShrugTextNodeMatcher, - IgnoredEmojiTextNodeMatcher, - EscapedSymbolTextNodeMatcher, - EscapedCharacterTextNodeMatcher, - - // Formatting - ItalicBoldFormattingNodeMatcher, - ItalicUnderlineFormattingNodeMatcher, - BoldFormattingNodeMatcher, - ItalicFormattingNodeMatcher, - UnderlineFormattingNodeMatcher, - ItalicAltFormattingNodeMatcher, - StrikethroughFormattingNodeMatcher, - SpoilerFormattingNodeMatcher, - MultiLineQuoteNodeMatcher, - RepeatedSingleLineQuoteNodeMatcher, - SingleLineQuoteNodeMatcher, - - // Code blocks - MultiLineCodeBlockNodeMatcher, - InlineCodeBlockNodeMatcher, - - // Mentions - EveryoneMentionNodeMatcher, - HereMentionNodeMatcher, - UserMentionNodeMatcher, - ChannelMentionNodeMatcher, - RoleMentionNodeMatcher, - - // Links - TitledLinkNodeMatcher, - AutoLinkNodeMatcher, - HiddenLinkNodeMatcher, - - // Emoji - StandardEmojiNodeMatcher, - CustomEmojiNodeMatcher, - CodedStandardEmojiNodeMatcher, - - // Misc - UnixTimestampNodeMatcher - ); - - // Minimal set of matchers for non-multimedia formats (e.g. plain text) - private static readonly IMatcher MinimalAggregateNodeMatcher = new AggregateMatcher( - // Mentions - EveryoneMentionNodeMatcher, - HereMentionNodeMatcher, - UserMentionNodeMatcher, - ChannelMentionNodeMatcher, - RoleMentionNodeMatcher, - - // Emoji - CustomEmojiNodeMatcher, - - // Misc - UnixTimestampNodeMatcher - ); - private static IReadOnlyList Parse(StringPart stringPart, IMatcher matcher) => - matcher - .MatchAll(stringPart, p => new TextNode(p.ToString())) - .Select(r => r.Value) - .ToArray(); - } + // Bound check + // https://github.com/Tyrrrz/DiscordChatExporter/issues/681 + if (offset < TimeSpan.MinValue.TotalSeconds || offset > TimeSpan.MaxValue.TotalSeconds) + { + return null; + } - internal static partial class MarkdownParser - { - private static IReadOnlyList Parse(StringPart stringPart) => - Parse(stringPart, AggregateNodeMatcher); + return new UnixTimestampNode(DateTimeOffset.UnixEpoch + TimeSpan.FromSeconds(offset)); + } + ); + + // Combine all matchers into one + // Matchers that have similar patterns are ordered from most specific to least specific + private static readonly IMatcher AggregateNodeMatcher = new AggregateMatcher( + // Escaped text + ShrugTextNodeMatcher, + IgnoredEmojiTextNodeMatcher, + EscapedSymbolTextNodeMatcher, + EscapedCharacterTextNodeMatcher, + + // Formatting + ItalicBoldFormattingNodeMatcher, + ItalicUnderlineFormattingNodeMatcher, + BoldFormattingNodeMatcher, + ItalicFormattingNodeMatcher, + UnderlineFormattingNodeMatcher, + ItalicAltFormattingNodeMatcher, + StrikethroughFormattingNodeMatcher, + SpoilerFormattingNodeMatcher, + MultiLineQuoteNodeMatcher, + RepeatedSingleLineQuoteNodeMatcher, + SingleLineQuoteNodeMatcher, + + // Code blocks + MultiLineCodeBlockNodeMatcher, + InlineCodeBlockNodeMatcher, + + // Mentions + EveryoneMentionNodeMatcher, + HereMentionNodeMatcher, + UserMentionNodeMatcher, + ChannelMentionNodeMatcher, + RoleMentionNodeMatcher, + + // Links + TitledLinkNodeMatcher, + AutoLinkNodeMatcher, + HiddenLinkNodeMatcher, + + // Emoji + StandardEmojiNodeMatcher, + CustomEmojiNodeMatcher, + CodedStandardEmojiNodeMatcher, + + // Misc + UnixTimestampNodeMatcher + ); + + // Minimal set of matchers for non-multimedia formats (e.g. plain text) + private static readonly IMatcher MinimalAggregateNodeMatcher = new AggregateMatcher( + // Mentions + EveryoneMentionNodeMatcher, + HereMentionNodeMatcher, + UserMentionNodeMatcher, + ChannelMentionNodeMatcher, + RoleMentionNodeMatcher, + + // Emoji + CustomEmojiNodeMatcher, + + // Misc + UnixTimestampNodeMatcher + ); + + private static IReadOnlyList Parse(StringPart stringPart, IMatcher matcher) => + matcher + .MatchAll(stringPart, p => new TextNode(p.ToString())) + .Select(r => r.Value) + .ToArray(); +} + +internal static partial class MarkdownParser +{ + private static IReadOnlyList Parse(StringPart stringPart) => + Parse(stringPart, AggregateNodeMatcher); - private static IReadOnlyList ParseMinimal(StringPart stringPart) => - Parse(stringPart, MinimalAggregateNodeMatcher); + private static IReadOnlyList ParseMinimal(StringPart stringPart) => + Parse(stringPart, MinimalAggregateNodeMatcher); - public static IReadOnlyList Parse(string input) => - Parse(new StringPart(input)); + public static IReadOnlyList Parse(string input) => + Parse(new StringPart(input)); - public static IReadOnlyList ParseMinimal(string input) => - ParseMinimal(new StringPart(input)); - } + public static IReadOnlyList ParseMinimal(string input) => + ParseMinimal(new StringPart(input)); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/MarkdownVisitor.cs b/DiscordChatExporter.Core/Markdown/Parsing/MarkdownVisitor.cs index 0f8154d..77750cf 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/MarkdownVisitor.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/MarkdownVisitor.cs @@ -1,57 +1,56 @@ using System; using System.Collections.Generic; -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal abstract class MarkdownVisitor { - internal abstract class MarkdownVisitor + protected virtual MarkdownNode VisitText(TextNode text) => + text; + + protected virtual MarkdownNode VisitFormatting(FormattingNode formatting) + { + Visit(formatting.Children); + return formatting; + } + + protected virtual MarkdownNode VisitInlineCodeBlock(InlineCodeBlockNode inlineCodeBlock) => + inlineCodeBlock; + + protected virtual MarkdownNode VisitMultiLineCodeBlock(MultiLineCodeBlockNode multiLineCodeBlock) => + multiLineCodeBlock; + + protected virtual MarkdownNode VisitLink(LinkNode link) + { + Visit(link.Children); + return link; + } + + protected virtual MarkdownNode VisitEmoji(EmojiNode emoji) => + emoji; + + protected virtual MarkdownNode VisitMention(MentionNode mention) => + mention; + + protected virtual MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp) => + timestamp; + + public MarkdownNode Visit(MarkdownNode node) => node switch + { + TextNode text => VisitText(text), + FormattingNode formatting => VisitFormatting(formatting), + InlineCodeBlockNode inlineCodeBlock => VisitInlineCodeBlock(inlineCodeBlock), + MultiLineCodeBlockNode multiLineCodeBlock => VisitMultiLineCodeBlock(multiLineCodeBlock), + LinkNode link => VisitLink(link), + EmojiNode emoji => VisitEmoji(emoji), + MentionNode mention => VisitMention(mention), + UnixTimestampNode timestamp => VisitUnixTimestamp(timestamp), + _ => throw new ArgumentOutOfRangeException(nameof(node)) + }; + + public void Visit(IEnumerable nodes) { - protected virtual MarkdownNode VisitText(TextNode text) => - text; - - protected virtual MarkdownNode VisitFormatting(FormattingNode formatting) - { - Visit(formatting.Children); - return formatting; - } - - protected virtual MarkdownNode VisitInlineCodeBlock(InlineCodeBlockNode inlineCodeBlock) => - inlineCodeBlock; - - protected virtual MarkdownNode VisitMultiLineCodeBlock(MultiLineCodeBlockNode multiLineCodeBlock) => - multiLineCodeBlock; - - protected virtual MarkdownNode VisitLink(LinkNode link) - { - Visit(link.Children); - return link; - } - - protected virtual MarkdownNode VisitEmoji(EmojiNode emoji) => - emoji; - - protected virtual MarkdownNode VisitMention(MentionNode mention) => - mention; - - protected virtual MarkdownNode VisitUnixTimestamp(UnixTimestampNode timestamp) => - timestamp; - - public MarkdownNode Visit(MarkdownNode node) => node switch - { - TextNode text => VisitText(text), - FormattingNode formatting => VisitFormatting(formatting), - InlineCodeBlockNode inlineCodeBlock => VisitInlineCodeBlock(inlineCodeBlock), - MultiLineCodeBlockNode multiLineCodeBlock => VisitMultiLineCodeBlock(multiLineCodeBlock), - LinkNode link => VisitLink(link), - EmojiNode emoji => VisitEmoji(emoji), - MentionNode mention => VisitMention(mention), - UnixTimestampNode timestamp => VisitUnixTimestamp(timestamp), - _ => throw new ArgumentOutOfRangeException(nameof(node)) - }; - - public void Visit(IEnumerable nodes) - { - foreach (var node in nodes) - Visit(node); - } + foreach (var node in nodes) + Visit(node); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/ParsedMatch.cs b/DiscordChatExporter.Core/Markdown/Parsing/ParsedMatch.cs index 0713335..c15afc4 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/ParsedMatch.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/ParsedMatch.cs @@ -1,15 +1,14 @@ -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal class ParsedMatch { - internal class ParsedMatch - { - public StringPart StringPart { get; } + public StringPart StringPart { get; } - public T Value { get; } + public T Value { get; } - public ParsedMatch(StringPart stringPart, T value) - { - StringPart = stringPart; - Value = value; - } + public ParsedMatch(StringPart stringPart, T value) + { + StringPart = stringPart; + Value = value; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/RegexMatcher.cs b/DiscordChatExporter.Core/Markdown/Parsing/RegexMatcher.cs index 7a9ffb9..592bdec 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/RegexMatcher.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/RegexMatcher.cs @@ -1,39 +1,38 @@ using System; using System.Text.RegularExpressions; -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal class RegexMatcher : IMatcher { - internal class RegexMatcher : IMatcher - { - private readonly Regex _regex; - private readonly Func _transform; + private readonly Regex _regex; + private readonly Func _transform; - public RegexMatcher(Regex regex, Func transform) - { - _regex = regex; - _transform = transform; - } + public RegexMatcher(Regex regex, Func transform) + { + _regex = regex; + _transform = transform; + } - public ParsedMatch? TryMatch(StringPart stringPart) - { - var match = _regex.Match(stringPart.Target, stringPart.StartIndex, stringPart.Length); - if (!match.Success) - return null; + public ParsedMatch? TryMatch(StringPart stringPart) + { + var match = _regex.Match(stringPart.Target, stringPart.StartIndex, stringPart.Length); + if (!match.Success) + return null; - // Overload regex.Match(string, int, int) doesn't take the whole string into account, - // it effectively functions as a match check on a substring. - // Which is super weird because regex.Match(string, int) takes the whole input in context. - // So in order to properly account for ^/$ regex tokens, we need to make sure that - // the expression also matches on the bigger part of the input. - if (!_regex.IsMatch(stringPart.Target[..stringPart.EndIndex], stringPart.StartIndex)) - return null; + // Overload regex.Match(string, int, int) doesn't take the whole string into account, + // it effectively functions as a match check on a substring. + // Which is super weird because regex.Match(string, int) takes the whole input in context. + // So in order to properly account for ^/$ regex tokens, we need to make sure that + // the expression also matches on the bigger part of the input. + if (!_regex.IsMatch(stringPart.Target[..stringPart.EndIndex], stringPart.StartIndex)) + return null; - var stringPartMatch = stringPart.Slice(match.Index, match.Length); - var value = _transform(stringPartMatch, match); + var stringPartMatch = stringPart.Slice(match.Index, match.Length); + var value = _transform(stringPartMatch, match); - return value is not null - ? new ParsedMatch(stringPartMatch, value) - : null; - } + return value is not null + ? new ParsedMatch(stringPartMatch, value) + : null; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/StringMatcher.cs b/DiscordChatExporter.Core/Markdown/Parsing/StringMatcher.cs index 380819b..949fb5d 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/StringMatcher.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/StringMatcher.cs @@ -1,37 +1,36 @@ using System; -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal class StringMatcher : IMatcher { - internal class StringMatcher : IMatcher - { - private readonly string _needle; - private readonly StringComparison _comparison; - private readonly Func _transform; + private readonly string _needle; + private readonly StringComparison _comparison; + private readonly Func _transform; - public StringMatcher(string needle, StringComparison comparison, Func transform) - { - _needle = needle; - _comparison = comparison; - _transform = transform; - } + public StringMatcher(string needle, StringComparison comparison, Func transform) + { + _needle = needle; + _comparison = comparison; + _transform = transform; + } - public StringMatcher(string needle, Func transform) - : this(needle, StringComparison.Ordinal, transform) - { - } + public StringMatcher(string needle, Func transform) + : this(needle, StringComparison.Ordinal, transform) + { + } - public ParsedMatch? TryMatch(StringPart stringPart) - { - var index = stringPart.Target.IndexOf(_needle, stringPart.StartIndex, stringPart.Length, _comparison); - if (index < 0) - return null; + public ParsedMatch? TryMatch(StringPart stringPart) + { + var index = stringPart.Target.IndexOf(_needle, stringPart.StartIndex, stringPart.Length, _comparison); + if (index < 0) + return null; - var stringPartMatch = stringPart.Slice(index, _needle.Length); - var value = _transform(stringPartMatch); + var stringPartMatch = stringPart.Slice(index, _needle.Length); + var value = _transform(stringPartMatch); - return value is not null - ? new ParsedMatch(stringPartMatch, value) - : null; - } + return value is not null + ? new ParsedMatch(stringPartMatch, value) + : null; } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs b/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs index 889e3b1..46658a6 100644 --- a/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs +++ b/DiscordChatExporter.Core/Markdown/Parsing/StringPart.cs @@ -1,22 +1,21 @@ using System.Text.RegularExpressions; -namespace DiscordChatExporter.Core.Markdown.Parsing +namespace DiscordChatExporter.Core.Markdown.Parsing; + +internal readonly record struct StringPart(string Target, int StartIndex, int Length) { - internal readonly record struct StringPart(string Target, int StartIndex, int Length) - { - public int EndIndex => StartIndex + Length; + public int EndIndex => StartIndex + Length; - public StringPart(string target) - : this(target, 0, target.Length) - { - } + public StringPart(string target) + : this(target, 0, target.Length) + { + } - public StringPart Slice(int newStartIndex, int newLength) => new(Target, newStartIndex, newLength); + public StringPart Slice(int newStartIndex, int newLength) => new(Target, newStartIndex, newLength); - public StringPart Slice(int newStartIndex) => Slice(newStartIndex, EndIndex - newStartIndex); + public StringPart Slice(int newStartIndex) => Slice(newStartIndex, EndIndex - newStartIndex); - public StringPart Slice(Capture capture) => Slice(capture.Index, capture.Length); + public StringPart Slice(Capture capture) => Slice(capture.Index, capture.Length); - public override string ToString() => Target.Substring(StartIndex, Length); - } + public override string ToString() => Target.Substring(StartIndex, Length); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/TextNode.cs b/DiscordChatExporter.Core/Markdown/TextNode.cs index 47fcdfd..846fcb0 100644 --- a/DiscordChatExporter.Core/Markdown/TextNode.cs +++ b/DiscordChatExporter.Core/Markdown/TextNode.cs @@ -1,4 +1,3 @@ -namespace DiscordChatExporter.Core.Markdown -{ - internal record TextNode(string Text) : MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal record TextNode(string Text) : MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs b/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs index d4d7918..f053466 100644 --- a/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs +++ b/DiscordChatExporter.Core/Markdown/UnixTimestampNode.cs @@ -1,6 +1,5 @@ using System; -namespace DiscordChatExporter.Core.Markdown -{ - internal record UnixTimestampNode(DateTimeOffset Value) : MarkdownNode; -} \ No newline at end of file +namespace DiscordChatExporter.Core.Markdown; + +internal record UnixTimestampNode(DateTimeOffset Value) : MarkdownNode; \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/EmojiIndex.cs b/DiscordChatExporter.Core/Utils/EmojiIndex.cs index 97f0cdf..1a44458 100644 --- a/DiscordChatExporter.Core/Utils/EmojiIndex.cs +++ b/DiscordChatExporter.Core/Utils/EmojiIndex.cs @@ -2,8851 +2,8850 @@ using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; -namespace DiscordChatExporter.Core.Utils +namespace DiscordChatExporter.Core.Utils; + +// Data sourced from: https://github.com/Tyrrrz/DiscordChatExporter/issues/599#issuecomment-863431045 +[ExcludeFromCodeCoverage] +internal static class EmojiIndex { - // Data sourced from: https://github.com/Tyrrrz/DiscordChatExporter/issues/599#issuecomment-863431045 - [ExcludeFromCodeCoverage] - internal static class EmojiIndex + private static Dictionary _toCodes = new(5000, StringComparer.Ordinal) { - private static Dictionary _toCodes = new(5000, StringComparer.Ordinal) - { - ["😀"] = "grinning", - ["😃"] = "smiley", - ["😄"] = "smile", - ["😁"] = "grin", - ["😆"] = "laughing", - ["😅"] = "sweat_smile", - ["😂"] = "joy", - ["🤣"] = "rofl", - ["☺️"] = "relaxed", - ["😊"] = "blush", - ["😇"] = "innocent", - ["🙂"] = "slight_smile", - ["🙃"] = "upside_down", - ["😉"] = "wink", - ["😌"] = "relieved", - ["🥲"] = "smiling_face_with_tear", - ["😍"] = "heart_eyes", - ["🥰"] = "smiling_face_with_3_hearts", - ["😘"] = "kissing_heart", - ["😗"] = "kissing", - ["😙"] = "kissing_smiling_eyes", - ["😚"] = "kissing_closed_eyes", - ["😋"] = "yum", - ["😛"] = "stuck_out_tongue", - ["😝"] = "stuck_out_tongue_closed_eyes", - ["😜"] = "stuck_out_tongue_winking_eye", - ["🤪"] = "zany_face", - ["🤨"] = "face_with_raised_eyebrow", - ["🧐"] = "face_with_monocle", - ["🤓"] = "nerd", - ["😎"] = "sunglasses", - ["🤩"] = "star_struck", - ["🥳"] = "partying_face", - ["😏"] = "smirk", - ["😒"] = "unamused", - ["😞"] = "disappointed", - ["😔"] = "pensive", - ["😟"] = "worried", - ["😕"] = "confused", - ["🙁"] = "slight_frown", - ["☹️"] = "frowning2", - ["😣"] = "persevere", - ["😖"] = "confounded", - ["😫"] = "tired_face", - ["😩"] = "weary", - ["🥺"] = "pleading_face", - ["😢"] = "cry", - ["😭"] = "sob", - ["😤"] = "triumph", - ["😮‍💨"] = "face_exhaling", - ["😠"] = "angry", - ["😡"] = "rage", - ["🤬"] = "face_with_symbols_over_mouth", - ["🤯"] = "exploding_head", - ["😳"] = "flushed", - ["😶‍🌫️"] = "face_in_clouds", - ["🥵"] = "hot_face", - ["🥶"] = "cold_face", - ["😱"] = "scream", - ["😨"] = "fearful", - ["😰"] = "cold_sweat", - ["😥"] = "disappointed_relieved", - ["😓"] = "sweat", - ["🤗"] = "hugging", - ["🤔"] = "thinking", - ["🤭"] = "face_with_hand_over_mouth", - ["🥱"] = "yawning_face", - ["🤫"] = "shushing_face", - ["🤥"] = "lying_face", - ["😶"] = "no_mouth", - ["😐"] = "neutral_face", - ["😑"] = "expressionless", - ["😬"] = "grimacing", - ["🙄"] = "rolling_eyes", - ["😯"] = "hushed", - ["😦"] = "frowning", - ["😧"] = "anguished", - ["😮"] = "open_mouth", - ["😲"] = "astonished", - ["😴"] = "sleeping", - ["🤤"] = "drooling_face", - ["😪"] = "sleepy", - ["😵"] = "dizzy_face", - ["😵‍💫"] = "face_with_spiral_eyes", - ["🤐"] = "zipper_mouth", - ["🥴"] = "woozy_face", - ["🤢"] = "nauseated_face", - ["🤮"] = "face_vomiting", - ["🤧"] = "sneezing_face", - ["😷"] = "mask", - ["🤒"] = "thermometer_face", - ["🤕"] = "head_bandage", - ["🤑"] = "money_mouth", - ["🤠"] = "cowboy", - ["🥸"] = "disguised_face", - ["😈"] = "smiling_imp", - ["👿"] = "imp", - ["👹"] = "japanese_ogre", - ["👺"] = "japanese_goblin", - ["🤡"] = "clown", - ["💩"] = "poop", - ["👻"] = "ghost", - ["💀"] = "skull", - ["☠️"] = "skull_crossbones", - ["👽"] = "alien", - ["👾"] = "space_invader", - ["🤖"] = "robot", - ["🎃"] = "jack_o_lantern", - ["😺"] = "smiley_cat", - ["😸"] = "smile_cat", - ["😹"] = "joy_cat", - ["😻"] = "heart_eyes_cat", - ["😼"] = "smirk_cat", - ["😽"] = "kissing_cat", - ["🙀"] = "scream_cat", - ["😿"] = "crying_cat_face", - ["😾"] = "pouting_cat", - ["🤲"] = "palms_up_together", - ["🤲🏻"] = "palms_up_together_tone1", - ["🤲🏼"] = "palms_up_together_tone2", - ["🤲🏽"] = "palms_up_together_tone3", - ["🤲🏾"] = "palms_up_together_tone4", - ["🤲🏿"] = "palms_up_together_tone5", - ["👐"] = "open_hands", - ["👐🏻"] = "open_hands_tone1", - ["👐🏼"] = "open_hands_tone2", - ["👐🏽"] = "open_hands_tone3", - ["👐🏾"] = "open_hands_tone4", - ["👐🏿"] = "open_hands_tone5", - ["🙌"] = "raised_hands", - ["🙌🏻"] = "raised_hands_tone1", - ["🙌🏼"] = "raised_hands_tone2", - ["🙌🏽"] = "raised_hands_tone3", - ["🙌🏾"] = "raised_hands_tone4", - ["🙌🏿"] = "raised_hands_tone5", - ["👏"] = "clap", - ["👏🏻"] = "clap_tone1", - ["👏🏼"] = "clap_tone2", - ["👏🏽"] = "clap_tone3", - ["👏🏾"] = "clap_tone4", - ["👏🏿"] = "clap_tone5", - ["🤝"] = "handshake", - ["👍"] = "thumbsup", - ["👍🏻"] = "thumbsup_tone1", - ["👍🏼"] = "thumbsup_tone2", - ["👍🏽"] = "thumbsup_tone3", - ["👍🏾"] = "thumbsup_tone4", - ["👍🏿"] = "thumbsup_tone5", - ["👎"] = "thumbsdown", - ["👎🏻"] = "thumbsdown_tone1", - ["👎🏼"] = "thumbsdown_tone2", - ["👎🏽"] = "thumbsdown_tone3", - ["👎🏾"] = "thumbsdown_tone4", - ["👎🏿"] = "thumbsdown_tone5", - ["👊"] = "punch", - ["👊🏻"] = "punch_tone1", - ["👊🏼"] = "punch_tone2", - ["👊🏽"] = "punch_tone3", - ["👊🏾"] = "punch_tone4", - ["👊🏿"] = "punch_tone5", - ["✊"] = "fist", - ["✊🏻"] = "fist_tone1", - ["✊🏼"] = "fist_tone2", - ["✊🏽"] = "fist_tone3", - ["✊🏾"] = "fist_tone4", - ["✊🏿"] = "fist_tone5", - ["🤛"] = "left_facing_fist", - ["🤛🏻"] = "left_facing_fist_tone1", - ["🤛🏼"] = "left_facing_fist_tone2", - ["🤛🏽"] = "left_facing_fist_tone3", - ["🤛🏾"] = "left_facing_fist_tone4", - ["🤛🏿"] = "left_facing_fist_tone5", - ["🤜"] = "right_facing_fist", - ["🤜🏻"] = "right_facing_fist_tone1", - ["🤜🏼"] = "right_facing_fist_tone2", - ["🤜🏽"] = "right_facing_fist_tone3", - ["🤜🏾"] = "right_facing_fist_tone4", - ["🤜🏿"] = "right_facing_fist_tone5", - ["🤞"] = "fingers_crossed", - ["🤞🏻"] = "fingers_crossed_tone1", - ["🤞🏼"] = "fingers_crossed_tone2", - ["🤞🏽"] = "fingers_crossed_tone3", - ["🤞🏾"] = "fingers_crossed_tone4", - ["🤞🏿"] = "fingers_crossed_tone5", - ["✌️"] = "v", - ["✌🏻"] = "v_tone1", - ["✌🏼"] = "v_tone2", - ["✌🏽"] = "v_tone3", - ["✌🏾"] = "v_tone4", - ["✌🏿"] = "v_tone5", - ["🤟"] = "love_you_gesture", - ["🤟🏻"] = "love_you_gesture_tone1", - ["🤟🏼"] = "love_you_gesture_tone2", - ["🤟🏽"] = "love_you_gesture_tone3", - ["🤟🏾"] = "love_you_gesture_tone4", - ["🤟🏿"] = "love_you_gesture_tone5", - ["🤘"] = "metal", - ["🤘🏻"] = "metal_tone1", - ["🤘🏼"] = "metal_tone2", - ["🤘🏽"] = "metal_tone3", - ["🤘🏾"] = "metal_tone4", - ["🤘🏿"] = "metal_tone5", - ["👌"] = "ok_hand", - ["👌🏻"] = "ok_hand_tone1", - ["👌🏼"] = "ok_hand_tone2", - ["👌🏽"] = "ok_hand_tone3", - ["👌🏾"] = "ok_hand_tone4", - ["👌🏿"] = "ok_hand_tone5", - ["🤏"] = "pinching_hand", - ["🤏🏻"] = "pinching_hand_tone1", - ["🤏🏼"] = "pinching_hand_tone2", - ["🤏🏽"] = "pinching_hand_tone3", - ["🤏🏾"] = "pinching_hand_tone4", - ["🤏🏿"] = "pinching_hand_tone5", - ["🤌"] = "pinched_fingers", - ["🤌🏼"] = "pinched_fingers_tone2", - ["🤌🏻"] = "pinched_fingers_tone1", - ["🤌🏽"] = "pinched_fingers_tone3", - ["🤌🏾"] = "pinched_fingers_tone4", - ["🤌🏿"] = "pinched_fingers_tone5", - ["👈"] = "point_left", - ["👈🏻"] = "point_left_tone1", - ["👈🏼"] = "point_left_tone2", - ["👈🏽"] = "point_left_tone3", - ["👈🏾"] = "point_left_tone4", - ["👈🏿"] = "point_left_tone5", - ["👉"] = "point_right", - ["👉🏻"] = "point_right_tone1", - ["👉🏼"] = "point_right_tone2", - ["👉🏽"] = "point_right_tone3", - ["👉🏾"] = "point_right_tone4", - ["👉🏿"] = "point_right_tone5", - ["👆"] = "point_up_2", - ["👆🏻"] = "point_up_2_tone1", - ["👆🏼"] = "point_up_2_tone2", - ["👆🏽"] = "point_up_2_tone3", - ["👆🏾"] = "point_up_2_tone4", - ["👆🏿"] = "point_up_2_tone5", - ["👇"] = "point_down", - ["👇🏻"] = "point_down_tone1", - ["👇🏼"] = "point_down_tone2", - ["👇🏽"] = "point_down_tone3", - ["👇🏾"] = "point_down_tone4", - ["👇🏿"] = "point_down_tone5", - ["☝️"] = "point_up", - ["☝🏻"] = "point_up_tone1", - ["☝🏼"] = "point_up_tone2", - ["☝🏽"] = "point_up_tone3", - ["☝🏾"] = "point_up_tone4", - ["☝🏿"] = "point_up_tone5", - ["✋"] = "raised_hand", - ["✋🏻"] = "raised_hand_tone1", - ["✋🏼"] = "raised_hand_tone2", - ["✋🏽"] = "raised_hand_tone3", - ["✋🏾"] = "raised_hand_tone4", - ["✋🏿"] = "raised_hand_tone5", - ["🤚"] = "raised_back_of_hand", - ["🤚🏻"] = "raised_back_of_hand_tone1", - ["🤚🏼"] = "raised_back_of_hand_tone2", - ["🤚🏽"] = "raised_back_of_hand_tone3", - ["🤚🏾"] = "raised_back_of_hand_tone4", - ["🤚🏿"] = "raised_back_of_hand_tone5", - ["🖐️"] = "hand_splayed", - ["🖐🏻"] = "hand_splayed_tone1", - ["🖐🏼"] = "hand_splayed_tone2", - ["🖐🏽"] = "hand_splayed_tone3", - ["🖐🏾"] = "hand_splayed_tone4", - ["🖐🏿"] = "hand_splayed_tone5", - ["🖖"] = "vulcan", - ["🖖🏻"] = "vulcan_tone1", - ["🖖🏼"] = "vulcan_tone2", - ["🖖🏽"] = "vulcan_tone3", - ["🖖🏾"] = "vulcan_tone4", - ["🖖🏿"] = "vulcan_tone5", - ["👋"] = "wave", - ["👋🏻"] = "wave_tone1", - ["👋🏼"] = "wave_tone2", - ["👋🏽"] = "wave_tone3", - ["👋🏾"] = "wave_tone4", - ["👋🏿"] = "wave_tone5", - ["🤙"] = "call_me", - ["🤙🏻"] = "call_me_tone1", - ["🤙🏼"] = "call_me_tone2", - ["🤙🏽"] = "call_me_tone3", - ["🤙🏾"] = "call_me_tone4", - ["🤙🏿"] = "call_me_tone5", - ["💪"] = "muscle", - ["💪🏻"] = "muscle_tone1", - ["💪🏼"] = "muscle_tone2", - ["💪🏽"] = "muscle_tone3", - ["💪🏾"] = "muscle_tone4", - ["💪🏿"] = "muscle_tone5", - ["🦾"] = "mechanical_arm", - ["🖕"] = "middle_finger", - ["🖕🏻"] = "middle_finger_tone1", - ["🖕🏼"] = "middle_finger_tone2", - ["🖕🏽"] = "middle_finger_tone3", - ["🖕🏾"] = "middle_finger_tone4", - ["🖕🏿"] = "middle_finger_tone5", - ["✍️"] = "writing_hand", - ["✍🏻"] = "writing_hand_tone1", - ["✍🏼"] = "writing_hand_tone2", - ["✍🏽"] = "writing_hand_tone3", - ["✍🏾"] = "writing_hand_tone4", - ["✍🏿"] = "writing_hand_tone5", - ["🙏"] = "pray", - ["🙏🏻"] = "pray_tone1", - ["🙏🏼"] = "pray_tone2", - ["🙏🏽"] = "pray_tone3", - ["🙏🏾"] = "pray_tone4", - ["🙏🏿"] = "pray_tone5", - ["🦶"] = "foot", - ["🦶🏻"] = "foot_tone1", - ["🦶🏼"] = "foot_tone2", - ["🦶🏽"] = "foot_tone3", - ["🦶🏾"] = "foot_tone4", - ["🦶🏿"] = "foot_tone5", - ["🦵"] = "leg", - ["🦵🏻"] = "leg_tone1", - ["🦵🏼"] = "leg_tone2", - ["🦵🏽"] = "leg_tone3", - ["🦵🏾"] = "leg_tone4", - ["🦵🏿"] = "leg_tone5", - ["🦿"] = "mechanical_leg", - ["💄"] = "lipstick", - ["💋"] = "kiss", - ["👄"] = "lips", - ["🦷"] = "tooth", - ["👅"] = "tongue", - ["👂"] = "ear", - ["👂🏻"] = "ear_tone1", - ["👂🏼"] = "ear_tone2", - ["👂🏽"] = "ear_tone3", - ["👂🏾"] = "ear_tone4", - ["👂🏿"] = "ear_tone5", - ["🦻"] = "ear_with_hearing_aid", - ["🦻🏻"] = "ear_with_hearing_aid_tone1", - ["🦻🏼"] = "ear_with_hearing_aid_tone2", - ["🦻🏽"] = "ear_with_hearing_aid_tone3", - ["🦻🏾"] = "ear_with_hearing_aid_tone4", - ["🦻🏿"] = "ear_with_hearing_aid_tone5", - ["👃"] = "nose", - ["👃🏻"] = "nose_tone1", - ["👃🏼"] = "nose_tone2", - ["👃🏽"] = "nose_tone3", - ["👃🏾"] = "nose_tone4", - ["👃🏿"] = "nose_tone5", - ["👣"] = "footprints", - ["👁️"] = "eye", - ["👀"] = "eyes", - ["🧠"] = "brain", - ["🫀"] = "anatomical_heart", - ["🫁"] = "lungs", - ["🦴"] = "bone", - ["🗣️"] = "speaking_head", - ["👤"] = "bust_in_silhouette", - ["👥"] = "busts_in_silhouette", - ["🫂"] = "people_hugging", - ["👶"] = "baby", - ["👶🏻"] = "baby_tone1", - ["👶🏼"] = "baby_tone2", - ["👶🏽"] = "baby_tone3", - ["👶🏾"] = "baby_tone4", - ["👶🏿"] = "baby_tone5", - ["👧"] = "girl", - ["👧🏻"] = "girl_tone1", - ["👧🏼"] = "girl_tone2", - ["👧🏽"] = "girl_tone3", - ["👧🏾"] = "girl_tone4", - ["👧🏿"] = "girl_tone5", - ["🧒"] = "child", - ["🧒🏻"] = "child_tone1", - ["🧒🏼"] = "child_tone2", - ["🧒🏽"] = "child_tone3", - ["🧒🏾"] = "child_tone4", - ["🧒🏿"] = "child_tone5", - ["👦"] = "boy", - ["👦🏻"] = "boy_tone1", - ["👦🏼"] = "boy_tone2", - ["👦🏽"] = "boy_tone3", - ["👦🏾"] = "boy_tone4", - ["👦🏿"] = "boy_tone5", - ["👩"] = "woman", - ["👩🏻"] = "woman_tone1", - ["👩🏼"] = "woman_tone2", - ["👩🏽"] = "woman_tone3", - ["👩🏾"] = "woman_tone4", - ["👩🏿"] = "woman_tone5", - ["🧑"] = "adult", - ["🧑🏻"] = "adult_tone1", - ["🧑🏼"] = "adult_tone2", - ["🧑🏽"] = "adult_tone3", - ["🧑🏾"] = "adult_tone4", - ["🧑🏿"] = "adult_tone5", - ["👨"] = "man", - ["👨🏻"] = "man_tone1", - ["👨🏼"] = "man_tone2", - ["👨🏽"] = "man_tone3", - ["👨🏾"] = "man_tone4", - ["👨🏿"] = "man_tone5", - ["🧑‍🦱"] = "person_curly_hair", - ["🧑🏻‍🦱"] = "person_tone1_curly_hair", - ["🧑🏼‍🦱"] = "person_tone2_curly_hair", - ["🧑🏽‍🦱"] = "person_tone3_curly_hair", - ["🧑🏾‍🦱"] = "person_tone4_curly_hair", - ["🧑🏿‍🦱"] = "person_tone5_curly_hair", - ["👩‍🦱"] = "woman_curly_haired", - ["👩🏻‍🦱"] = "woman_curly_haired_tone1", - ["👩🏼‍🦱"] = "woman_curly_haired_tone2", - ["👩🏽‍🦱"] = "woman_curly_haired_tone3", - ["👩🏾‍🦱"] = "woman_curly_haired_tone4", - ["👩🏿‍🦱"] = "woman_curly_haired_tone5", - ["👨‍🦱"] = "man_curly_haired", - ["👨🏻‍🦱"] = "man_curly_haired_tone1", - ["👨🏼‍🦱"] = "man_curly_haired_tone2", - ["👨🏽‍🦱"] = "man_curly_haired_tone3", - ["👨🏾‍🦱"] = "man_curly_haired_tone4", - ["👨🏿‍🦱"] = "man_curly_haired_tone5", - ["🧑‍🦰"] = "person_red_hair", - ["🧑🏻‍🦰"] = "person_tone1_red_hair", - ["🧑🏼‍🦰"] = "person_tone2_red_hair", - ["🧑🏽‍🦰"] = "person_tone3_red_hair", - ["🧑🏾‍🦰"] = "person_tone4_red_hair", - ["🧑🏿‍🦰"] = "person_tone5_red_hair", - ["👩‍🦰"] = "woman_red_haired", - ["👩🏻‍🦰"] = "woman_red_haired_tone1", - ["👩🏼‍🦰"] = "woman_red_haired_tone2", - ["👩🏽‍🦰"] = "woman_red_haired_tone3", - ["👩🏾‍🦰"] = "woman_red_haired_tone4", - ["👩🏿‍🦰"] = "woman_red_haired_tone5", - ["👨‍🦰"] = "man_red_haired", - ["👨🏻‍🦰"] = "man_red_haired_tone1", - ["👨🏼‍🦰"] = "man_red_haired_tone2", - ["👨🏽‍🦰"] = "man_red_haired_tone3", - ["👨🏾‍🦰"] = "man_red_haired_tone4", - ["👨🏿‍🦰"] = "man_red_haired_tone5", - ["👱‍♀️"] = "blond_haired_woman", - ["👱🏻‍♀️"] = "blond_haired_woman_tone1", - ["👱🏼‍♀️"] = "blond_haired_woman_tone2", - ["👱🏽‍♀️"] = "blond_haired_woman_tone3", - ["👱🏾‍♀️"] = "blond_haired_woman_tone4", - ["👱🏿‍♀️"] = "blond_haired_woman_tone5", - ["👱"] = "blond_haired_person", - ["👱🏻"] = "blond_haired_person_tone1", - ["👱🏼"] = "blond_haired_person_tone2", - ["👱🏽"] = "blond_haired_person_tone3", - ["👱🏾"] = "blond_haired_person_tone4", - ["👱🏿"] = "blond_haired_person_tone5", - ["👱‍♂️"] = "blond_haired_man", - ["👱🏻‍♂️"] = "blond_haired_man_tone1", - ["👱🏼‍♂️"] = "blond_haired_man_tone2", - ["👱🏽‍♂️"] = "blond_haired_man_tone3", - ["👱🏾‍♂️"] = "blond_haired_man_tone4", - ["👱🏿‍♂️"] = "blond_haired_man_tone5", - ["🧑‍🦳"] = "person_white_hair", - ["🧑🏻‍🦳"] = "person_tone1_white_hair", - ["🧑🏼‍🦳"] = "person_tone2_white_hair", - ["🧑🏽‍🦳"] = "person_tone3_white_hair", - ["🧑🏾‍🦳"] = "person_tone4_white_hair", - ["🧑🏿‍🦳"] = "person_tone5_white_hair", - ["👩‍🦳"] = "woman_white_haired", - ["👩🏻‍🦳"] = "woman_white_haired_tone1", - ["👩🏼‍🦳"] = "woman_white_haired_tone2", - ["👩🏽‍🦳"] = "woman_white_haired_tone3", - ["👩🏾‍🦳"] = "woman_white_haired_tone4", - ["👩🏿‍🦳"] = "woman_white_haired_tone5", - ["👨‍🦳"] = "man_white_haired", - ["👨🏻‍🦳"] = "man_white_haired_tone1", - ["👨🏼‍🦳"] = "man_white_haired_tone2", - ["👨🏽‍🦳"] = "man_white_haired_tone3", - ["👨🏾‍🦳"] = "man_white_haired_tone4", - ["👨🏿‍🦳"] = "man_white_haired_tone5", - ["🧑‍🦲"] = "person_bald", - ["🧑🏻‍🦲"] = "person_tone1_bald", - ["🧑🏼‍🦲"] = "person_tone2_bald", - ["🧑🏽‍🦲"] = "person_tone3_bald", - ["🧑🏾‍🦲"] = "person_tone4_bald", - ["🧑🏿‍🦲"] = "person_tone5_bald", - ["👩‍🦲"] = "woman_bald", - ["👩🏻‍🦲"] = "woman_bald_tone1", - ["👩🏼‍🦲"] = "woman_bald_tone2", - ["👩🏽‍🦲"] = "woman_bald_tone3", - ["👩🏾‍🦲"] = "woman_bald_tone4", - ["👩🏿‍🦲"] = "woman_bald_tone5", - ["👨‍🦲"] = "man_bald", - ["👨🏻‍🦲"] = "man_bald_tone1", - ["👨🏼‍🦲"] = "man_bald_tone2", - ["👨🏽‍🦲"] = "man_bald_tone3", - ["👨🏾‍🦲"] = "man_bald_tone4", - ["👨🏿‍🦲"] = "man_bald_tone5", - ["🧔"] = "bearded_person", - ["🧔🏻"] = "bearded_person_tone1", - ["🧔🏼"] = "bearded_person_tone2", - ["🧔🏽"] = "bearded_person_tone3", - ["🧔🏾"] = "bearded_person_tone4", - ["🧔🏿"] = "bearded_person_tone5", - ["🧔‍♂️"] = "man_beard", - ["🧔🏻‍♂️"] = "man_tone1_beard", - ["🧔🏼‍♂️"] = "man_tone2_beard", - ["🧔🏽‍♂️"] = "man_tone3_beard", - ["🧔🏾‍♂️"] = "man_tone4_beard", - ["🧔🏿‍♂️"] = "man_tone5_beard", - ["🧔‍♀️"] = "woman_beard", - ["🧔🏻‍♀️"] = "woman_tone1_beard", - ["🧔🏼‍♀️"] = "woman_tone2_beard", - ["🧔🏽‍♀️"] = "woman_tone3_beard", - ["🧔🏾‍♀️"] = "woman_tone4_beard", - ["🧔🏿‍♀️"] = "woman_tone5_beard", - ["👵"] = "older_woman", - ["👵🏻"] = "older_woman_tone1", - ["👵🏼"] = "older_woman_tone2", - ["👵🏽"] = "older_woman_tone3", - ["👵🏾"] = "older_woman_tone4", - ["👵🏿"] = "older_woman_tone5", - ["🧓"] = "older_adult", - ["🧓🏻"] = "older_adult_tone1", - ["🧓🏼"] = "older_adult_tone2", - ["🧓🏽"] = "older_adult_tone3", - ["🧓🏾"] = "older_adult_tone4", - ["🧓🏿"] = "older_adult_tone5", - ["👴"] = "older_man", - ["👴🏻"] = "older_man_tone1", - ["👴🏼"] = "older_man_tone2", - ["👴🏽"] = "older_man_tone3", - ["👴🏾"] = "older_man_tone4", - ["👴🏿"] = "older_man_tone5", - ["👲"] = "man_with_chinese_cap", - ["👲🏻"] = "man_with_chinese_cap_tone1", - ["👲🏼"] = "man_with_chinese_cap_tone2", - ["👲🏽"] = "man_with_chinese_cap_tone3", - ["👲🏾"] = "man_with_chinese_cap_tone4", - ["👲🏿"] = "man_with_chinese_cap_tone5", - ["👳"] = "person_wearing_turban", - ["👳🏻"] = "person_wearing_turban_tone1", - ["👳🏼"] = "person_wearing_turban_tone2", - ["👳🏽"] = "person_wearing_turban_tone3", - ["👳🏾"] = "person_wearing_turban_tone4", - ["👳🏿"] = "person_wearing_turban_tone5", - ["👳‍♀️"] = "woman_wearing_turban", - ["👳🏻‍♀️"] = "woman_wearing_turban_tone1", - ["👳🏼‍♀️"] = "woman_wearing_turban_tone2", - ["👳🏽‍♀️"] = "woman_wearing_turban_tone3", - ["👳🏾‍♀️"] = "woman_wearing_turban_tone4", - ["👳🏿‍♀️"] = "woman_wearing_turban_tone5", - ["👳‍♂️"] = "man_wearing_turban", - ["👳🏻‍♂️"] = "man_wearing_turban_tone1", - ["👳🏼‍♂️"] = "man_wearing_turban_tone2", - ["👳🏽‍♂️"] = "man_wearing_turban_tone3", - ["👳🏾‍♂️"] = "man_wearing_turban_tone4", - ["👳🏿‍♂️"] = "man_wearing_turban_tone5", - ["🧕"] = "woman_with_headscarf", - ["🧕🏻"] = "woman_with_headscarf_tone1", - ["🧕🏼"] = "woman_with_headscarf_tone2", - ["🧕🏽"] = "woman_with_headscarf_tone3", - ["🧕🏾"] = "woman_with_headscarf_tone4", - ["🧕🏿"] = "woman_with_headscarf_tone5", - ["👮"] = "police_officer", - ["👮🏻"] = "police_officer_tone1", - ["👮🏼"] = "police_officer_tone2", - ["👮🏽"] = "police_officer_tone3", - ["👮🏾"] = "police_officer_tone4", - ["👮🏿"] = "police_officer_tone5", - ["👮‍♀️"] = "woman_police_officer", - ["👮🏻‍♀️"] = "woman_police_officer_tone1", - ["👮🏼‍♀️"] = "woman_police_officer_tone2", - ["👮🏽‍♀️"] = "woman_police_officer_tone3", - ["👮🏾‍♀️"] = "woman_police_officer_tone4", - ["👮🏿‍♀️"] = "woman_police_officer_tone5", - ["👮‍♂️"] = "man_police_officer", - ["👮🏻‍♂️"] = "man_police_officer_tone1", - ["👮🏼‍♂️"] = "man_police_officer_tone2", - ["👮🏽‍♂️"] = "man_police_officer_tone3", - ["👮🏾‍♂️"] = "man_police_officer_tone4", - ["👮🏿‍♂️"] = "man_police_officer_tone5", - ["👷"] = "construction_worker", - ["👷🏻"] = "construction_worker_tone1", - ["👷🏼"] = "construction_worker_tone2", - ["👷🏽"] = "construction_worker_tone3", - ["👷🏾"] = "construction_worker_tone4", - ["👷🏿"] = "construction_worker_tone5", - ["👷‍♀️"] = "woman_construction_worker", - ["👷🏻‍♀️"] = "woman_construction_worker_tone1", - ["👷🏼‍♀️"] = "woman_construction_worker_tone2", - ["👷🏽‍♀️"] = "woman_construction_worker_tone3", - ["👷🏾‍♀️"] = "woman_construction_worker_tone4", - ["👷🏿‍♀️"] = "woman_construction_worker_tone5", - ["👷‍♂️"] = "man_construction_worker", - ["👷🏻‍♂️"] = "man_construction_worker_tone1", - ["👷🏼‍♂️"] = "man_construction_worker_tone2", - ["👷🏽‍♂️"] = "man_construction_worker_tone3", - ["👷🏾‍♂️"] = "man_construction_worker_tone4", - ["👷🏿‍♂️"] = "man_construction_worker_tone5", - ["💂"] = "guard", - ["💂🏻"] = "guard_tone1", - ["💂🏼"] = "guard_tone2", - ["💂🏽"] = "guard_tone3", - ["💂🏾"] = "guard_tone4", - ["💂🏿"] = "guard_tone5", - ["💂‍♀️"] = "woman_guard", - ["💂🏻‍♀️"] = "woman_guard_tone1", - ["💂🏼‍♀️"] = "woman_guard_tone2", - ["💂🏽‍♀️"] = "woman_guard_tone3", - ["💂🏾‍♀️"] = "woman_guard_tone4", - ["💂🏿‍♀️"] = "woman_guard_tone5", - ["💂‍♂️"] = "man_guard", - ["💂🏻‍♂️"] = "man_guard_tone1", - ["💂🏼‍♂️"] = "man_guard_tone2", - ["💂🏽‍♂️"] = "man_guard_tone3", - ["💂🏾‍♂️"] = "man_guard_tone4", - ["💂🏿‍♂️"] = "man_guard_tone5", - ["🕵️"] = "detective", - ["🕵🏻"] = "detective_tone1", - ["🕵🏼"] = "detective_tone2", - ["🕵🏽"] = "detective_tone3", - ["🕵🏾"] = "detective_tone4", - ["🕵🏿"] = "detective_tone5", - ["🕵️‍♀️"] = "woman_detective", - ["🕵🏻‍♀️"] = "woman_detective_tone1", - ["🕵🏼‍♀️"] = "woman_detective_tone2", - ["🕵🏽‍♀️"] = "woman_detective_tone3", - ["🕵🏾‍♀️"] = "woman_detective_tone4", - ["🕵🏿‍♀️"] = "woman_detective_tone5", - ["🕵️‍♂️"] = "man_detective", - ["🕵🏻‍♂️"] = "man_detective_tone1", - ["🕵🏼‍♂️"] = "man_detective_tone2", - ["🕵🏽‍♂️"] = "man_detective_tone3", - ["🕵🏾‍♂️"] = "man_detective_tone4", - ["🕵🏿‍♂️"] = "man_detective_tone5", - ["🧑‍⚕️"] = "health_worker", - ["🧑🏻‍⚕️"] = "health_worker_tone1", - ["🧑🏼‍⚕️"] = "health_worker_tone2", - ["🧑🏽‍⚕️"] = "health_worker_tone3", - ["🧑🏾‍⚕️"] = "health_worker_tone4", - ["🧑🏿‍⚕️"] = "health_worker_tone5", - ["👩‍⚕️"] = "woman_health_worker", - ["👩🏻‍⚕️"] = "woman_health_worker_tone1", - ["👩🏼‍⚕️"] = "woman_health_worker_tone2", - ["👩🏽‍⚕️"] = "woman_health_worker_tone3", - ["👩🏾‍⚕️"] = "woman_health_worker_tone4", - ["👩🏿‍⚕️"] = "woman_health_worker_tone5", - ["👨‍⚕️"] = "man_health_worker", - ["👨🏻‍⚕️"] = "man_health_worker_tone1", - ["👨🏼‍⚕️"] = "man_health_worker_tone2", - ["👨🏽‍⚕️"] = "man_health_worker_tone3", - ["👨🏾‍⚕️"] = "man_health_worker_tone4", - ["👨🏿‍⚕️"] = "man_health_worker_tone5", - ["🧑‍🌾"] = "farmer", - ["🧑🏻‍🌾"] = "farmer_tone1", - ["🧑🏼‍🌾"] = "farmer_tone2", - ["🧑🏽‍🌾"] = "farmer_tone3", - ["🧑🏾‍🌾"] = "farmer_tone4", - ["🧑🏿‍🌾"] = "farmer_tone5", - ["👩‍🌾"] = "woman_farmer", - ["👩🏻‍🌾"] = "woman_farmer_tone1", - ["👩🏼‍🌾"] = "woman_farmer_tone2", - ["👩🏽‍🌾"] = "woman_farmer_tone3", - ["👩🏾‍🌾"] = "woman_farmer_tone4", - ["👩🏿‍🌾"] = "woman_farmer_tone5", - ["👨‍🌾"] = "man_farmer", - ["👨🏻‍🌾"] = "man_farmer_tone1", - ["👨🏼‍🌾"] = "man_farmer_tone2", - ["👨🏽‍🌾"] = "man_farmer_tone3", - ["👨🏾‍🌾"] = "man_farmer_tone4", - ["👨🏿‍🌾"] = "man_farmer_tone5", - ["🧑‍🍳"] = "cook", - ["🧑🏻‍🍳"] = "cook_tone1", - ["🧑🏼‍🍳"] = "cook_tone2", - ["🧑🏽‍🍳"] = "cook_tone3", - ["🧑🏾‍🍳"] = "cook_tone4", - ["🧑🏿‍🍳"] = "cook_tone5", - ["👩‍🍳"] = "woman_cook", - ["👩🏻‍🍳"] = "woman_cook_tone1", - ["👩🏼‍🍳"] = "woman_cook_tone2", - ["👩🏽‍🍳"] = "woman_cook_tone3", - ["👩🏾‍🍳"] = "woman_cook_tone4", - ["👩🏿‍🍳"] = "woman_cook_tone5", - ["👨‍🍳"] = "man_cook", - ["👨🏻‍🍳"] = "man_cook_tone1", - ["👨🏼‍🍳"] = "man_cook_tone2", - ["👨🏽‍🍳"] = "man_cook_tone3", - ["👨🏾‍🍳"] = "man_cook_tone4", - ["👨🏿‍🍳"] = "man_cook_tone5", - ["🧑‍🎓"] = "student", - ["🧑🏻‍🎓"] = "student_tone1", - ["🧑🏼‍🎓"] = "student_tone2", - ["🧑🏽‍🎓"] = "student_tone3", - ["🧑🏾‍🎓"] = "student_tone4", - ["🧑🏿‍🎓"] = "student_tone5", - ["👩‍🎓"] = "woman_student", - ["👩🏻‍🎓"] = "woman_student_tone1", - ["👩🏼‍🎓"] = "woman_student_tone2", - ["👩🏽‍🎓"] = "woman_student_tone3", - ["👩🏾‍🎓"] = "woman_student_tone4", - ["👩🏿‍🎓"] = "woman_student_tone5", - ["👨‍🎓"] = "man_student", - ["👨🏻‍🎓"] = "man_student_tone1", - ["👨🏼‍🎓"] = "man_student_tone2", - ["👨🏽‍🎓"] = "man_student_tone3", - ["👨🏾‍🎓"] = "man_student_tone4", - ["👨🏿‍🎓"] = "man_student_tone5", - ["🧑‍🎤"] = "singer", - ["🧑🏻‍🎤"] = "singer_tone1", - ["🧑🏼‍🎤"] = "singer_tone2", - ["🧑🏽‍🎤"] = "singer_tone3", - ["🧑🏾‍🎤"] = "singer_tone4", - ["🧑🏿‍🎤"] = "singer_tone5", - ["👩‍🎤"] = "woman_singer", - ["👩🏻‍🎤"] = "woman_singer_tone1", - ["👩🏼‍🎤"] = "woman_singer_tone2", - ["👩🏽‍🎤"] = "woman_singer_tone3", - ["👩🏾‍🎤"] = "woman_singer_tone4", - ["👩🏿‍🎤"] = "woman_singer_tone5", - ["👨‍🎤"] = "man_singer", - ["👨🏻‍🎤"] = "man_singer_tone1", - ["👨🏼‍🎤"] = "man_singer_tone2", - ["👨🏽‍🎤"] = "man_singer_tone3", - ["👨🏾‍🎤"] = "man_singer_tone4", - ["👨🏿‍🎤"] = "man_singer_tone5", - ["🧑‍🏫"] = "teacher", - ["🧑🏻‍🏫"] = "teacher_tone1", - ["🧑🏼‍🏫"] = "teacher_tone2", - ["🧑🏽‍🏫"] = "teacher_tone3", - ["🧑🏾‍🏫"] = "teacher_tone4", - ["🧑🏿‍🏫"] = "teacher_tone5", - ["👩‍🏫"] = "woman_teacher", - ["👩🏻‍🏫"] = "woman_teacher_tone1", - ["👩🏼‍🏫"] = "woman_teacher_tone2", - ["👩🏽‍🏫"] = "woman_teacher_tone3", - ["👩🏾‍🏫"] = "woman_teacher_tone4", - ["👩🏿‍🏫"] = "woman_teacher_tone5", - ["👨‍🏫"] = "man_teacher", - ["👨🏻‍🏫"] = "man_teacher_tone1", - ["👨🏼‍🏫"] = "man_teacher_tone2", - ["👨🏽‍🏫"] = "man_teacher_tone3", - ["👨🏾‍🏫"] = "man_teacher_tone4", - ["👨🏿‍🏫"] = "man_teacher_tone5", - ["🧑‍🏭"] = "factory_worker", - ["🧑🏻‍🏭"] = "factory_worker_tone1", - ["🧑🏼‍🏭"] = "factory_worker_tone2", - ["🧑🏽‍🏭"] = "factory_worker_tone3", - ["🧑🏾‍🏭"] = "factory_worker_tone4", - ["🧑🏿‍🏭"] = "factory_worker_tone5", - ["👩‍🏭"] = "woman_factory_worker", - ["👩🏻‍🏭"] = "woman_factory_worker_tone1", - ["👩🏼‍🏭"] = "woman_factory_worker_tone2", - ["👩🏽‍🏭"] = "woman_factory_worker_tone3", - ["👩🏾‍🏭"] = "woman_factory_worker_tone4", - ["👩🏿‍🏭"] = "woman_factory_worker_tone5", - ["👨‍🏭"] = "man_factory_worker", - ["👨🏻‍🏭"] = "man_factory_worker_tone1", - ["👨🏼‍🏭"] = "man_factory_worker_tone2", - ["👨🏽‍🏭"] = "man_factory_worker_tone3", - ["👨🏾‍🏭"] = "man_factory_worker_tone4", - ["👨🏿‍🏭"] = "man_factory_worker_tone5", - ["🧑‍💻"] = "technologist", - ["🧑🏻‍💻"] = "technologist_tone1", - ["🧑🏼‍💻"] = "technologist_tone2", - ["🧑🏽‍💻"] = "technologist_tone3", - ["🧑🏾‍💻"] = "technologist_tone4", - ["🧑🏿‍💻"] = "technologist_tone5", - ["👩‍💻"] = "woman_technologist", - ["👩🏻‍💻"] = "woman_technologist_tone1", - ["👩🏼‍💻"] = "woman_technologist_tone2", - ["👩🏽‍💻"] = "woman_technologist_tone3", - ["👩🏾‍💻"] = "woman_technologist_tone4", - ["👩🏿‍💻"] = "woman_technologist_tone5", - ["👨‍💻"] = "man_technologist", - ["👨🏻‍💻"] = "man_technologist_tone1", - ["👨🏼‍💻"] = "man_technologist_tone2", - ["👨🏽‍💻"] = "man_technologist_tone3", - ["👨🏾‍💻"] = "man_technologist_tone4", - ["👨🏿‍💻"] = "man_technologist_tone5", - ["🧑‍💼"] = "office_worker", - ["🧑🏻‍💼"] = "office_worker_tone1", - ["🧑🏼‍💼"] = "office_worker_tone2", - ["🧑🏽‍💼"] = "office_worker_tone3", - ["🧑🏾‍💼"] = "office_worker_tone4", - ["🧑🏿‍💼"] = "office_worker_tone5", - ["👩‍💼"] = "woman_office_worker", - ["👩🏻‍💼"] = "woman_office_worker_tone1", - ["👩🏼‍💼"] = "woman_office_worker_tone2", - ["👩🏽‍💼"] = "woman_office_worker_tone3", - ["👩🏾‍💼"] = "woman_office_worker_tone4", - ["👩🏿‍💼"] = "woman_office_worker_tone5", - ["👨‍💼"] = "man_office_worker", - ["👨🏻‍💼"] = "man_office_worker_tone1", - ["👨🏼‍💼"] = "man_office_worker_tone2", - ["👨🏽‍💼"] = "man_office_worker_tone3", - ["👨🏾‍💼"] = "man_office_worker_tone4", - ["👨🏿‍💼"] = "man_office_worker_tone5", - ["🧑‍🔧"] = "mechanic", - ["🧑🏻‍🔧"] = "mechanic_tone1", - ["🧑🏼‍🔧"] = "mechanic_tone2", - ["🧑🏽‍🔧"] = "mechanic_tone3", - ["🧑🏾‍🔧"] = "mechanic_tone4", - ["🧑🏿‍🔧"] = "mechanic_tone5", - ["👩‍🔧"] = "woman_mechanic", - ["👩🏻‍🔧"] = "woman_mechanic_tone1", - ["👩🏼‍🔧"] = "woman_mechanic_tone2", - ["👩🏽‍🔧"] = "woman_mechanic_tone3", - ["👩🏾‍🔧"] = "woman_mechanic_tone4", - ["👩🏿‍🔧"] = "woman_mechanic_tone5", - ["👨‍🔧"] = "man_mechanic", - ["👨🏻‍🔧"] = "man_mechanic_tone1", - ["👨🏼‍🔧"] = "man_mechanic_tone2", - ["👨🏽‍🔧"] = "man_mechanic_tone3", - ["👨🏾‍🔧"] = "man_mechanic_tone4", - ["👨🏿‍🔧"] = "man_mechanic_tone5", - ["🧑‍🔬"] = "scientist", - ["🧑🏻‍🔬"] = "scientist_tone1", - ["🧑🏼‍🔬"] = "scientist_tone2", - ["🧑🏽‍🔬"] = "scientist_tone3", - ["🧑🏾‍🔬"] = "scientist_tone4", - ["🧑🏿‍🔬"] = "scientist_tone5", - ["👩‍🔬"] = "woman_scientist", - ["👩🏻‍🔬"] = "woman_scientist_tone1", - ["👩🏼‍🔬"] = "woman_scientist_tone2", - ["👩🏽‍🔬"] = "woman_scientist_tone3", - ["👩🏾‍🔬"] = "woman_scientist_tone4", - ["👩🏿‍🔬"] = "woman_scientist_tone5", - ["👨‍🔬"] = "man_scientist", - ["👨🏻‍🔬"] = "man_scientist_tone1", - ["👨🏼‍🔬"] = "man_scientist_tone2", - ["👨🏽‍🔬"] = "man_scientist_tone3", - ["👨🏾‍🔬"] = "man_scientist_tone4", - ["👨🏿‍🔬"] = "man_scientist_tone5", - ["🧑‍🎨"] = "artist", - ["🧑🏻‍🎨"] = "artist_tone1", - ["🧑🏼‍🎨"] = "artist_tone2", - ["🧑🏽‍🎨"] = "artist_tone3", - ["🧑🏾‍🎨"] = "artist_tone4", - ["🧑🏿‍🎨"] = "artist_tone5", - ["👩‍🎨"] = "woman_artist", - ["👩🏻‍🎨"] = "woman_artist_tone1", - ["👩🏼‍🎨"] = "woman_artist_tone2", - ["👩🏽‍🎨"] = "woman_artist_tone3", - ["👩🏾‍🎨"] = "woman_artist_tone4", - ["👩🏿‍🎨"] = "woman_artist_tone5", - ["👨‍🎨"] = "man_artist", - ["👨🏻‍🎨"] = "man_artist_tone1", - ["👨🏼‍🎨"] = "man_artist_tone2", - ["👨🏽‍🎨"] = "man_artist_tone3", - ["👨🏾‍🎨"] = "man_artist_tone4", - ["👨🏿‍🎨"] = "man_artist_tone5", - ["🧑‍🚒"] = "firefighter", - ["🧑🏻‍🚒"] = "firefighter_tone1", - ["🧑🏼‍🚒"] = "firefighter_tone2", - ["🧑🏽‍🚒"] = "firefighter_tone3", - ["🧑🏾‍🚒"] = "firefighter_tone4", - ["🧑🏿‍🚒"] = "firefighter_tone5", - ["👩‍🚒"] = "woman_firefighter", - ["👩🏻‍🚒"] = "woman_firefighter_tone1", - ["👩🏼‍🚒"] = "woman_firefighter_tone2", - ["👩🏽‍🚒"] = "woman_firefighter_tone3", - ["👩🏾‍🚒"] = "woman_firefighter_tone4", - ["👩🏿‍🚒"] = "woman_firefighter_tone5", - ["👨‍🚒"] = "man_firefighter", - ["👨🏻‍🚒"] = "man_firefighter_tone1", - ["👨🏼‍🚒"] = "man_firefighter_tone2", - ["👨🏽‍🚒"] = "man_firefighter_tone3", - ["👨🏾‍🚒"] = "man_firefighter_tone4", - ["👨🏿‍🚒"] = "man_firefighter_tone5", - ["🧑‍✈️"] = "pilot", - ["🧑🏻‍✈️"] = "pilot_tone1", - ["🧑🏼‍✈️"] = "pilot_tone2", - ["🧑🏽‍✈️"] = "pilot_tone3", - ["🧑🏾‍✈️"] = "pilot_tone4", - ["🧑🏿‍✈️"] = "pilot_tone5", - ["👩‍✈️"] = "woman_pilot", - ["👩🏻‍✈️"] = "woman_pilot_tone1", - ["👩🏼‍✈️"] = "woman_pilot_tone2", - ["👩🏽‍✈️"] = "woman_pilot_tone3", - ["👩🏾‍✈️"] = "woman_pilot_tone4", - ["👩🏿‍✈️"] = "woman_pilot_tone5", - ["👨‍✈️"] = "man_pilot", - ["👨🏻‍✈️"] = "man_pilot_tone1", - ["👨🏼‍✈️"] = "man_pilot_tone2", - ["👨🏽‍✈️"] = "man_pilot_tone3", - ["👨🏾‍✈️"] = "man_pilot_tone4", - ["👨🏿‍✈️"] = "man_pilot_tone5", - ["🧑‍🚀"] = "astronaut", - ["🧑🏻‍🚀"] = "astronaut_tone1", - ["🧑🏼‍🚀"] = "astronaut_tone2", - ["🧑🏽‍🚀"] = "astronaut_tone3", - ["🧑🏾‍🚀"] = "astronaut_tone4", - ["🧑🏿‍🚀"] = "astronaut_tone5", - ["👩‍🚀"] = "woman_astronaut", - ["👩🏻‍🚀"] = "woman_astronaut_tone1", - ["👩🏼‍🚀"] = "woman_astronaut_tone2", - ["👩🏽‍🚀"] = "woman_astronaut_tone3", - ["👩🏾‍🚀"] = "woman_astronaut_tone4", - ["👩🏿‍🚀"] = "woman_astronaut_tone5", - ["👨‍🚀"] = "man_astronaut", - ["👨🏻‍🚀"] = "man_astronaut_tone1", - ["👨🏼‍🚀"] = "man_astronaut_tone2", - ["👨🏽‍🚀"] = "man_astronaut_tone3", - ["👨🏾‍🚀"] = "man_astronaut_tone4", - ["👨🏿‍🚀"] = "man_astronaut_tone5", - ["🧑‍⚖️"] = "judge", - ["🧑🏻‍⚖️"] = "judge_tone1", - ["🧑🏼‍⚖️"] = "judge_tone2", - ["🧑🏽‍⚖️"] = "judge_tone3", - ["🧑🏾‍⚖️"] = "judge_tone4", - ["🧑🏿‍⚖️"] = "judge_tone5", - ["👩‍⚖️"] = "woman_judge", - ["👩🏻‍⚖️"] = "woman_judge_tone1", - ["👩🏼‍⚖️"] = "woman_judge_tone2", - ["👩🏽‍⚖️"] = "woman_judge_tone3", - ["👩🏾‍⚖️"] = "woman_judge_tone4", - ["👩🏿‍⚖️"] = "woman_judge_tone5", - ["👨‍⚖️"] = "man_judge", - ["👨🏻‍⚖️"] = "man_judge_tone1", - ["👨🏼‍⚖️"] = "man_judge_tone2", - ["👨🏽‍⚖️"] = "man_judge_tone3", - ["👨🏾‍⚖️"] = "man_judge_tone4", - ["👨🏿‍⚖️"] = "man_judge_tone5", - ["👰"] = "person_with_veil", - ["👰🏻"] = "person_with_veil_tone1", - ["👰🏼"] = "person_with_veil_tone2", - ["👰🏽"] = "person_with_veil_tone3", - ["👰🏾"] = "person_with_veil_tone4", - ["👰🏿"] = "person_with_veil_tone5", - ["👰‍♀️"] = "woman_with_veil", - ["👰🏻‍♀️"] = "woman_with_veil_tone1", - ["👰🏼‍♀️"] = "woman_with_veil_tone2", - ["👰🏽‍♀️"] = "woman_with_veil_tone3", - ["👰🏾‍♀️"] = "woman_with_veil_tone4", - ["👰🏿‍♀️"] = "woman_with_veil_tone5", - ["👰‍♂️"] = "man_with_veil", - ["👰🏻‍♂️"] = "man_with_veil_tone1", - ["👰🏼‍♂️"] = "man_with_veil_tone2", - ["👰🏽‍♂️"] = "man_with_veil_tone3", - ["👰🏾‍♂️"] = "man_with_veil_tone4", - ["👰🏿‍♂️"] = "man_with_veil_tone5", - ["🤵"] = "person_in_tuxedo", - ["🤵🏻"] = "person_in_tuxedo_tone1", - ["🤵🏼"] = "person_in_tuxedo_tone2", - ["🤵🏽"] = "person_in_tuxedo_tone3", - ["🤵🏾"] = "person_in_tuxedo_tone4", - ["🤵🏿"] = "person_in_tuxedo_tone5", - ["🤵‍♀️"] = "woman_in_tuxedo", - ["🤵🏻‍♀️"] = "woman_in_tuxedo_tone1", - ["🤵🏼‍♀️"] = "woman_in_tuxedo_tone2", - ["🤵🏽‍♀️"] = "woman_in_tuxedo_tone3", - ["🤵🏾‍♀️"] = "woman_in_tuxedo_tone4", - ["🤵🏿‍♀️"] = "woman_in_tuxedo_tone5", - ["🤵‍♂️"] = "man_in_tuxedo", - ["🤵🏻‍♂️"] = "man_in_tuxedo_tone1", - ["🤵🏼‍♂️"] = "man_in_tuxedo_tone2", - ["🤵🏽‍♂️"] = "man_in_tuxedo_tone3", - ["🤵🏾‍♂️"] = "man_in_tuxedo_tone4", - ["🤵🏿‍♂️"] = "man_in_tuxedo_tone5", - ["👸"] = "princess", - ["👸🏻"] = "princess_tone1", - ["👸🏼"] = "princess_tone2", - ["👸🏽"] = "princess_tone3", - ["👸🏾"] = "princess_tone4", - ["👸🏿"] = "princess_tone5", - ["🤴"] = "prince", - ["🤴🏻"] = "prince_tone1", - ["🤴🏼"] = "prince_tone2", - ["🤴🏽"] = "prince_tone3", - ["🤴🏾"] = "prince_tone4", - ["🤴🏿"] = "prince_tone5", - ["🦸"] = "superhero", - ["🦸🏻"] = "superhero_tone1", - ["🦸🏼"] = "superhero_tone2", - ["🦸🏽"] = "superhero_tone3", - ["🦸🏾"] = "superhero_tone4", - ["🦸🏿"] = "superhero_tone5", - ["🦸‍♀️"] = "woman_superhero", - ["🦸🏻‍♀️"] = "woman_superhero_tone1", - ["🦸🏼‍♀️"] = "woman_superhero_tone2", - ["🦸🏽‍♀️"] = "woman_superhero_tone3", - ["🦸🏾‍♀️"] = "woman_superhero_tone4", - ["🦸🏿‍♀️"] = "woman_superhero_tone5", - ["🦸‍♂️"] = "man_superhero", - ["🦸🏻‍♂️"] = "man_superhero_tone1", - ["🦸🏼‍♂️"] = "man_superhero_tone2", - ["🦸🏽‍♂️"] = "man_superhero_tone3", - ["🦸🏾‍♂️"] = "man_superhero_tone4", - ["🦸🏿‍♂️"] = "man_superhero_tone5", - ["🦹"] = "supervillain", - ["🦹🏻"] = "supervillain_tone1", - ["🦹🏼"] = "supervillain_tone2", - ["🦹🏽"] = "supervillain_tone3", - ["🦹🏾"] = "supervillain_tone4", - ["🦹🏿"] = "supervillain_tone5", - ["🦹‍♀️"] = "woman_supervillain", - ["🦹🏻‍♀️"] = "woman_supervillain_tone1", - ["🦹🏼‍♀️"] = "woman_supervillain_tone2", - ["🦹🏽‍♀️"] = "woman_supervillain_tone3", - ["🦹🏾‍♀️"] = "woman_supervillain_tone4", - ["🦹🏿‍♀️"] = "woman_supervillain_tone5", - ["🦹‍♂️"] = "man_supervillain", - ["🦹🏻‍♂️"] = "man_supervillain_tone1", - ["🦹🏼‍♂️"] = "man_supervillain_tone2", - ["🦹🏽‍♂️"] = "man_supervillain_tone3", - ["🦹🏾‍♂️"] = "man_supervillain_tone4", - ["🦹🏿‍♂️"] = "man_supervillain_tone5", - ["🥷"] = "ninja", - ["🥷🏻"] = "ninja_tone1", - ["🥷🏼"] = "ninja_tone2", - ["🥷🏽"] = "ninja_tone3", - ["🥷🏾"] = "ninja_tone4", - ["🥷🏿"] = "ninja_tone5", - ["🧑‍🎄"] = "mx_claus", - ["🧑🏻‍🎄"] = "mx_claus_tone1", - ["🧑🏼‍🎄"] = "mx_claus_tone2", - ["🧑🏽‍🎄"] = "mx_claus_tone3", - ["🧑🏾‍🎄"] = "mx_claus_tone4", - ["🧑🏿‍🎄"] = "mx_claus_tone5", - ["🤶"] = "mrs_claus", - ["🤶🏻"] = "mrs_claus_tone1", - ["🤶🏼"] = "mrs_claus_tone2", - ["🤶🏽"] = "mrs_claus_tone3", - ["🤶🏾"] = "mrs_claus_tone4", - ["🤶🏿"] = "mrs_claus_tone5", - ["🎅"] = "santa", - ["🎅🏻"] = "santa_tone1", - ["🎅🏼"] = "santa_tone2", - ["🎅🏽"] = "santa_tone3", - ["🎅🏾"] = "santa_tone4", - ["🎅🏿"] = "santa_tone5", - ["🧙"] = "mage", - ["🧙🏻"] = "mage_tone1", - ["🧙🏼"] = "mage_tone2", - ["🧙🏽"] = "mage_tone3", - ["🧙🏾"] = "mage_tone4", - ["🧙🏿"] = "mage_tone5", - ["🧙‍♀️"] = "woman_mage", - ["🧙🏻‍♀️"] = "woman_mage_tone1", - ["🧙🏼‍♀️"] = "woman_mage_tone2", - ["🧙🏽‍♀️"] = "woman_mage_tone3", - ["🧙🏾‍♀️"] = "woman_mage_tone4", - ["🧙🏿‍♀️"] = "woman_mage_tone5", - ["🧙‍♂️"] = "man_mage", - ["🧙🏻‍♂️"] = "man_mage_tone1", - ["🧙🏼‍♂️"] = "man_mage_tone2", - ["🧙🏽‍♂️"] = "man_mage_tone3", - ["🧙🏾‍♂️"] = "man_mage_tone4", - ["🧙🏿‍♂️"] = "man_mage_tone5", - ["🧝"] = "elf", - ["🧝🏻"] = "elf_tone1", - ["🧝🏼"] = "elf_tone2", - ["🧝🏽"] = "elf_tone3", - ["🧝🏾"] = "elf_tone4", - ["🧝🏿"] = "elf_tone5", - ["🧝‍♀️"] = "woman_elf", - ["🧝🏻‍♀️"] = "woman_elf_tone1", - ["🧝🏼‍♀️"] = "woman_elf_tone2", - ["🧝🏽‍♀️"] = "woman_elf_tone3", - ["🧝🏾‍♀️"] = "woman_elf_tone4", - ["🧝🏿‍♀️"] = "woman_elf_tone5", - ["🧝‍♂️"] = "man_elf", - ["🧝🏻‍♂️"] = "man_elf_tone1", - ["🧝🏼‍♂️"] = "man_elf_tone2", - ["🧝🏽‍♂️"] = "man_elf_tone3", - ["🧝🏾‍♂️"] = "man_elf_tone4", - ["🧝🏿‍♂️"] = "man_elf_tone5", - ["🧛"] = "vampire", - ["🧛🏻"] = "vampire_tone1", - ["🧛🏼"] = "vampire_tone2", - ["🧛🏽"] = "vampire_tone3", - ["🧛🏾"] = "vampire_tone4", - ["🧛🏿"] = "vampire_tone5", - ["🧛‍♀️"] = "woman_vampire", - ["🧛🏻‍♀️"] = "woman_vampire_tone1", - ["🧛🏼‍♀️"] = "woman_vampire_tone2", - ["🧛🏽‍♀️"] = "woman_vampire_tone3", - ["🧛🏾‍♀️"] = "woman_vampire_tone4", - ["🧛🏿‍♀️"] = "woman_vampire_tone5", - ["🧛‍♂️"] = "man_vampire", - ["🧛🏻‍♂️"] = "man_vampire_tone1", - ["🧛🏼‍♂️"] = "man_vampire_tone2", - ["🧛🏽‍♂️"] = "man_vampire_tone3", - ["🧛🏾‍♂️"] = "man_vampire_tone4", - ["🧛🏿‍♂️"] = "man_vampire_tone5", - ["🧟"] = "zombie", - ["🧟‍♀️"] = "woman_zombie", - ["🧟‍♂️"] = "man_zombie", - ["🧞"] = "genie", - ["🧞‍♀️"] = "woman_genie", - ["🧞‍♂️"] = "man_genie", - ["🧜"] = "merperson", - ["🧜🏻"] = "merperson_tone1", - ["🧜🏼"] = "merperson_tone2", - ["🧜🏽"] = "merperson_tone3", - ["🧜🏾"] = "merperson_tone4", - ["🧜🏿"] = "merperson_tone5", - ["🧜‍♀️"] = "mermaid", - ["🧜🏻‍♀️"] = "mermaid_tone1", - ["🧜🏼‍♀️"] = "mermaid_tone2", - ["🧜🏽‍♀️"] = "mermaid_tone3", - ["🧜🏾‍♀️"] = "mermaid_tone4", - ["🧜🏿‍♀️"] = "mermaid_tone5", - ["🧜‍♂️"] = "merman", - ["🧜🏻‍♂️"] = "merman_tone1", - ["🧜🏼‍♂️"] = "merman_tone2", - ["🧜🏽‍♂️"] = "merman_tone3", - ["🧜🏾‍♂️"] = "merman_tone4", - ["🧜🏿‍♂️"] = "merman_tone5", - ["🧚"] = "fairy", - ["🧚🏻"] = "fairy_tone1", - ["🧚🏼"] = "fairy_tone2", - ["🧚🏽"] = "fairy_tone3", - ["🧚🏾"] = "fairy_tone4", - ["🧚🏿"] = "fairy_tone5", - ["🧚‍♀️"] = "woman_fairy", - ["🧚🏻‍♀️"] = "woman_fairy_tone1", - ["🧚🏼‍♀️"] = "woman_fairy_tone2", - ["🧚🏽‍♀️"] = "woman_fairy_tone3", - ["🧚🏾‍♀️"] = "woman_fairy_tone4", - ["🧚🏿‍♀️"] = "woman_fairy_tone5", - ["🧚‍♂️"] = "man_fairy", - ["🧚🏻‍♂️"] = "man_fairy_tone1", - ["🧚🏼‍♂️"] = "man_fairy_tone2", - ["🧚🏽‍♂️"] = "man_fairy_tone3", - ["🧚🏾‍♂️"] = "man_fairy_tone4", - ["🧚🏿‍♂️"] = "man_fairy_tone5", - ["👼"] = "angel", - ["👼🏻"] = "angel_tone1", - ["👼🏼"] = "angel_tone2", - ["👼🏽"] = "angel_tone3", - ["👼🏾"] = "angel_tone4", - ["👼🏿"] = "angel_tone5", - ["🤰"] = "pregnant_woman", - ["🤰🏻"] = "pregnant_woman_tone1", - ["🤰🏼"] = "pregnant_woman_tone2", - ["🤰🏽"] = "pregnant_woman_tone3", - ["🤰🏾"] = "pregnant_woman_tone4", - ["🤰🏿"] = "pregnant_woman_tone5", - ["🤱"] = "breast_feeding", - ["🤱🏻"] = "breast_feeding_tone1", - ["🤱🏼"] = "breast_feeding_tone2", - ["🤱🏽"] = "breast_feeding_tone3", - ["🤱🏾"] = "breast_feeding_tone4", - ["🤱🏿"] = "breast_feeding_tone5", - ["🧑‍🍼"] = "person_feeding_baby", - ["🧑🏻‍🍼"] = "person_feeding_baby_tone1", - ["🧑🏼‍🍼"] = "person_feeding_baby_tone2", - ["🧑🏽‍🍼"] = "person_feeding_baby_tone3", - ["🧑🏾‍🍼"] = "person_feeding_baby_tone4", - ["🧑🏿‍🍼"] = "person_feeding_baby_tone5", - ["👩‍🍼"] = "woman_feeding_baby", - ["👩🏻‍🍼"] = "woman_feeding_baby_tone1", - ["👩🏼‍🍼"] = "woman_feeding_baby_tone2", - ["👩🏽‍🍼"] = "woman_feeding_baby_tone3", - ["👩🏾‍🍼"] = "woman_feeding_baby_tone4", - ["👩🏿‍🍼"] = "woman_feeding_baby_tone5", - ["👨‍🍼"] = "man_feeding_baby", - ["👨🏻‍🍼"] = "man_feeding_baby_tone1", - ["👨🏼‍🍼"] = "man_feeding_baby_tone2", - ["👨🏽‍🍼"] = "man_feeding_baby_tone3", - ["👨🏾‍🍼"] = "man_feeding_baby_tone4", - ["👨🏿‍🍼"] = "man_feeding_baby_tone5", - ["🙇"] = "person_bowing", - ["🙇🏻"] = "person_bowing_tone1", - ["🙇🏼"] = "person_bowing_tone2", - ["🙇🏽"] = "person_bowing_tone3", - ["🙇🏾"] = "person_bowing_tone4", - ["🙇🏿"] = "person_bowing_tone5", - ["🙇‍♀️"] = "woman_bowing", - ["🙇🏻‍♀️"] = "woman_bowing_tone1", - ["🙇🏼‍♀️"] = "woman_bowing_tone2", - ["🙇🏽‍♀️"] = "woman_bowing_tone3", - ["🙇🏾‍♀️"] = "woman_bowing_tone4", - ["🙇🏿‍♀️"] = "woman_bowing_tone5", - ["🙇‍♂️"] = "man_bowing", - ["🙇🏻‍♂️"] = "man_bowing_tone1", - ["🙇🏼‍♂️"] = "man_bowing_tone2", - ["🙇🏽‍♂️"] = "man_bowing_tone3", - ["🙇🏾‍♂️"] = "man_bowing_tone4", - ["🙇🏿‍♂️"] = "man_bowing_tone5", - ["💁"] = "person_tipping_hand", - ["💁🏻"] = "person_tipping_hand_tone1", - ["💁🏼"] = "person_tipping_hand_tone2", - ["💁🏽"] = "person_tipping_hand_tone3", - ["💁🏾"] = "person_tipping_hand_tone4", - ["💁🏿"] = "person_tipping_hand_tone5", - ["💁‍♀️"] = "woman_tipping_hand", - ["💁🏻‍♀️"] = "woman_tipping_hand_tone1", - ["💁🏼‍♀️"] = "woman_tipping_hand_tone2", - ["💁🏽‍♀️"] = "woman_tipping_hand_tone3", - ["💁🏾‍♀️"] = "woman_tipping_hand_tone4", - ["💁🏿‍♀️"] = "woman_tipping_hand_tone5", - ["💁‍♂️"] = "man_tipping_hand", - ["💁🏻‍♂️"] = "man_tipping_hand_tone1", - ["💁🏼‍♂️"] = "man_tipping_hand_tone2", - ["💁🏽‍♂️"] = "man_tipping_hand_tone3", - ["💁🏾‍♂️"] = "man_tipping_hand_tone4", - ["💁🏿‍♂️"] = "man_tipping_hand_tone5", - ["🙅"] = "person_gesturing_no", - ["🙅🏻"] = "person_gesturing_no_tone1", - ["🙅🏼"] = "person_gesturing_no_tone2", - ["🙅🏽"] = "person_gesturing_no_tone3", - ["🙅🏾"] = "person_gesturing_no_tone4", - ["🙅🏿"] = "person_gesturing_no_tone5", - ["🙅‍♀️"] = "woman_gesturing_no", - ["🙅🏻‍♀️"] = "woman_gesturing_no_tone1", - ["🙅🏼‍♀️"] = "woman_gesturing_no_tone2", - ["🙅🏽‍♀️"] = "woman_gesturing_no_tone3", - ["🙅🏾‍♀️"] = "woman_gesturing_no_tone4", - ["🙅🏿‍♀️"] = "woman_gesturing_no_tone5", - ["🙅‍♂️"] = "man_gesturing_no", - ["🙅🏻‍♂️"] = "man_gesturing_no_tone1", - ["🙅🏼‍♂️"] = "man_gesturing_no_tone2", - ["🙅🏽‍♂️"] = "man_gesturing_no_tone3", - ["🙅🏾‍♂️"] = "man_gesturing_no_tone4", - ["🙅🏿‍♂️"] = "man_gesturing_no_tone5", - ["🙆"] = "person_gesturing_ok", - ["🙆🏻"] = "person_gesturing_ok_tone1", - ["🙆🏼"] = "person_gesturing_ok_tone2", - ["🙆🏽"] = "person_gesturing_ok_tone3", - ["🙆🏾"] = "person_gesturing_ok_tone4", - ["🙆🏿"] = "person_gesturing_ok_tone5", - ["🙆‍♀️"] = "woman_gesturing_ok", - ["🙆🏻‍♀️"] = "woman_gesturing_ok_tone1", - ["🙆🏼‍♀️"] = "woman_gesturing_ok_tone2", - ["🙆🏽‍♀️"] = "woman_gesturing_ok_tone3", - ["🙆🏾‍♀️"] = "woman_gesturing_ok_tone4", - ["🙆🏿‍♀️"] = "woman_gesturing_ok_tone5", - ["🙆‍♂️"] = "man_gesturing_ok", - ["🙆🏻‍♂️"] = "man_gesturing_ok_tone1", - ["🙆🏼‍♂️"] = "man_gesturing_ok_tone2", - ["🙆🏽‍♂️"] = "man_gesturing_ok_tone3", - ["🙆🏾‍♂️"] = "man_gesturing_ok_tone4", - ["🙆🏿‍♂️"] = "man_gesturing_ok_tone5", - ["🙋"] = "person_raising_hand", - ["🙋🏻"] = "person_raising_hand_tone1", - ["🙋🏼"] = "person_raising_hand_tone2", - ["🙋🏽"] = "person_raising_hand_tone3", - ["🙋🏾"] = "person_raising_hand_tone4", - ["🙋🏿"] = "person_raising_hand_tone5", - ["🙋‍♀️"] = "woman_raising_hand", - ["🙋🏻‍♀️"] = "woman_raising_hand_tone1", - ["🙋🏼‍♀️"] = "woman_raising_hand_tone2", - ["🙋🏽‍♀️"] = "woman_raising_hand_tone3", - ["🙋🏾‍♀️"] = "woman_raising_hand_tone4", - ["🙋🏿‍♀️"] = "woman_raising_hand_tone5", - ["🙋‍♂️"] = "man_raising_hand", - ["🙋🏻‍♂️"] = "man_raising_hand_tone1", - ["🙋🏼‍♂️"] = "man_raising_hand_tone2", - ["🙋🏽‍♂️"] = "man_raising_hand_tone3", - ["🙋🏾‍♂️"] = "man_raising_hand_tone4", - ["🙋🏿‍♂️"] = "man_raising_hand_tone5", - ["🧏"] = "deaf_person", - ["🧏🏻"] = "deaf_person_tone1", - ["🧏🏼"] = "deaf_person_tone2", - ["🧏🏽"] = "deaf_person_tone3", - ["🧏🏾"] = "deaf_person_tone4", - ["🧏🏿"] = "deaf_person_tone5", - ["🧏‍♀️"] = "deaf_woman", - ["🧏🏻‍♀️"] = "deaf_woman_tone1", - ["🧏🏼‍♀️"] = "deaf_woman_tone2", - ["🧏🏽‍♀️"] = "deaf_woman_tone3", - ["🧏🏾‍♀️"] = "deaf_woman_tone4", - ["🧏🏿‍♀️"] = "deaf_woman_tone5", - ["🧏‍♂️"] = "deaf_man", - ["🧏🏻‍♂️"] = "deaf_man_tone1", - ["🧏🏼‍♂️"] = "deaf_man_tone2", - ["🧏🏽‍♂️"] = "deaf_man_tone3", - ["🧏🏾‍♂️"] = "deaf_man_tone4", - ["🧏🏿‍♂️"] = "deaf_man_tone5", - ["🤦"] = "person_facepalming", - ["🤦🏻"] = "person_facepalming_tone1", - ["🤦🏼"] = "person_facepalming_tone2", - ["🤦🏽"] = "person_facepalming_tone3", - ["🤦🏾"] = "person_facepalming_tone4", - ["🤦🏿"] = "person_facepalming_tone5", - ["🤦‍♀️"] = "woman_facepalming", - ["🤦🏻‍♀️"] = "woman_facepalming_tone1", - ["🤦🏼‍♀️"] = "woman_facepalming_tone2", - ["🤦🏽‍♀️"] = "woman_facepalming_tone3", - ["🤦🏾‍♀️"] = "woman_facepalming_tone4", - ["🤦🏿‍♀️"] = "woman_facepalming_tone5", - ["🤦‍♂️"] = "man_facepalming", - ["🤦🏻‍♂️"] = "man_facepalming_tone1", - ["🤦🏼‍♂️"] = "man_facepalming_tone2", - ["🤦🏽‍♂️"] = "man_facepalming_tone3", - ["🤦🏾‍♂️"] = "man_facepalming_tone4", - ["🤦🏿‍♂️"] = "man_facepalming_tone5", - ["🤷"] = "person_shrugging", - ["🤷🏻"] = "person_shrugging_tone1", - ["🤷🏼"] = "person_shrugging_tone2", - ["🤷🏽"] = "person_shrugging_tone3", - ["🤷🏾"] = "person_shrugging_tone4", - ["🤷🏿"] = "person_shrugging_tone5", - ["🤷‍♀️"] = "woman_shrugging", - ["🤷🏻‍♀️"] = "woman_shrugging_tone1", - ["🤷🏼‍♀️"] = "woman_shrugging_tone2", - ["🤷🏽‍♀️"] = "woman_shrugging_tone3", - ["🤷🏾‍♀️"] = "woman_shrugging_tone4", - ["🤷🏿‍♀️"] = "woman_shrugging_tone5", - ["🤷‍♂️"] = "man_shrugging", - ["🤷🏻‍♂️"] = "man_shrugging_tone1", - ["🤷🏼‍♂️"] = "man_shrugging_tone2", - ["🤷🏽‍♂️"] = "man_shrugging_tone3", - ["🤷🏾‍♂️"] = "man_shrugging_tone4", - ["🤷🏿‍♂️"] = "man_shrugging_tone5", - ["🙎"] = "person_pouting", - ["🙎🏻"] = "person_pouting_tone1", - ["🙎🏼"] = "person_pouting_tone2", - ["🙎🏽"] = "person_pouting_tone3", - ["🙎🏾"] = "person_pouting_tone4", - ["🙎🏿"] = "person_pouting_tone5", - ["🙎‍♀️"] = "woman_pouting", - ["🙎🏻‍♀️"] = "woman_pouting_tone1", - ["🙎🏼‍♀️"] = "woman_pouting_tone2", - ["🙎🏽‍♀️"] = "woman_pouting_tone3", - ["🙎🏾‍♀️"] = "woman_pouting_tone4", - ["🙎🏿‍♀️"] = "woman_pouting_tone5", - ["🙎‍♂️"] = "man_pouting", - ["🙎🏻‍♂️"] = "man_pouting_tone1", - ["🙎🏼‍♂️"] = "man_pouting_tone2", - ["🙎🏽‍♂️"] = "man_pouting_tone3", - ["🙎🏾‍♂️"] = "man_pouting_tone4", - ["🙎🏿‍♂️"] = "man_pouting_tone5", - ["🙍"] = "person_frowning", - ["🙍🏻"] = "person_frowning_tone1", - ["🙍🏼"] = "person_frowning_tone2", - ["🙍🏽"] = "person_frowning_tone3", - ["🙍🏾"] = "person_frowning_tone4", - ["🙍🏿"] = "person_frowning_tone5", - ["🙍‍♀️"] = "woman_frowning", - ["🙍🏻‍♀️"] = "woman_frowning_tone1", - ["🙍🏼‍♀️"] = "woman_frowning_tone2", - ["🙍🏽‍♀️"] = "woman_frowning_tone3", - ["🙍🏾‍♀️"] = "woman_frowning_tone4", - ["🙍🏿‍♀️"] = "woman_frowning_tone5", - ["🙍‍♂️"] = "man_frowning", - ["🙍🏻‍♂️"] = "man_frowning_tone1", - ["🙍🏼‍♂️"] = "man_frowning_tone2", - ["🙍🏽‍♂️"] = "man_frowning_tone3", - ["🙍🏾‍♂️"] = "man_frowning_tone4", - ["🙍🏿‍♂️"] = "man_frowning_tone5", - ["💇"] = "person_getting_haircut", - ["💇🏻"] = "person_getting_haircut_tone1", - ["💇🏼"] = "person_getting_haircut_tone2", - ["💇🏽"] = "person_getting_haircut_tone3", - ["💇🏾"] = "person_getting_haircut_tone4", - ["💇🏿"] = "person_getting_haircut_tone5", - ["💇‍♀️"] = "woman_getting_haircut", - ["💇🏻‍♀️"] = "woman_getting_haircut_tone1", - ["💇🏼‍♀️"] = "woman_getting_haircut_tone2", - ["💇🏽‍♀️"] = "woman_getting_haircut_tone3", - ["💇🏾‍♀️"] = "woman_getting_haircut_tone4", - ["💇🏿‍♀️"] = "woman_getting_haircut_tone5", - ["💇‍♂️"] = "man_getting_haircut", - ["💇🏻‍♂️"] = "man_getting_haircut_tone1", - ["💇🏼‍♂️"] = "man_getting_haircut_tone2", - ["💇🏽‍♂️"] = "man_getting_haircut_tone3", - ["💇🏾‍♂️"] = "man_getting_haircut_tone4", - ["💇🏿‍♂️"] = "man_getting_haircut_tone5", - ["💆"] = "person_getting_massage", - ["💆🏻"] = "person_getting_massage_tone1", - ["💆🏼"] = "person_getting_massage_tone2", - ["💆🏽"] = "person_getting_massage_tone3", - ["💆🏾"] = "person_getting_massage_tone4", - ["💆🏿"] = "person_getting_massage_tone5", - ["💆‍♀️"] = "woman_getting_face_massage", - ["💆🏻‍♀️"] = "woman_getting_face_massage_tone1", - ["💆🏼‍♀️"] = "woman_getting_face_massage_tone2", - ["💆🏽‍♀️"] = "woman_getting_face_massage_tone3", - ["💆🏾‍♀️"] = "woman_getting_face_massage_tone4", - ["💆🏿‍♀️"] = "woman_getting_face_massage_tone5", - ["💆‍♂️"] = "man_getting_face_massage", - ["💆🏻‍♂️"] = "man_getting_face_massage_tone1", - ["💆🏼‍♂️"] = "man_getting_face_massage_tone2", - ["💆🏽‍♂️"] = "man_getting_face_massage_tone3", - ["💆🏾‍♂️"] = "man_getting_face_massage_tone4", - ["💆🏿‍♂️"] = "man_getting_face_massage_tone5", - ["🧖"] = "person_in_steamy_room", - ["🧖🏻"] = "person_in_steamy_room_tone1", - ["🧖🏼"] = "person_in_steamy_room_tone2", - ["🧖🏽"] = "person_in_steamy_room_tone3", - ["🧖🏾"] = "person_in_steamy_room_tone4", - ["🧖🏿"] = "person_in_steamy_room_tone5", - ["🧖‍♀️"] = "woman_in_steamy_room", - ["🧖🏻‍♀️"] = "woman_in_steamy_room_tone1", - ["🧖🏼‍♀️"] = "woman_in_steamy_room_tone2", - ["🧖🏽‍♀️"] = "woman_in_steamy_room_tone3", - ["🧖🏾‍♀️"] = "woman_in_steamy_room_tone4", - ["🧖🏿‍♀️"] = "woman_in_steamy_room_tone5", - ["🧖‍♂️"] = "man_in_steamy_room", - ["🧖🏻‍♂️"] = "man_in_steamy_room_tone1", - ["🧖🏼‍♂️"] = "man_in_steamy_room_tone2", - ["🧖🏽‍♂️"] = "man_in_steamy_room_tone3", - ["🧖🏾‍♂️"] = "man_in_steamy_room_tone4", - ["🧖🏿‍♂️"] = "man_in_steamy_room_tone5", - ["💅"] = "nail_care", - ["💅🏻"] = "nail_care_tone1", - ["💅🏼"] = "nail_care_tone2", - ["💅🏽"] = "nail_care_tone3", - ["💅🏾"] = "nail_care_tone4", - ["💅🏿"] = "nail_care_tone5", - ["🤳"] = "selfie", - ["🤳🏻"] = "selfie_tone1", - ["🤳🏼"] = "selfie_tone2", - ["🤳🏽"] = "selfie_tone3", - ["🤳🏾"] = "selfie_tone4", - ["🤳🏿"] = "selfie_tone5", - ["💃"] = "dancer", - ["💃🏻"] = "dancer_tone1", - ["💃🏼"] = "dancer_tone2", - ["💃🏽"] = "dancer_tone3", - ["💃🏾"] = "dancer_tone4", - ["💃🏿"] = "dancer_tone5", - ["🕺"] = "man_dancing", - ["🕺🏻"] = "man_dancing_tone1", - ["🕺🏼"] = "man_dancing_tone2", - ["🕺🏽"] = "man_dancing_tone3", - ["🕺🏿"] = "man_dancing_tone5", - ["🕺🏾"] = "man_dancing_tone4", - ["👯"] = "people_with_bunny_ears_partying", - ["👯‍♀️"] = "women_with_bunny_ears_partying", - ["👯‍♂️"] = "men_with_bunny_ears_partying", - ["🕴️"] = "levitate", - ["🕴🏻"] = "levitate_tone1", - ["🕴🏼"] = "levitate_tone2", - ["🕴🏽"] = "levitate_tone3", - ["🕴🏾"] = "levitate_tone4", - ["🕴🏿"] = "levitate_tone5", - ["🧑‍🦽"] = "person_in_manual_wheelchair", - ["🧑🏻‍🦽"] = "person_in_manual_wheelchair_tone1", - ["🧑🏼‍🦽"] = "person_in_manual_wheelchair_tone2", - ["🧑🏽‍🦽"] = "person_in_manual_wheelchair_tone3", - ["🧑🏾‍🦽"] = "person_in_manual_wheelchair_tone4", - ["🧑🏿‍🦽"] = "person_in_manual_wheelchair_tone5", - ["👩‍🦽"] = "woman_in_manual_wheelchair", - ["👩🏻‍🦽"] = "woman_in_manual_wheelchair_tone1", - ["👩🏼‍🦽"] = "woman_in_manual_wheelchair_tone2", - ["👩🏽‍🦽"] = "woman_in_manual_wheelchair_tone3", - ["👩🏾‍🦽"] = "woman_in_manual_wheelchair_tone4", - ["👩🏿‍🦽"] = "woman_in_manual_wheelchair_tone5", - ["👨‍🦽"] = "man_in_manual_wheelchair", - ["👨🏻‍🦽"] = "man_in_manual_wheelchair_tone1", - ["👨🏼‍🦽"] = "man_in_manual_wheelchair_tone2", - ["👨🏽‍🦽"] = "man_in_manual_wheelchair_tone3", - ["👨🏾‍🦽"] = "man_in_manual_wheelchair_tone4", - ["👨🏿‍🦽"] = "man_in_manual_wheelchair_tone5", - ["🧑‍🦼"] = "person_in_motorized_wheelchair", - ["🧑🏻‍🦼"] = "person_in_motorized_wheelchair_tone1", - ["🧑🏼‍🦼"] = "person_in_motorized_wheelchair_tone2", - ["🧑🏽‍🦼"] = "person_in_motorized_wheelchair_tone3", - ["🧑🏾‍🦼"] = "person_in_motorized_wheelchair_tone4", - ["🧑🏿‍🦼"] = "person_in_motorized_wheelchair_tone5", - ["👩‍🦼"] = "woman_in_motorized_wheelchair", - ["👩🏻‍🦼"] = "woman_in_motorized_wheelchair_tone1", - ["👩🏼‍🦼"] = "woman_in_motorized_wheelchair_tone2", - ["👩🏽‍🦼"] = "woman_in_motorized_wheelchair_tone3", - ["👩🏾‍🦼"] = "woman_in_motorized_wheelchair_tone4", - ["👩🏿‍🦼"] = "woman_in_motorized_wheelchair_tone5", - ["👨‍🦼"] = "man_in_motorized_wheelchair", - ["👨🏻‍🦼"] = "man_in_motorized_wheelchair_tone1", - ["👨🏼‍🦼"] = "man_in_motorized_wheelchair_tone2", - ["👨🏽‍🦼"] = "man_in_motorized_wheelchair_tone3", - ["👨🏾‍🦼"] = "man_in_motorized_wheelchair_tone4", - ["👨🏿‍🦼"] = "man_in_motorized_wheelchair_tone5", - ["🚶"] = "person_walking", - ["🚶🏻"] = "person_walking_tone1", - ["🚶🏼"] = "person_walking_tone2", - ["🚶🏽"] = "person_walking_tone3", - ["🚶🏾"] = "person_walking_tone4", - ["🚶🏿"] = "person_walking_tone5", - ["🚶‍♀️"] = "woman_walking", - ["🚶🏻‍♀️"] = "woman_walking_tone1", - ["🚶🏼‍♀️"] = "woman_walking_tone2", - ["🚶🏽‍♀️"] = "woman_walking_tone3", - ["🚶🏾‍♀️"] = "woman_walking_tone4", - ["🚶🏿‍♀️"] = "woman_walking_tone5", - ["🚶‍♂️"] = "man_walking", - ["🚶🏻‍♂️"] = "man_walking_tone1", - ["🚶🏼‍♂️"] = "man_walking_tone2", - ["🚶🏽‍♂️"] = "man_walking_tone3", - ["🚶🏾‍♂️"] = "man_walking_tone4", - ["🚶🏿‍♂️"] = "man_walking_tone5", - ["🧑‍🦯"] = "person_with_probing_cane", - ["🧑🏻‍🦯"] = "person_with_probing_cane_tone1", - ["🧑🏼‍🦯"] = "person_with_probing_cane_tone2", - ["🧑🏽‍🦯"] = "person_with_probing_cane_tone3", - ["🧑🏾‍🦯"] = "person_with_probing_cane_tone4", - ["🧑🏿‍🦯"] = "person_with_probing_cane_tone5", - ["👩‍🦯"] = "woman_with_probing_cane", - ["👩🏻‍🦯"] = "woman_with_probing_cane_tone1", - ["👩🏼‍🦯"] = "woman_with_probing_cane_tone2", - ["👩🏽‍🦯"] = "woman_with_probing_cane_tone3", - ["👩🏾‍🦯"] = "woman_with_probing_cane_tone4", - ["👩🏿‍🦯"] = "woman_with_probing_cane_tone5", - ["👨‍🦯"] = "man_with_probing_cane", - ["👨🏻‍🦯"] = "man_with_probing_cane_tone1", - ["👨🏽‍🦯"] = "man_with_probing_cane_tone3", - ["👨🏼‍🦯"] = "man_with_probing_cane_tone2", - ["👨🏾‍🦯"] = "man_with_probing_cane_tone4", - ["👨🏿‍🦯"] = "man_with_probing_cane_tone5", - ["🧎"] = "person_kneeling", - ["🧎🏻"] = "person_kneeling_tone1", - ["🧎🏼"] = "person_kneeling_tone2", - ["🧎🏽"] = "person_kneeling_tone3", - ["🧎🏾"] = "person_kneeling_tone4", - ["🧎🏿"] = "person_kneeling_tone5", - ["🧎‍♀️"] = "woman_kneeling", - ["🧎🏻‍♀️"] = "woman_kneeling_tone1", - ["🧎🏼‍♀️"] = "woman_kneeling_tone2", - ["🧎🏽‍♀️"] = "woman_kneeling_tone3", - ["🧎🏾‍♀️"] = "woman_kneeling_tone4", - ["🧎🏿‍♀️"] = "woman_kneeling_tone5", - ["🧎‍♂️"] = "man_kneeling", - ["🧎🏻‍♂️"] = "man_kneeling_tone1", - ["🧎🏼‍♂️"] = "man_kneeling_tone2", - ["🧎🏽‍♂️"] = "man_kneeling_tone3", - ["🧎🏾‍♂️"] = "man_kneeling_tone4", - ["🧎🏿‍♂️"] = "man_kneeling_tone5", - ["🏃"] = "person_running", - ["🏃🏻"] = "person_running_tone1", - ["🏃🏼"] = "person_running_tone2", - ["🏃🏽"] = "person_running_tone3", - ["🏃🏾"] = "person_running_tone4", - ["🏃🏿"] = "person_running_tone5", - ["🏃‍♀️"] = "woman_running", - ["🏃🏻‍♀️"] = "woman_running_tone1", - ["🏃🏼‍♀️"] = "woman_running_tone2", - ["🏃🏽‍♀️"] = "woman_running_tone3", - ["🏃🏾‍♀️"] = "woman_running_tone4", - ["🏃🏿‍♀️"] = "woman_running_tone5", - ["🏃‍♂️"] = "man_running", - ["🏃🏻‍♂️"] = "man_running_tone1", - ["🏃🏼‍♂️"] = "man_running_tone2", - ["🏃🏽‍♂️"] = "man_running_tone3", - ["🏃🏾‍♂️"] = "man_running_tone4", - ["🏃🏿‍♂️"] = "man_running_tone5", - ["🧍"] = "person_standing", - ["🧍🏻"] = "person_standing_tone1", - ["🧍🏼"] = "person_standing_tone2", - ["🧍🏽"] = "person_standing_tone3", - ["🧍🏾"] = "person_standing_tone4", - ["🧍🏿"] = "person_standing_tone5", - ["🧍‍♀️"] = "woman_standing", - ["🧍🏻‍♀️"] = "woman_standing_tone1", - ["🧍🏼‍♀️"] = "woman_standing_tone2", - ["🧍🏽‍♀️"] = "woman_standing_tone3", - ["🧍🏾‍♀️"] = "woman_standing_tone4", - ["🧍🏿‍♀️"] = "woman_standing_tone5", - ["🧍‍♂️"] = "man_standing", - ["🧍🏻‍♂️"] = "man_standing_tone1", - ["🧍🏼‍♂️"] = "man_standing_tone2", - ["🧍🏽‍♂️"] = "man_standing_tone3", - ["🧍🏾‍♂️"] = "man_standing_tone4", - ["🧍🏿‍♂️"] = "man_standing_tone5", - ["🧑‍🤝‍🧑"] = "people_holding_hands", - ["🧑🏻‍🤝‍🧑🏻"] = "people_holding_hands_tone1", - ["🧑🏻‍🤝‍🧑🏼"] = "people_holding_hands_tone1_tone2", - ["🧑🏻‍🤝‍🧑🏽"] = "people_holding_hands_tone1_tone3", - ["🧑🏻‍🤝‍🧑🏾"] = "people_holding_hands_tone1_tone4", - ["🧑🏻‍🤝‍🧑🏿"] = "people_holding_hands_tone1_tone5", - ["🧑🏼‍🤝‍🧑🏻"] = "people_holding_hands_tone2_tone1", - ["🧑🏼‍🤝‍🧑🏼"] = "people_holding_hands_tone2", - ["🧑🏼‍🤝‍🧑🏽"] = "people_holding_hands_tone2_tone3", - ["🧑🏼‍🤝‍🧑🏾"] = "people_holding_hands_tone2_tone4", - ["🧑🏼‍🤝‍🧑🏿"] = "people_holding_hands_tone2_tone5", - ["🧑🏽‍🤝‍🧑🏻"] = "people_holding_hands_tone3_tone1", - ["🧑🏽‍🤝‍🧑🏼"] = "people_holding_hands_tone3_tone2", - ["🧑🏽‍🤝‍🧑🏽"] = "people_holding_hands_tone3", - ["🧑🏽‍🤝‍🧑🏾"] = "people_holding_hands_tone3_tone4", - ["🧑🏽‍🤝‍🧑🏿"] = "people_holding_hands_tone3_tone5", - ["🧑🏾‍🤝‍🧑🏻"] = "people_holding_hands_tone4_tone1", - ["🧑🏾‍🤝‍🧑🏼"] = "people_holding_hands_tone4_tone2", - ["🧑🏾‍🤝‍🧑🏽"] = "people_holding_hands_tone4_tone3", - ["🧑🏾‍🤝‍🧑🏾"] = "people_holding_hands_tone4", - ["🧑🏾‍🤝‍🧑🏿"] = "people_holding_hands_tone4_tone5", - ["🧑🏿‍🤝‍🧑🏻"] = "people_holding_hands_tone5_tone1", - ["🧑🏿‍🤝‍🧑🏼"] = "people_holding_hands_tone5_tone2", - ["🧑🏿‍🤝‍🧑🏽"] = "people_holding_hands_tone5_tone3", - ["🧑🏿‍🤝‍🧑🏾"] = "people_holding_hands_tone5_tone4", - ["🧑🏿‍🤝‍🧑🏿"] = "people_holding_hands_tone5", - ["👫"] = "couple", - ["👫🏻"] = "woman_and_man_holding_hands_tone1", - ["👩🏻‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone1_tone2", - ["👩🏻‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone1_tone3", - ["👩🏻‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone1_tone4", - ["👩🏻‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone1_tone5", - ["👩🏼‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone2_tone1", - ["👫🏼"] = "woman_and_man_holding_hands_tone2", - ["👩🏼‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone2_tone3", - ["👩🏼‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone2_tone4", - ["👩🏼‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone2_tone5", - ["👩🏽‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone3_tone1", - ["👩🏽‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone3_tone2", - ["👫🏽"] = "woman_and_man_holding_hands_tone3", - ["👩🏽‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone3_tone4", - ["👩🏽‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone3_tone5", - ["👩🏾‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone4_tone1", - ["👩🏾‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone4_tone2", - ["👩🏾‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone4_tone3", - ["👫🏾"] = "woman_and_man_holding_hands_tone4", - ["👩🏾‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone4_tone5", - ["👩🏿‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone5_tone1", - ["👩🏿‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone5_tone2", - ["👩🏿‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone5_tone3", - ["👩🏿‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone5_tone4", - ["👫🏿"] = "woman_and_man_holding_hands_tone5", - ["👭"] = "two_women_holding_hands", - ["👭🏻"] = "women_holding_hands_tone1", - ["👩🏻‍🤝‍👩🏼"] = "women_holding_hands_tone1_tone2", - ["👩🏻‍🤝‍👩🏽"] = "women_holding_hands_tone1_tone3", - ["👩🏻‍🤝‍👩🏾"] = "women_holding_hands_tone1_tone4", - ["👩🏻‍🤝‍👩🏿"] = "women_holding_hands_tone1_tone5", - ["👩🏼‍🤝‍👩🏻"] = "women_holding_hands_tone2_tone1", - ["👭🏼"] = "women_holding_hands_tone2", - ["👩🏼‍🤝‍👩🏽"] = "women_holding_hands_tone2_tone3", - ["👩🏼‍🤝‍👩🏾"] = "women_holding_hands_tone2_tone4", - ["👩🏼‍🤝‍👩🏿"] = "women_holding_hands_tone2_tone5", - ["👩🏽‍🤝‍👩🏻"] = "women_holding_hands_tone3_tone1", - ["👩🏽‍🤝‍👩🏼"] = "women_holding_hands_tone3_tone2", - ["👭🏽"] = "women_holding_hands_tone3", - ["👩🏽‍🤝‍👩🏾"] = "women_holding_hands_tone3_tone4", - ["👩🏽‍🤝‍👩🏿"] = "women_holding_hands_tone3_tone5", - ["👩🏾‍🤝‍👩🏻"] = "women_holding_hands_tone4_tone1", - ["👩🏾‍🤝‍👩🏼"] = "women_holding_hands_tone4_tone2", - ["👩🏾‍🤝‍👩🏽"] = "women_holding_hands_tone4_tone3", - ["👭🏾"] = "women_holding_hands_tone4", - ["👩🏾‍🤝‍👩🏿"] = "women_holding_hands_tone4_tone5", - ["👩🏿‍🤝‍👩🏻"] = "women_holding_hands_tone5_tone1", - ["👩🏿‍🤝‍👩🏼"] = "women_holding_hands_tone5_tone2", - ["👩🏿‍🤝‍👩🏽"] = "women_holding_hands_tone5_tone3", - ["👩🏿‍🤝‍👩🏾"] = "women_holding_hands_tone5_tone4", - ["👭🏿"] = "women_holding_hands_tone5", - ["👬"] = "two_men_holding_hands", - ["👬🏻"] = "men_holding_hands_tone1", - ["👨🏻‍🤝‍👨🏼"] = "men_holding_hands_tone1_tone2", - ["👨🏻‍🤝‍👨🏽"] = "men_holding_hands_tone1_tone3", - ["👨🏻‍🤝‍👨🏾"] = "men_holding_hands_tone1_tone4", - ["👨🏻‍🤝‍👨🏿"] = "men_holding_hands_tone1_tone5", - ["👨🏼‍🤝‍👨🏻"] = "men_holding_hands_tone2_tone1", - ["👬🏼"] = "men_holding_hands_tone2", - ["👨🏼‍🤝‍👨🏽"] = "men_holding_hands_tone2_tone3", - ["👨🏼‍🤝‍👨🏾"] = "men_holding_hands_tone2_tone4", - ["👨🏼‍🤝‍👨🏿"] = "men_holding_hands_tone2_tone5", - ["👨🏽‍🤝‍👨🏻"] = "men_holding_hands_tone3_tone1", - ["👨🏽‍🤝‍👨🏼"] = "men_holding_hands_tone3_tone2", - ["👬🏽"] = "men_holding_hands_tone3", - ["👨🏽‍🤝‍👨🏾"] = "men_holding_hands_tone3_tone4", - ["👨🏽‍🤝‍👨🏿"] = "men_holding_hands_tone3_tone5", - ["👨🏾‍🤝‍👨🏻"] = "men_holding_hands_tone4_tone1", - ["👨🏾‍🤝‍👨🏼"] = "men_holding_hands_tone4_tone2", - ["👨🏾‍🤝‍👨🏽"] = "men_holding_hands_tone4_tone3", - ["👬🏾"] = "men_holding_hands_tone4", - ["👨🏾‍🤝‍👨🏿"] = "men_holding_hands_tone4_tone5", - ["👨🏿‍🤝‍👨🏻"] = "men_holding_hands_tone5_tone1", - ["👨🏿‍🤝‍👨🏼"] = "men_holding_hands_tone5_tone2", - ["👨🏿‍🤝‍👨🏽"] = "men_holding_hands_tone5_tone3", - ["👨🏿‍🤝‍👨🏾"] = "men_holding_hands_tone5_tone4", - ["👬🏿"] = "men_holding_hands_tone5", - ["💑"] = "couple_with_heart", - ["💑🏻"] = "couple_with_heart_tone1", - ["🧑🏻‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone1_tone2", - ["🧑🏻‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone1_tone3", - ["🧑🏻‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone1_tone4", - ["🧑🏻‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone1_tone5", - ["🧑🏼‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone2_tone1", - ["💑🏼"] = "couple_with_heart_tone2", - ["🧑🏼‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone2_tone3", - ["🧑🏼‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone2_tone4", - ["🧑🏼‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone2_tone5", - ["🧑🏽‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone3_tone1", - ["🧑🏽‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone3_tone2", - ["💑🏽"] = "couple_with_heart_tone3", - ["🧑🏽‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone3_tone4", - ["🧑🏽‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone3_tone5", - ["🧑🏾‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone4_tone1", - ["🧑🏾‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone4_tone2", - ["🧑🏾‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone4_tone3", - ["💑🏾"] = "couple_with_heart_tone4", - ["🧑🏾‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone4_tone5", - ["🧑🏿‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone5_tone1", - ["🧑🏿‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone5_tone2", - ["🧑🏿‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone5_tone3", - ["🧑🏿‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone5_tone4", - ["💑🏿"] = "couple_with_heart_tone5", - ["👩‍❤️‍👨"] = "couple_with_heart_woman_man", - ["👩🏻‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone1", - ["👩🏻‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone1_tone2", - ["👩🏻‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone1_tone3", - ["👩🏻‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone1_tone4", - ["👩🏻‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone1_tone5", - ["👩🏼‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone2_tone1", - ["👩🏼‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone2", - ["👩🏼‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone2_tone3", - ["👩🏼‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone2_tone4", - ["👩🏼‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone2_tone5", - ["👩🏽‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone3_tone1", - ["👩🏽‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone3_tone2", - ["👩🏽‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone3", - ["👩🏽‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone3_tone4", - ["👩🏽‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone3_tone5", - ["👩🏾‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone4_tone1", - ["👩🏾‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone4_tone2", - ["👩🏾‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone4_tone3", - ["👩🏾‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone4", - ["👩🏾‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone4_tone5", - ["👩🏿‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone5_tone1", - ["👩🏿‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone5_tone2", - ["👩🏿‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone5_tone3", - ["👩🏿‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone5_tone4", - ["👩🏿‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone5", - ["👩‍❤️‍👩"] = "couple_ww", - ["👩🏻‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone1", - ["👩🏻‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone1_tone2", - ["👩🏻‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone1_tone3", - ["👩🏻‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone1_tone4", - ["👩🏻‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone1_tone5", - ["👩🏼‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone2_tone1", - ["👩🏼‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone2", - ["👩🏼‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone2_tone3", - ["👩🏼‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone2_tone4", - ["👩🏼‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone2_tone5", - ["👩🏽‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone3_tone1", - ["👩🏽‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone3_tone2", - ["👩🏽‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone3", - ["👩🏽‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone3_tone4", - ["👩🏽‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone3_tone5", - ["👩🏾‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone4_tone1", - ["👩🏾‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone4_tone2", - ["👩🏾‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone4_tone3", - ["👩🏾‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone4", - ["👩🏾‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone4_tone5", - ["👩🏿‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone5_tone1", - ["👩🏿‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone5_tone2", - ["👩🏿‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone5_tone3", - ["👩🏿‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone5_tone4", - ["👩🏿‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone5", - ["👨‍❤️‍👨"] = "couple_mm", - ["👨🏻‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone1", - ["👨🏻‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone1_tone2", - ["👨🏻‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone1_tone3", - ["👨🏻‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone1_tone4", - ["👨🏻‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone1_tone5", - ["👨🏼‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone2_tone1", - ["👨🏼‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone2", - ["👨🏼‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone2_tone3", - ["👨🏼‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone2_tone4", - ["👨🏼‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone2_tone5", - ["👨🏽‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone3_tone1", - ["👨🏽‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone3_tone2", - ["👨🏽‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone3", - ["👨🏽‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone3_tone4", - ["👨🏽‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone3_tone5", - ["👨🏾‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone4_tone1", - ["👨🏾‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone4_tone2", - ["👨🏾‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone4_tone3", - ["👨🏾‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone4", - ["👨🏾‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone4_tone5", - ["👨🏿‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone5_tone1", - ["👨🏿‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone5_tone2", - ["👨🏿‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone5_tone3", - ["👨🏿‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone5_tone4", - ["👨🏿‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone5", - ["💏"] = "couplekiss", - ["🧑🏿‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone5_tone4", - ["💏🏻"] = "kiss_tone1", - ["🧑🏻‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone1_tone2", - ["🧑🏻‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone1_tone3", - ["🧑🏻‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone1_tone4", - ["🧑🏻‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone1_tone5", - ["🧑🏼‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone2_tone1", - ["💏🏼"] = "kiss_tone2", - ["🧑🏼‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone2_tone3", - ["🧑🏼‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone2_tone4", - ["🧑🏼‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone2_tone5", - ["🧑🏽‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone3_tone1", - ["🧑🏽‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone3_tone2", - ["💏🏽"] = "kiss_tone3", - ["🧑🏽‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone3_tone4", - ["🧑🏽‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone3_tone5", - ["🧑🏾‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone4_tone1", - ["🧑🏾‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone4_tone2", - ["🧑🏾‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone4_tone3", - ["💏🏾"] = "kiss_tone4", - ["🧑🏾‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone4_tone5", - ["🧑🏿‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone5_tone1", - ["🧑🏿‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone5_tone2", - ["🧑🏿‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone5_tone3", - ["💏🏿"] = "kiss_tone5", - ["👩‍❤️‍💋‍👨"] = "kiss_woman_man", - ["👩🏻‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone1", - ["👩🏻‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone1_tone2", - ["👩🏻‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone1_tone3", - ["👩🏻‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone1_tone4", - ["👩🏻‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone1_tone5", - ["👩🏼‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone2_tone1", - ["👩🏼‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone2", - ["👩🏼‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone2_tone3", - ["👩🏼‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone2_tone4", - ["👩🏼‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone2_tone5", - ["👩🏽‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone3_tone1", - ["👩🏽‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone3_tone2", - ["👩🏽‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone3", - ["👩🏽‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone3_tone4", - ["👩🏽‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone3_tone5", - ["👩🏾‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone4_tone1", - ["👩🏾‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone4_tone2", - ["👩🏾‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone4_tone3", - ["👩🏾‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone4", - ["👩🏾‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone4_tone5", - ["👩🏿‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone5_tone1", - ["👩🏿‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone5_tone2", - ["👩🏿‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone5_tone3", - ["👩🏿‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone5_tone4", - ["👩🏿‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone5", - ["👩‍❤️‍💋‍👩"] = "kiss_ww", - ["👩🏻‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone1", - ["👩🏻‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone1_tone2", - ["👩🏻‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone1_tone3", - ["👩🏻‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone1_tone4", - ["👩🏻‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone1_tone5", - ["👩🏼‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone2_tone1", - ["👩🏼‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone2", - ["👩🏼‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone2_tone3", - ["👩🏼‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone2_tone4", - ["👩🏼‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone2_tone5", - ["👩🏽‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone3_tone1", - ["👩🏽‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone3_tone2", - ["👩🏽‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone3", - ["👩🏽‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone3_tone4", - ["👩🏽‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone3_tone5", - ["👩🏾‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone4_tone1", - ["👩🏾‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone4_tone2", - ["👩🏾‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone4_tone3", - ["👩🏾‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone4", - ["👩🏾‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone4_tone5", - ["👩🏿‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone5_tone1", - ["👩🏿‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone5_tone2", - ["👩🏿‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone5_tone3", - ["👩🏿‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone5_tone4", - ["👩🏿‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone5", - ["👨‍❤️‍💋‍👨"] = "kiss_mm", - ["👨🏻‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone1", - ["👨🏻‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone1_tone2", - ["👨🏻‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone1_tone3", - ["👨🏻‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone1_tone4", - ["👨🏻‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone1_tone5", - ["👨🏼‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone2_tone1", - ["👨🏼‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone2", - ["👨🏼‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone2_tone3", - ["👨🏼‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone2_tone4", - ["👨🏼‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone2_tone5", - ["👨🏽‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone3_tone1", - ["👨🏽‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone3_tone2", - ["👨🏽‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone3", - ["👨🏽‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone3_tone4", - ["👨🏽‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone3_tone5", - ["👨🏾‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone4_tone1", - ["👨🏾‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone4_tone2", - ["👨🏾‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone4_tone3", - ["👨🏾‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone4", - ["👨🏾‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone4_tone5", - ["👨🏿‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone5_tone1", - ["👨🏿‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone5_tone2", - ["👨🏿‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone5_tone3", - ["👨🏿‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone5_tone4", - ["👨🏿‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone5", - ["👪"] = "family", - ["👨‍👩‍👦"] = "family_man_woman_boy", - ["👨‍👩‍👧"] = "family_mwg", - ["👨‍👩‍👧‍👦"] = "family_mwgb", - ["👨‍👩‍👦‍👦"] = "family_mwbb", - ["👨‍👩‍👧‍👧"] = "family_mwgg", - ["👩‍👩‍👦"] = "family_wwb", - ["👩‍👩‍👧"] = "family_wwg", - ["👩‍👩‍👧‍👦"] = "family_wwgb", - ["👩‍👩‍👦‍👦"] = "family_wwbb", - ["👩‍👩‍👧‍👧"] = "family_wwgg", - ["👨‍👨‍👦"] = "family_mmb", - ["👨‍👨‍👧"] = "family_mmg", - ["👨‍👨‍👧‍👦"] = "family_mmgb", - ["👨‍👨‍👦‍👦"] = "family_mmbb", - ["👨‍👨‍👧‍👧"] = "family_mmgg", - ["👩‍👦"] = "family_woman_boy", - ["👩‍👧"] = "family_woman_girl", - ["👩‍👧‍👦"] = "family_woman_girl_boy", - ["👩‍👦‍👦"] = "family_woman_boy_boy", - ["👩‍👧‍👧"] = "family_woman_girl_girl", - ["👨‍👦"] = "family_man_boy", - ["👨‍👧"] = "family_man_girl", - ["👨‍👧‍👦"] = "family_man_girl_boy", - ["👨‍👦‍👦"] = "family_man_boy_boy", - ["👨‍👧‍👧"] = "family_man_girl_girl", - ["🧶"] = "yarn", - ["🧵"] = "thread", - ["🧥"] = "coat", - ["🥼"] = "lab_coat", - ["🦺"] = "safety_vest", - ["👚"] = "womans_clothes", - ["👕"] = "shirt", - ["👖"] = "jeans", - ["🩲"] = "briefs", - ["🩳"] = "shorts", - ["👔"] = "necktie", - ["👗"] = "dress", - ["👙"] = "bikini", - ["🩱"] = "one_piece_swimsuit", - ["👘"] = "kimono", - ["🥻"] = "sari", - ["🥿"] = "womans_flat_shoe", - ["👠"] = "high_heel", - ["👡"] = "sandal", - ["👢"] = "boot", - ["👞"] = "mans_shoe", - ["👟"] = "athletic_shoe", - ["🥾"] = "hiking_boot", - ["🩴"] = "thong_sandal", - ["🧦"] = "socks", - ["🧤"] = "gloves", - ["🧣"] = "scarf", - ["🎩"] = "tophat", - ["🧢"] = "billed_cap", - ["👒"] = "womans_hat", - ["🎓"] = "mortar_board", - ["⛑️"] = "helmet_with_cross", - ["🪖"] = "military_helmet", - ["👑"] = "crown", - ["💍"] = "ring", - ["👝"] = "pouch", - ["👛"] = "purse", - ["👜"] = "handbag", - ["💼"] = "briefcase", - ["🎒"] = "school_satchel", - ["🧳"] = "luggage", - ["👓"] = "eyeglasses", - ["🕶️"] = "dark_sunglasses", - ["🥽"] = "goggles", - ["🌂"] = "closed_umbrella", - ["🐶"] = "dog", - ["🐱"] = "cat", - ["🐭"] = "mouse", - ["🐹"] = "hamster", - ["🐰"] = "rabbit", - ["🦊"] = "fox", - ["🐻"] = "bear", - ["🐼"] = "panda_face", - ["🐻‍❄️"] = "polar_bear", - ["🐨"] = "koala", - ["🐯"] = "tiger", - ["🦁"] = "lion_face", - ["🐮"] = "cow", - ["🐷"] = "pig", - ["🐽"] = "pig_nose", - ["🐸"] = "frog", - ["🐵"] = "monkey_face", - ["🙈"] = "see_no_evil", - ["🙉"] = "hear_no_evil", - ["🙊"] = "speak_no_evil", - ["🐒"] = "monkey", - ["🐔"] = "chicken", - ["🐧"] = "penguin", - ["🐦"] = "bird", - ["🐤"] = "baby_chick", - ["🐣"] = "hatching_chick", - ["🐥"] = "hatched_chick", - ["🦆"] = "duck", - ["🦤"] = "dodo", - ["🦅"] = "eagle", - ["🦉"] = "owl", - ["🦇"] = "bat", - ["🐺"] = "wolf", - ["🐗"] = "boar", - ["🐴"] = "horse", - ["🦄"] = "unicorn", - ["🐝"] = "bee", - ["🐛"] = "bug", - ["🦋"] = "butterfly", - ["🐌"] = "snail", - ["🪱"] = "worm", - ["🐞"] = "lady_beetle", - ["🐜"] = "ant", - ["🪰"] = "fly", - ["🦟"] = "mosquito", - ["🪳"] = "cockroach", - ["🪲"] = "beetle", - ["🦗"] = "cricket", - ["🕷️"] = "spider", - ["🕸️"] = "spider_web", - ["🦂"] = "scorpion", - ["🐢"] = "turtle", - ["🐍"] = "snake", - ["🦎"] = "lizard", - ["🦖"] = "t_rex", - ["🦕"] = "sauropod", - ["🐙"] = "octopus", - ["🦑"] = "squid", - ["🦐"] = "shrimp", - ["🦞"] = "lobster", - ["🦀"] = "crab", - ["🐡"] = "blowfish", - ["🐠"] = "tropical_fish", - ["🐟"] = "fish", - ["🦭"] = "seal", - ["🐬"] = "dolphin", - ["🐳"] = "whale", - ["🐋"] = "whale2", - ["🦈"] = "shark", - ["🐊"] = "crocodile", - ["🐅"] = "tiger2", - ["🐆"] = "leopard", - ["🦓"] = "zebra", - ["🦍"] = "gorilla", - ["🦧"] = "orangutan", - ["🐘"] = "elephant", - ["🦣"] = "mammoth", - ["🦬"] = "bison", - ["🦛"] = "hippopotamus", - ["🦏"] = "rhino", - ["🐪"] = "dromedary_camel", - ["🐫"] = "camel", - ["🦒"] = "giraffe", - ["🦘"] = "kangaroo", - ["🐃"] = "water_buffalo", - ["🐂"] = "ox", - ["🐄"] = "cow2", - ["🐎"] = "racehorse", - ["🐖"] = "pig2", - ["🐏"] = "ram", - ["🐑"] = "sheep", - ["🦙"] = "llama", - ["🐐"] = "goat", - ["🦌"] = "deer", - ["🐕"] = "dog2", - ["🐩"] = "poodle", - ["🦮"] = "guide_dog", - ["🐕‍🦺"] = "service_dog", - ["🐈"] = "cat2", - ["🐈‍⬛"] = "black_cat", - ["🐓"] = "rooster", - ["🦃"] = "turkey", - ["🦚"] = "peacock", - ["🦜"] = "parrot", - ["🦢"] = "swan", - ["🦩"] = "flamingo", - ["🕊️"] = "dove", - ["🐇"] = "rabbit2", - ["🦝"] = "raccoon", - ["🦨"] = "skunk", - ["🦡"] = "badger", - ["🦫"] = "beaver", - ["🦦"] = "otter", - ["🦥"] = "sloth", - ["🐁"] = "mouse2", - ["🐀"] = "rat", - ["🐿️"] = "chipmunk", - ["🦔"] = "hedgehog", - ["🐾"] = "feet", - ["🐉"] = "dragon", - ["🐲"] = "dragon_face", - ["🌵"] = "cactus", - ["🎄"] = "christmas_tree", - ["🌲"] = "evergreen_tree", - ["🌳"] = "deciduous_tree", - ["🌴"] = "palm_tree", - ["🌱"] = "seedling", - ["🌿"] = "herb", - ["☘️"] = "shamrock", - ["🍀"] = "four_leaf_clover", - ["🎍"] = "bamboo", - ["🎋"] = "tanabata_tree", - ["🍃"] = "leaves", - ["🍂"] = "fallen_leaf", - ["🍁"] = "maple_leaf", - ["🪶"] = "feather", - ["🍄"] = "mushroom", - ["🐚"] = "shell", - ["🪨"] = "rock", - ["🪵"] = "wood", - ["🌾"] = "ear_of_rice", - ["🪴"] = "potted_plant", - ["💐"] = "bouquet", - ["🌷"] = "tulip", - ["🌹"] = "rose", - ["🥀"] = "wilted_rose", - ["🌺"] = "hibiscus", - ["🌸"] = "cherry_blossom", - ["🌼"] = "blossom", - ["🌻"] = "sunflower", - ["🌞"] = "sun_with_face", - ["🌝"] = "full_moon_with_face", - ["🌛"] = "first_quarter_moon_with_face", - ["🌜"] = "last_quarter_moon_with_face", - ["🌚"] = "new_moon_with_face", - ["🌕"] = "full_moon", - ["🌖"] = "waning_gibbous_moon", - ["🌗"] = "last_quarter_moon", - ["🌘"] = "waning_crescent_moon", - ["🌑"] = "new_moon", - ["🌒"] = "waxing_crescent_moon", - ["🌓"] = "first_quarter_moon", - ["🌔"] = "waxing_gibbous_moon", - ["🌙"] = "crescent_moon", - ["🌎"] = "earth_americas", - ["🌍"] = "earth_africa", - ["🌏"] = "earth_asia", - ["🪐"] = "ringed_planet", - ["💫"] = "dizzy", - ["⭐"] = "star", - ["🌟"] = "star2", - ["✨"] = "sparkles", - ["⚡"] = "zap", - ["☄️"] = "comet", - ["💥"] = "boom", - ["🔥"] = "fire", - ["🌪️"] = "cloud_tornado", - ["🌈"] = "rainbow", - ["☀️"] = "sunny", - ["🌤️"] = "white_sun_small_cloud", - ["⛅"] = "partly_sunny", - ["🌥️"] = "white_sun_cloud", - ["☁️"] = "cloud", - ["🌦️"] = "white_sun_rain_cloud", - ["🌧️"] = "cloud_rain", - ["⛈️"] = "thunder_cloud_rain", - ["🌩️"] = "cloud_lightning", - ["🌨️"] = "cloud_snow", - ["❄️"] = "snowflake", - ["☃️"] = "snowman2", - ["⛄"] = "snowman", - ["🌬️"] = "wind_blowing_face", - ["💨"] = "dash", - ["💧"] = "droplet", - ["💦"] = "sweat_drops", - ["☔"] = "umbrella", - ["☂️"] = "umbrella2", - ["🌊"] = "ocean", - ["🌫️"] = "fog", - ["🍏"] = "green_apple", - ["🍎"] = "apple", - ["🍐"] = "pear", - ["🍊"] = "tangerine", - ["🍋"] = "lemon", - ["🍌"] = "banana", - ["🍉"] = "watermelon", - ["🍇"] = "grapes", - ["🫐"] = "blueberries", - ["🍓"] = "strawberry", - ["🍈"] = "melon", - ["🍒"] = "cherries", - ["🍑"] = "peach", - ["🥭"] = "mango", - ["🍍"] = "pineapple", - ["🥥"] = "coconut", - ["🥝"] = "kiwi", - ["🍅"] = "tomato", - ["🍆"] = "eggplant", - ["🥑"] = "avocado", - ["🫒"] = "olive", - ["🥦"] = "broccoli", - ["🥬"] = "leafy_green", - ["🫑"] = "bell_pepper", - ["🥒"] = "cucumber", - ["🌶️"] = "hot_pepper", - ["🌽"] = "corn", - ["🥕"] = "carrot", - ["🧄"] = "garlic", - ["🧅"] = "onion", - ["🥔"] = "potato", - ["🍠"] = "sweet_potato", - ["🥐"] = "croissant", - ["🥯"] = "bagel", - ["🍞"] = "bread", - ["🥖"] = "french_bread", - ["🫓"] = "flatbread", - ["🥨"] = "pretzel", - ["🧀"] = "cheese", - ["🥚"] = "egg", - ["🍳"] = "cooking", - ["🧈"] = "butter", - ["🥞"] = "pancakes", - ["🧇"] = "waffle", - ["🥓"] = "bacon", - ["🥩"] = "cut_of_meat", - ["🍗"] = "poultry_leg", - ["🍖"] = "meat_on_bone", - ["🌭"] = "hotdog", - ["🍔"] = "hamburger", - ["🍟"] = "fries", - ["🍕"] = "pizza", - ["🥪"] = "sandwich", - ["🥙"] = "stuffed_flatbread", - ["🧆"] = "falafel", - ["🌮"] = "taco", - ["🌯"] = "burrito", - ["🫔"] = "tamale", - ["🥗"] = "salad", - ["🥘"] = "shallow_pan_of_food", - ["🫕"] = "fondue", - ["🥫"] = "canned_food", - ["🍝"] = "spaghetti", - ["🍜"] = "ramen", - ["🍲"] = "stew", - ["🍛"] = "curry", - ["🍣"] = "sushi", - ["🍱"] = "bento", - ["🥟"] = "dumpling", - ["🦪"] = "oyster", - ["🍤"] = "fried_shrimp", - ["🍙"] = "rice_ball", - ["🍚"] = "rice", - ["🍘"] = "rice_cracker", - ["🍥"] = "fish_cake", - ["🥠"] = "fortune_cookie", - ["🥮"] = "moon_cake", - ["🍢"] = "oden", - ["🍡"] = "dango", - ["🍧"] = "shaved_ice", - ["🍨"] = "ice_cream", - ["🍦"] = "icecream", - ["🥧"] = "pie", - ["🧁"] = "cupcake", - ["🍰"] = "cake", - ["🎂"] = "birthday", - ["🍮"] = "custard", - ["🍭"] = "lollipop", - ["🍬"] = "candy", - ["🍫"] = "chocolate_bar", - ["🍿"] = "popcorn", - ["🍩"] = "doughnut", - ["🍪"] = "cookie", - ["🌰"] = "chestnut", - ["🥜"] = "peanuts", - ["🍯"] = "honey_pot", - ["🥛"] = "milk", - ["🍼"] = "baby_bottle", - ["☕"] = "coffee", - ["🍵"] = "tea", - ["🫖"] = "teapot", - ["🧉"] = "mate", - ["🧋"] = "bubble_tea", - ["🧃"] = "beverage_box", - ["🥤"] = "cup_with_straw", - ["🍶"] = "sake", - ["🍺"] = "beer", - ["🍻"] = "beers", - ["🥂"] = "champagne_glass", - ["🍷"] = "wine_glass", - ["🥃"] = "tumbler_glass", - ["🍸"] = "cocktail", - ["🍹"] = "tropical_drink", - ["🍾"] = "champagne", - ["🧊"] = "ice_cube", - ["🥄"] = "spoon", - ["🍴"] = "fork_and_knife", - ["🍽️"] = "fork_knife_plate", - ["🥣"] = "bowl_with_spoon", - ["🥡"] = "takeout_box", - ["🥢"] = "chopsticks", - ["🧂"] = "salt", - ["⚽"] = "soccer", - ["🏀"] = "basketball", - ["🏈"] = "football", - ["⚾"] = "baseball", - ["🥎"] = "softball", - ["🎾"] = "tennis", - ["🏐"] = "volleyball", - ["🏉"] = "rugby_football", - ["🥏"] = "flying_disc", - ["🪃"] = "boomerang", - ["🎱"] = "8ball", - ["🪀"] = "yo_yo", - ["🏓"] = "ping_pong", - ["🏸"] = "badminton", - ["🏒"] = "hockey", - ["🏑"] = "field_hockey", - ["🥍"] = "lacrosse", - ["🏏"] = "cricket_game", - ["🥅"] = "goal", - ["⛳"] = "golf", - ["🪁"] = "kite", - ["🏹"] = "bow_and_arrow", - ["🎣"] = "fishing_pole_and_fish", - ["🤿"] = "diving_mask", - ["🥊"] = "boxing_glove", - ["🥋"] = "martial_arts_uniform", - ["🎽"] = "running_shirt_with_sash", - ["🛹"] = "skateboard", - ["🛼"] = "roller_skate", - ["🛷"] = "sled", - ["⛸️"] = "ice_skate", - ["🥌"] = "curling_stone", - ["🎿"] = "ski", - ["⛷️"] = "skier", - ["🏂"] = "snowboarder", - ["🏂🏻"] = "snowboarder_tone1", - ["🏂🏼"] = "snowboarder_tone2", - ["🏂🏽"] = "snowboarder_tone3", - ["🏂🏾"] = "snowboarder_tone4", - ["🏂🏿"] = "snowboarder_tone5", - ["🪂"] = "parachute", - ["🏋️"] = "person_lifting_weights", - ["🏋🏻"] = "person_lifting_weights_tone1", - ["🏋🏼"] = "person_lifting_weights_tone2", - ["🏋🏽"] = "person_lifting_weights_tone3", - ["🏋🏾"] = "person_lifting_weights_tone4", - ["🏋🏿"] = "person_lifting_weights_tone5", - ["🏋️‍♀️"] = "woman_lifting_weights", - ["🏋🏻‍♀️"] = "woman_lifting_weights_tone1", - ["🏋🏼‍♀️"] = "woman_lifting_weights_tone2", - ["🏋🏽‍♀️"] = "woman_lifting_weights_tone3", - ["🏋🏾‍♀️"] = "woman_lifting_weights_tone4", - ["🏋🏿‍♀️"] = "woman_lifting_weights_tone5", - ["🏋️‍♂️"] = "man_lifting_weights", - ["🏋🏻‍♂️"] = "man_lifting_weights_tone1", - ["🏋🏼‍♂️"] = "man_lifting_weights_tone2", - ["🏋🏽‍♂️"] = "man_lifting_weights_tone3", - ["🏋🏾‍♂️"] = "man_lifting_weights_tone4", - ["🏋🏿‍♂️"] = "man_lifting_weights_tone5", - ["🤼"] = "people_wrestling", - ["🤼‍♀️"] = "women_wrestling", - ["🤼‍♂️"] = "men_wrestling", - ["🤸"] = "person_doing_cartwheel", - ["🤸🏻"] = "person_doing_cartwheel_tone1", - ["🤸🏼"] = "person_doing_cartwheel_tone2", - ["🤸🏽"] = "person_doing_cartwheel_tone3", - ["🤸🏾"] = "person_doing_cartwheel_tone4", - ["🤸🏿"] = "person_doing_cartwheel_tone5", - ["🤸‍♀️"] = "woman_cartwheeling", - ["🤸🏻‍♀️"] = "woman_cartwheeling_tone1", - ["🤸🏼‍♀️"] = "woman_cartwheeling_tone2", - ["🤸🏽‍♀️"] = "woman_cartwheeling_tone3", - ["🤸🏾‍♀️"] = "woman_cartwheeling_tone4", - ["🤸🏿‍♀️"] = "woman_cartwheeling_tone5", - ["🤸‍♂️"] = "man_cartwheeling", - ["🤸🏻‍♂️"] = "man_cartwheeling_tone1", - ["🤸🏼‍♂️"] = "man_cartwheeling_tone2", - ["🤸🏽‍♂️"] = "man_cartwheeling_tone3", - ["🤸🏾‍♂️"] = "man_cartwheeling_tone4", - ["🤸🏿‍♂️"] = "man_cartwheeling_tone5", - ["⛹️"] = "person_bouncing_ball", - ["⛹🏻"] = "person_bouncing_ball_tone1", - ["⛹🏼"] = "person_bouncing_ball_tone2", - ["⛹🏽"] = "person_bouncing_ball_tone3", - ["⛹🏾"] = "person_bouncing_ball_tone4", - ["⛹🏿"] = "person_bouncing_ball_tone5", - ["⛹️‍♀️"] = "woman_bouncing_ball", - ["⛹🏻‍♀️"] = "woman_bouncing_ball_tone1", - ["⛹🏼‍♀️"] = "woman_bouncing_ball_tone2", - ["⛹🏽‍♀️"] = "woman_bouncing_ball_tone3", - ["⛹🏾‍♀️"] = "woman_bouncing_ball_tone4", - ["⛹🏿‍♀️"] = "woman_bouncing_ball_tone5", - ["⛹️‍♂️"] = "man_bouncing_ball", - ["⛹🏻‍♂️"] = "man_bouncing_ball_tone1", - ["⛹🏼‍♂️"] = "man_bouncing_ball_tone2", - ["⛹🏽‍♂️"] = "man_bouncing_ball_tone3", - ["⛹🏾‍♂️"] = "man_bouncing_ball_tone4", - ["⛹🏿‍♂️"] = "man_bouncing_ball_tone5", - ["🤺"] = "person_fencing", - ["🤾"] = "person_playing_handball", - ["🤾🏻"] = "person_playing_handball_tone1", - ["🤾🏼"] = "person_playing_handball_tone2", - ["🤾🏽"] = "person_playing_handball_tone3", - ["🤾🏾"] = "person_playing_handball_tone4", - ["🤾🏿"] = "person_playing_handball_tone5", - ["🤾‍♀️"] = "woman_playing_handball", - ["🤾🏻‍♀️"] = "woman_playing_handball_tone1", - ["🤾🏼‍♀️"] = "woman_playing_handball_tone2", - ["🤾🏽‍♀️"] = "woman_playing_handball_tone3", - ["🤾🏾‍♀️"] = "woman_playing_handball_tone4", - ["🤾🏿‍♀️"] = "woman_playing_handball_tone5", - ["🤾‍♂️"] = "man_playing_handball", - ["🤾🏻‍♂️"] = "man_playing_handball_tone1", - ["🤾🏼‍♂️"] = "man_playing_handball_tone2", - ["🤾🏽‍♂️"] = "man_playing_handball_tone3", - ["🤾🏾‍♂️"] = "man_playing_handball_tone4", - ["🤾🏿‍♂️"] = "man_playing_handball_tone5", - ["🏌️"] = "person_golfing", - ["🏌🏻"] = "person_golfing_tone1", - ["🏌🏼"] = "person_golfing_tone2", - ["🏌🏽"] = "person_golfing_tone3", - ["🏌🏾"] = "person_golfing_tone4", - ["🏌🏿"] = "person_golfing_tone5", - ["🏌️‍♀️"] = "woman_golfing", - ["🏌🏻‍♀️"] = "woman_golfing_tone1", - ["🏌🏼‍♀️"] = "woman_golfing_tone2", - ["🏌🏽‍♀️"] = "woman_golfing_tone3", - ["🏌🏾‍♀️"] = "woman_golfing_tone4", - ["🏌🏿‍♀️"] = "woman_golfing_tone5", - ["🏌️‍♂️"] = "man_golfing", - ["🏌🏻‍♂️"] = "man_golfing_tone1", - ["🏌🏼‍♂️"] = "man_golfing_tone2", - ["🏌🏽‍♂️"] = "man_golfing_tone3", - ["🏌🏾‍♂️"] = "man_golfing_tone4", - ["🏌🏿‍♂️"] = "man_golfing_tone5", - ["🏇"] = "horse_racing", - ["🏇🏻"] = "horse_racing_tone1", - ["🏇🏼"] = "horse_racing_tone2", - ["🏇🏽"] = "horse_racing_tone3", - ["🏇🏾"] = "horse_racing_tone4", - ["🏇🏿"] = "horse_racing_tone5", - ["🧘"] = "person_in_lotus_position", - ["🧘🏻"] = "person_in_lotus_position_tone1", - ["🧘🏼"] = "person_in_lotus_position_tone2", - ["🧘🏽"] = "person_in_lotus_position_tone3", - ["🧘🏾"] = "person_in_lotus_position_tone4", - ["🧘🏿"] = "person_in_lotus_position_tone5", - ["🧘‍♀️"] = "woman_in_lotus_position", - ["🧘🏻‍♀️"] = "woman_in_lotus_position_tone1", - ["🧘🏼‍♀️"] = "woman_in_lotus_position_tone2", - ["🧘🏽‍♀️"] = "woman_in_lotus_position_tone3", - ["🧘🏾‍♀️"] = "woman_in_lotus_position_tone4", - ["🧘🏿‍♀️"] = "woman_in_lotus_position_tone5", - ["🧘‍♂️"] = "man_in_lotus_position", - ["🧘🏻‍♂️"] = "man_in_lotus_position_tone1", - ["🧘🏼‍♂️"] = "man_in_lotus_position_tone2", - ["🧘🏽‍♂️"] = "man_in_lotus_position_tone3", - ["🧘🏾‍♂️"] = "man_in_lotus_position_tone4", - ["🧘🏿‍♂️"] = "man_in_lotus_position_tone5", - ["🏄"] = "person_surfing", - ["🏄🏻"] = "person_surfing_tone1", - ["🏄🏼"] = "person_surfing_tone2", - ["🏄🏽"] = "person_surfing_tone3", - ["🏄🏾"] = "person_surfing_tone4", - ["🏄🏿"] = "person_surfing_tone5", - ["🏄‍♀️"] = "woman_surfing", - ["🏄🏻‍♀️"] = "woman_surfing_tone1", - ["🏄🏼‍♀️"] = "woman_surfing_tone2", - ["🏄🏽‍♀️"] = "woman_surfing_tone3", - ["🏄🏾‍♀️"] = "woman_surfing_tone4", - ["🏄🏿‍♀️"] = "woman_surfing_tone5", - ["🏄‍♂️"] = "man_surfing", - ["🏄🏻‍♂️"] = "man_surfing_tone1", - ["🏄🏼‍♂️"] = "man_surfing_tone2", - ["🏄🏽‍♂️"] = "man_surfing_tone3", - ["🏄🏾‍♂️"] = "man_surfing_tone4", - ["🏄🏿‍♂️"] = "man_surfing_tone5", - ["🏊"] = "person_swimming", - ["🏊🏻"] = "person_swimming_tone1", - ["🏊🏼"] = "person_swimming_tone2", - ["🏊🏽"] = "person_swimming_tone3", - ["🏊🏾"] = "person_swimming_tone4", - ["🏊🏿"] = "person_swimming_tone5", - ["🏊‍♀️"] = "woman_swimming", - ["🏊🏻‍♀️"] = "woman_swimming_tone1", - ["🏊🏼‍♀️"] = "woman_swimming_tone2", - ["🏊🏽‍♀️"] = "woman_swimming_tone3", - ["🏊🏾‍♀️"] = "woman_swimming_tone4", - ["🏊🏿‍♀️"] = "woman_swimming_tone5", - ["🏊‍♂️"] = "man_swimming", - ["🏊🏻‍♂️"] = "man_swimming_tone1", - ["🏊🏼‍♂️"] = "man_swimming_tone2", - ["🏊🏽‍♂️"] = "man_swimming_tone3", - ["🏊🏾‍♂️"] = "man_swimming_tone4", - ["🏊🏿‍♂️"] = "man_swimming_tone5", - ["🤽"] = "person_playing_water_polo", - ["🤽🏻"] = "person_playing_water_polo_tone1", - ["🤽🏼"] = "person_playing_water_polo_tone2", - ["🤽🏽"] = "person_playing_water_polo_tone3", - ["🤽🏾"] = "person_playing_water_polo_tone4", - ["🤽🏿"] = "person_playing_water_polo_tone5", - ["🤽‍♀️"] = "woman_playing_water_polo", - ["🤽🏻‍♀️"] = "woman_playing_water_polo_tone1", - ["🤽🏼‍♀️"] = "woman_playing_water_polo_tone2", - ["🤽🏽‍♀️"] = "woman_playing_water_polo_tone3", - ["🤽🏾‍♀️"] = "woman_playing_water_polo_tone4", - ["🤽🏿‍♀️"] = "woman_playing_water_polo_tone5", - ["🤽‍♂️"] = "man_playing_water_polo", - ["🤽🏻‍♂️"] = "man_playing_water_polo_tone1", - ["🤽🏼‍♂️"] = "man_playing_water_polo_tone2", - ["🤽🏽‍♂️"] = "man_playing_water_polo_tone3", - ["🤽🏾‍♂️"] = "man_playing_water_polo_tone4", - ["🤽🏿‍♂️"] = "man_playing_water_polo_tone5", - ["🚣"] = "person_rowing_boat", - ["🚣🏻"] = "person_rowing_boat_tone1", - ["🚣🏼"] = "person_rowing_boat_tone2", - ["🚣🏽"] = "person_rowing_boat_tone3", - ["🚣🏾"] = "person_rowing_boat_tone4", - ["🚣🏿"] = "person_rowing_boat_tone5", - ["🚣‍♀️"] = "woman_rowing_boat", - ["🚣🏻‍♀️"] = "woman_rowing_boat_tone1", - ["🚣🏼‍♀️"] = "woman_rowing_boat_tone2", - ["🚣🏽‍♀️"] = "woman_rowing_boat_tone3", - ["🚣🏾‍♀️"] = "woman_rowing_boat_tone4", - ["🚣🏿‍♀️"] = "woman_rowing_boat_tone5", - ["🚣‍♂️"] = "man_rowing_boat", - ["🚣🏻‍♂️"] = "man_rowing_boat_tone1", - ["🚣🏼‍♂️"] = "man_rowing_boat_tone2", - ["🚣🏽‍♂️"] = "man_rowing_boat_tone3", - ["🚣🏾‍♂️"] = "man_rowing_boat_tone4", - ["🚣🏿‍♂️"] = "man_rowing_boat_tone5", - ["🧗"] = "person_climbing", - ["🧗🏻"] = "person_climbing_tone1", - ["🧗🏼"] = "person_climbing_tone2", - ["🧗🏽"] = "person_climbing_tone3", - ["🧗🏾"] = "person_climbing_tone4", - ["🧗🏿"] = "person_climbing_tone5", - ["🧗‍♀️"] = "woman_climbing", - ["🧗🏻‍♀️"] = "woman_climbing_tone1", - ["🧗🏼‍♀️"] = "woman_climbing_tone2", - ["🧗🏽‍♀️"] = "woman_climbing_tone3", - ["🧗🏾‍♀️"] = "woman_climbing_tone4", - ["🧗🏿‍♀️"] = "woman_climbing_tone5", - ["🧗‍♂️"] = "man_climbing", - ["🧗🏻‍♂️"] = "man_climbing_tone1", - ["🧗🏼‍♂️"] = "man_climbing_tone2", - ["🧗🏽‍♂️"] = "man_climbing_tone3", - ["🧗🏾‍♂️"] = "man_climbing_tone4", - ["🧗🏿‍♂️"] = "man_climbing_tone5", - ["🚵"] = "person_mountain_biking", - ["🚵🏻"] = "person_mountain_biking_tone1", - ["🚵🏼"] = "person_mountain_biking_tone2", - ["🚵🏽"] = "person_mountain_biking_tone3", - ["🚵🏾"] = "person_mountain_biking_tone4", - ["🚵🏿"] = "person_mountain_biking_tone5", - ["🚵‍♀️"] = "woman_mountain_biking", - ["🚵🏻‍♀️"] = "woman_mountain_biking_tone1", - ["🚵🏼‍♀️"] = "woman_mountain_biking_tone2", - ["🚵🏽‍♀️"] = "woman_mountain_biking_tone3", - ["🚵🏾‍♀️"] = "woman_mountain_biking_tone4", - ["🚵🏿‍♀️"] = "woman_mountain_biking_tone5", - ["🚵‍♂️"] = "man_mountain_biking", - ["🚵🏻‍♂️"] = "man_mountain_biking_tone1", - ["🚵🏼‍♂️"] = "man_mountain_biking_tone2", - ["🚵🏽‍♂️"] = "man_mountain_biking_tone3", - ["🚵🏾‍♂️"] = "man_mountain_biking_tone4", - ["🚵🏿‍♂️"] = "man_mountain_biking_tone5", - ["🚴"] = "person_biking", - ["🚴🏻"] = "person_biking_tone1", - ["🚴🏼"] = "person_biking_tone2", - ["🚴🏽"] = "person_biking_tone3", - ["🚴🏾"] = "person_biking_tone4", - ["🚴🏿"] = "person_biking_tone5", - ["🚴‍♀️"] = "woman_biking", - ["🚴🏻‍♀️"] = "woman_biking_tone1", - ["🚴🏼‍♀️"] = "woman_biking_tone2", - ["🚴🏽‍♀️"] = "woman_biking_tone3", - ["🚴🏾‍♀️"] = "woman_biking_tone4", - ["🚴🏿‍♀️"] = "woman_biking_tone5", - ["🚴‍♂️"] = "man_biking", - ["🚴🏻‍♂️"] = "man_biking_tone1", - ["🚴🏼‍♂️"] = "man_biking_tone2", - ["🚴🏽‍♂️"] = "man_biking_tone3", - ["🚴🏾‍♂️"] = "man_biking_tone4", - ["🚴🏿‍♂️"] = "man_biking_tone5", - ["🏆"] = "trophy", - ["🥇"] = "first_place", - ["🥈"] = "second_place", - ["🥉"] = "third_place", - ["🏅"] = "medal", - ["🎖️"] = "military_medal", - ["🏵️"] = "rosette", - ["🎗️"] = "reminder_ribbon", - ["🎫"] = "ticket", - ["🎟️"] = "tickets", - ["🎪"] = "circus_tent", - ["🤹"] = "person_juggling", - ["🤹🏻"] = "person_juggling_tone1", - ["🤹🏼"] = "person_juggling_tone2", - ["🤹🏽"] = "person_juggling_tone3", - ["🤹🏾"] = "person_juggling_tone4", - ["🤹🏿"] = "person_juggling_tone5", - ["🤹‍♀️"] = "woman_juggling", - ["🤹🏻‍♀️"] = "woman_juggling_tone1", - ["🤹🏼‍♀️"] = "woman_juggling_tone2", - ["🤹🏽‍♀️"] = "woman_juggling_tone3", - ["🤹🏾‍♀️"] = "woman_juggling_tone4", - ["🤹🏿‍♀️"] = "woman_juggling_tone5", - ["🤹‍♂️"] = "man_juggling", - ["🤹🏻‍♂️"] = "man_juggling_tone1", - ["🤹🏼‍♂️"] = "man_juggling_tone2", - ["🤹🏽‍♂️"] = "man_juggling_tone3", - ["🤹🏾‍♂️"] = "man_juggling_tone4", - ["🤹🏿‍♂️"] = "man_juggling_tone5", - ["🎭"] = "performing_arts", - ["🩰"] = "ballet_shoes", - ["🎨"] = "art", - ["🎬"] = "clapper", - ["🎤"] = "microphone", - ["🎧"] = "headphones", - ["🎼"] = "musical_score", - ["🎹"] = "musical_keyboard", - ["🥁"] = "drum", - ["🪘"] = "long_drum", - ["🎷"] = "saxophone", - ["🎺"] = "trumpet", - ["🎸"] = "guitar", - ["🪕"] = "banjo", - ["🎻"] = "violin", - ["🪗"] = "accordion", - ["🎲"] = "game_die", - ["♟️"] = "chess_pawn", - ["🎯"] = "dart", - ["🎳"] = "bowling", - ["🎮"] = "video_game", - ["🎰"] = "slot_machine", - ["🧩"] = "jigsaw", - ["🚗"] = "red_car", - ["🚕"] = "taxi", - ["🚙"] = "blue_car", - ["🛻"] = "pickup_truck", - ["🚌"] = "bus", - ["🚎"] = "trolleybus", - ["🏎️"] = "race_car", - ["🚓"] = "police_car", - ["🚑"] = "ambulance", - ["🚒"] = "fire_engine", - ["🚐"] = "minibus", - ["🚚"] = "truck", - ["🚛"] = "articulated_lorry", - ["🚜"] = "tractor", - ["🦯"] = "probing_cane", - ["🦽"] = "manual_wheelchair", - ["🦼"] = "motorized_wheelchair", - ["🛴"] = "scooter", - ["🚲"] = "bike", - ["🛵"] = "motor_scooter", - ["🏍️"] = "motorcycle", - ["🛺"] = "auto_rickshaw", - ["🚨"] = "rotating_light", - ["🚔"] = "oncoming_police_car", - ["🚍"] = "oncoming_bus", - ["🚘"] = "oncoming_automobile", - ["🚖"] = "oncoming_taxi", - ["🚡"] = "aerial_tramway", - ["🚠"] = "mountain_cableway", - ["🚟"] = "suspension_railway", - ["🚃"] = "railway_car", - ["🚋"] = "train", - ["🚞"] = "mountain_railway", - ["🚝"] = "monorail", - ["🚄"] = "bullettrain_side", - ["🚅"] = "bullettrain_front", - ["🚈"] = "light_rail", - ["🚂"] = "steam_locomotive", - ["🚆"] = "train2", - ["🚇"] = "metro", - ["🚊"] = "tram", - ["🚉"] = "station", - ["✈️"] = "airplane", - ["🛫"] = "airplane_departure", - ["🛬"] = "airplane_arriving", - ["🛩️"] = "airplane_small", - ["💺"] = "seat", - ["🛰️"] = "satellite_orbital", - ["🚀"] = "rocket", - ["🛸"] = "flying_saucer", - ["🚁"] = "helicopter", - ["🛶"] = "canoe", - ["⛵"] = "sailboat", - ["🚤"] = "speedboat", - ["🛥️"] = "motorboat", - ["🛳️"] = "cruise_ship", - ["⛴️"] = "ferry", - ["🚢"] = "ship", - ["⚓"] = "anchor", - ["⛽"] = "fuelpump", - ["🚧"] = "construction", - ["🚦"] = "vertical_traffic_light", - ["🚥"] = "traffic_light", - ["🚏"] = "busstop", - ["🗺️"] = "map", - ["🗿"] = "moyai", - ["🗽"] = "statue_of_liberty", - ["🗼"] = "tokyo_tower", - ["🏰"] = "european_castle", - ["🏯"] = "japanese_castle", - ["🏟️"] = "stadium", - ["🎡"] = "ferris_wheel", - ["🎢"] = "roller_coaster", - ["🎠"] = "carousel_horse", - ["⛲"] = "fountain", - ["⛱️"] = "beach_umbrella", - ["🏖️"] = "beach", - ["🏝️"] = "island", - ["🏜️"] = "desert", - ["🌋"] = "volcano", - ["⛰️"] = "mountain", - ["🏔️"] = "mountain_snow", - ["🗻"] = "mount_fuji", - ["🏕️"] = "camping", - ["⛺"] = "tent", - ["🏠"] = "house", - ["🏡"] = "house_with_garden", - ["🏘️"] = "homes", - ["🏚️"] = "house_abandoned", - ["🛖"] = "hut", - ["🏗️"] = "construction_site", - ["🏭"] = "factory", - ["🏢"] = "office", - ["🏬"] = "department_store", - ["🏣"] = "post_office", - ["🏤"] = "european_post_office", - ["🏥"] = "hospital", - ["🏦"] = "bank", - ["🏨"] = "hotel", - ["🏪"] = "convenience_store", - ["🏫"] = "school", - ["🏩"] = "love_hotel", - ["💒"] = "wedding", - ["🏛️"] = "classical_building", - ["⛪"] = "church", - ["🕌"] = "mosque", - ["🕍"] = "synagogue", - ["🛕"] = "hindu_temple", - ["🕋"] = "kaaba", - ["⛩️"] = "shinto_shrine", - ["🛤️"] = "railway_track", - ["🛣️"] = "motorway", - ["🗾"] = "japan", - ["🎑"] = "rice_scene", - ["🏞️"] = "park", - ["🌅"] = "sunrise", - ["🌄"] = "sunrise_over_mountains", - ["🌠"] = "stars", - ["🎇"] = "sparkler", - ["🎆"] = "fireworks", - ["🌇"] = "city_sunset", - ["🌆"] = "city_dusk", - ["🏙️"] = "cityscape", - ["🌃"] = "night_with_stars", - ["🌌"] = "milky_way", - ["🌉"] = "bridge_at_night", - ["🌁"] = "foggy", - ["⌚"] = "watch", - ["📱"] = "mobile_phone", - ["📲"] = "calling", - ["💻"] = "computer", - ["⌨️"] = "keyboard", - ["🖥️"] = "desktop", - ["🖨️"] = "printer", - ["🖱️"] = "mouse_three_button", - ["🖲️"] = "trackball", - ["🕹️"] = "joystick", - ["🗜️"] = "compression", - ["💽"] = "minidisc", - ["💾"] = "floppy_disk", - ["💿"] = "cd", - ["📀"] = "dvd", - ["📼"] = "vhs", - ["📷"] = "camera", - ["📸"] = "camera_with_flash", - ["📹"] = "video_camera", - ["🎥"] = "movie_camera", - ["📽️"] = "projector", - ["🎞️"] = "film_frames", - ["📞"] = "telephone_receiver", - ["☎️"] = "telephone", - ["📟"] = "pager", - ["📠"] = "fax", - ["📺"] = "tv", - ["📻"] = "radio", - ["🎙️"] = "microphone2", - ["🎚️"] = "level_slider", - ["🎛️"] = "control_knobs", - ["🧭"] = "compass", - ["⏱️"] = "stopwatch", - ["⏲️"] = "timer", - ["⏰"] = "alarm_clock", - ["🕰️"] = "clock", - ["⌛"] = "hourglass", - ["⏳"] = "hourglass_flowing_sand", - ["📡"] = "satellite", - ["🔋"] = "battery", - ["🔌"] = "electric_plug", - ["💡"] = "bulb", - ["🔦"] = "flashlight", - ["🕯️"] = "candle", - ["🪔"] = "diya_lamp", - ["🧯"] = "fire_extinguisher", - ["🛢️"] = "oil", - ["💸"] = "money_with_wings", - ["💵"] = "dollar", - ["💴"] = "yen", - ["💶"] = "euro", - ["💷"] = "pound", - ["🪙"] = "coin", - ["💰"] = "moneybag", - ["💳"] = "credit_card", - ["💎"] = "gem", - ["⚖️"] = "scales", - ["🪜"] = "ladder", - ["🧰"] = "toolbox", - ["🪛"] = "screwdriver", - ["🔧"] = "wrench", - ["🔨"] = "hammer", - ["⚒️"] = "hammer_pick", - ["🛠️"] = "tools", - ["⛏️"] = "pick", - ["🔩"] = "nut_and_bolt", - ["⚙️"] = "gear", - ["🧱"] = "bricks", - ["⛓️"] = "chains", - ["🪝"] = "hook", - ["🪢"] = "knot", - ["🧲"] = "magnet", - ["🔫"] = "gun", - ["💣"] = "bomb", - ["🧨"] = "firecracker", - ["🪓"] = "axe", - ["🪚"] = "carpentry_saw", - ["🔪"] = "knife", - ["🗡️"] = "dagger", - ["⚔️"] = "crossed_swords", - ["🛡️"] = "shield", - ["🚬"] = "smoking", - ["⚰️"] = "coffin", - ["🪦"] = "headstone", - ["⚱️"] = "urn", - ["🏺"] = "amphora", - ["🪄"] = "magic_wand", - ["🔮"] = "crystal_ball", - ["📿"] = "prayer_beads", - ["🧿"] = "nazar_amulet", - ["💈"] = "barber", - ["⚗️"] = "alembic", - ["🔭"] = "telescope", - ["🔬"] = "microscope", - ["🕳️"] = "hole", - ["🪟"] = "window", - ["🩹"] = "adhesive_bandage", - ["🩺"] = "stethoscope", - ["💊"] = "pill", - ["💉"] = "syringe", - ["🩸"] = "drop_of_blood", - ["🧬"] = "dna", - ["🦠"] = "microbe", - ["🧫"] = "petri_dish", - ["🧪"] = "test_tube", - ["🌡️"] = "thermometer", - ["🪤"] = "mouse_trap", - ["🧹"] = "broom", - ["🧺"] = "basket", - ["🪡"] = "sewing_needle", - ["🧻"] = "roll_of_paper", - ["🚽"] = "toilet", - ["🪠"] = "plunger", - ["🪣"] = "bucket", - ["🚰"] = "potable_water", - ["🚿"] = "shower", - ["🛁"] = "bathtub", - ["🛀"] = "bath", - ["🛀🏻"] = "bath_tone1", - ["🛀🏼"] = "bath_tone2", - ["🛀🏽"] = "bath_tone3", - ["🛀🏾"] = "bath_tone4", - ["🛀🏿"] = "bath_tone5", - ["🪥"] = "toothbrush", - ["🧼"] = "soap", - ["🪒"] = "razor", - ["🧽"] = "sponge", - ["🧴"] = "squeeze_bottle", - ["🛎️"] = "bellhop", - ["🔑"] = "key", - ["🗝️"] = "key2", - ["🚪"] = "door", - ["🪑"] = "chair", - ["🪞"] = "mirror", - ["🛋️"] = "couch", - ["🛏️"] = "bed", - ["🛌"] = "sleeping_accommodation", - ["🛌🏻"] = "person_in_bed_tone1", - ["🛌🏼"] = "person_in_bed_tone2", - ["🛌🏽"] = "person_in_bed_tone3", - ["🛌🏾"] = "person_in_bed_tone4", - ["🛌🏿"] = "person_in_bed_tone5", - ["🧸"] = "teddy_bear", - ["🖼️"] = "frame_photo", - ["🛍️"] = "shopping_bags", - ["🛒"] = "shopping_cart", - ["🎁"] = "gift", - ["🎈"] = "balloon", - ["🎏"] = "flags", - ["🎀"] = "ribbon", - ["🎊"] = "confetti_ball", - ["🎉"] = "tada", - ["🪅"] = "piñata", - ["🪆"] = "nesting_dolls", - ["🎎"] = "dolls", - ["🏮"] = "izakaya_lantern", - ["🎐"] = "wind_chime", - ["🧧"] = "red_envelope", - ["✉️"] = "envelope", - ["📩"] = "envelope_with_arrow", - ["📨"] = "incoming_envelope", - ["📧"] = "e_mail", - ["💌"] = "love_letter", - ["📥"] = "inbox_tray", - ["📤"] = "outbox_tray", - ["📦"] = "package", - ["🏷️"] = "label", - ["📪"] = "mailbox_closed", - ["📫"] = "mailbox", - ["📬"] = "mailbox_with_mail", - ["📭"] = "mailbox_with_no_mail", - ["📮"] = "postbox", - ["📯"] = "postal_horn", - ["🪧"] = "placard", - ["📜"] = "scroll", - ["📃"] = "page_with_curl", - ["📄"] = "page_facing_up", - ["📑"] = "bookmark_tabs", - ["🧾"] = "receipt", - ["📊"] = "bar_chart", - ["📈"] = "chart_with_upwards_trend", - ["📉"] = "chart_with_downwards_trend", - ["🗒️"] = "notepad_spiral", - ["🗓️"] = "calendar_spiral", - ["📆"] = "calendar", - ["📅"] = "date", - ["🗑️"] = "wastebasket", - ["📇"] = "card_index", - ["🗃️"] = "card_box", - ["🗳️"] = "ballot_box", - ["🗄️"] = "file_cabinet", - ["📋"] = "clipboard", - ["📁"] = "file_folder", - ["📂"] = "open_file_folder", - ["🗂️"] = "dividers", - ["🗞️"] = "newspaper2", - ["📰"] = "newspaper", - ["📓"] = "notebook", - ["📔"] = "notebook_with_decorative_cover", - ["📒"] = "ledger", - ["📕"] = "closed_book", - ["📗"] = "green_book", - ["📘"] = "blue_book", - ["📙"] = "orange_book", - ["📚"] = "books", - ["📖"] = "book", - ["🔖"] = "bookmark", - ["🧷"] = "safety_pin", - ["🔗"] = "link", - ["📎"] = "paperclip", - ["🖇️"] = "paperclips", - ["📐"] = "triangular_ruler", - ["📏"] = "straight_ruler", - ["🧮"] = "abacus", - ["📌"] = "pushpin", - ["📍"] = "round_pushpin", - ["✂️"] = "scissors", - ["🖊️"] = "pen_ballpoint", - ["🖋️"] = "pen_fountain", - ["✒️"] = "black_nib", - ["🖌️"] = "paintbrush", - ["🖍️"] = "crayon", - ["📝"] = "pencil", - ["✏️"] = "pencil2", - ["🔍"] = "mag", - ["🔎"] = "mag_right", - ["🔏"] = "lock_with_ink_pen", - ["🔐"] = "closed_lock_with_key", - ["🔒"] = "lock", - ["🔓"] = "unlock", - ["❤️"] = "heart", - ["🧡"] = "orange_heart", - ["💛"] = "yellow_heart", - ["💚"] = "green_heart", - ["💙"] = "blue_heart", - ["💜"] = "purple_heart", - ["🖤"] = "black_heart", - ["🤎"] = "brown_heart", - ["🤍"] = "white_heart", - ["💔"] = "broken_heart", - ["❣️"] = "heart_exclamation", - ["💕"] = "two_hearts", - ["💞"] = "revolving_hearts", - ["💓"] = "heartbeat", - ["💗"] = "heartpulse", - ["💖"] = "sparkling_heart", - ["💘"] = "cupid", - ["💝"] = "gift_heart", - ["❤️‍🩹"] = "mending_heart", - ["❤️‍🔥"] = "heart_on_fire", - ["💟"] = "heart_decoration", - ["☮️"] = "peace", - ["✝️"] = "cross", - ["☪️"] = "star_and_crescent", - ["🕉️"] = "om_symbol", - ["☸️"] = "wheel_of_dharma", - ["✡️"] = "star_of_david", - ["🔯"] = "six_pointed_star", - ["🕎"] = "menorah", - ["☯️"] = "yin_yang", - ["☦️"] = "orthodox_cross", - ["🛐"] = "place_of_worship", - ["⛎"] = "ophiuchus", - ["♈"] = "aries", - ["♉"] = "taurus", - ["♊"] = "gemini", - ["♋"] = "cancer", - ["♌"] = "leo", - ["♍"] = "virgo", - ["♎"] = "libra", - ["♏"] = "scorpius", - ["♐"] = "sagittarius", - ["♑"] = "capricorn", - ["♒"] = "aquarius", - ["♓"] = "pisces", - ["🆔"] = "id", - ["⚛️"] = "atom", - ["🉑"] = "accept", - ["☢️"] = "radioactive", - ["☣️"] = "biohazard", - ["📴"] = "mobile_phone_off", - ["📳"] = "vibration_mode", - ["🈶"] = "u6709", - ["🈚"] = "u7121", - ["🈸"] = "u7533", - ["🈺"] = "u55b6", - ["🈷️"] = "u6708", - ["✴️"] = "eight_pointed_black_star", - ["🆚"] = "vs", - ["💮"] = "white_flower", - ["🉐"] = "ideograph_advantage", - ["㊙️"] = "secret", - ["㊗️"] = "congratulations", - ["🈴"] = "u5408", - ["🈵"] = "u6e80", - ["🈹"] = "u5272", - ["🈲"] = "u7981", - ["🅰️"] = "a", - ["🅱️"] = "b", - ["🆎"] = "ab", - ["🆑"] = "cl", - ["🅾️"] = "o2", - ["🆘"] = "sos", - ["❌"] = "x", - ["⭕"] = "o", - ["🛑"] = "octagonal_sign", - ["⛔"] = "no_entry", - ["📛"] = "name_badge", - ["🚫"] = "no_entry_sign", - ["💯"] = "100", - ["💢"] = "anger", - ["♨️"] = "hotsprings", - ["🚷"] = "no_pedestrians", - ["🚯"] = "do_not_litter", - ["🚳"] = "no_bicycles", - ["🚱"] = "non_potable_water", - ["🔞"] = "underage", - ["📵"] = "no_mobile_phones", - ["🚭"] = "no_smoking", - ["❗"] = "exclamation", - ["❕"] = "grey_exclamation", - ["❓"] = "question", - ["❔"] = "grey_question", - ["‼️"] = "bangbang", - ["⁉️"] = "interrobang", - ["🔅"] = "low_brightness", - ["🔆"] = "high_brightness", - ["〽️"] = "part_alternation_mark", - ["⚠️"] = "warning", - ["🚸"] = "children_crossing", - ["🔱"] = "trident", - ["⚜️"] = "fleur_de_lis", - ["🔰"] = "beginner", - ["♻️"] = "recycle", - ["✅"] = "white_check_mark", - ["🈯"] = "u6307", - ["💹"] = "chart", - ["❇️"] = "sparkle", - ["✳️"] = "eight_spoked_asterisk", - ["❎"] = "negative_squared_cross_mark", - ["🌐"] = "globe_with_meridians", - ["💠"] = "diamond_shape_with_a_dot_inside", - ["Ⓜ️"] = "m", - ["🌀"] = "cyclone", - ["💤"] = "zzz", - ["🏧"] = "atm", - ["🚾"] = "wc", - ["♿"] = "wheelchair", - ["🅿️"] = "parking", - ["🈳"] = "u7a7a", - ["🈂️"] = "sa", - ["🛂"] = "passport_control", - ["🛃"] = "customs", - ["🛄"] = "baggage_claim", - ["🛅"] = "left_luggage", - ["🛗"] = "elevator", - ["🚹"] = "mens", - ["🚺"] = "womens", - ["🚼"] = "baby_symbol", - ["🚻"] = "restroom", - ["🚮"] = "put_litter_in_its_place", - ["🎦"] = "cinema", - ["📶"] = "signal_strength", - ["🈁"] = "koko", - ["🔣"] = "symbols", - ["ℹ️"] = "information_source", - ["🔤"] = "abc", - ["🔡"] = "abcd", - ["🔠"] = "capital_abcd", - ["🆖"] = "ng", - ["🆗"] = "ok", - ["🆙"] = "up", - ["🆒"] = "cool", - ["🆕"] = "new", - ["🆓"] = "free", - ["0️⃣"] = "zero", - ["1️⃣"] = "one", - ["2️⃣"] = "two", - ["3️⃣"] = "three", - ["4️⃣"] = "four", - ["5️⃣"] = "five", - ["6️⃣"] = "six", - ["7️⃣"] = "seven", - ["8️⃣"] = "eight", - ["9️⃣"] = "nine", - ["🔟"] = "keycap_ten", - ["🔢"] = "1234", - ["#️⃣"] = "hash", - ["*️⃣"] = "asterisk", - ["⏏️"] = "eject", - ["▶️"] = "arrow_forward", - ["⏸️"] = "pause_button", - ["⏯️"] = "play_pause", - ["⏹️"] = "stop_button", - ["⏺️"] = "record_button", - ["⏭️"] = "track_next", - ["⏮️"] = "track_previous", - ["⏩"] = "fast_forward", - ["⏪"] = "rewind", - ["⏫"] = "arrow_double_up", - ["⏬"] = "arrow_double_down", - ["◀️"] = "arrow_backward", - ["🔼"] = "arrow_up_small", - ["🔽"] = "arrow_down_small", - ["➡️"] = "arrow_right", - ["⬅️"] = "arrow_left", - ["⬆️"] = "arrow_up", - ["⬇️"] = "arrow_down", - ["↗️"] = "arrow_upper_right", - ["↘️"] = "arrow_lower_right", - ["↙️"] = "arrow_lower_left", - ["↖️"] = "arrow_upper_left", - ["↕️"] = "arrow_up_down", - ["↔️"] = "left_right_arrow", - ["↪️"] = "arrow_right_hook", - ["↩️"] = "leftwards_arrow_with_hook", - ["⤴️"] = "arrow_heading_up", - ["⤵️"] = "arrow_heading_down", - ["🔀"] = "twisted_rightwards_arrows", - ["🔁"] = "repeat", - ["🔂"] = "repeat_one", - ["🔄"] = "arrows_counterclockwise", - ["🔃"] = "arrows_clockwise", - ["🎵"] = "musical_note", - ["🎶"] = "notes", - ["➕"] = "heavy_plus_sign", - ["➖"] = "heavy_minus_sign", - ["➗"] = "heavy_division_sign", - ["✖️"] = "heavy_multiplication_x", - ["♾️"] = "infinity", - ["💲"] = "heavy_dollar_sign", - ["💱"] = "currency_exchange", - ["™️"] = "tm", - ["©️"] = "copyright", - ["®️"] = "registered", - ["〰️"] = "wavy_dash", - ["➰"] = "curly_loop", - ["➿"] = "loop", - ["🔚"] = "end", - ["🔙"] = "back", - ["🔛"] = "on", - ["🔝"] = "top", - ["🔜"] = "soon", - ["✔️"] = "heavy_check_mark", - ["☑️"] = "ballot_box_with_check", - ["🔘"] = "radio_button", - ["⚪"] = "white_circle", - ["⚫"] = "black_circle", - ["🔴"] = "red_circle", - ["🔵"] = "blue_circle", - ["🟤"] = "brown_circle", - ["🟣"] = "purple_circle", - ["🟢"] = "green_circle", - ["🟡"] = "yellow_circle", - ["🟠"] = "orange_circle", - ["🔺"] = "small_red_triangle", - ["🔻"] = "small_red_triangle_down", - ["🔸"] = "small_orange_diamond", - ["🔹"] = "small_blue_diamond", - ["🔶"] = "large_orange_diamond", - ["🔷"] = "large_blue_diamond", - ["🔳"] = "white_square_button", - ["🔲"] = "black_square_button", - ["▪️"] = "black_small_square", - ["▫️"] = "white_small_square", - ["◾"] = "black_medium_small_square", - ["◽"] = "white_medium_small_square", - ["◼️"] = "black_medium_square", - ["◻️"] = "white_medium_square", - ["⬛"] = "black_large_square", - ["⬜"] = "white_large_square", - ["🟧"] = "orange_square", - ["🟦"] = "blue_square", - ["🟥"] = "red_square", - ["🟫"] = "brown_square", - ["🟪"] = "purple_square", - ["🟩"] = "green_square", - ["🟨"] = "yellow_square", - ["🔈"] = "speaker", - ["🔇"] = "mute", - ["🔉"] = "sound", - ["🔊"] = "loud_sound", - ["🔔"] = "bell", - ["🔕"] = "no_bell", - ["📣"] = "mega", - ["📢"] = "loudspeaker", - ["🗨️"] = "speech_left", - ["👁‍🗨"] = "eye_in_speech_bubble", - ["💬"] = "speech_balloon", - ["💭"] = "thought_balloon", - ["🗯️"] = "anger_right", - ["♠️"] = "spades", - ["♣️"] = "clubs", - ["♥️"] = "hearts", - ["♦️"] = "diamonds", - ["🃏"] = "black_joker", - ["🎴"] = "flower_playing_cards", - ["🀄"] = "mahjong", - ["🕐"] = "clock1", - ["🕑"] = "clock2", - ["🕒"] = "clock3", - ["🕓"] = "clock4", - ["🕔"] = "clock5", - ["🕕"] = "clock6", - ["🕖"] = "clock7", - ["🕗"] = "clock8", - ["🕘"] = "clock9", - ["🕙"] = "clock10", - ["🕚"] = "clock11", - ["🕛"] = "clock12", - ["🕜"] = "clock130", - ["🕝"] = "clock230", - ["🕞"] = "clock330", - ["🕟"] = "clock430", - ["🕠"] = "clock530", - ["🕡"] = "clock630", - ["🕢"] = "clock730", - ["🕣"] = "clock830", - ["🕤"] = "clock930", - ["🕥"] = "clock1030", - ["🕦"] = "clock1130", - ["🕧"] = "clock1230", - ["♀️"] = "female_sign", - ["♂️"] = "male_sign", - ["⚧"] = "transgender_symbol", - ["⚕️"] = "medical_symbol", - ["🇿"] = "regional_indicator_z", - ["🇾"] = "regional_indicator_y", - ["🇽"] = "regional_indicator_x", - ["🇼"] = "regional_indicator_w", - ["🇻"] = "regional_indicator_v", - ["🇺"] = "regional_indicator_u", - ["🇹"] = "regional_indicator_t", - ["🇸"] = "regional_indicator_s", - ["🇷"] = "regional_indicator_r", - ["🇶"] = "regional_indicator_q", - ["🇵"] = "regional_indicator_p", - ["🇴"] = "regional_indicator_o", - ["🇳"] = "regional_indicator_n", - ["🇲"] = "regional_indicator_m", - ["🇱"] = "regional_indicator_l", - ["🇰"] = "regional_indicator_k", - ["🇯"] = "regional_indicator_j", - ["🇮"] = "regional_indicator_i", - ["🇭"] = "regional_indicator_h", - ["🇬"] = "regional_indicator_g", - ["🇫"] = "regional_indicator_f", - ["🇪"] = "regional_indicator_e", - ["🇩"] = "regional_indicator_d", - ["🇨"] = "regional_indicator_c", - ["🇧"] = "regional_indicator_b", - ["🇦"] = "regional_indicator_a", - ["🏳️"] = "flag_white", - ["🏴"] = "flag_black", - ["🏁"] = "checkered_flag", - ["🚩"] = "triangular_flag_on_post", - ["🏳️‍🌈"] = "rainbow_flag", - ["🏳️‍⚧️"] = "transgender_flag", - ["🏴‍☠️"] = "pirate_flag", - ["🇦🇫"] = "flag_af", - ["🇦🇽"] = "flag_ax", - ["🇦🇱"] = "flag_al", - ["🇩🇿"] = "flag_dz", - ["🇦🇸"] = "flag_as", - ["🇦🇩"] = "flag_ad", - ["🇦🇴"] = "flag_ao", - ["🇦🇮"] = "flag_ai", - ["🇦🇶"] = "flag_aq", - ["🇦🇬"] = "flag_ag", - ["🇦🇷"] = "flag_ar", - ["🇦🇲"] = "flag_am", - ["🇦🇼"] = "flag_aw", - ["🇦🇺"] = "flag_au", - ["🇦🇹"] = "flag_at", - ["🇦🇿"] = "flag_az", - ["🇧🇸"] = "flag_bs", - ["🇧🇭"] = "flag_bh", - ["🇧🇩"] = "flag_bd", - ["🇧🇧"] = "flag_bb", - ["🇧🇾"] = "flag_by", - ["🇧🇪"] = "flag_be", - ["🇧🇿"] = "flag_bz", - ["🇧🇯"] = "flag_bj", - ["🇧🇲"] = "flag_bm", - ["🇧🇹"] = "flag_bt", - ["🇧🇴"] = "flag_bo", - ["🇧🇦"] = "flag_ba", - ["🇧🇼"] = "flag_bw", - ["🇧🇷"] = "flag_br", - ["🇮🇴"] = "flag_io", - ["🇻🇬"] = "flag_vg", - ["🇧🇳"] = "flag_bn", - ["🇧🇬"] = "flag_bg", - ["🇧🇫"] = "flag_bf", - ["🇧🇮"] = "flag_bi", - ["🇰🇭"] = "flag_kh", - ["🇨🇲"] = "flag_cm", - ["🇨🇦"] = "flag_ca", - ["🇮🇨"] = "flag_ic", - ["🇨🇻"] = "flag_cv", - ["🇧🇶"] = "flag_bq", - ["🇰🇾"] = "flag_ky", - ["🇨🇫"] = "flag_cf", - ["🇹🇩"] = "flag_td", - ["🇨🇱"] = "flag_cl", - ["🇨🇳"] = "flag_cn", - ["🇨🇽"] = "flag_cx", - ["🇨🇨"] = "flag_cc", - ["🇨🇴"] = "flag_co", - ["🇰🇲"] = "flag_km", - ["🇨🇬"] = "flag_cg", - ["🇨🇩"] = "flag_cd", - ["🇨🇰"] = "flag_ck", - ["🇨🇷"] = "flag_cr", - ["🇨🇮"] = "flag_ci", - ["🇭🇷"] = "flag_hr", - ["🇨🇺"] = "flag_cu", - ["🇨🇼"] = "flag_cw", - ["🇨🇾"] = "flag_cy", - ["🇨🇿"] = "flag_cz", - ["🇩🇰"] = "flag_dk", - ["🇩🇯"] = "flag_dj", - ["🇩🇲"] = "flag_dm", - ["🇩🇴"] = "flag_do", - ["🇪🇨"] = "flag_ec", - ["🇪🇬"] = "flag_eg", - ["🇸🇻"] = "flag_sv", - ["🇬🇶"] = "flag_gq", - ["🇪🇷"] = "flag_er", - ["🇪🇪"] = "flag_ee", - ["🇪🇹"] = "flag_et", - ["🇪🇺"] = "flag_eu", - ["🇫🇰"] = "flag_fk", - ["🇫🇴"] = "flag_fo", - ["🇫🇯"] = "flag_fj", - ["🇫🇮"] = "flag_fi", - ["🇫🇷"] = "flag_fr", - ["🇬🇫"] = "flag_gf", - ["🇵🇫"] = "flag_pf", - ["🇹🇫"] = "flag_tf", - ["🇬🇦"] = "flag_ga", - ["🇬🇲"] = "flag_gm", - ["🇬🇪"] = "flag_ge", - ["🇩🇪"] = "flag_de", - ["🇬🇭"] = "flag_gh", - ["🇬🇮"] = "flag_gi", - ["🇬🇷"] = "flag_gr", - ["🇬🇱"] = "flag_gl", - ["🇬🇩"] = "flag_gd", - ["🇬🇵"] = "flag_gp", - ["🇬🇺"] = "flag_gu", - ["🇬🇹"] = "flag_gt", - ["🇬🇬"] = "flag_gg", - ["🇬🇳"] = "flag_gn", - ["🇬🇼"] = "flag_gw", - ["🇬🇾"] = "flag_gy", - ["🇭🇹"] = "flag_ht", - ["🇭🇳"] = "flag_hn", - ["🇭🇰"] = "flag_hk", - ["🇭🇺"] = "flag_hu", - ["🇮🇸"] = "flag_is", - ["🇮🇳"] = "flag_in", - ["🇮🇩"] = "flag_id", - ["🇮🇷"] = "flag_ir", - ["🇮🇶"] = "flag_iq", - ["🇮🇪"] = "flag_ie", - ["🇮🇲"] = "flag_im", - ["🇮🇱"] = "flag_il", - ["🇮🇹"] = "flag_it", - ["🇯🇲"] = "flag_jm", - ["🇯🇵"] = "flag_jp", - ["🎌"] = "crossed_flags", - ["🇯🇪"] = "flag_je", - ["🇯🇴"] = "flag_jo", - ["🇰🇿"] = "flag_kz", - ["🇰🇪"] = "flag_ke", - ["🇰🇮"] = "flag_ki", - ["🇽🇰"] = "flag_xk", - ["🇰🇼"] = "flag_kw", - ["🇰🇬"] = "flag_kg", - ["🇱🇦"] = "flag_la", - ["🇱🇻"] = "flag_lv", - ["🇱🇧"] = "flag_lb", - ["🇱🇸"] = "flag_ls", - ["🇱🇷"] = "flag_lr", - ["🇱🇾"] = "flag_ly", - ["🇱🇮"] = "flag_li", - ["🇱🇹"] = "flag_lt", - ["🇱🇺"] = "flag_lu", - ["🇲🇴"] = "flag_mo", - ["🇲🇰"] = "flag_mk", - ["🇲🇬"] = "flag_mg", - ["🇲🇼"] = "flag_mw", - ["🇲🇾"] = "flag_my", - ["🇲🇻"] = "flag_mv", - ["🇲🇱"] = "flag_ml", - ["🇲🇹"] = "flag_mt", - ["🇲🇭"] = "flag_mh", - ["🇲🇶"] = "flag_mq", - ["🇲🇷"] = "flag_mr", - ["🇲🇺"] = "flag_mu", - ["🇾🇹"] = "flag_yt", - ["🇲🇽"] = "flag_mx", - ["🇫🇲"] = "flag_fm", - ["🇲🇩"] = "flag_md", - ["🇲🇨"] = "flag_mc", - ["🇲🇳"] = "flag_mn", - ["🇲🇪"] = "flag_me", - ["🇲🇸"] = "flag_ms", - ["🇲🇦"] = "flag_ma", - ["🇲🇿"] = "flag_mz", - ["🇲🇲"] = "flag_mm", - ["🇳🇦"] = "flag_na", - ["🇳🇷"] = "flag_nr", - ["🇳🇵"] = "flag_np", - ["🇳🇱"] = "flag_nl", - ["🇳🇨"] = "flag_nc", - ["🇳🇿"] = "flag_nz", - ["🇳🇮"] = "flag_ni", - ["🇳🇪"] = "flag_ne", - ["🇳🇬"] = "flag_ng", - ["🇳🇺"] = "flag_nu", - ["🇳🇫"] = "flag_nf", - ["🇰🇵"] = "flag_kp", - ["🇲🇵"] = "flag_mp", - ["🇳🇴"] = "flag_no", - ["🇴🇲"] = "flag_om", - ["🇵🇰"] = "flag_pk", - ["🇵🇼"] = "flag_pw", - ["🇵🇸"] = "flag_ps", - ["🇵🇦"] = "flag_pa", - ["🇵🇬"] = "flag_pg", - ["🇵🇾"] = "flag_py", - ["🇵🇪"] = "flag_pe", - ["🇵🇭"] = "flag_ph", - ["🇵🇳"] = "flag_pn", - ["🇵🇱"] = "flag_pl", - ["🇵🇹"] = "flag_pt", - ["🇵🇷"] = "flag_pr", - ["🇶🇦"] = "flag_qa", - ["🇷🇪"] = "flag_re", - ["🇷🇴"] = "flag_ro", - ["🇷🇺"] = "flag_ru", - ["🇷🇼"] = "flag_rw", - ["🇼🇸"] = "flag_ws", - ["🇸🇲"] = "flag_sm", - ["🇸🇹"] = "flag_st", - ["🇸🇦"] = "flag_sa", - ["🇸🇳"] = "flag_sn", - ["🇷🇸"] = "flag_rs", - ["🇸🇨"] = "flag_sc", - ["🇸🇱"] = "flag_sl", - ["🇸🇬"] = "flag_sg", - ["🇸🇽"] = "flag_sx", - ["🇸🇰"] = "flag_sk", - ["🇸🇮"] = "flag_si", - ["🇬🇸"] = "flag_gs", - ["🇸🇧"] = "flag_sb", - ["🇸🇴"] = "flag_so", - ["🇿🇦"] = "flag_za", - ["🇰🇷"] = "flag_kr", - ["🇸🇸"] = "flag_ss", - ["🇪🇸"] = "flag_es", - ["🇱🇰"] = "flag_lk", - ["🇧🇱"] = "flag_bl", - ["🇸🇭"] = "flag_sh", - ["🇰🇳"] = "flag_kn", - ["🇱🇨"] = "flag_lc", - ["🇵🇲"] = "flag_pm", - ["🇻🇨"] = "flag_vc", - ["🇸🇩"] = "flag_sd", - ["🇸🇷"] = "flag_sr", - ["🇸🇿"] = "flag_sz", - ["🇸🇪"] = "flag_se", - ["🇨🇭"] = "flag_ch", - ["🇸🇾"] = "flag_sy", - ["🇹🇼"] = "flag_tw", - ["🇹🇯"] = "flag_tj", - ["🇹🇿"] = "flag_tz", - ["🇹🇭"] = "flag_th", - ["🇹🇱"] = "flag_tl", - ["🇹🇬"] = "flag_tg", - ["🇹🇰"] = "flag_tk", - ["🇹🇴"] = "flag_to", - ["🇹🇹"] = "flag_tt", - ["🇹🇳"] = "flag_tn", - ["🇹🇷"] = "flag_tr", - ["🇹🇲"] = "flag_tm", - ["🇹🇨"] = "flag_tc", - ["🇻🇮"] = "flag_vi", - ["🇹🇻"] = "flag_tv", - ["🇺🇬"] = "flag_ug", - ["🇺🇦"] = "flag_ua", - ["🇦🇪"] = "flag_ae", - ["🇬🇧"] = "flag_gb", - ["🏴󠁧󠁢󠁥󠁮󠁧󠁿"] = "england", - ["🏴󠁧󠁢󠁳󠁣󠁴󠁿"] = "scotland", - ["🏴󠁧󠁢󠁷󠁬󠁳󠁿"] = "wales", - ["🇺🇸"] = "flag_us", - ["🇺🇾"] = "flag_uy", - ["🇺🇿"] = "flag_uz", - ["🇻🇺"] = "flag_vu", - ["🇻🇦"] = "flag_va", - ["🇻🇪"] = "flag_ve", - ["🇻🇳"] = "flag_vn", - ["🇼🇫"] = "flag_wf", - ["🇪🇭"] = "flag_eh", - ["🇾🇪"] = "flag_ye", - ["🇿🇲"] = "flag_zm", - ["🇿🇼"] = "flag_zw", - ["🇦🇨"] = "flag_ac", - ["🇧🇻"] = "flag_bv", - ["🇨🇵"] = "flag_cp", - ["🇪🇦"] = "flag_ea", - ["🇩🇬"] = "flag_dg", - ["🇭🇲"] = "flag_hm", - ["🇲🇫"] = "flag_mf", - ["🇸🇯"] = "flag_sj", - ["🇹🇦"] = "flag_ta", - ["🇺🇲"] = "flag_um", - ["🇺🇳"] = "united_nations" - }; + ["😀"] = "grinning", + ["😃"] = "smiley", + ["😄"] = "smile", + ["😁"] = "grin", + ["😆"] = "laughing", + ["😅"] = "sweat_smile", + ["😂"] = "joy", + ["🤣"] = "rofl", + ["☺️"] = "relaxed", + ["😊"] = "blush", + ["😇"] = "innocent", + ["🙂"] = "slight_smile", + ["🙃"] = "upside_down", + ["😉"] = "wink", + ["😌"] = "relieved", + ["🥲"] = "smiling_face_with_tear", + ["😍"] = "heart_eyes", + ["🥰"] = "smiling_face_with_3_hearts", + ["😘"] = "kissing_heart", + ["😗"] = "kissing", + ["😙"] = "kissing_smiling_eyes", + ["😚"] = "kissing_closed_eyes", + ["😋"] = "yum", + ["😛"] = "stuck_out_tongue", + ["😝"] = "stuck_out_tongue_closed_eyes", + ["😜"] = "stuck_out_tongue_winking_eye", + ["🤪"] = "zany_face", + ["🤨"] = "face_with_raised_eyebrow", + ["🧐"] = "face_with_monocle", + ["🤓"] = "nerd", + ["😎"] = "sunglasses", + ["🤩"] = "star_struck", + ["🥳"] = "partying_face", + ["😏"] = "smirk", + ["😒"] = "unamused", + ["😞"] = "disappointed", + ["😔"] = "pensive", + ["😟"] = "worried", + ["😕"] = "confused", + ["🙁"] = "slight_frown", + ["☹️"] = "frowning2", + ["😣"] = "persevere", + ["😖"] = "confounded", + ["😫"] = "tired_face", + ["😩"] = "weary", + ["🥺"] = "pleading_face", + ["😢"] = "cry", + ["😭"] = "sob", + ["😤"] = "triumph", + ["😮‍💨"] = "face_exhaling", + ["😠"] = "angry", + ["😡"] = "rage", + ["🤬"] = "face_with_symbols_over_mouth", + ["🤯"] = "exploding_head", + ["😳"] = "flushed", + ["😶‍🌫️"] = "face_in_clouds", + ["🥵"] = "hot_face", + ["🥶"] = "cold_face", + ["😱"] = "scream", + ["😨"] = "fearful", + ["😰"] = "cold_sweat", + ["😥"] = "disappointed_relieved", + ["😓"] = "sweat", + ["🤗"] = "hugging", + ["🤔"] = "thinking", + ["🤭"] = "face_with_hand_over_mouth", + ["🥱"] = "yawning_face", + ["🤫"] = "shushing_face", + ["🤥"] = "lying_face", + ["😶"] = "no_mouth", + ["😐"] = "neutral_face", + ["😑"] = "expressionless", + ["😬"] = "grimacing", + ["🙄"] = "rolling_eyes", + ["😯"] = "hushed", + ["😦"] = "frowning", + ["😧"] = "anguished", + ["😮"] = "open_mouth", + ["😲"] = "astonished", + ["😴"] = "sleeping", + ["🤤"] = "drooling_face", + ["😪"] = "sleepy", + ["😵"] = "dizzy_face", + ["😵‍💫"] = "face_with_spiral_eyes", + ["🤐"] = "zipper_mouth", + ["🥴"] = "woozy_face", + ["🤢"] = "nauseated_face", + ["🤮"] = "face_vomiting", + ["🤧"] = "sneezing_face", + ["😷"] = "mask", + ["🤒"] = "thermometer_face", + ["🤕"] = "head_bandage", + ["🤑"] = "money_mouth", + ["🤠"] = "cowboy", + ["🥸"] = "disguised_face", + ["😈"] = "smiling_imp", + ["👿"] = "imp", + ["👹"] = "japanese_ogre", + ["👺"] = "japanese_goblin", + ["🤡"] = "clown", + ["💩"] = "poop", + ["👻"] = "ghost", + ["💀"] = "skull", + ["☠️"] = "skull_crossbones", + ["👽"] = "alien", + ["👾"] = "space_invader", + ["🤖"] = "robot", + ["🎃"] = "jack_o_lantern", + ["😺"] = "smiley_cat", + ["😸"] = "smile_cat", + ["😹"] = "joy_cat", + ["😻"] = "heart_eyes_cat", + ["😼"] = "smirk_cat", + ["😽"] = "kissing_cat", + ["🙀"] = "scream_cat", + ["😿"] = "crying_cat_face", + ["😾"] = "pouting_cat", + ["🤲"] = "palms_up_together", + ["🤲🏻"] = "palms_up_together_tone1", + ["🤲🏼"] = "palms_up_together_tone2", + ["🤲🏽"] = "palms_up_together_tone3", + ["🤲🏾"] = "palms_up_together_tone4", + ["🤲🏿"] = "palms_up_together_tone5", + ["👐"] = "open_hands", + ["👐🏻"] = "open_hands_tone1", + ["👐🏼"] = "open_hands_tone2", + ["👐🏽"] = "open_hands_tone3", + ["👐🏾"] = "open_hands_tone4", + ["👐🏿"] = "open_hands_tone5", + ["🙌"] = "raised_hands", + ["🙌🏻"] = "raised_hands_tone1", + ["🙌🏼"] = "raised_hands_tone2", + ["🙌🏽"] = "raised_hands_tone3", + ["🙌🏾"] = "raised_hands_tone4", + ["🙌🏿"] = "raised_hands_tone5", + ["👏"] = "clap", + ["👏🏻"] = "clap_tone1", + ["👏🏼"] = "clap_tone2", + ["👏🏽"] = "clap_tone3", + ["👏🏾"] = "clap_tone4", + ["👏🏿"] = "clap_tone5", + ["🤝"] = "handshake", + ["👍"] = "thumbsup", + ["👍🏻"] = "thumbsup_tone1", + ["👍🏼"] = "thumbsup_tone2", + ["👍🏽"] = "thumbsup_tone3", + ["👍🏾"] = "thumbsup_tone4", + ["👍🏿"] = "thumbsup_tone5", + ["👎"] = "thumbsdown", + ["👎🏻"] = "thumbsdown_tone1", + ["👎🏼"] = "thumbsdown_tone2", + ["👎🏽"] = "thumbsdown_tone3", + ["👎🏾"] = "thumbsdown_tone4", + ["👎🏿"] = "thumbsdown_tone5", + ["👊"] = "punch", + ["👊🏻"] = "punch_tone1", + ["👊🏼"] = "punch_tone2", + ["👊🏽"] = "punch_tone3", + ["👊🏾"] = "punch_tone4", + ["👊🏿"] = "punch_tone5", + ["✊"] = "fist", + ["✊🏻"] = "fist_tone1", + ["✊🏼"] = "fist_tone2", + ["✊🏽"] = "fist_tone3", + ["✊🏾"] = "fist_tone4", + ["✊🏿"] = "fist_tone5", + ["🤛"] = "left_facing_fist", + ["🤛🏻"] = "left_facing_fist_tone1", + ["🤛🏼"] = "left_facing_fist_tone2", + ["🤛🏽"] = "left_facing_fist_tone3", + ["🤛🏾"] = "left_facing_fist_tone4", + ["🤛🏿"] = "left_facing_fist_tone5", + ["🤜"] = "right_facing_fist", + ["🤜🏻"] = "right_facing_fist_tone1", + ["🤜🏼"] = "right_facing_fist_tone2", + ["🤜🏽"] = "right_facing_fist_tone3", + ["🤜🏾"] = "right_facing_fist_tone4", + ["🤜🏿"] = "right_facing_fist_tone5", + ["🤞"] = "fingers_crossed", + ["🤞🏻"] = "fingers_crossed_tone1", + ["🤞🏼"] = "fingers_crossed_tone2", + ["🤞🏽"] = "fingers_crossed_tone3", + ["🤞🏾"] = "fingers_crossed_tone4", + ["🤞🏿"] = "fingers_crossed_tone5", + ["✌️"] = "v", + ["✌🏻"] = "v_tone1", + ["✌🏼"] = "v_tone2", + ["✌🏽"] = "v_tone3", + ["✌🏾"] = "v_tone4", + ["✌🏿"] = "v_tone5", + ["🤟"] = "love_you_gesture", + ["🤟🏻"] = "love_you_gesture_tone1", + ["🤟🏼"] = "love_you_gesture_tone2", + ["🤟🏽"] = "love_you_gesture_tone3", + ["🤟🏾"] = "love_you_gesture_tone4", + ["🤟🏿"] = "love_you_gesture_tone5", + ["🤘"] = "metal", + ["🤘🏻"] = "metal_tone1", + ["🤘🏼"] = "metal_tone2", + ["🤘🏽"] = "metal_tone3", + ["🤘🏾"] = "metal_tone4", + ["🤘🏿"] = "metal_tone5", + ["👌"] = "ok_hand", + ["👌🏻"] = "ok_hand_tone1", + ["👌🏼"] = "ok_hand_tone2", + ["👌🏽"] = "ok_hand_tone3", + ["👌🏾"] = "ok_hand_tone4", + ["👌🏿"] = "ok_hand_tone5", + ["🤏"] = "pinching_hand", + ["🤏🏻"] = "pinching_hand_tone1", + ["🤏🏼"] = "pinching_hand_tone2", + ["🤏🏽"] = "pinching_hand_tone3", + ["🤏🏾"] = "pinching_hand_tone4", + ["🤏🏿"] = "pinching_hand_tone5", + ["🤌"] = "pinched_fingers", + ["🤌🏼"] = "pinched_fingers_tone2", + ["🤌🏻"] = "pinched_fingers_tone1", + ["🤌🏽"] = "pinched_fingers_tone3", + ["🤌🏾"] = "pinched_fingers_tone4", + ["🤌🏿"] = "pinched_fingers_tone5", + ["👈"] = "point_left", + ["👈🏻"] = "point_left_tone1", + ["👈🏼"] = "point_left_tone2", + ["👈🏽"] = "point_left_tone3", + ["👈🏾"] = "point_left_tone4", + ["👈🏿"] = "point_left_tone5", + ["👉"] = "point_right", + ["👉🏻"] = "point_right_tone1", + ["👉🏼"] = "point_right_tone2", + ["👉🏽"] = "point_right_tone3", + ["👉🏾"] = "point_right_tone4", + ["👉🏿"] = "point_right_tone5", + ["👆"] = "point_up_2", + ["👆🏻"] = "point_up_2_tone1", + ["👆🏼"] = "point_up_2_tone2", + ["👆🏽"] = "point_up_2_tone3", + ["👆🏾"] = "point_up_2_tone4", + ["👆🏿"] = "point_up_2_tone5", + ["👇"] = "point_down", + ["👇🏻"] = "point_down_tone1", + ["👇🏼"] = "point_down_tone2", + ["👇🏽"] = "point_down_tone3", + ["👇🏾"] = "point_down_tone4", + ["👇🏿"] = "point_down_tone5", + ["☝️"] = "point_up", + ["☝🏻"] = "point_up_tone1", + ["☝🏼"] = "point_up_tone2", + ["☝🏽"] = "point_up_tone3", + ["☝🏾"] = "point_up_tone4", + ["☝🏿"] = "point_up_tone5", + ["✋"] = "raised_hand", + ["✋🏻"] = "raised_hand_tone1", + ["✋🏼"] = "raised_hand_tone2", + ["✋🏽"] = "raised_hand_tone3", + ["✋🏾"] = "raised_hand_tone4", + ["✋🏿"] = "raised_hand_tone5", + ["🤚"] = "raised_back_of_hand", + ["🤚🏻"] = "raised_back_of_hand_tone1", + ["🤚🏼"] = "raised_back_of_hand_tone2", + ["🤚🏽"] = "raised_back_of_hand_tone3", + ["🤚🏾"] = "raised_back_of_hand_tone4", + ["🤚🏿"] = "raised_back_of_hand_tone5", + ["🖐️"] = "hand_splayed", + ["🖐🏻"] = "hand_splayed_tone1", + ["🖐🏼"] = "hand_splayed_tone2", + ["🖐🏽"] = "hand_splayed_tone3", + ["🖐🏾"] = "hand_splayed_tone4", + ["🖐🏿"] = "hand_splayed_tone5", + ["🖖"] = "vulcan", + ["🖖🏻"] = "vulcan_tone1", + ["🖖🏼"] = "vulcan_tone2", + ["🖖🏽"] = "vulcan_tone3", + ["🖖🏾"] = "vulcan_tone4", + ["🖖🏿"] = "vulcan_tone5", + ["👋"] = "wave", + ["👋🏻"] = "wave_tone1", + ["👋🏼"] = "wave_tone2", + ["👋🏽"] = "wave_tone3", + ["👋🏾"] = "wave_tone4", + ["👋🏿"] = "wave_tone5", + ["🤙"] = "call_me", + ["🤙🏻"] = "call_me_tone1", + ["🤙🏼"] = "call_me_tone2", + ["🤙🏽"] = "call_me_tone3", + ["🤙🏾"] = "call_me_tone4", + ["🤙🏿"] = "call_me_tone5", + ["💪"] = "muscle", + ["💪🏻"] = "muscle_tone1", + ["💪🏼"] = "muscle_tone2", + ["💪🏽"] = "muscle_tone3", + ["💪🏾"] = "muscle_tone4", + ["💪🏿"] = "muscle_tone5", + ["🦾"] = "mechanical_arm", + ["🖕"] = "middle_finger", + ["🖕🏻"] = "middle_finger_tone1", + ["🖕🏼"] = "middle_finger_tone2", + ["🖕🏽"] = "middle_finger_tone3", + ["🖕🏾"] = "middle_finger_tone4", + ["🖕🏿"] = "middle_finger_tone5", + ["✍️"] = "writing_hand", + ["✍🏻"] = "writing_hand_tone1", + ["✍🏼"] = "writing_hand_tone2", + ["✍🏽"] = "writing_hand_tone3", + ["✍🏾"] = "writing_hand_tone4", + ["✍🏿"] = "writing_hand_tone5", + ["🙏"] = "pray", + ["🙏🏻"] = "pray_tone1", + ["🙏🏼"] = "pray_tone2", + ["🙏🏽"] = "pray_tone3", + ["🙏🏾"] = "pray_tone4", + ["🙏🏿"] = "pray_tone5", + ["🦶"] = "foot", + ["🦶🏻"] = "foot_tone1", + ["🦶🏼"] = "foot_tone2", + ["🦶🏽"] = "foot_tone3", + ["🦶🏾"] = "foot_tone4", + ["🦶🏿"] = "foot_tone5", + ["🦵"] = "leg", + ["🦵🏻"] = "leg_tone1", + ["🦵🏼"] = "leg_tone2", + ["🦵🏽"] = "leg_tone3", + ["🦵🏾"] = "leg_tone4", + ["🦵🏿"] = "leg_tone5", + ["🦿"] = "mechanical_leg", + ["💄"] = "lipstick", + ["💋"] = "kiss", + ["👄"] = "lips", + ["🦷"] = "tooth", + ["👅"] = "tongue", + ["👂"] = "ear", + ["👂🏻"] = "ear_tone1", + ["👂🏼"] = "ear_tone2", + ["👂🏽"] = "ear_tone3", + ["👂🏾"] = "ear_tone4", + ["👂🏿"] = "ear_tone5", + ["🦻"] = "ear_with_hearing_aid", + ["🦻🏻"] = "ear_with_hearing_aid_tone1", + ["🦻🏼"] = "ear_with_hearing_aid_tone2", + ["🦻🏽"] = "ear_with_hearing_aid_tone3", + ["🦻🏾"] = "ear_with_hearing_aid_tone4", + ["🦻🏿"] = "ear_with_hearing_aid_tone5", + ["👃"] = "nose", + ["👃🏻"] = "nose_tone1", + ["👃🏼"] = "nose_tone2", + ["👃🏽"] = "nose_tone3", + ["👃🏾"] = "nose_tone4", + ["👃🏿"] = "nose_tone5", + ["👣"] = "footprints", + ["👁️"] = "eye", + ["👀"] = "eyes", + ["🧠"] = "brain", + ["🫀"] = "anatomical_heart", + ["🫁"] = "lungs", + ["🦴"] = "bone", + ["🗣️"] = "speaking_head", + ["👤"] = "bust_in_silhouette", + ["👥"] = "busts_in_silhouette", + ["🫂"] = "people_hugging", + ["👶"] = "baby", + ["👶🏻"] = "baby_tone1", + ["👶🏼"] = "baby_tone2", + ["👶🏽"] = "baby_tone3", + ["👶🏾"] = "baby_tone4", + ["👶🏿"] = "baby_tone5", + ["👧"] = "girl", + ["👧🏻"] = "girl_tone1", + ["👧🏼"] = "girl_tone2", + ["👧🏽"] = "girl_tone3", + ["👧🏾"] = "girl_tone4", + ["👧🏿"] = "girl_tone5", + ["🧒"] = "child", + ["🧒🏻"] = "child_tone1", + ["🧒🏼"] = "child_tone2", + ["🧒🏽"] = "child_tone3", + ["🧒🏾"] = "child_tone4", + ["🧒🏿"] = "child_tone5", + ["👦"] = "boy", + ["👦🏻"] = "boy_tone1", + ["👦🏼"] = "boy_tone2", + ["👦🏽"] = "boy_tone3", + ["👦🏾"] = "boy_tone4", + ["👦🏿"] = "boy_tone5", + ["👩"] = "woman", + ["👩🏻"] = "woman_tone1", + ["👩🏼"] = "woman_tone2", + ["👩🏽"] = "woman_tone3", + ["👩🏾"] = "woman_tone4", + ["👩🏿"] = "woman_tone5", + ["🧑"] = "adult", + ["🧑🏻"] = "adult_tone1", + ["🧑🏼"] = "adult_tone2", + ["🧑🏽"] = "adult_tone3", + ["🧑🏾"] = "adult_tone4", + ["🧑🏿"] = "adult_tone5", + ["👨"] = "man", + ["👨🏻"] = "man_tone1", + ["👨🏼"] = "man_tone2", + ["👨🏽"] = "man_tone3", + ["👨🏾"] = "man_tone4", + ["👨🏿"] = "man_tone5", + ["🧑‍🦱"] = "person_curly_hair", + ["🧑🏻‍🦱"] = "person_tone1_curly_hair", + ["🧑🏼‍🦱"] = "person_tone2_curly_hair", + ["🧑🏽‍🦱"] = "person_tone3_curly_hair", + ["🧑🏾‍🦱"] = "person_tone4_curly_hair", + ["🧑🏿‍🦱"] = "person_tone5_curly_hair", + ["👩‍🦱"] = "woman_curly_haired", + ["👩🏻‍🦱"] = "woman_curly_haired_tone1", + ["👩🏼‍🦱"] = "woman_curly_haired_tone2", + ["👩🏽‍🦱"] = "woman_curly_haired_tone3", + ["👩🏾‍🦱"] = "woman_curly_haired_tone4", + ["👩🏿‍🦱"] = "woman_curly_haired_tone5", + ["👨‍🦱"] = "man_curly_haired", + ["👨🏻‍🦱"] = "man_curly_haired_tone1", + ["👨🏼‍🦱"] = "man_curly_haired_tone2", + ["👨🏽‍🦱"] = "man_curly_haired_tone3", + ["👨🏾‍🦱"] = "man_curly_haired_tone4", + ["👨🏿‍🦱"] = "man_curly_haired_tone5", + ["🧑‍🦰"] = "person_red_hair", + ["🧑🏻‍🦰"] = "person_tone1_red_hair", + ["🧑🏼‍🦰"] = "person_tone2_red_hair", + ["🧑🏽‍🦰"] = "person_tone3_red_hair", + ["🧑🏾‍🦰"] = "person_tone4_red_hair", + ["🧑🏿‍🦰"] = "person_tone5_red_hair", + ["👩‍🦰"] = "woman_red_haired", + ["👩🏻‍🦰"] = "woman_red_haired_tone1", + ["👩🏼‍🦰"] = "woman_red_haired_tone2", + ["👩🏽‍🦰"] = "woman_red_haired_tone3", + ["👩🏾‍🦰"] = "woman_red_haired_tone4", + ["👩🏿‍🦰"] = "woman_red_haired_tone5", + ["👨‍🦰"] = "man_red_haired", + ["👨🏻‍🦰"] = "man_red_haired_tone1", + ["👨🏼‍🦰"] = "man_red_haired_tone2", + ["👨🏽‍🦰"] = "man_red_haired_tone3", + ["👨🏾‍🦰"] = "man_red_haired_tone4", + ["👨🏿‍🦰"] = "man_red_haired_tone5", + ["👱‍♀️"] = "blond_haired_woman", + ["👱🏻‍♀️"] = "blond_haired_woman_tone1", + ["👱🏼‍♀️"] = "blond_haired_woman_tone2", + ["👱🏽‍♀️"] = "blond_haired_woman_tone3", + ["👱🏾‍♀️"] = "blond_haired_woman_tone4", + ["👱🏿‍♀️"] = "blond_haired_woman_tone5", + ["👱"] = "blond_haired_person", + ["👱🏻"] = "blond_haired_person_tone1", + ["👱🏼"] = "blond_haired_person_tone2", + ["👱🏽"] = "blond_haired_person_tone3", + ["👱🏾"] = "blond_haired_person_tone4", + ["👱🏿"] = "blond_haired_person_tone5", + ["👱‍♂️"] = "blond_haired_man", + ["👱🏻‍♂️"] = "blond_haired_man_tone1", + ["👱🏼‍♂️"] = "blond_haired_man_tone2", + ["👱🏽‍♂️"] = "blond_haired_man_tone3", + ["👱🏾‍♂️"] = "blond_haired_man_tone4", + ["👱🏿‍♂️"] = "blond_haired_man_tone5", + ["🧑‍🦳"] = "person_white_hair", + ["🧑🏻‍🦳"] = "person_tone1_white_hair", + ["🧑🏼‍🦳"] = "person_tone2_white_hair", + ["🧑🏽‍🦳"] = "person_tone3_white_hair", + ["🧑🏾‍🦳"] = "person_tone4_white_hair", + ["🧑🏿‍🦳"] = "person_tone5_white_hair", + ["👩‍🦳"] = "woman_white_haired", + ["👩🏻‍🦳"] = "woman_white_haired_tone1", + ["👩🏼‍🦳"] = "woman_white_haired_tone2", + ["👩🏽‍🦳"] = "woman_white_haired_tone3", + ["👩🏾‍🦳"] = "woman_white_haired_tone4", + ["👩🏿‍🦳"] = "woman_white_haired_tone5", + ["👨‍🦳"] = "man_white_haired", + ["👨🏻‍🦳"] = "man_white_haired_tone1", + ["👨🏼‍🦳"] = "man_white_haired_tone2", + ["👨🏽‍🦳"] = "man_white_haired_tone3", + ["👨🏾‍🦳"] = "man_white_haired_tone4", + ["👨🏿‍🦳"] = "man_white_haired_tone5", + ["🧑‍🦲"] = "person_bald", + ["🧑🏻‍🦲"] = "person_tone1_bald", + ["🧑🏼‍🦲"] = "person_tone2_bald", + ["🧑🏽‍🦲"] = "person_tone3_bald", + ["🧑🏾‍🦲"] = "person_tone4_bald", + ["🧑🏿‍🦲"] = "person_tone5_bald", + ["👩‍🦲"] = "woman_bald", + ["👩🏻‍🦲"] = "woman_bald_tone1", + ["👩🏼‍🦲"] = "woman_bald_tone2", + ["👩🏽‍🦲"] = "woman_bald_tone3", + ["👩🏾‍🦲"] = "woman_bald_tone4", + ["👩🏿‍🦲"] = "woman_bald_tone5", + ["👨‍🦲"] = "man_bald", + ["👨🏻‍🦲"] = "man_bald_tone1", + ["👨🏼‍🦲"] = "man_bald_tone2", + ["👨🏽‍🦲"] = "man_bald_tone3", + ["👨🏾‍🦲"] = "man_bald_tone4", + ["👨🏿‍🦲"] = "man_bald_tone5", + ["🧔"] = "bearded_person", + ["🧔🏻"] = "bearded_person_tone1", + ["🧔🏼"] = "bearded_person_tone2", + ["🧔🏽"] = "bearded_person_tone3", + ["🧔🏾"] = "bearded_person_tone4", + ["🧔🏿"] = "bearded_person_tone5", + ["🧔‍♂️"] = "man_beard", + ["🧔🏻‍♂️"] = "man_tone1_beard", + ["🧔🏼‍♂️"] = "man_tone2_beard", + ["🧔🏽‍♂️"] = "man_tone3_beard", + ["🧔🏾‍♂️"] = "man_tone4_beard", + ["🧔🏿‍♂️"] = "man_tone5_beard", + ["🧔‍♀️"] = "woman_beard", + ["🧔🏻‍♀️"] = "woman_tone1_beard", + ["🧔🏼‍♀️"] = "woman_tone2_beard", + ["🧔🏽‍♀️"] = "woman_tone3_beard", + ["🧔🏾‍♀️"] = "woman_tone4_beard", + ["🧔🏿‍♀️"] = "woman_tone5_beard", + ["👵"] = "older_woman", + ["👵🏻"] = "older_woman_tone1", + ["👵🏼"] = "older_woman_tone2", + ["👵🏽"] = "older_woman_tone3", + ["👵🏾"] = "older_woman_tone4", + ["👵🏿"] = "older_woman_tone5", + ["🧓"] = "older_adult", + ["🧓🏻"] = "older_adult_tone1", + ["🧓🏼"] = "older_adult_tone2", + ["🧓🏽"] = "older_adult_tone3", + ["🧓🏾"] = "older_adult_tone4", + ["🧓🏿"] = "older_adult_tone5", + ["👴"] = "older_man", + ["👴🏻"] = "older_man_tone1", + ["👴🏼"] = "older_man_tone2", + ["👴🏽"] = "older_man_tone3", + ["👴🏾"] = "older_man_tone4", + ["👴🏿"] = "older_man_tone5", + ["👲"] = "man_with_chinese_cap", + ["👲🏻"] = "man_with_chinese_cap_tone1", + ["👲🏼"] = "man_with_chinese_cap_tone2", + ["👲🏽"] = "man_with_chinese_cap_tone3", + ["👲🏾"] = "man_with_chinese_cap_tone4", + ["👲🏿"] = "man_with_chinese_cap_tone5", + ["👳"] = "person_wearing_turban", + ["👳🏻"] = "person_wearing_turban_tone1", + ["👳🏼"] = "person_wearing_turban_tone2", + ["👳🏽"] = "person_wearing_turban_tone3", + ["👳🏾"] = "person_wearing_turban_tone4", + ["👳🏿"] = "person_wearing_turban_tone5", + ["👳‍♀️"] = "woman_wearing_turban", + ["👳🏻‍♀️"] = "woman_wearing_turban_tone1", + ["👳🏼‍♀️"] = "woman_wearing_turban_tone2", + ["👳🏽‍♀️"] = "woman_wearing_turban_tone3", + ["👳🏾‍♀️"] = "woman_wearing_turban_tone4", + ["👳🏿‍♀️"] = "woman_wearing_turban_tone5", + ["👳‍♂️"] = "man_wearing_turban", + ["👳🏻‍♂️"] = "man_wearing_turban_tone1", + ["👳🏼‍♂️"] = "man_wearing_turban_tone2", + ["👳🏽‍♂️"] = "man_wearing_turban_tone3", + ["👳🏾‍♂️"] = "man_wearing_turban_tone4", + ["👳🏿‍♂️"] = "man_wearing_turban_tone5", + ["🧕"] = "woman_with_headscarf", + ["🧕🏻"] = "woman_with_headscarf_tone1", + ["🧕🏼"] = "woman_with_headscarf_tone2", + ["🧕🏽"] = "woman_with_headscarf_tone3", + ["🧕🏾"] = "woman_with_headscarf_tone4", + ["🧕🏿"] = "woman_with_headscarf_tone5", + ["👮"] = "police_officer", + ["👮🏻"] = "police_officer_tone1", + ["👮🏼"] = "police_officer_tone2", + ["👮🏽"] = "police_officer_tone3", + ["👮🏾"] = "police_officer_tone4", + ["👮🏿"] = "police_officer_tone5", + ["👮‍♀️"] = "woman_police_officer", + ["👮🏻‍♀️"] = "woman_police_officer_tone1", + ["👮🏼‍♀️"] = "woman_police_officer_tone2", + ["👮🏽‍♀️"] = "woman_police_officer_tone3", + ["👮🏾‍♀️"] = "woman_police_officer_tone4", + ["👮🏿‍♀️"] = "woman_police_officer_tone5", + ["👮‍♂️"] = "man_police_officer", + ["👮🏻‍♂️"] = "man_police_officer_tone1", + ["👮🏼‍♂️"] = "man_police_officer_tone2", + ["👮🏽‍♂️"] = "man_police_officer_tone3", + ["👮🏾‍♂️"] = "man_police_officer_tone4", + ["👮🏿‍♂️"] = "man_police_officer_tone5", + ["👷"] = "construction_worker", + ["👷🏻"] = "construction_worker_tone1", + ["👷🏼"] = "construction_worker_tone2", + ["👷🏽"] = "construction_worker_tone3", + ["👷🏾"] = "construction_worker_tone4", + ["👷🏿"] = "construction_worker_tone5", + ["👷‍♀️"] = "woman_construction_worker", + ["👷🏻‍♀️"] = "woman_construction_worker_tone1", + ["👷🏼‍♀️"] = "woman_construction_worker_tone2", + ["👷🏽‍♀️"] = "woman_construction_worker_tone3", + ["👷🏾‍♀️"] = "woman_construction_worker_tone4", + ["👷🏿‍♀️"] = "woman_construction_worker_tone5", + ["👷‍♂️"] = "man_construction_worker", + ["👷🏻‍♂️"] = "man_construction_worker_tone1", + ["👷🏼‍♂️"] = "man_construction_worker_tone2", + ["👷🏽‍♂️"] = "man_construction_worker_tone3", + ["👷🏾‍♂️"] = "man_construction_worker_tone4", + ["👷🏿‍♂️"] = "man_construction_worker_tone5", + ["💂"] = "guard", + ["💂🏻"] = "guard_tone1", + ["💂🏼"] = "guard_tone2", + ["💂🏽"] = "guard_tone3", + ["💂🏾"] = "guard_tone4", + ["💂🏿"] = "guard_tone5", + ["💂‍♀️"] = "woman_guard", + ["💂🏻‍♀️"] = "woman_guard_tone1", + ["💂🏼‍♀️"] = "woman_guard_tone2", + ["💂🏽‍♀️"] = "woman_guard_tone3", + ["💂🏾‍♀️"] = "woman_guard_tone4", + ["💂🏿‍♀️"] = "woman_guard_tone5", + ["💂‍♂️"] = "man_guard", + ["💂🏻‍♂️"] = "man_guard_tone1", + ["💂🏼‍♂️"] = "man_guard_tone2", + ["💂🏽‍♂️"] = "man_guard_tone3", + ["💂🏾‍♂️"] = "man_guard_tone4", + ["💂🏿‍♂️"] = "man_guard_tone5", + ["🕵️"] = "detective", + ["🕵🏻"] = "detective_tone1", + ["🕵🏼"] = "detective_tone2", + ["🕵🏽"] = "detective_tone3", + ["🕵🏾"] = "detective_tone4", + ["🕵🏿"] = "detective_tone5", + ["🕵️‍♀️"] = "woman_detective", + ["🕵🏻‍♀️"] = "woman_detective_tone1", + ["🕵🏼‍♀️"] = "woman_detective_tone2", + ["🕵🏽‍♀️"] = "woman_detective_tone3", + ["🕵🏾‍♀️"] = "woman_detective_tone4", + ["🕵🏿‍♀️"] = "woman_detective_tone5", + ["🕵️‍♂️"] = "man_detective", + ["🕵🏻‍♂️"] = "man_detective_tone1", + ["🕵🏼‍♂️"] = "man_detective_tone2", + ["🕵🏽‍♂️"] = "man_detective_tone3", + ["🕵🏾‍♂️"] = "man_detective_tone4", + ["🕵🏿‍♂️"] = "man_detective_tone5", + ["🧑‍⚕️"] = "health_worker", + ["🧑🏻‍⚕️"] = "health_worker_tone1", + ["🧑🏼‍⚕️"] = "health_worker_tone2", + ["🧑🏽‍⚕️"] = "health_worker_tone3", + ["🧑🏾‍⚕️"] = "health_worker_tone4", + ["🧑🏿‍⚕️"] = "health_worker_tone5", + ["👩‍⚕️"] = "woman_health_worker", + ["👩🏻‍⚕️"] = "woman_health_worker_tone1", + ["👩🏼‍⚕️"] = "woman_health_worker_tone2", + ["👩🏽‍⚕️"] = "woman_health_worker_tone3", + ["👩🏾‍⚕️"] = "woman_health_worker_tone4", + ["👩🏿‍⚕️"] = "woman_health_worker_tone5", + ["👨‍⚕️"] = "man_health_worker", + ["👨🏻‍⚕️"] = "man_health_worker_tone1", + ["👨🏼‍⚕️"] = "man_health_worker_tone2", + ["👨🏽‍⚕️"] = "man_health_worker_tone3", + ["👨🏾‍⚕️"] = "man_health_worker_tone4", + ["👨🏿‍⚕️"] = "man_health_worker_tone5", + ["🧑‍🌾"] = "farmer", + ["🧑🏻‍🌾"] = "farmer_tone1", + ["🧑🏼‍🌾"] = "farmer_tone2", + ["🧑🏽‍🌾"] = "farmer_tone3", + ["🧑🏾‍🌾"] = "farmer_tone4", + ["🧑🏿‍🌾"] = "farmer_tone5", + ["👩‍🌾"] = "woman_farmer", + ["👩🏻‍🌾"] = "woman_farmer_tone1", + ["👩🏼‍🌾"] = "woman_farmer_tone2", + ["👩🏽‍🌾"] = "woman_farmer_tone3", + ["👩🏾‍🌾"] = "woman_farmer_tone4", + ["👩🏿‍🌾"] = "woman_farmer_tone5", + ["👨‍🌾"] = "man_farmer", + ["👨🏻‍🌾"] = "man_farmer_tone1", + ["👨🏼‍🌾"] = "man_farmer_tone2", + ["👨🏽‍🌾"] = "man_farmer_tone3", + ["👨🏾‍🌾"] = "man_farmer_tone4", + ["👨🏿‍🌾"] = "man_farmer_tone5", + ["🧑‍🍳"] = "cook", + ["🧑🏻‍🍳"] = "cook_tone1", + ["🧑🏼‍🍳"] = "cook_tone2", + ["🧑🏽‍🍳"] = "cook_tone3", + ["🧑🏾‍🍳"] = "cook_tone4", + ["🧑🏿‍🍳"] = "cook_tone5", + ["👩‍🍳"] = "woman_cook", + ["👩🏻‍🍳"] = "woman_cook_tone1", + ["👩🏼‍🍳"] = "woman_cook_tone2", + ["👩🏽‍🍳"] = "woman_cook_tone3", + ["👩🏾‍🍳"] = "woman_cook_tone4", + ["👩🏿‍🍳"] = "woman_cook_tone5", + ["👨‍🍳"] = "man_cook", + ["👨🏻‍🍳"] = "man_cook_tone1", + ["👨🏼‍🍳"] = "man_cook_tone2", + ["👨🏽‍🍳"] = "man_cook_tone3", + ["👨🏾‍🍳"] = "man_cook_tone4", + ["👨🏿‍🍳"] = "man_cook_tone5", + ["🧑‍🎓"] = "student", + ["🧑🏻‍🎓"] = "student_tone1", + ["🧑🏼‍🎓"] = "student_tone2", + ["🧑🏽‍🎓"] = "student_tone3", + ["🧑🏾‍🎓"] = "student_tone4", + ["🧑🏿‍🎓"] = "student_tone5", + ["👩‍🎓"] = "woman_student", + ["👩🏻‍🎓"] = "woman_student_tone1", + ["👩🏼‍🎓"] = "woman_student_tone2", + ["👩🏽‍🎓"] = "woman_student_tone3", + ["👩🏾‍🎓"] = "woman_student_tone4", + ["👩🏿‍🎓"] = "woman_student_tone5", + ["👨‍🎓"] = "man_student", + ["👨🏻‍🎓"] = "man_student_tone1", + ["👨🏼‍🎓"] = "man_student_tone2", + ["👨🏽‍🎓"] = "man_student_tone3", + ["👨🏾‍🎓"] = "man_student_tone4", + ["👨🏿‍🎓"] = "man_student_tone5", + ["🧑‍🎤"] = "singer", + ["🧑🏻‍🎤"] = "singer_tone1", + ["🧑🏼‍🎤"] = "singer_tone2", + ["🧑🏽‍🎤"] = "singer_tone3", + ["🧑🏾‍🎤"] = "singer_tone4", + ["🧑🏿‍🎤"] = "singer_tone5", + ["👩‍🎤"] = "woman_singer", + ["👩🏻‍🎤"] = "woman_singer_tone1", + ["👩🏼‍🎤"] = "woman_singer_tone2", + ["👩🏽‍🎤"] = "woman_singer_tone3", + ["👩🏾‍🎤"] = "woman_singer_tone4", + ["👩🏿‍🎤"] = "woman_singer_tone5", + ["👨‍🎤"] = "man_singer", + ["👨🏻‍🎤"] = "man_singer_tone1", + ["👨🏼‍🎤"] = "man_singer_tone2", + ["👨🏽‍🎤"] = "man_singer_tone3", + ["👨🏾‍🎤"] = "man_singer_tone4", + ["👨🏿‍🎤"] = "man_singer_tone5", + ["🧑‍🏫"] = "teacher", + ["🧑🏻‍🏫"] = "teacher_tone1", + ["🧑🏼‍🏫"] = "teacher_tone2", + ["🧑🏽‍🏫"] = "teacher_tone3", + ["🧑🏾‍🏫"] = "teacher_tone4", + ["🧑🏿‍🏫"] = "teacher_tone5", + ["👩‍🏫"] = "woman_teacher", + ["👩🏻‍🏫"] = "woman_teacher_tone1", + ["👩🏼‍🏫"] = "woman_teacher_tone2", + ["👩🏽‍🏫"] = "woman_teacher_tone3", + ["👩🏾‍🏫"] = "woman_teacher_tone4", + ["👩🏿‍🏫"] = "woman_teacher_tone5", + ["👨‍🏫"] = "man_teacher", + ["👨🏻‍🏫"] = "man_teacher_tone1", + ["👨🏼‍🏫"] = "man_teacher_tone2", + ["👨🏽‍🏫"] = "man_teacher_tone3", + ["👨🏾‍🏫"] = "man_teacher_tone4", + ["👨🏿‍🏫"] = "man_teacher_tone5", + ["🧑‍🏭"] = "factory_worker", + ["🧑🏻‍🏭"] = "factory_worker_tone1", + ["🧑🏼‍🏭"] = "factory_worker_tone2", + ["🧑🏽‍🏭"] = "factory_worker_tone3", + ["🧑🏾‍🏭"] = "factory_worker_tone4", + ["🧑🏿‍🏭"] = "factory_worker_tone5", + ["👩‍🏭"] = "woman_factory_worker", + ["👩🏻‍🏭"] = "woman_factory_worker_tone1", + ["👩🏼‍🏭"] = "woman_factory_worker_tone2", + ["👩🏽‍🏭"] = "woman_factory_worker_tone3", + ["👩🏾‍🏭"] = "woman_factory_worker_tone4", + ["👩🏿‍🏭"] = "woman_factory_worker_tone5", + ["👨‍🏭"] = "man_factory_worker", + ["👨🏻‍🏭"] = "man_factory_worker_tone1", + ["👨🏼‍🏭"] = "man_factory_worker_tone2", + ["👨🏽‍🏭"] = "man_factory_worker_tone3", + ["👨🏾‍🏭"] = "man_factory_worker_tone4", + ["👨🏿‍🏭"] = "man_factory_worker_tone5", + ["🧑‍💻"] = "technologist", + ["🧑🏻‍💻"] = "technologist_tone1", + ["🧑🏼‍💻"] = "technologist_tone2", + ["🧑🏽‍💻"] = "technologist_tone3", + ["🧑🏾‍💻"] = "technologist_tone4", + ["🧑🏿‍💻"] = "technologist_tone5", + ["👩‍💻"] = "woman_technologist", + ["👩🏻‍💻"] = "woman_technologist_tone1", + ["👩🏼‍💻"] = "woman_technologist_tone2", + ["👩🏽‍💻"] = "woman_technologist_tone3", + ["👩🏾‍💻"] = "woman_technologist_tone4", + ["👩🏿‍💻"] = "woman_technologist_tone5", + ["👨‍💻"] = "man_technologist", + ["👨🏻‍💻"] = "man_technologist_tone1", + ["👨🏼‍💻"] = "man_technologist_tone2", + ["👨🏽‍💻"] = "man_technologist_tone3", + ["👨🏾‍💻"] = "man_technologist_tone4", + ["👨🏿‍💻"] = "man_technologist_tone5", + ["🧑‍💼"] = "office_worker", + ["🧑🏻‍💼"] = "office_worker_tone1", + ["🧑🏼‍💼"] = "office_worker_tone2", + ["🧑🏽‍💼"] = "office_worker_tone3", + ["🧑🏾‍💼"] = "office_worker_tone4", + ["🧑🏿‍💼"] = "office_worker_tone5", + ["👩‍💼"] = "woman_office_worker", + ["👩🏻‍💼"] = "woman_office_worker_tone1", + ["👩🏼‍💼"] = "woman_office_worker_tone2", + ["👩🏽‍💼"] = "woman_office_worker_tone3", + ["👩🏾‍💼"] = "woman_office_worker_tone4", + ["👩🏿‍💼"] = "woman_office_worker_tone5", + ["👨‍💼"] = "man_office_worker", + ["👨🏻‍💼"] = "man_office_worker_tone1", + ["👨🏼‍💼"] = "man_office_worker_tone2", + ["👨🏽‍💼"] = "man_office_worker_tone3", + ["👨🏾‍💼"] = "man_office_worker_tone4", + ["👨🏿‍💼"] = "man_office_worker_tone5", + ["🧑‍🔧"] = "mechanic", + ["🧑🏻‍🔧"] = "mechanic_tone1", + ["🧑🏼‍🔧"] = "mechanic_tone2", + ["🧑🏽‍🔧"] = "mechanic_tone3", + ["🧑🏾‍🔧"] = "mechanic_tone4", + ["🧑🏿‍🔧"] = "mechanic_tone5", + ["👩‍🔧"] = "woman_mechanic", + ["👩🏻‍🔧"] = "woman_mechanic_tone1", + ["👩🏼‍🔧"] = "woman_mechanic_tone2", + ["👩🏽‍🔧"] = "woman_mechanic_tone3", + ["👩🏾‍🔧"] = "woman_mechanic_tone4", + ["👩🏿‍🔧"] = "woman_mechanic_tone5", + ["👨‍🔧"] = "man_mechanic", + ["👨🏻‍🔧"] = "man_mechanic_tone1", + ["👨🏼‍🔧"] = "man_mechanic_tone2", + ["👨🏽‍🔧"] = "man_mechanic_tone3", + ["👨🏾‍🔧"] = "man_mechanic_tone4", + ["👨🏿‍🔧"] = "man_mechanic_tone5", + ["🧑‍🔬"] = "scientist", + ["🧑🏻‍🔬"] = "scientist_tone1", + ["🧑🏼‍🔬"] = "scientist_tone2", + ["🧑🏽‍🔬"] = "scientist_tone3", + ["🧑🏾‍🔬"] = "scientist_tone4", + ["🧑🏿‍🔬"] = "scientist_tone5", + ["👩‍🔬"] = "woman_scientist", + ["👩🏻‍🔬"] = "woman_scientist_tone1", + ["👩🏼‍🔬"] = "woman_scientist_tone2", + ["👩🏽‍🔬"] = "woman_scientist_tone3", + ["👩🏾‍🔬"] = "woman_scientist_tone4", + ["👩🏿‍🔬"] = "woman_scientist_tone5", + ["👨‍🔬"] = "man_scientist", + ["👨🏻‍🔬"] = "man_scientist_tone1", + ["👨🏼‍🔬"] = "man_scientist_tone2", + ["👨🏽‍🔬"] = "man_scientist_tone3", + ["👨🏾‍🔬"] = "man_scientist_tone4", + ["👨🏿‍🔬"] = "man_scientist_tone5", + ["🧑‍🎨"] = "artist", + ["🧑🏻‍🎨"] = "artist_tone1", + ["🧑🏼‍🎨"] = "artist_tone2", + ["🧑🏽‍🎨"] = "artist_tone3", + ["🧑🏾‍🎨"] = "artist_tone4", + ["🧑🏿‍🎨"] = "artist_tone5", + ["👩‍🎨"] = "woman_artist", + ["👩🏻‍🎨"] = "woman_artist_tone1", + ["👩🏼‍🎨"] = "woman_artist_tone2", + ["👩🏽‍🎨"] = "woman_artist_tone3", + ["👩🏾‍🎨"] = "woman_artist_tone4", + ["👩🏿‍🎨"] = "woman_artist_tone5", + ["👨‍🎨"] = "man_artist", + ["👨🏻‍🎨"] = "man_artist_tone1", + ["👨🏼‍🎨"] = "man_artist_tone2", + ["👨🏽‍🎨"] = "man_artist_tone3", + ["👨🏾‍🎨"] = "man_artist_tone4", + ["👨🏿‍🎨"] = "man_artist_tone5", + ["🧑‍🚒"] = "firefighter", + ["🧑🏻‍🚒"] = "firefighter_tone1", + ["🧑🏼‍🚒"] = "firefighter_tone2", + ["🧑🏽‍🚒"] = "firefighter_tone3", + ["🧑🏾‍🚒"] = "firefighter_tone4", + ["🧑🏿‍🚒"] = "firefighter_tone5", + ["👩‍🚒"] = "woman_firefighter", + ["👩🏻‍🚒"] = "woman_firefighter_tone1", + ["👩🏼‍🚒"] = "woman_firefighter_tone2", + ["👩🏽‍🚒"] = "woman_firefighter_tone3", + ["👩🏾‍🚒"] = "woman_firefighter_tone4", + ["👩🏿‍🚒"] = "woman_firefighter_tone5", + ["👨‍🚒"] = "man_firefighter", + ["👨🏻‍🚒"] = "man_firefighter_tone1", + ["👨🏼‍🚒"] = "man_firefighter_tone2", + ["👨🏽‍🚒"] = "man_firefighter_tone3", + ["👨🏾‍🚒"] = "man_firefighter_tone4", + ["👨🏿‍🚒"] = "man_firefighter_tone5", + ["🧑‍✈️"] = "pilot", + ["🧑🏻‍✈️"] = "pilot_tone1", + ["🧑🏼‍✈️"] = "pilot_tone2", + ["🧑🏽‍✈️"] = "pilot_tone3", + ["🧑🏾‍✈️"] = "pilot_tone4", + ["🧑🏿‍✈️"] = "pilot_tone5", + ["👩‍✈️"] = "woman_pilot", + ["👩🏻‍✈️"] = "woman_pilot_tone1", + ["👩🏼‍✈️"] = "woman_pilot_tone2", + ["👩🏽‍✈️"] = "woman_pilot_tone3", + ["👩🏾‍✈️"] = "woman_pilot_tone4", + ["👩🏿‍✈️"] = "woman_pilot_tone5", + ["👨‍✈️"] = "man_pilot", + ["👨🏻‍✈️"] = "man_pilot_tone1", + ["👨🏼‍✈️"] = "man_pilot_tone2", + ["👨🏽‍✈️"] = "man_pilot_tone3", + ["👨🏾‍✈️"] = "man_pilot_tone4", + ["👨🏿‍✈️"] = "man_pilot_tone5", + ["🧑‍🚀"] = "astronaut", + ["🧑🏻‍🚀"] = "astronaut_tone1", + ["🧑🏼‍🚀"] = "astronaut_tone2", + ["🧑🏽‍🚀"] = "astronaut_tone3", + ["🧑🏾‍🚀"] = "astronaut_tone4", + ["🧑🏿‍🚀"] = "astronaut_tone5", + ["👩‍🚀"] = "woman_astronaut", + ["👩🏻‍🚀"] = "woman_astronaut_tone1", + ["👩🏼‍🚀"] = "woman_astronaut_tone2", + ["👩🏽‍🚀"] = "woman_astronaut_tone3", + ["👩🏾‍🚀"] = "woman_astronaut_tone4", + ["👩🏿‍🚀"] = "woman_astronaut_tone5", + ["👨‍🚀"] = "man_astronaut", + ["👨🏻‍🚀"] = "man_astronaut_tone1", + ["👨🏼‍🚀"] = "man_astronaut_tone2", + ["👨🏽‍🚀"] = "man_astronaut_tone3", + ["👨🏾‍🚀"] = "man_astronaut_tone4", + ["👨🏿‍🚀"] = "man_astronaut_tone5", + ["🧑‍⚖️"] = "judge", + ["🧑🏻‍⚖️"] = "judge_tone1", + ["🧑🏼‍⚖️"] = "judge_tone2", + ["🧑🏽‍⚖️"] = "judge_tone3", + ["🧑🏾‍⚖️"] = "judge_tone4", + ["🧑🏿‍⚖️"] = "judge_tone5", + ["👩‍⚖️"] = "woman_judge", + ["👩🏻‍⚖️"] = "woman_judge_tone1", + ["👩🏼‍⚖️"] = "woman_judge_tone2", + ["👩🏽‍⚖️"] = "woman_judge_tone3", + ["👩🏾‍⚖️"] = "woman_judge_tone4", + ["👩🏿‍⚖️"] = "woman_judge_tone5", + ["👨‍⚖️"] = "man_judge", + ["👨🏻‍⚖️"] = "man_judge_tone1", + ["👨🏼‍⚖️"] = "man_judge_tone2", + ["👨🏽‍⚖️"] = "man_judge_tone3", + ["👨🏾‍⚖️"] = "man_judge_tone4", + ["👨🏿‍⚖️"] = "man_judge_tone5", + ["👰"] = "person_with_veil", + ["👰🏻"] = "person_with_veil_tone1", + ["👰🏼"] = "person_with_veil_tone2", + ["👰🏽"] = "person_with_veil_tone3", + ["👰🏾"] = "person_with_veil_tone4", + ["👰🏿"] = "person_with_veil_tone5", + ["👰‍♀️"] = "woman_with_veil", + ["👰🏻‍♀️"] = "woman_with_veil_tone1", + ["👰🏼‍♀️"] = "woman_with_veil_tone2", + ["👰🏽‍♀️"] = "woman_with_veil_tone3", + ["👰🏾‍♀️"] = "woman_with_veil_tone4", + ["👰🏿‍♀️"] = "woman_with_veil_tone5", + ["👰‍♂️"] = "man_with_veil", + ["👰🏻‍♂️"] = "man_with_veil_tone1", + ["👰🏼‍♂️"] = "man_with_veil_tone2", + ["👰🏽‍♂️"] = "man_with_veil_tone3", + ["👰🏾‍♂️"] = "man_with_veil_tone4", + ["👰🏿‍♂️"] = "man_with_veil_tone5", + ["🤵"] = "person_in_tuxedo", + ["🤵🏻"] = "person_in_tuxedo_tone1", + ["🤵🏼"] = "person_in_tuxedo_tone2", + ["🤵🏽"] = "person_in_tuxedo_tone3", + ["🤵🏾"] = "person_in_tuxedo_tone4", + ["🤵🏿"] = "person_in_tuxedo_tone5", + ["🤵‍♀️"] = "woman_in_tuxedo", + ["🤵🏻‍♀️"] = "woman_in_tuxedo_tone1", + ["🤵🏼‍♀️"] = "woman_in_tuxedo_tone2", + ["🤵🏽‍♀️"] = "woman_in_tuxedo_tone3", + ["🤵🏾‍♀️"] = "woman_in_tuxedo_tone4", + ["🤵🏿‍♀️"] = "woman_in_tuxedo_tone5", + ["🤵‍♂️"] = "man_in_tuxedo", + ["🤵🏻‍♂️"] = "man_in_tuxedo_tone1", + ["🤵🏼‍♂️"] = "man_in_tuxedo_tone2", + ["🤵🏽‍♂️"] = "man_in_tuxedo_tone3", + ["🤵🏾‍♂️"] = "man_in_tuxedo_tone4", + ["🤵🏿‍♂️"] = "man_in_tuxedo_tone5", + ["👸"] = "princess", + ["👸🏻"] = "princess_tone1", + ["👸🏼"] = "princess_tone2", + ["👸🏽"] = "princess_tone3", + ["👸🏾"] = "princess_tone4", + ["👸🏿"] = "princess_tone5", + ["🤴"] = "prince", + ["🤴🏻"] = "prince_tone1", + ["🤴🏼"] = "prince_tone2", + ["🤴🏽"] = "prince_tone3", + ["🤴🏾"] = "prince_tone4", + ["🤴🏿"] = "prince_tone5", + ["🦸"] = "superhero", + ["🦸🏻"] = "superhero_tone1", + ["🦸🏼"] = "superhero_tone2", + ["🦸🏽"] = "superhero_tone3", + ["🦸🏾"] = "superhero_tone4", + ["🦸🏿"] = "superhero_tone5", + ["🦸‍♀️"] = "woman_superhero", + ["🦸🏻‍♀️"] = "woman_superhero_tone1", + ["🦸🏼‍♀️"] = "woman_superhero_tone2", + ["🦸🏽‍♀️"] = "woman_superhero_tone3", + ["🦸🏾‍♀️"] = "woman_superhero_tone4", + ["🦸🏿‍♀️"] = "woman_superhero_tone5", + ["🦸‍♂️"] = "man_superhero", + ["🦸🏻‍♂️"] = "man_superhero_tone1", + ["🦸🏼‍♂️"] = "man_superhero_tone2", + ["🦸🏽‍♂️"] = "man_superhero_tone3", + ["🦸🏾‍♂️"] = "man_superhero_tone4", + ["🦸🏿‍♂️"] = "man_superhero_tone5", + ["🦹"] = "supervillain", + ["🦹🏻"] = "supervillain_tone1", + ["🦹🏼"] = "supervillain_tone2", + ["🦹🏽"] = "supervillain_tone3", + ["🦹🏾"] = "supervillain_tone4", + ["🦹🏿"] = "supervillain_tone5", + ["🦹‍♀️"] = "woman_supervillain", + ["🦹🏻‍♀️"] = "woman_supervillain_tone1", + ["🦹🏼‍♀️"] = "woman_supervillain_tone2", + ["🦹🏽‍♀️"] = "woman_supervillain_tone3", + ["🦹🏾‍♀️"] = "woman_supervillain_tone4", + ["🦹🏿‍♀️"] = "woman_supervillain_tone5", + ["🦹‍♂️"] = "man_supervillain", + ["🦹🏻‍♂️"] = "man_supervillain_tone1", + ["🦹🏼‍♂️"] = "man_supervillain_tone2", + ["🦹🏽‍♂️"] = "man_supervillain_tone3", + ["🦹🏾‍♂️"] = "man_supervillain_tone4", + ["🦹🏿‍♂️"] = "man_supervillain_tone5", + ["🥷"] = "ninja", + ["🥷🏻"] = "ninja_tone1", + ["🥷🏼"] = "ninja_tone2", + ["🥷🏽"] = "ninja_tone3", + ["🥷🏾"] = "ninja_tone4", + ["🥷🏿"] = "ninja_tone5", + ["🧑‍🎄"] = "mx_claus", + ["🧑🏻‍🎄"] = "mx_claus_tone1", + ["🧑🏼‍🎄"] = "mx_claus_tone2", + ["🧑🏽‍🎄"] = "mx_claus_tone3", + ["🧑🏾‍🎄"] = "mx_claus_tone4", + ["🧑🏿‍🎄"] = "mx_claus_tone5", + ["🤶"] = "mrs_claus", + ["🤶🏻"] = "mrs_claus_tone1", + ["🤶🏼"] = "mrs_claus_tone2", + ["🤶🏽"] = "mrs_claus_tone3", + ["🤶🏾"] = "mrs_claus_tone4", + ["🤶🏿"] = "mrs_claus_tone5", + ["🎅"] = "santa", + ["🎅🏻"] = "santa_tone1", + ["🎅🏼"] = "santa_tone2", + ["🎅🏽"] = "santa_tone3", + ["🎅🏾"] = "santa_tone4", + ["🎅🏿"] = "santa_tone5", + ["🧙"] = "mage", + ["🧙🏻"] = "mage_tone1", + ["🧙🏼"] = "mage_tone2", + ["🧙🏽"] = "mage_tone3", + ["🧙🏾"] = "mage_tone4", + ["🧙🏿"] = "mage_tone5", + ["🧙‍♀️"] = "woman_mage", + ["🧙🏻‍♀️"] = "woman_mage_tone1", + ["🧙🏼‍♀️"] = "woman_mage_tone2", + ["🧙🏽‍♀️"] = "woman_mage_tone3", + ["🧙🏾‍♀️"] = "woman_mage_tone4", + ["🧙🏿‍♀️"] = "woman_mage_tone5", + ["🧙‍♂️"] = "man_mage", + ["🧙🏻‍♂️"] = "man_mage_tone1", + ["🧙🏼‍♂️"] = "man_mage_tone2", + ["🧙🏽‍♂️"] = "man_mage_tone3", + ["🧙🏾‍♂️"] = "man_mage_tone4", + ["🧙🏿‍♂️"] = "man_mage_tone5", + ["🧝"] = "elf", + ["🧝🏻"] = "elf_tone1", + ["🧝🏼"] = "elf_tone2", + ["🧝🏽"] = "elf_tone3", + ["🧝🏾"] = "elf_tone4", + ["🧝🏿"] = "elf_tone5", + ["🧝‍♀️"] = "woman_elf", + ["🧝🏻‍♀️"] = "woman_elf_tone1", + ["🧝🏼‍♀️"] = "woman_elf_tone2", + ["🧝🏽‍♀️"] = "woman_elf_tone3", + ["🧝🏾‍♀️"] = "woman_elf_tone4", + ["🧝🏿‍♀️"] = "woman_elf_tone5", + ["🧝‍♂️"] = "man_elf", + ["🧝🏻‍♂️"] = "man_elf_tone1", + ["🧝🏼‍♂️"] = "man_elf_tone2", + ["🧝🏽‍♂️"] = "man_elf_tone3", + ["🧝🏾‍♂️"] = "man_elf_tone4", + ["🧝🏿‍♂️"] = "man_elf_tone5", + ["🧛"] = "vampire", + ["🧛🏻"] = "vampire_tone1", + ["🧛🏼"] = "vampire_tone2", + ["🧛🏽"] = "vampire_tone3", + ["🧛🏾"] = "vampire_tone4", + ["🧛🏿"] = "vampire_tone5", + ["🧛‍♀️"] = "woman_vampire", + ["🧛🏻‍♀️"] = "woman_vampire_tone1", + ["🧛🏼‍♀️"] = "woman_vampire_tone2", + ["🧛🏽‍♀️"] = "woman_vampire_tone3", + ["🧛🏾‍♀️"] = "woman_vampire_tone4", + ["🧛🏿‍♀️"] = "woman_vampire_tone5", + ["🧛‍♂️"] = "man_vampire", + ["🧛🏻‍♂️"] = "man_vampire_tone1", + ["🧛🏼‍♂️"] = "man_vampire_tone2", + ["🧛🏽‍♂️"] = "man_vampire_tone3", + ["🧛🏾‍♂️"] = "man_vampire_tone4", + ["🧛🏿‍♂️"] = "man_vampire_tone5", + ["🧟"] = "zombie", + ["🧟‍♀️"] = "woman_zombie", + ["🧟‍♂️"] = "man_zombie", + ["🧞"] = "genie", + ["🧞‍♀️"] = "woman_genie", + ["🧞‍♂️"] = "man_genie", + ["🧜"] = "merperson", + ["🧜🏻"] = "merperson_tone1", + ["🧜🏼"] = "merperson_tone2", + ["🧜🏽"] = "merperson_tone3", + ["🧜🏾"] = "merperson_tone4", + ["🧜🏿"] = "merperson_tone5", + ["🧜‍♀️"] = "mermaid", + ["🧜🏻‍♀️"] = "mermaid_tone1", + ["🧜🏼‍♀️"] = "mermaid_tone2", + ["🧜🏽‍♀️"] = "mermaid_tone3", + ["🧜🏾‍♀️"] = "mermaid_tone4", + ["🧜🏿‍♀️"] = "mermaid_tone5", + ["🧜‍♂️"] = "merman", + ["🧜🏻‍♂️"] = "merman_tone1", + ["🧜🏼‍♂️"] = "merman_tone2", + ["🧜🏽‍♂️"] = "merman_tone3", + ["🧜🏾‍♂️"] = "merman_tone4", + ["🧜🏿‍♂️"] = "merman_tone5", + ["🧚"] = "fairy", + ["🧚🏻"] = "fairy_tone1", + ["🧚🏼"] = "fairy_tone2", + ["🧚🏽"] = "fairy_tone3", + ["🧚🏾"] = "fairy_tone4", + ["🧚🏿"] = "fairy_tone5", + ["🧚‍♀️"] = "woman_fairy", + ["🧚🏻‍♀️"] = "woman_fairy_tone1", + ["🧚🏼‍♀️"] = "woman_fairy_tone2", + ["🧚🏽‍♀️"] = "woman_fairy_tone3", + ["🧚🏾‍♀️"] = "woman_fairy_tone4", + ["🧚🏿‍♀️"] = "woman_fairy_tone5", + ["🧚‍♂️"] = "man_fairy", + ["🧚🏻‍♂️"] = "man_fairy_tone1", + ["🧚🏼‍♂️"] = "man_fairy_tone2", + ["🧚🏽‍♂️"] = "man_fairy_tone3", + ["🧚🏾‍♂️"] = "man_fairy_tone4", + ["🧚🏿‍♂️"] = "man_fairy_tone5", + ["👼"] = "angel", + ["👼🏻"] = "angel_tone1", + ["👼🏼"] = "angel_tone2", + ["👼🏽"] = "angel_tone3", + ["👼🏾"] = "angel_tone4", + ["👼🏿"] = "angel_tone5", + ["🤰"] = "pregnant_woman", + ["🤰🏻"] = "pregnant_woman_tone1", + ["🤰🏼"] = "pregnant_woman_tone2", + ["🤰🏽"] = "pregnant_woman_tone3", + ["🤰🏾"] = "pregnant_woman_tone4", + ["🤰🏿"] = "pregnant_woman_tone5", + ["🤱"] = "breast_feeding", + ["🤱🏻"] = "breast_feeding_tone1", + ["🤱🏼"] = "breast_feeding_tone2", + ["🤱🏽"] = "breast_feeding_tone3", + ["🤱🏾"] = "breast_feeding_tone4", + ["🤱🏿"] = "breast_feeding_tone5", + ["🧑‍🍼"] = "person_feeding_baby", + ["🧑🏻‍🍼"] = "person_feeding_baby_tone1", + ["🧑🏼‍🍼"] = "person_feeding_baby_tone2", + ["🧑🏽‍🍼"] = "person_feeding_baby_tone3", + ["🧑🏾‍🍼"] = "person_feeding_baby_tone4", + ["🧑🏿‍🍼"] = "person_feeding_baby_tone5", + ["👩‍🍼"] = "woman_feeding_baby", + ["👩🏻‍🍼"] = "woman_feeding_baby_tone1", + ["👩🏼‍🍼"] = "woman_feeding_baby_tone2", + ["👩🏽‍🍼"] = "woman_feeding_baby_tone3", + ["👩🏾‍🍼"] = "woman_feeding_baby_tone4", + ["👩🏿‍🍼"] = "woman_feeding_baby_tone5", + ["👨‍🍼"] = "man_feeding_baby", + ["👨🏻‍🍼"] = "man_feeding_baby_tone1", + ["👨🏼‍🍼"] = "man_feeding_baby_tone2", + ["👨🏽‍🍼"] = "man_feeding_baby_tone3", + ["👨🏾‍🍼"] = "man_feeding_baby_tone4", + ["👨🏿‍🍼"] = "man_feeding_baby_tone5", + ["🙇"] = "person_bowing", + ["🙇🏻"] = "person_bowing_tone1", + ["🙇🏼"] = "person_bowing_tone2", + ["🙇🏽"] = "person_bowing_tone3", + ["🙇🏾"] = "person_bowing_tone4", + ["🙇🏿"] = "person_bowing_tone5", + ["🙇‍♀️"] = "woman_bowing", + ["🙇🏻‍♀️"] = "woman_bowing_tone1", + ["🙇🏼‍♀️"] = "woman_bowing_tone2", + ["🙇🏽‍♀️"] = "woman_bowing_tone3", + ["🙇🏾‍♀️"] = "woman_bowing_tone4", + ["🙇🏿‍♀️"] = "woman_bowing_tone5", + ["🙇‍♂️"] = "man_bowing", + ["🙇🏻‍♂️"] = "man_bowing_tone1", + ["🙇🏼‍♂️"] = "man_bowing_tone2", + ["🙇🏽‍♂️"] = "man_bowing_tone3", + ["🙇🏾‍♂️"] = "man_bowing_tone4", + ["🙇🏿‍♂️"] = "man_bowing_tone5", + ["💁"] = "person_tipping_hand", + ["💁🏻"] = "person_tipping_hand_tone1", + ["💁🏼"] = "person_tipping_hand_tone2", + ["💁🏽"] = "person_tipping_hand_tone3", + ["💁🏾"] = "person_tipping_hand_tone4", + ["💁🏿"] = "person_tipping_hand_tone5", + ["💁‍♀️"] = "woman_tipping_hand", + ["💁🏻‍♀️"] = "woman_tipping_hand_tone1", + ["💁🏼‍♀️"] = "woman_tipping_hand_tone2", + ["💁🏽‍♀️"] = "woman_tipping_hand_tone3", + ["💁🏾‍♀️"] = "woman_tipping_hand_tone4", + ["💁🏿‍♀️"] = "woman_tipping_hand_tone5", + ["💁‍♂️"] = "man_tipping_hand", + ["💁🏻‍♂️"] = "man_tipping_hand_tone1", + ["💁🏼‍♂️"] = "man_tipping_hand_tone2", + ["💁🏽‍♂️"] = "man_tipping_hand_tone3", + ["💁🏾‍♂️"] = "man_tipping_hand_tone4", + ["💁🏿‍♂️"] = "man_tipping_hand_tone5", + ["🙅"] = "person_gesturing_no", + ["🙅🏻"] = "person_gesturing_no_tone1", + ["🙅🏼"] = "person_gesturing_no_tone2", + ["🙅🏽"] = "person_gesturing_no_tone3", + ["🙅🏾"] = "person_gesturing_no_tone4", + ["🙅🏿"] = "person_gesturing_no_tone5", + ["🙅‍♀️"] = "woman_gesturing_no", + ["🙅🏻‍♀️"] = "woman_gesturing_no_tone1", + ["🙅🏼‍♀️"] = "woman_gesturing_no_tone2", + ["🙅🏽‍♀️"] = "woman_gesturing_no_tone3", + ["🙅🏾‍♀️"] = "woman_gesturing_no_tone4", + ["🙅🏿‍♀️"] = "woman_gesturing_no_tone5", + ["🙅‍♂️"] = "man_gesturing_no", + ["🙅🏻‍♂️"] = "man_gesturing_no_tone1", + ["🙅🏼‍♂️"] = "man_gesturing_no_tone2", + ["🙅🏽‍♂️"] = "man_gesturing_no_tone3", + ["🙅🏾‍♂️"] = "man_gesturing_no_tone4", + ["🙅🏿‍♂️"] = "man_gesturing_no_tone5", + ["🙆"] = "person_gesturing_ok", + ["🙆🏻"] = "person_gesturing_ok_tone1", + ["🙆🏼"] = "person_gesturing_ok_tone2", + ["🙆🏽"] = "person_gesturing_ok_tone3", + ["🙆🏾"] = "person_gesturing_ok_tone4", + ["🙆🏿"] = "person_gesturing_ok_tone5", + ["🙆‍♀️"] = "woman_gesturing_ok", + ["🙆🏻‍♀️"] = "woman_gesturing_ok_tone1", + ["🙆🏼‍♀️"] = "woman_gesturing_ok_tone2", + ["🙆🏽‍♀️"] = "woman_gesturing_ok_tone3", + ["🙆🏾‍♀️"] = "woman_gesturing_ok_tone4", + ["🙆🏿‍♀️"] = "woman_gesturing_ok_tone5", + ["🙆‍♂️"] = "man_gesturing_ok", + ["🙆🏻‍♂️"] = "man_gesturing_ok_tone1", + ["🙆🏼‍♂️"] = "man_gesturing_ok_tone2", + ["🙆🏽‍♂️"] = "man_gesturing_ok_tone3", + ["🙆🏾‍♂️"] = "man_gesturing_ok_tone4", + ["🙆🏿‍♂️"] = "man_gesturing_ok_tone5", + ["🙋"] = "person_raising_hand", + ["🙋🏻"] = "person_raising_hand_tone1", + ["🙋🏼"] = "person_raising_hand_tone2", + ["🙋🏽"] = "person_raising_hand_tone3", + ["🙋🏾"] = "person_raising_hand_tone4", + ["🙋🏿"] = "person_raising_hand_tone5", + ["🙋‍♀️"] = "woman_raising_hand", + ["🙋🏻‍♀️"] = "woman_raising_hand_tone1", + ["🙋🏼‍♀️"] = "woman_raising_hand_tone2", + ["🙋🏽‍♀️"] = "woman_raising_hand_tone3", + ["🙋🏾‍♀️"] = "woman_raising_hand_tone4", + ["🙋🏿‍♀️"] = "woman_raising_hand_tone5", + ["🙋‍♂️"] = "man_raising_hand", + ["🙋🏻‍♂️"] = "man_raising_hand_tone1", + ["🙋🏼‍♂️"] = "man_raising_hand_tone2", + ["🙋🏽‍♂️"] = "man_raising_hand_tone3", + ["🙋🏾‍♂️"] = "man_raising_hand_tone4", + ["🙋🏿‍♂️"] = "man_raising_hand_tone5", + ["🧏"] = "deaf_person", + ["🧏🏻"] = "deaf_person_tone1", + ["🧏🏼"] = "deaf_person_tone2", + ["🧏🏽"] = "deaf_person_tone3", + ["🧏🏾"] = "deaf_person_tone4", + ["🧏🏿"] = "deaf_person_tone5", + ["🧏‍♀️"] = "deaf_woman", + ["🧏🏻‍♀️"] = "deaf_woman_tone1", + ["🧏🏼‍♀️"] = "deaf_woman_tone2", + ["🧏🏽‍♀️"] = "deaf_woman_tone3", + ["🧏🏾‍♀️"] = "deaf_woman_tone4", + ["🧏🏿‍♀️"] = "deaf_woman_tone5", + ["🧏‍♂️"] = "deaf_man", + ["🧏🏻‍♂️"] = "deaf_man_tone1", + ["🧏🏼‍♂️"] = "deaf_man_tone2", + ["🧏🏽‍♂️"] = "deaf_man_tone3", + ["🧏🏾‍♂️"] = "deaf_man_tone4", + ["🧏🏿‍♂️"] = "deaf_man_tone5", + ["🤦"] = "person_facepalming", + ["🤦🏻"] = "person_facepalming_tone1", + ["🤦🏼"] = "person_facepalming_tone2", + ["🤦🏽"] = "person_facepalming_tone3", + ["🤦🏾"] = "person_facepalming_tone4", + ["🤦🏿"] = "person_facepalming_tone5", + ["🤦‍♀️"] = "woman_facepalming", + ["🤦🏻‍♀️"] = "woman_facepalming_tone1", + ["🤦🏼‍♀️"] = "woman_facepalming_tone2", + ["🤦🏽‍♀️"] = "woman_facepalming_tone3", + ["🤦🏾‍♀️"] = "woman_facepalming_tone4", + ["🤦🏿‍♀️"] = "woman_facepalming_tone5", + ["🤦‍♂️"] = "man_facepalming", + ["🤦🏻‍♂️"] = "man_facepalming_tone1", + ["🤦🏼‍♂️"] = "man_facepalming_tone2", + ["🤦🏽‍♂️"] = "man_facepalming_tone3", + ["🤦🏾‍♂️"] = "man_facepalming_tone4", + ["🤦🏿‍♂️"] = "man_facepalming_tone5", + ["🤷"] = "person_shrugging", + ["🤷🏻"] = "person_shrugging_tone1", + ["🤷🏼"] = "person_shrugging_tone2", + ["🤷🏽"] = "person_shrugging_tone3", + ["🤷🏾"] = "person_shrugging_tone4", + ["🤷🏿"] = "person_shrugging_tone5", + ["🤷‍♀️"] = "woman_shrugging", + ["🤷🏻‍♀️"] = "woman_shrugging_tone1", + ["🤷🏼‍♀️"] = "woman_shrugging_tone2", + ["🤷🏽‍♀️"] = "woman_shrugging_tone3", + ["🤷🏾‍♀️"] = "woman_shrugging_tone4", + ["🤷🏿‍♀️"] = "woman_shrugging_tone5", + ["🤷‍♂️"] = "man_shrugging", + ["🤷🏻‍♂️"] = "man_shrugging_tone1", + ["🤷🏼‍♂️"] = "man_shrugging_tone2", + ["🤷🏽‍♂️"] = "man_shrugging_tone3", + ["🤷🏾‍♂️"] = "man_shrugging_tone4", + ["🤷🏿‍♂️"] = "man_shrugging_tone5", + ["🙎"] = "person_pouting", + ["🙎🏻"] = "person_pouting_tone1", + ["🙎🏼"] = "person_pouting_tone2", + ["🙎🏽"] = "person_pouting_tone3", + ["🙎🏾"] = "person_pouting_tone4", + ["🙎🏿"] = "person_pouting_tone5", + ["🙎‍♀️"] = "woman_pouting", + ["🙎🏻‍♀️"] = "woman_pouting_tone1", + ["🙎🏼‍♀️"] = "woman_pouting_tone2", + ["🙎🏽‍♀️"] = "woman_pouting_tone3", + ["🙎🏾‍♀️"] = "woman_pouting_tone4", + ["🙎🏿‍♀️"] = "woman_pouting_tone5", + ["🙎‍♂️"] = "man_pouting", + ["🙎🏻‍♂️"] = "man_pouting_tone1", + ["🙎🏼‍♂️"] = "man_pouting_tone2", + ["🙎🏽‍♂️"] = "man_pouting_tone3", + ["🙎🏾‍♂️"] = "man_pouting_tone4", + ["🙎🏿‍♂️"] = "man_pouting_tone5", + ["🙍"] = "person_frowning", + ["🙍🏻"] = "person_frowning_tone1", + ["🙍🏼"] = "person_frowning_tone2", + ["🙍🏽"] = "person_frowning_tone3", + ["🙍🏾"] = "person_frowning_tone4", + ["🙍🏿"] = "person_frowning_tone5", + ["🙍‍♀️"] = "woman_frowning", + ["🙍🏻‍♀️"] = "woman_frowning_tone1", + ["🙍🏼‍♀️"] = "woman_frowning_tone2", + ["🙍🏽‍♀️"] = "woman_frowning_tone3", + ["🙍🏾‍♀️"] = "woman_frowning_tone4", + ["🙍🏿‍♀️"] = "woman_frowning_tone5", + ["🙍‍♂️"] = "man_frowning", + ["🙍🏻‍♂️"] = "man_frowning_tone1", + ["🙍🏼‍♂️"] = "man_frowning_tone2", + ["🙍🏽‍♂️"] = "man_frowning_tone3", + ["🙍🏾‍♂️"] = "man_frowning_tone4", + ["🙍🏿‍♂️"] = "man_frowning_tone5", + ["💇"] = "person_getting_haircut", + ["💇🏻"] = "person_getting_haircut_tone1", + ["💇🏼"] = "person_getting_haircut_tone2", + ["💇🏽"] = "person_getting_haircut_tone3", + ["💇🏾"] = "person_getting_haircut_tone4", + ["💇🏿"] = "person_getting_haircut_tone5", + ["💇‍♀️"] = "woman_getting_haircut", + ["💇🏻‍♀️"] = "woman_getting_haircut_tone1", + ["💇🏼‍♀️"] = "woman_getting_haircut_tone2", + ["💇🏽‍♀️"] = "woman_getting_haircut_tone3", + ["💇🏾‍♀️"] = "woman_getting_haircut_tone4", + ["💇🏿‍♀️"] = "woman_getting_haircut_tone5", + ["💇‍♂️"] = "man_getting_haircut", + ["💇🏻‍♂️"] = "man_getting_haircut_tone1", + ["💇🏼‍♂️"] = "man_getting_haircut_tone2", + ["💇🏽‍♂️"] = "man_getting_haircut_tone3", + ["💇🏾‍♂️"] = "man_getting_haircut_tone4", + ["💇🏿‍♂️"] = "man_getting_haircut_tone5", + ["💆"] = "person_getting_massage", + ["💆🏻"] = "person_getting_massage_tone1", + ["💆🏼"] = "person_getting_massage_tone2", + ["💆🏽"] = "person_getting_massage_tone3", + ["💆🏾"] = "person_getting_massage_tone4", + ["💆🏿"] = "person_getting_massage_tone5", + ["💆‍♀️"] = "woman_getting_face_massage", + ["💆🏻‍♀️"] = "woman_getting_face_massage_tone1", + ["💆🏼‍♀️"] = "woman_getting_face_massage_tone2", + ["💆🏽‍♀️"] = "woman_getting_face_massage_tone3", + ["💆🏾‍♀️"] = "woman_getting_face_massage_tone4", + ["💆🏿‍♀️"] = "woman_getting_face_massage_tone5", + ["💆‍♂️"] = "man_getting_face_massage", + ["💆🏻‍♂️"] = "man_getting_face_massage_tone1", + ["💆🏼‍♂️"] = "man_getting_face_massage_tone2", + ["💆🏽‍♂️"] = "man_getting_face_massage_tone3", + ["💆🏾‍♂️"] = "man_getting_face_massage_tone4", + ["💆🏿‍♂️"] = "man_getting_face_massage_tone5", + ["🧖"] = "person_in_steamy_room", + ["🧖🏻"] = "person_in_steamy_room_tone1", + ["🧖🏼"] = "person_in_steamy_room_tone2", + ["🧖🏽"] = "person_in_steamy_room_tone3", + ["🧖🏾"] = "person_in_steamy_room_tone4", + ["🧖🏿"] = "person_in_steamy_room_tone5", + ["🧖‍♀️"] = "woman_in_steamy_room", + ["🧖🏻‍♀️"] = "woman_in_steamy_room_tone1", + ["🧖🏼‍♀️"] = "woman_in_steamy_room_tone2", + ["🧖🏽‍♀️"] = "woman_in_steamy_room_tone3", + ["🧖🏾‍♀️"] = "woman_in_steamy_room_tone4", + ["🧖🏿‍♀️"] = "woman_in_steamy_room_tone5", + ["🧖‍♂️"] = "man_in_steamy_room", + ["🧖🏻‍♂️"] = "man_in_steamy_room_tone1", + ["🧖🏼‍♂️"] = "man_in_steamy_room_tone2", + ["🧖🏽‍♂️"] = "man_in_steamy_room_tone3", + ["🧖🏾‍♂️"] = "man_in_steamy_room_tone4", + ["🧖🏿‍♂️"] = "man_in_steamy_room_tone5", + ["💅"] = "nail_care", + ["💅🏻"] = "nail_care_tone1", + ["💅🏼"] = "nail_care_tone2", + ["💅🏽"] = "nail_care_tone3", + ["💅🏾"] = "nail_care_tone4", + ["💅🏿"] = "nail_care_tone5", + ["🤳"] = "selfie", + ["🤳🏻"] = "selfie_tone1", + ["🤳🏼"] = "selfie_tone2", + ["🤳🏽"] = "selfie_tone3", + ["🤳🏾"] = "selfie_tone4", + ["🤳🏿"] = "selfie_tone5", + ["💃"] = "dancer", + ["💃🏻"] = "dancer_tone1", + ["💃🏼"] = "dancer_tone2", + ["💃🏽"] = "dancer_tone3", + ["💃🏾"] = "dancer_tone4", + ["💃🏿"] = "dancer_tone5", + ["🕺"] = "man_dancing", + ["🕺🏻"] = "man_dancing_tone1", + ["🕺🏼"] = "man_dancing_tone2", + ["🕺🏽"] = "man_dancing_tone3", + ["🕺🏿"] = "man_dancing_tone5", + ["🕺🏾"] = "man_dancing_tone4", + ["👯"] = "people_with_bunny_ears_partying", + ["👯‍♀️"] = "women_with_bunny_ears_partying", + ["👯‍♂️"] = "men_with_bunny_ears_partying", + ["🕴️"] = "levitate", + ["🕴🏻"] = "levitate_tone1", + ["🕴🏼"] = "levitate_tone2", + ["🕴🏽"] = "levitate_tone3", + ["🕴🏾"] = "levitate_tone4", + ["🕴🏿"] = "levitate_tone5", + ["🧑‍🦽"] = "person_in_manual_wheelchair", + ["🧑🏻‍🦽"] = "person_in_manual_wheelchair_tone1", + ["🧑🏼‍🦽"] = "person_in_manual_wheelchair_tone2", + ["🧑🏽‍🦽"] = "person_in_manual_wheelchair_tone3", + ["🧑🏾‍🦽"] = "person_in_manual_wheelchair_tone4", + ["🧑🏿‍🦽"] = "person_in_manual_wheelchair_tone5", + ["👩‍🦽"] = "woman_in_manual_wheelchair", + ["👩🏻‍🦽"] = "woman_in_manual_wheelchair_tone1", + ["👩🏼‍🦽"] = "woman_in_manual_wheelchair_tone2", + ["👩🏽‍🦽"] = "woman_in_manual_wheelchair_tone3", + ["👩🏾‍🦽"] = "woman_in_manual_wheelchair_tone4", + ["👩🏿‍🦽"] = "woman_in_manual_wheelchair_tone5", + ["👨‍🦽"] = "man_in_manual_wheelchair", + ["👨🏻‍🦽"] = "man_in_manual_wheelchair_tone1", + ["👨🏼‍🦽"] = "man_in_manual_wheelchair_tone2", + ["👨🏽‍🦽"] = "man_in_manual_wheelchair_tone3", + ["👨🏾‍🦽"] = "man_in_manual_wheelchair_tone4", + ["👨🏿‍🦽"] = "man_in_manual_wheelchair_tone5", + ["🧑‍🦼"] = "person_in_motorized_wheelchair", + ["🧑🏻‍🦼"] = "person_in_motorized_wheelchair_tone1", + ["🧑🏼‍🦼"] = "person_in_motorized_wheelchair_tone2", + ["🧑🏽‍🦼"] = "person_in_motorized_wheelchair_tone3", + ["🧑🏾‍🦼"] = "person_in_motorized_wheelchair_tone4", + ["🧑🏿‍🦼"] = "person_in_motorized_wheelchair_tone5", + ["👩‍🦼"] = "woman_in_motorized_wheelchair", + ["👩🏻‍🦼"] = "woman_in_motorized_wheelchair_tone1", + ["👩🏼‍🦼"] = "woman_in_motorized_wheelchair_tone2", + ["👩🏽‍🦼"] = "woman_in_motorized_wheelchair_tone3", + ["👩🏾‍🦼"] = "woman_in_motorized_wheelchair_tone4", + ["👩🏿‍🦼"] = "woman_in_motorized_wheelchair_tone5", + ["👨‍🦼"] = "man_in_motorized_wheelchair", + ["👨🏻‍🦼"] = "man_in_motorized_wheelchair_tone1", + ["👨🏼‍🦼"] = "man_in_motorized_wheelchair_tone2", + ["👨🏽‍🦼"] = "man_in_motorized_wheelchair_tone3", + ["👨🏾‍🦼"] = "man_in_motorized_wheelchair_tone4", + ["👨🏿‍🦼"] = "man_in_motorized_wheelchair_tone5", + ["🚶"] = "person_walking", + ["🚶🏻"] = "person_walking_tone1", + ["🚶🏼"] = "person_walking_tone2", + ["🚶🏽"] = "person_walking_tone3", + ["🚶🏾"] = "person_walking_tone4", + ["🚶🏿"] = "person_walking_tone5", + ["🚶‍♀️"] = "woman_walking", + ["🚶🏻‍♀️"] = "woman_walking_tone1", + ["🚶🏼‍♀️"] = "woman_walking_tone2", + ["🚶🏽‍♀️"] = "woman_walking_tone3", + ["🚶🏾‍♀️"] = "woman_walking_tone4", + ["🚶🏿‍♀️"] = "woman_walking_tone5", + ["🚶‍♂️"] = "man_walking", + ["🚶🏻‍♂️"] = "man_walking_tone1", + ["🚶🏼‍♂️"] = "man_walking_tone2", + ["🚶🏽‍♂️"] = "man_walking_tone3", + ["🚶🏾‍♂️"] = "man_walking_tone4", + ["🚶🏿‍♂️"] = "man_walking_tone5", + ["🧑‍🦯"] = "person_with_probing_cane", + ["🧑🏻‍🦯"] = "person_with_probing_cane_tone1", + ["🧑🏼‍🦯"] = "person_with_probing_cane_tone2", + ["🧑🏽‍🦯"] = "person_with_probing_cane_tone3", + ["🧑🏾‍🦯"] = "person_with_probing_cane_tone4", + ["🧑🏿‍🦯"] = "person_with_probing_cane_tone5", + ["👩‍🦯"] = "woman_with_probing_cane", + ["👩🏻‍🦯"] = "woman_with_probing_cane_tone1", + ["👩🏼‍🦯"] = "woman_with_probing_cane_tone2", + ["👩🏽‍🦯"] = "woman_with_probing_cane_tone3", + ["👩🏾‍🦯"] = "woman_with_probing_cane_tone4", + ["👩🏿‍🦯"] = "woman_with_probing_cane_tone5", + ["👨‍🦯"] = "man_with_probing_cane", + ["👨🏻‍🦯"] = "man_with_probing_cane_tone1", + ["👨🏽‍🦯"] = "man_with_probing_cane_tone3", + ["👨🏼‍🦯"] = "man_with_probing_cane_tone2", + ["👨🏾‍🦯"] = "man_with_probing_cane_tone4", + ["👨🏿‍🦯"] = "man_with_probing_cane_tone5", + ["🧎"] = "person_kneeling", + ["🧎🏻"] = "person_kneeling_tone1", + ["🧎🏼"] = "person_kneeling_tone2", + ["🧎🏽"] = "person_kneeling_tone3", + ["🧎🏾"] = "person_kneeling_tone4", + ["🧎🏿"] = "person_kneeling_tone5", + ["🧎‍♀️"] = "woman_kneeling", + ["🧎🏻‍♀️"] = "woman_kneeling_tone1", + ["🧎🏼‍♀️"] = "woman_kneeling_tone2", + ["🧎🏽‍♀️"] = "woman_kneeling_tone3", + ["🧎🏾‍♀️"] = "woman_kneeling_tone4", + ["🧎🏿‍♀️"] = "woman_kneeling_tone5", + ["🧎‍♂️"] = "man_kneeling", + ["🧎🏻‍♂️"] = "man_kneeling_tone1", + ["🧎🏼‍♂️"] = "man_kneeling_tone2", + ["🧎🏽‍♂️"] = "man_kneeling_tone3", + ["🧎🏾‍♂️"] = "man_kneeling_tone4", + ["🧎🏿‍♂️"] = "man_kneeling_tone5", + ["🏃"] = "person_running", + ["🏃🏻"] = "person_running_tone1", + ["🏃🏼"] = "person_running_tone2", + ["🏃🏽"] = "person_running_tone3", + ["🏃🏾"] = "person_running_tone4", + ["🏃🏿"] = "person_running_tone5", + ["🏃‍♀️"] = "woman_running", + ["🏃🏻‍♀️"] = "woman_running_tone1", + ["🏃🏼‍♀️"] = "woman_running_tone2", + ["🏃🏽‍♀️"] = "woman_running_tone3", + ["🏃🏾‍♀️"] = "woman_running_tone4", + ["🏃🏿‍♀️"] = "woman_running_tone5", + ["🏃‍♂️"] = "man_running", + ["🏃🏻‍♂️"] = "man_running_tone1", + ["🏃🏼‍♂️"] = "man_running_tone2", + ["🏃🏽‍♂️"] = "man_running_tone3", + ["🏃🏾‍♂️"] = "man_running_tone4", + ["🏃🏿‍♂️"] = "man_running_tone5", + ["🧍"] = "person_standing", + ["🧍🏻"] = "person_standing_tone1", + ["🧍🏼"] = "person_standing_tone2", + ["🧍🏽"] = "person_standing_tone3", + ["🧍🏾"] = "person_standing_tone4", + ["🧍🏿"] = "person_standing_tone5", + ["🧍‍♀️"] = "woman_standing", + ["🧍🏻‍♀️"] = "woman_standing_tone1", + ["🧍🏼‍♀️"] = "woman_standing_tone2", + ["🧍🏽‍♀️"] = "woman_standing_tone3", + ["🧍🏾‍♀️"] = "woman_standing_tone4", + ["🧍🏿‍♀️"] = "woman_standing_tone5", + ["🧍‍♂️"] = "man_standing", + ["🧍🏻‍♂️"] = "man_standing_tone1", + ["🧍🏼‍♂️"] = "man_standing_tone2", + ["🧍🏽‍♂️"] = "man_standing_tone3", + ["🧍🏾‍♂️"] = "man_standing_tone4", + ["🧍🏿‍♂️"] = "man_standing_tone5", + ["🧑‍🤝‍🧑"] = "people_holding_hands", + ["🧑🏻‍🤝‍🧑🏻"] = "people_holding_hands_tone1", + ["🧑🏻‍🤝‍🧑🏼"] = "people_holding_hands_tone1_tone2", + ["🧑🏻‍🤝‍🧑🏽"] = "people_holding_hands_tone1_tone3", + ["🧑🏻‍🤝‍🧑🏾"] = "people_holding_hands_tone1_tone4", + ["🧑🏻‍🤝‍🧑🏿"] = "people_holding_hands_tone1_tone5", + ["🧑🏼‍🤝‍🧑🏻"] = "people_holding_hands_tone2_tone1", + ["🧑🏼‍🤝‍🧑🏼"] = "people_holding_hands_tone2", + ["🧑🏼‍🤝‍🧑🏽"] = "people_holding_hands_tone2_tone3", + ["🧑🏼‍🤝‍🧑🏾"] = "people_holding_hands_tone2_tone4", + ["🧑🏼‍🤝‍🧑🏿"] = "people_holding_hands_tone2_tone5", + ["🧑🏽‍🤝‍🧑🏻"] = "people_holding_hands_tone3_tone1", + ["🧑🏽‍🤝‍🧑🏼"] = "people_holding_hands_tone3_tone2", + ["🧑🏽‍🤝‍🧑🏽"] = "people_holding_hands_tone3", + ["🧑🏽‍🤝‍🧑🏾"] = "people_holding_hands_tone3_tone4", + ["🧑🏽‍🤝‍🧑🏿"] = "people_holding_hands_tone3_tone5", + ["🧑🏾‍🤝‍🧑🏻"] = "people_holding_hands_tone4_tone1", + ["🧑🏾‍🤝‍🧑🏼"] = "people_holding_hands_tone4_tone2", + ["🧑🏾‍🤝‍🧑🏽"] = "people_holding_hands_tone4_tone3", + ["🧑🏾‍🤝‍🧑🏾"] = "people_holding_hands_tone4", + ["🧑🏾‍🤝‍🧑🏿"] = "people_holding_hands_tone4_tone5", + ["🧑🏿‍🤝‍🧑🏻"] = "people_holding_hands_tone5_tone1", + ["🧑🏿‍🤝‍🧑🏼"] = "people_holding_hands_tone5_tone2", + ["🧑🏿‍🤝‍🧑🏽"] = "people_holding_hands_tone5_tone3", + ["🧑🏿‍🤝‍🧑🏾"] = "people_holding_hands_tone5_tone4", + ["🧑🏿‍🤝‍🧑🏿"] = "people_holding_hands_tone5", + ["👫"] = "couple", + ["👫🏻"] = "woman_and_man_holding_hands_tone1", + ["👩🏻‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone1_tone2", + ["👩🏻‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone1_tone3", + ["👩🏻‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone1_tone4", + ["👩🏻‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone1_tone5", + ["👩🏼‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone2_tone1", + ["👫🏼"] = "woman_and_man_holding_hands_tone2", + ["👩🏼‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone2_tone3", + ["👩🏼‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone2_tone4", + ["👩🏼‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone2_tone5", + ["👩🏽‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone3_tone1", + ["👩🏽‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone3_tone2", + ["👫🏽"] = "woman_and_man_holding_hands_tone3", + ["👩🏽‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone3_tone4", + ["👩🏽‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone3_tone5", + ["👩🏾‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone4_tone1", + ["👩🏾‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone4_tone2", + ["👩🏾‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone4_tone3", + ["👫🏾"] = "woman_and_man_holding_hands_tone4", + ["👩🏾‍🤝‍👨🏿"] = "woman_and_man_holding_hands_tone4_tone5", + ["👩🏿‍🤝‍👨🏻"] = "woman_and_man_holding_hands_tone5_tone1", + ["👩🏿‍🤝‍👨🏼"] = "woman_and_man_holding_hands_tone5_tone2", + ["👩🏿‍🤝‍👨🏽"] = "woman_and_man_holding_hands_tone5_tone3", + ["👩🏿‍🤝‍👨🏾"] = "woman_and_man_holding_hands_tone5_tone4", + ["👫🏿"] = "woman_and_man_holding_hands_tone5", + ["👭"] = "two_women_holding_hands", + ["👭🏻"] = "women_holding_hands_tone1", + ["👩🏻‍🤝‍👩🏼"] = "women_holding_hands_tone1_tone2", + ["👩🏻‍🤝‍👩🏽"] = "women_holding_hands_tone1_tone3", + ["👩🏻‍🤝‍👩🏾"] = "women_holding_hands_tone1_tone4", + ["👩🏻‍🤝‍👩🏿"] = "women_holding_hands_tone1_tone5", + ["👩🏼‍🤝‍👩🏻"] = "women_holding_hands_tone2_tone1", + ["👭🏼"] = "women_holding_hands_tone2", + ["👩🏼‍🤝‍👩🏽"] = "women_holding_hands_tone2_tone3", + ["👩🏼‍🤝‍👩🏾"] = "women_holding_hands_tone2_tone4", + ["👩🏼‍🤝‍👩🏿"] = "women_holding_hands_tone2_tone5", + ["👩🏽‍🤝‍👩🏻"] = "women_holding_hands_tone3_tone1", + ["👩🏽‍🤝‍👩🏼"] = "women_holding_hands_tone3_tone2", + ["👭🏽"] = "women_holding_hands_tone3", + ["👩🏽‍🤝‍👩🏾"] = "women_holding_hands_tone3_tone4", + ["👩🏽‍🤝‍👩🏿"] = "women_holding_hands_tone3_tone5", + ["👩🏾‍🤝‍👩🏻"] = "women_holding_hands_tone4_tone1", + ["👩🏾‍🤝‍👩🏼"] = "women_holding_hands_tone4_tone2", + ["👩🏾‍🤝‍👩🏽"] = "women_holding_hands_tone4_tone3", + ["👭🏾"] = "women_holding_hands_tone4", + ["👩🏾‍🤝‍👩🏿"] = "women_holding_hands_tone4_tone5", + ["👩🏿‍🤝‍👩🏻"] = "women_holding_hands_tone5_tone1", + ["👩🏿‍🤝‍👩🏼"] = "women_holding_hands_tone5_tone2", + ["👩🏿‍🤝‍👩🏽"] = "women_holding_hands_tone5_tone3", + ["👩🏿‍🤝‍👩🏾"] = "women_holding_hands_tone5_tone4", + ["👭🏿"] = "women_holding_hands_tone5", + ["👬"] = "two_men_holding_hands", + ["👬🏻"] = "men_holding_hands_tone1", + ["👨🏻‍🤝‍👨🏼"] = "men_holding_hands_tone1_tone2", + ["👨🏻‍🤝‍👨🏽"] = "men_holding_hands_tone1_tone3", + ["👨🏻‍🤝‍👨🏾"] = "men_holding_hands_tone1_tone4", + ["👨🏻‍🤝‍👨🏿"] = "men_holding_hands_tone1_tone5", + ["👨🏼‍🤝‍👨🏻"] = "men_holding_hands_tone2_tone1", + ["👬🏼"] = "men_holding_hands_tone2", + ["👨🏼‍🤝‍👨🏽"] = "men_holding_hands_tone2_tone3", + ["👨🏼‍🤝‍👨🏾"] = "men_holding_hands_tone2_tone4", + ["👨🏼‍🤝‍👨🏿"] = "men_holding_hands_tone2_tone5", + ["👨🏽‍🤝‍👨🏻"] = "men_holding_hands_tone3_tone1", + ["👨🏽‍🤝‍👨🏼"] = "men_holding_hands_tone3_tone2", + ["👬🏽"] = "men_holding_hands_tone3", + ["👨🏽‍🤝‍👨🏾"] = "men_holding_hands_tone3_tone4", + ["👨🏽‍🤝‍👨🏿"] = "men_holding_hands_tone3_tone5", + ["👨🏾‍🤝‍👨🏻"] = "men_holding_hands_tone4_tone1", + ["👨🏾‍🤝‍👨🏼"] = "men_holding_hands_tone4_tone2", + ["👨🏾‍🤝‍👨🏽"] = "men_holding_hands_tone4_tone3", + ["👬🏾"] = "men_holding_hands_tone4", + ["👨🏾‍🤝‍👨🏿"] = "men_holding_hands_tone4_tone5", + ["👨🏿‍🤝‍👨🏻"] = "men_holding_hands_tone5_tone1", + ["👨🏿‍🤝‍👨🏼"] = "men_holding_hands_tone5_tone2", + ["👨🏿‍🤝‍👨🏽"] = "men_holding_hands_tone5_tone3", + ["👨🏿‍🤝‍👨🏾"] = "men_holding_hands_tone5_tone4", + ["👬🏿"] = "men_holding_hands_tone5", + ["💑"] = "couple_with_heart", + ["💑🏻"] = "couple_with_heart_tone1", + ["🧑🏻‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone1_tone2", + ["🧑🏻‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone1_tone3", + ["🧑🏻‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone1_tone4", + ["🧑🏻‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone1_tone5", + ["🧑🏼‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone2_tone1", + ["💑🏼"] = "couple_with_heart_tone2", + ["🧑🏼‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone2_tone3", + ["🧑🏼‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone2_tone4", + ["🧑🏼‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone2_tone5", + ["🧑🏽‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone3_tone1", + ["🧑🏽‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone3_tone2", + ["💑🏽"] = "couple_with_heart_tone3", + ["🧑🏽‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone3_tone4", + ["🧑🏽‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone3_tone5", + ["🧑🏾‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone4_tone1", + ["🧑🏾‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone4_tone2", + ["🧑🏾‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone4_tone3", + ["💑🏾"] = "couple_with_heart_tone4", + ["🧑🏾‍❤️‍🧑🏿"] = "couple_with_heart_person_person_tone4_tone5", + ["🧑🏿‍❤️‍🧑🏻"] = "couple_with_heart_person_person_tone5_tone1", + ["🧑🏿‍❤️‍🧑🏼"] = "couple_with_heart_person_person_tone5_tone2", + ["🧑🏿‍❤️‍🧑🏽"] = "couple_with_heart_person_person_tone5_tone3", + ["🧑🏿‍❤️‍🧑🏾"] = "couple_with_heart_person_person_tone5_tone4", + ["💑🏿"] = "couple_with_heart_tone5", + ["👩‍❤️‍👨"] = "couple_with_heart_woman_man", + ["👩🏻‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone1", + ["👩🏻‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone1_tone2", + ["👩🏻‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone1_tone3", + ["👩🏻‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone1_tone4", + ["👩🏻‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone1_tone5", + ["👩🏼‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone2_tone1", + ["👩🏼‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone2", + ["👩🏼‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone2_tone3", + ["👩🏼‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone2_tone4", + ["👩🏼‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone2_tone5", + ["👩🏽‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone3_tone1", + ["👩🏽‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone3_tone2", + ["👩🏽‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone3", + ["👩🏽‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone3_tone4", + ["👩🏽‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone3_tone5", + ["👩🏾‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone4_tone1", + ["👩🏾‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone4_tone2", + ["👩🏾‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone4_tone3", + ["👩🏾‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone4", + ["👩🏾‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone4_tone5", + ["👩🏿‍❤️‍👨🏻"] = "couple_with_heart_woman_man_tone5_tone1", + ["👩🏿‍❤️‍👨🏼"] = "couple_with_heart_woman_man_tone5_tone2", + ["👩🏿‍❤️‍👨🏽"] = "couple_with_heart_woman_man_tone5_tone3", + ["👩🏿‍❤️‍👨🏾"] = "couple_with_heart_woman_man_tone5_tone4", + ["👩🏿‍❤️‍👨🏿"] = "couple_with_heart_woman_man_tone5", + ["👩‍❤️‍👩"] = "couple_ww", + ["👩🏻‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone1", + ["👩🏻‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone1_tone2", + ["👩🏻‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone1_tone3", + ["👩🏻‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone1_tone4", + ["👩🏻‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone1_tone5", + ["👩🏼‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone2_tone1", + ["👩🏼‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone2", + ["👩🏼‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone2_tone3", + ["👩🏼‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone2_tone4", + ["👩🏼‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone2_tone5", + ["👩🏽‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone3_tone1", + ["👩🏽‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone3_tone2", + ["👩🏽‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone3", + ["👩🏽‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone3_tone4", + ["👩🏽‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone3_tone5", + ["👩🏾‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone4_tone1", + ["👩🏾‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone4_tone2", + ["👩🏾‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone4_tone3", + ["👩🏾‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone4", + ["👩🏾‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone4_tone5", + ["👩🏿‍❤️‍👩🏻"] = "couple_with_heart_woman_woman_tone5_tone1", + ["👩🏿‍❤️‍👩🏼"] = "couple_with_heart_woman_woman_tone5_tone2", + ["👩🏿‍❤️‍👩🏽"] = "couple_with_heart_woman_woman_tone5_tone3", + ["👩🏿‍❤️‍👩🏾"] = "couple_with_heart_woman_woman_tone5_tone4", + ["👩🏿‍❤️‍👩🏿"] = "couple_with_heart_woman_woman_tone5", + ["👨‍❤️‍👨"] = "couple_mm", + ["👨🏻‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone1", + ["👨🏻‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone1_tone2", + ["👨🏻‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone1_tone3", + ["👨🏻‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone1_tone4", + ["👨🏻‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone1_tone5", + ["👨🏼‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone2_tone1", + ["👨🏼‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone2", + ["👨🏼‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone2_tone3", + ["👨🏼‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone2_tone4", + ["👨🏼‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone2_tone5", + ["👨🏽‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone3_tone1", + ["👨🏽‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone3_tone2", + ["👨🏽‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone3", + ["👨🏽‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone3_tone4", + ["👨🏽‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone3_tone5", + ["👨🏾‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone4_tone1", + ["👨🏾‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone4_tone2", + ["👨🏾‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone4_tone3", + ["👨🏾‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone4", + ["👨🏾‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone4_tone5", + ["👨🏿‍❤️‍👨🏻"] = "couple_with_heart_man_man_tone5_tone1", + ["👨🏿‍❤️‍👨🏼"] = "couple_with_heart_man_man_tone5_tone2", + ["👨🏿‍❤️‍👨🏽"] = "couple_with_heart_man_man_tone5_tone3", + ["👨🏿‍❤️‍👨🏾"] = "couple_with_heart_man_man_tone5_tone4", + ["👨🏿‍❤️‍👨🏿"] = "couple_with_heart_man_man_tone5", + ["💏"] = "couplekiss", + ["🧑🏿‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone5_tone4", + ["💏🏻"] = "kiss_tone1", + ["🧑🏻‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone1_tone2", + ["🧑🏻‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone1_tone3", + ["🧑🏻‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone1_tone4", + ["🧑🏻‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone1_tone5", + ["🧑🏼‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone2_tone1", + ["💏🏼"] = "kiss_tone2", + ["🧑🏼‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone2_tone3", + ["🧑🏼‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone2_tone4", + ["🧑🏼‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone2_tone5", + ["🧑🏽‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone3_tone1", + ["🧑🏽‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone3_tone2", + ["💏🏽"] = "kiss_tone3", + ["🧑🏽‍❤️‍💋‍🧑🏾"] = "kiss_person_person_tone3_tone4", + ["🧑🏽‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone3_tone5", + ["🧑🏾‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone4_tone1", + ["🧑🏾‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone4_tone2", + ["🧑🏾‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone4_tone3", + ["💏🏾"] = "kiss_tone4", + ["🧑🏾‍❤️‍💋‍🧑🏿"] = "kiss_person_person_tone4_tone5", + ["🧑🏿‍❤️‍💋‍🧑🏻"] = "kiss_person_person_tone5_tone1", + ["🧑🏿‍❤️‍💋‍🧑🏼"] = "kiss_person_person_tone5_tone2", + ["🧑🏿‍❤️‍💋‍🧑🏽"] = "kiss_person_person_tone5_tone3", + ["💏🏿"] = "kiss_tone5", + ["👩‍❤️‍💋‍👨"] = "kiss_woman_man", + ["👩🏻‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone1", + ["👩🏻‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone1_tone2", + ["👩🏻‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone1_tone3", + ["👩🏻‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone1_tone4", + ["👩🏻‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone1_tone5", + ["👩🏼‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone2_tone1", + ["👩🏼‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone2", + ["👩🏼‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone2_tone3", + ["👩🏼‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone2_tone4", + ["👩🏼‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone2_tone5", + ["👩🏽‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone3_tone1", + ["👩🏽‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone3_tone2", + ["👩🏽‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone3", + ["👩🏽‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone3_tone4", + ["👩🏽‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone3_tone5", + ["👩🏾‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone4_tone1", + ["👩🏾‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone4_tone2", + ["👩🏾‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone4_tone3", + ["👩🏾‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone4", + ["👩🏾‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone4_tone5", + ["👩🏿‍❤️‍💋‍👨🏻"] = "kiss_woman_man_tone5_tone1", + ["👩🏿‍❤️‍💋‍👨🏼"] = "kiss_woman_man_tone5_tone2", + ["👩🏿‍❤️‍💋‍👨🏽"] = "kiss_woman_man_tone5_tone3", + ["👩🏿‍❤️‍💋‍👨🏾"] = "kiss_woman_man_tone5_tone4", + ["👩🏿‍❤️‍💋‍👨🏿"] = "kiss_woman_man_tone5", + ["👩‍❤️‍💋‍👩"] = "kiss_ww", + ["👩🏻‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone1", + ["👩🏻‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone1_tone2", + ["👩🏻‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone1_tone3", + ["👩🏻‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone1_tone4", + ["👩🏻‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone1_tone5", + ["👩🏼‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone2_tone1", + ["👩🏼‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone2", + ["👩🏼‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone2_tone3", + ["👩🏼‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone2_tone4", + ["👩🏼‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone2_tone5", + ["👩🏽‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone3_tone1", + ["👩🏽‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone3_tone2", + ["👩🏽‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone3", + ["👩🏽‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone3_tone4", + ["👩🏽‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone3_tone5", + ["👩🏾‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone4_tone1", + ["👩🏾‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone4_tone2", + ["👩🏾‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone4_tone3", + ["👩🏾‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone4", + ["👩🏾‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone4_tone5", + ["👩🏿‍❤️‍💋‍👩🏻"] = "kiss_woman_woman_tone5_tone1", + ["👩🏿‍❤️‍💋‍👩🏼"] = "kiss_woman_woman_tone5_tone2", + ["👩🏿‍❤️‍💋‍👩🏽"] = "kiss_woman_woman_tone5_tone3", + ["👩🏿‍❤️‍💋‍👩🏾"] = "kiss_woman_woman_tone5_tone4", + ["👩🏿‍❤️‍💋‍👩🏿"] = "kiss_woman_woman_tone5", + ["👨‍❤️‍💋‍👨"] = "kiss_mm", + ["👨🏻‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone1", + ["👨🏻‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone1_tone2", + ["👨🏻‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone1_tone3", + ["👨🏻‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone1_tone4", + ["👨🏻‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone1_tone5", + ["👨🏼‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone2_tone1", + ["👨🏼‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone2", + ["👨🏼‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone2_tone3", + ["👨🏼‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone2_tone4", + ["👨🏼‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone2_tone5", + ["👨🏽‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone3_tone1", + ["👨🏽‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone3_tone2", + ["👨🏽‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone3", + ["👨🏽‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone3_tone4", + ["👨🏽‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone3_tone5", + ["👨🏾‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone4_tone1", + ["👨🏾‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone4_tone2", + ["👨🏾‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone4_tone3", + ["👨🏾‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone4", + ["👨🏾‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone4_tone5", + ["👨🏿‍❤️‍💋‍👨🏻"] = "kiss_man_man_tone5_tone1", + ["👨🏿‍❤️‍💋‍👨🏼"] = "kiss_man_man_tone5_tone2", + ["👨🏿‍❤️‍💋‍👨🏽"] = "kiss_man_man_tone5_tone3", + ["👨🏿‍❤️‍💋‍👨🏾"] = "kiss_man_man_tone5_tone4", + ["👨🏿‍❤️‍💋‍👨🏿"] = "kiss_man_man_tone5", + ["👪"] = "family", + ["👨‍👩‍👦"] = "family_man_woman_boy", + ["👨‍👩‍👧"] = "family_mwg", + ["👨‍👩‍👧‍👦"] = "family_mwgb", + ["👨‍👩‍👦‍👦"] = "family_mwbb", + ["👨‍👩‍👧‍👧"] = "family_mwgg", + ["👩‍👩‍👦"] = "family_wwb", + ["👩‍👩‍👧"] = "family_wwg", + ["👩‍👩‍👧‍👦"] = "family_wwgb", + ["👩‍👩‍👦‍👦"] = "family_wwbb", + ["👩‍👩‍👧‍👧"] = "family_wwgg", + ["👨‍👨‍👦"] = "family_mmb", + ["👨‍👨‍👧"] = "family_mmg", + ["👨‍👨‍👧‍👦"] = "family_mmgb", + ["👨‍👨‍👦‍👦"] = "family_mmbb", + ["👨‍👨‍👧‍👧"] = "family_mmgg", + ["👩‍👦"] = "family_woman_boy", + ["👩‍👧"] = "family_woman_girl", + ["👩‍👧‍👦"] = "family_woman_girl_boy", + ["👩‍👦‍👦"] = "family_woman_boy_boy", + ["👩‍👧‍👧"] = "family_woman_girl_girl", + ["👨‍👦"] = "family_man_boy", + ["👨‍👧"] = "family_man_girl", + ["👨‍👧‍👦"] = "family_man_girl_boy", + ["👨‍👦‍👦"] = "family_man_boy_boy", + ["👨‍👧‍👧"] = "family_man_girl_girl", + ["🧶"] = "yarn", + ["🧵"] = "thread", + ["🧥"] = "coat", + ["🥼"] = "lab_coat", + ["🦺"] = "safety_vest", + ["👚"] = "womans_clothes", + ["👕"] = "shirt", + ["👖"] = "jeans", + ["🩲"] = "briefs", + ["🩳"] = "shorts", + ["👔"] = "necktie", + ["👗"] = "dress", + ["👙"] = "bikini", + ["🩱"] = "one_piece_swimsuit", + ["👘"] = "kimono", + ["🥻"] = "sari", + ["🥿"] = "womans_flat_shoe", + ["👠"] = "high_heel", + ["👡"] = "sandal", + ["👢"] = "boot", + ["👞"] = "mans_shoe", + ["👟"] = "athletic_shoe", + ["🥾"] = "hiking_boot", + ["🩴"] = "thong_sandal", + ["🧦"] = "socks", + ["🧤"] = "gloves", + ["🧣"] = "scarf", + ["🎩"] = "tophat", + ["🧢"] = "billed_cap", + ["👒"] = "womans_hat", + ["🎓"] = "mortar_board", + ["⛑️"] = "helmet_with_cross", + ["🪖"] = "military_helmet", + ["👑"] = "crown", + ["💍"] = "ring", + ["👝"] = "pouch", + ["👛"] = "purse", + ["👜"] = "handbag", + ["💼"] = "briefcase", + ["🎒"] = "school_satchel", + ["🧳"] = "luggage", + ["👓"] = "eyeglasses", + ["🕶️"] = "dark_sunglasses", + ["🥽"] = "goggles", + ["🌂"] = "closed_umbrella", + ["🐶"] = "dog", + ["🐱"] = "cat", + ["🐭"] = "mouse", + ["🐹"] = "hamster", + ["🐰"] = "rabbit", + ["🦊"] = "fox", + ["🐻"] = "bear", + ["🐼"] = "panda_face", + ["🐻‍❄️"] = "polar_bear", + ["🐨"] = "koala", + ["🐯"] = "tiger", + ["🦁"] = "lion_face", + ["🐮"] = "cow", + ["🐷"] = "pig", + ["🐽"] = "pig_nose", + ["🐸"] = "frog", + ["🐵"] = "monkey_face", + ["🙈"] = "see_no_evil", + ["🙉"] = "hear_no_evil", + ["🙊"] = "speak_no_evil", + ["🐒"] = "monkey", + ["🐔"] = "chicken", + ["🐧"] = "penguin", + ["🐦"] = "bird", + ["🐤"] = "baby_chick", + ["🐣"] = "hatching_chick", + ["🐥"] = "hatched_chick", + ["🦆"] = "duck", + ["🦤"] = "dodo", + ["🦅"] = "eagle", + ["🦉"] = "owl", + ["🦇"] = "bat", + ["🐺"] = "wolf", + ["🐗"] = "boar", + ["🐴"] = "horse", + ["🦄"] = "unicorn", + ["🐝"] = "bee", + ["🐛"] = "bug", + ["🦋"] = "butterfly", + ["🐌"] = "snail", + ["🪱"] = "worm", + ["🐞"] = "lady_beetle", + ["🐜"] = "ant", + ["🪰"] = "fly", + ["🦟"] = "mosquito", + ["🪳"] = "cockroach", + ["🪲"] = "beetle", + ["🦗"] = "cricket", + ["🕷️"] = "spider", + ["🕸️"] = "spider_web", + ["🦂"] = "scorpion", + ["🐢"] = "turtle", + ["🐍"] = "snake", + ["🦎"] = "lizard", + ["🦖"] = "t_rex", + ["🦕"] = "sauropod", + ["🐙"] = "octopus", + ["🦑"] = "squid", + ["🦐"] = "shrimp", + ["🦞"] = "lobster", + ["🦀"] = "crab", + ["🐡"] = "blowfish", + ["🐠"] = "tropical_fish", + ["🐟"] = "fish", + ["🦭"] = "seal", + ["🐬"] = "dolphin", + ["🐳"] = "whale", + ["🐋"] = "whale2", + ["🦈"] = "shark", + ["🐊"] = "crocodile", + ["🐅"] = "tiger2", + ["🐆"] = "leopard", + ["🦓"] = "zebra", + ["🦍"] = "gorilla", + ["🦧"] = "orangutan", + ["🐘"] = "elephant", + ["🦣"] = "mammoth", + ["🦬"] = "bison", + ["🦛"] = "hippopotamus", + ["🦏"] = "rhino", + ["🐪"] = "dromedary_camel", + ["🐫"] = "camel", + ["🦒"] = "giraffe", + ["🦘"] = "kangaroo", + ["🐃"] = "water_buffalo", + ["🐂"] = "ox", + ["🐄"] = "cow2", + ["🐎"] = "racehorse", + ["🐖"] = "pig2", + ["🐏"] = "ram", + ["🐑"] = "sheep", + ["🦙"] = "llama", + ["🐐"] = "goat", + ["🦌"] = "deer", + ["🐕"] = "dog2", + ["🐩"] = "poodle", + ["🦮"] = "guide_dog", + ["🐕‍🦺"] = "service_dog", + ["🐈"] = "cat2", + ["🐈‍⬛"] = "black_cat", + ["🐓"] = "rooster", + ["🦃"] = "turkey", + ["🦚"] = "peacock", + ["🦜"] = "parrot", + ["🦢"] = "swan", + ["🦩"] = "flamingo", + ["🕊️"] = "dove", + ["🐇"] = "rabbit2", + ["🦝"] = "raccoon", + ["🦨"] = "skunk", + ["🦡"] = "badger", + ["🦫"] = "beaver", + ["🦦"] = "otter", + ["🦥"] = "sloth", + ["🐁"] = "mouse2", + ["🐀"] = "rat", + ["🐿️"] = "chipmunk", + ["🦔"] = "hedgehog", + ["🐾"] = "feet", + ["🐉"] = "dragon", + ["🐲"] = "dragon_face", + ["🌵"] = "cactus", + ["🎄"] = "christmas_tree", + ["🌲"] = "evergreen_tree", + ["🌳"] = "deciduous_tree", + ["🌴"] = "palm_tree", + ["🌱"] = "seedling", + ["🌿"] = "herb", + ["☘️"] = "shamrock", + ["🍀"] = "four_leaf_clover", + ["🎍"] = "bamboo", + ["🎋"] = "tanabata_tree", + ["🍃"] = "leaves", + ["🍂"] = "fallen_leaf", + ["🍁"] = "maple_leaf", + ["🪶"] = "feather", + ["🍄"] = "mushroom", + ["🐚"] = "shell", + ["🪨"] = "rock", + ["🪵"] = "wood", + ["🌾"] = "ear_of_rice", + ["🪴"] = "potted_plant", + ["💐"] = "bouquet", + ["🌷"] = "tulip", + ["🌹"] = "rose", + ["🥀"] = "wilted_rose", + ["🌺"] = "hibiscus", + ["🌸"] = "cherry_blossom", + ["🌼"] = "blossom", + ["🌻"] = "sunflower", + ["🌞"] = "sun_with_face", + ["🌝"] = "full_moon_with_face", + ["🌛"] = "first_quarter_moon_with_face", + ["🌜"] = "last_quarter_moon_with_face", + ["🌚"] = "new_moon_with_face", + ["🌕"] = "full_moon", + ["🌖"] = "waning_gibbous_moon", + ["🌗"] = "last_quarter_moon", + ["🌘"] = "waning_crescent_moon", + ["🌑"] = "new_moon", + ["🌒"] = "waxing_crescent_moon", + ["🌓"] = "first_quarter_moon", + ["🌔"] = "waxing_gibbous_moon", + ["🌙"] = "crescent_moon", + ["🌎"] = "earth_americas", + ["🌍"] = "earth_africa", + ["🌏"] = "earth_asia", + ["🪐"] = "ringed_planet", + ["💫"] = "dizzy", + ["⭐"] = "star", + ["🌟"] = "star2", + ["✨"] = "sparkles", + ["⚡"] = "zap", + ["☄️"] = "comet", + ["💥"] = "boom", + ["🔥"] = "fire", + ["🌪️"] = "cloud_tornado", + ["🌈"] = "rainbow", + ["☀️"] = "sunny", + ["🌤️"] = "white_sun_small_cloud", + ["⛅"] = "partly_sunny", + ["🌥️"] = "white_sun_cloud", + ["☁️"] = "cloud", + ["🌦️"] = "white_sun_rain_cloud", + ["🌧️"] = "cloud_rain", + ["⛈️"] = "thunder_cloud_rain", + ["🌩️"] = "cloud_lightning", + ["🌨️"] = "cloud_snow", + ["❄️"] = "snowflake", + ["☃️"] = "snowman2", + ["⛄"] = "snowman", + ["🌬️"] = "wind_blowing_face", + ["💨"] = "dash", + ["💧"] = "droplet", + ["💦"] = "sweat_drops", + ["☔"] = "umbrella", + ["☂️"] = "umbrella2", + ["🌊"] = "ocean", + ["🌫️"] = "fog", + ["🍏"] = "green_apple", + ["🍎"] = "apple", + ["🍐"] = "pear", + ["🍊"] = "tangerine", + ["🍋"] = "lemon", + ["🍌"] = "banana", + ["🍉"] = "watermelon", + ["🍇"] = "grapes", + ["🫐"] = "blueberries", + ["🍓"] = "strawberry", + ["🍈"] = "melon", + ["🍒"] = "cherries", + ["🍑"] = "peach", + ["🥭"] = "mango", + ["🍍"] = "pineapple", + ["🥥"] = "coconut", + ["🥝"] = "kiwi", + ["🍅"] = "tomato", + ["🍆"] = "eggplant", + ["🥑"] = "avocado", + ["🫒"] = "olive", + ["🥦"] = "broccoli", + ["🥬"] = "leafy_green", + ["🫑"] = "bell_pepper", + ["🥒"] = "cucumber", + ["🌶️"] = "hot_pepper", + ["🌽"] = "corn", + ["🥕"] = "carrot", + ["🧄"] = "garlic", + ["🧅"] = "onion", + ["🥔"] = "potato", + ["🍠"] = "sweet_potato", + ["🥐"] = "croissant", + ["🥯"] = "bagel", + ["🍞"] = "bread", + ["🥖"] = "french_bread", + ["🫓"] = "flatbread", + ["🥨"] = "pretzel", + ["🧀"] = "cheese", + ["🥚"] = "egg", + ["🍳"] = "cooking", + ["🧈"] = "butter", + ["🥞"] = "pancakes", + ["🧇"] = "waffle", + ["🥓"] = "bacon", + ["🥩"] = "cut_of_meat", + ["🍗"] = "poultry_leg", + ["🍖"] = "meat_on_bone", + ["🌭"] = "hotdog", + ["🍔"] = "hamburger", + ["🍟"] = "fries", + ["🍕"] = "pizza", + ["🥪"] = "sandwich", + ["🥙"] = "stuffed_flatbread", + ["🧆"] = "falafel", + ["🌮"] = "taco", + ["🌯"] = "burrito", + ["🫔"] = "tamale", + ["🥗"] = "salad", + ["🥘"] = "shallow_pan_of_food", + ["🫕"] = "fondue", + ["🥫"] = "canned_food", + ["🍝"] = "spaghetti", + ["🍜"] = "ramen", + ["🍲"] = "stew", + ["🍛"] = "curry", + ["🍣"] = "sushi", + ["🍱"] = "bento", + ["🥟"] = "dumpling", + ["🦪"] = "oyster", + ["🍤"] = "fried_shrimp", + ["🍙"] = "rice_ball", + ["🍚"] = "rice", + ["🍘"] = "rice_cracker", + ["🍥"] = "fish_cake", + ["🥠"] = "fortune_cookie", + ["🥮"] = "moon_cake", + ["🍢"] = "oden", + ["🍡"] = "dango", + ["🍧"] = "shaved_ice", + ["🍨"] = "ice_cream", + ["🍦"] = "icecream", + ["🥧"] = "pie", + ["🧁"] = "cupcake", + ["🍰"] = "cake", + ["🎂"] = "birthday", + ["🍮"] = "custard", + ["🍭"] = "lollipop", + ["🍬"] = "candy", + ["🍫"] = "chocolate_bar", + ["🍿"] = "popcorn", + ["🍩"] = "doughnut", + ["🍪"] = "cookie", + ["🌰"] = "chestnut", + ["🥜"] = "peanuts", + ["🍯"] = "honey_pot", + ["🥛"] = "milk", + ["🍼"] = "baby_bottle", + ["☕"] = "coffee", + ["🍵"] = "tea", + ["🫖"] = "teapot", + ["🧉"] = "mate", + ["🧋"] = "bubble_tea", + ["🧃"] = "beverage_box", + ["🥤"] = "cup_with_straw", + ["🍶"] = "sake", + ["🍺"] = "beer", + ["🍻"] = "beers", + ["🥂"] = "champagne_glass", + ["🍷"] = "wine_glass", + ["🥃"] = "tumbler_glass", + ["🍸"] = "cocktail", + ["🍹"] = "tropical_drink", + ["🍾"] = "champagne", + ["🧊"] = "ice_cube", + ["🥄"] = "spoon", + ["🍴"] = "fork_and_knife", + ["🍽️"] = "fork_knife_plate", + ["🥣"] = "bowl_with_spoon", + ["🥡"] = "takeout_box", + ["🥢"] = "chopsticks", + ["🧂"] = "salt", + ["⚽"] = "soccer", + ["🏀"] = "basketball", + ["🏈"] = "football", + ["⚾"] = "baseball", + ["🥎"] = "softball", + ["🎾"] = "tennis", + ["🏐"] = "volleyball", + ["🏉"] = "rugby_football", + ["🥏"] = "flying_disc", + ["🪃"] = "boomerang", + ["🎱"] = "8ball", + ["🪀"] = "yo_yo", + ["🏓"] = "ping_pong", + ["🏸"] = "badminton", + ["🏒"] = "hockey", + ["🏑"] = "field_hockey", + ["🥍"] = "lacrosse", + ["🏏"] = "cricket_game", + ["🥅"] = "goal", + ["⛳"] = "golf", + ["🪁"] = "kite", + ["🏹"] = "bow_and_arrow", + ["🎣"] = "fishing_pole_and_fish", + ["🤿"] = "diving_mask", + ["🥊"] = "boxing_glove", + ["🥋"] = "martial_arts_uniform", + ["🎽"] = "running_shirt_with_sash", + ["🛹"] = "skateboard", + ["🛼"] = "roller_skate", + ["🛷"] = "sled", + ["⛸️"] = "ice_skate", + ["🥌"] = "curling_stone", + ["🎿"] = "ski", + ["⛷️"] = "skier", + ["🏂"] = "snowboarder", + ["🏂🏻"] = "snowboarder_tone1", + ["🏂🏼"] = "snowboarder_tone2", + ["🏂🏽"] = "snowboarder_tone3", + ["🏂🏾"] = "snowboarder_tone4", + ["🏂🏿"] = "snowboarder_tone5", + ["🪂"] = "parachute", + ["🏋️"] = "person_lifting_weights", + ["🏋🏻"] = "person_lifting_weights_tone1", + ["🏋🏼"] = "person_lifting_weights_tone2", + ["🏋🏽"] = "person_lifting_weights_tone3", + ["🏋🏾"] = "person_lifting_weights_tone4", + ["🏋🏿"] = "person_lifting_weights_tone5", + ["🏋️‍♀️"] = "woman_lifting_weights", + ["🏋🏻‍♀️"] = "woman_lifting_weights_tone1", + ["🏋🏼‍♀️"] = "woman_lifting_weights_tone2", + ["🏋🏽‍♀️"] = "woman_lifting_weights_tone3", + ["🏋🏾‍♀️"] = "woman_lifting_weights_tone4", + ["🏋🏿‍♀️"] = "woman_lifting_weights_tone5", + ["🏋️‍♂️"] = "man_lifting_weights", + ["🏋🏻‍♂️"] = "man_lifting_weights_tone1", + ["🏋🏼‍♂️"] = "man_lifting_weights_tone2", + ["🏋🏽‍♂️"] = "man_lifting_weights_tone3", + ["🏋🏾‍♂️"] = "man_lifting_weights_tone4", + ["🏋🏿‍♂️"] = "man_lifting_weights_tone5", + ["🤼"] = "people_wrestling", + ["🤼‍♀️"] = "women_wrestling", + ["🤼‍♂️"] = "men_wrestling", + ["🤸"] = "person_doing_cartwheel", + ["🤸🏻"] = "person_doing_cartwheel_tone1", + ["🤸🏼"] = "person_doing_cartwheel_tone2", + ["🤸🏽"] = "person_doing_cartwheel_tone3", + ["🤸🏾"] = "person_doing_cartwheel_tone4", + ["🤸🏿"] = "person_doing_cartwheel_tone5", + ["🤸‍♀️"] = "woman_cartwheeling", + ["🤸🏻‍♀️"] = "woman_cartwheeling_tone1", + ["🤸🏼‍♀️"] = "woman_cartwheeling_tone2", + ["🤸🏽‍♀️"] = "woman_cartwheeling_tone3", + ["🤸🏾‍♀️"] = "woman_cartwheeling_tone4", + ["🤸🏿‍♀️"] = "woman_cartwheeling_tone5", + ["🤸‍♂️"] = "man_cartwheeling", + ["🤸🏻‍♂️"] = "man_cartwheeling_tone1", + ["🤸🏼‍♂️"] = "man_cartwheeling_tone2", + ["🤸🏽‍♂️"] = "man_cartwheeling_tone3", + ["🤸🏾‍♂️"] = "man_cartwheeling_tone4", + ["🤸🏿‍♂️"] = "man_cartwheeling_tone5", + ["⛹️"] = "person_bouncing_ball", + ["⛹🏻"] = "person_bouncing_ball_tone1", + ["⛹🏼"] = "person_bouncing_ball_tone2", + ["⛹🏽"] = "person_bouncing_ball_tone3", + ["⛹🏾"] = "person_bouncing_ball_tone4", + ["⛹🏿"] = "person_bouncing_ball_tone5", + ["⛹️‍♀️"] = "woman_bouncing_ball", + ["⛹🏻‍♀️"] = "woman_bouncing_ball_tone1", + ["⛹🏼‍♀️"] = "woman_bouncing_ball_tone2", + ["⛹🏽‍♀️"] = "woman_bouncing_ball_tone3", + ["⛹🏾‍♀️"] = "woman_bouncing_ball_tone4", + ["⛹🏿‍♀️"] = "woman_bouncing_ball_tone5", + ["⛹️‍♂️"] = "man_bouncing_ball", + ["⛹🏻‍♂️"] = "man_bouncing_ball_tone1", + ["⛹🏼‍♂️"] = "man_bouncing_ball_tone2", + ["⛹🏽‍♂️"] = "man_bouncing_ball_tone3", + ["⛹🏾‍♂️"] = "man_bouncing_ball_tone4", + ["⛹🏿‍♂️"] = "man_bouncing_ball_tone5", + ["🤺"] = "person_fencing", + ["🤾"] = "person_playing_handball", + ["🤾🏻"] = "person_playing_handball_tone1", + ["🤾🏼"] = "person_playing_handball_tone2", + ["🤾🏽"] = "person_playing_handball_tone3", + ["🤾🏾"] = "person_playing_handball_tone4", + ["🤾🏿"] = "person_playing_handball_tone5", + ["🤾‍♀️"] = "woman_playing_handball", + ["🤾🏻‍♀️"] = "woman_playing_handball_tone1", + ["🤾🏼‍♀️"] = "woman_playing_handball_tone2", + ["🤾🏽‍♀️"] = "woman_playing_handball_tone3", + ["🤾🏾‍♀️"] = "woman_playing_handball_tone4", + ["🤾🏿‍♀️"] = "woman_playing_handball_tone5", + ["🤾‍♂️"] = "man_playing_handball", + ["🤾🏻‍♂️"] = "man_playing_handball_tone1", + ["🤾🏼‍♂️"] = "man_playing_handball_tone2", + ["🤾🏽‍♂️"] = "man_playing_handball_tone3", + ["🤾🏾‍♂️"] = "man_playing_handball_tone4", + ["🤾🏿‍♂️"] = "man_playing_handball_tone5", + ["🏌️"] = "person_golfing", + ["🏌🏻"] = "person_golfing_tone1", + ["🏌🏼"] = "person_golfing_tone2", + ["🏌🏽"] = "person_golfing_tone3", + ["🏌🏾"] = "person_golfing_tone4", + ["🏌🏿"] = "person_golfing_tone5", + ["🏌️‍♀️"] = "woman_golfing", + ["🏌🏻‍♀️"] = "woman_golfing_tone1", + ["🏌🏼‍♀️"] = "woman_golfing_tone2", + ["🏌🏽‍♀️"] = "woman_golfing_tone3", + ["🏌🏾‍♀️"] = "woman_golfing_tone4", + ["🏌🏿‍♀️"] = "woman_golfing_tone5", + ["🏌️‍♂️"] = "man_golfing", + ["🏌🏻‍♂️"] = "man_golfing_tone1", + ["🏌🏼‍♂️"] = "man_golfing_tone2", + ["🏌🏽‍♂️"] = "man_golfing_tone3", + ["🏌🏾‍♂️"] = "man_golfing_tone4", + ["🏌🏿‍♂️"] = "man_golfing_tone5", + ["🏇"] = "horse_racing", + ["🏇🏻"] = "horse_racing_tone1", + ["🏇🏼"] = "horse_racing_tone2", + ["🏇🏽"] = "horse_racing_tone3", + ["🏇🏾"] = "horse_racing_tone4", + ["🏇🏿"] = "horse_racing_tone5", + ["🧘"] = "person_in_lotus_position", + ["🧘🏻"] = "person_in_lotus_position_tone1", + ["🧘🏼"] = "person_in_lotus_position_tone2", + ["🧘🏽"] = "person_in_lotus_position_tone3", + ["🧘🏾"] = "person_in_lotus_position_tone4", + ["🧘🏿"] = "person_in_lotus_position_tone5", + ["🧘‍♀️"] = "woman_in_lotus_position", + ["🧘🏻‍♀️"] = "woman_in_lotus_position_tone1", + ["🧘🏼‍♀️"] = "woman_in_lotus_position_tone2", + ["🧘🏽‍♀️"] = "woman_in_lotus_position_tone3", + ["🧘🏾‍♀️"] = "woman_in_lotus_position_tone4", + ["🧘🏿‍♀️"] = "woman_in_lotus_position_tone5", + ["🧘‍♂️"] = "man_in_lotus_position", + ["🧘🏻‍♂️"] = "man_in_lotus_position_tone1", + ["🧘🏼‍♂️"] = "man_in_lotus_position_tone2", + ["🧘🏽‍♂️"] = "man_in_lotus_position_tone3", + ["🧘🏾‍♂️"] = "man_in_lotus_position_tone4", + ["🧘🏿‍♂️"] = "man_in_lotus_position_tone5", + ["🏄"] = "person_surfing", + ["🏄🏻"] = "person_surfing_tone1", + ["🏄🏼"] = "person_surfing_tone2", + ["🏄🏽"] = "person_surfing_tone3", + ["🏄🏾"] = "person_surfing_tone4", + ["🏄🏿"] = "person_surfing_tone5", + ["🏄‍♀️"] = "woman_surfing", + ["🏄🏻‍♀️"] = "woman_surfing_tone1", + ["🏄🏼‍♀️"] = "woman_surfing_tone2", + ["🏄🏽‍♀️"] = "woman_surfing_tone3", + ["🏄🏾‍♀️"] = "woman_surfing_tone4", + ["🏄🏿‍♀️"] = "woman_surfing_tone5", + ["🏄‍♂️"] = "man_surfing", + ["🏄🏻‍♂️"] = "man_surfing_tone1", + ["🏄🏼‍♂️"] = "man_surfing_tone2", + ["🏄🏽‍♂️"] = "man_surfing_tone3", + ["🏄🏾‍♂️"] = "man_surfing_tone4", + ["🏄🏿‍♂️"] = "man_surfing_tone5", + ["🏊"] = "person_swimming", + ["🏊🏻"] = "person_swimming_tone1", + ["🏊🏼"] = "person_swimming_tone2", + ["🏊🏽"] = "person_swimming_tone3", + ["🏊🏾"] = "person_swimming_tone4", + ["🏊🏿"] = "person_swimming_tone5", + ["🏊‍♀️"] = "woman_swimming", + ["🏊🏻‍♀️"] = "woman_swimming_tone1", + ["🏊🏼‍♀️"] = "woman_swimming_tone2", + ["🏊🏽‍♀️"] = "woman_swimming_tone3", + ["🏊🏾‍♀️"] = "woman_swimming_tone4", + ["🏊🏿‍♀️"] = "woman_swimming_tone5", + ["🏊‍♂️"] = "man_swimming", + ["🏊🏻‍♂️"] = "man_swimming_tone1", + ["🏊🏼‍♂️"] = "man_swimming_tone2", + ["🏊🏽‍♂️"] = "man_swimming_tone3", + ["🏊🏾‍♂️"] = "man_swimming_tone4", + ["🏊🏿‍♂️"] = "man_swimming_tone5", + ["🤽"] = "person_playing_water_polo", + ["🤽🏻"] = "person_playing_water_polo_tone1", + ["🤽🏼"] = "person_playing_water_polo_tone2", + ["🤽🏽"] = "person_playing_water_polo_tone3", + ["🤽🏾"] = "person_playing_water_polo_tone4", + ["🤽🏿"] = "person_playing_water_polo_tone5", + ["🤽‍♀️"] = "woman_playing_water_polo", + ["🤽🏻‍♀️"] = "woman_playing_water_polo_tone1", + ["🤽🏼‍♀️"] = "woman_playing_water_polo_tone2", + ["🤽🏽‍♀️"] = "woman_playing_water_polo_tone3", + ["🤽🏾‍♀️"] = "woman_playing_water_polo_tone4", + ["🤽🏿‍♀️"] = "woman_playing_water_polo_tone5", + ["🤽‍♂️"] = "man_playing_water_polo", + ["🤽🏻‍♂️"] = "man_playing_water_polo_tone1", + ["🤽🏼‍♂️"] = "man_playing_water_polo_tone2", + ["🤽🏽‍♂️"] = "man_playing_water_polo_tone3", + ["🤽🏾‍♂️"] = "man_playing_water_polo_tone4", + ["🤽🏿‍♂️"] = "man_playing_water_polo_tone5", + ["🚣"] = "person_rowing_boat", + ["🚣🏻"] = "person_rowing_boat_tone1", + ["🚣🏼"] = "person_rowing_boat_tone2", + ["🚣🏽"] = "person_rowing_boat_tone3", + ["🚣🏾"] = "person_rowing_boat_tone4", + ["🚣🏿"] = "person_rowing_boat_tone5", + ["🚣‍♀️"] = "woman_rowing_boat", + ["🚣🏻‍♀️"] = "woman_rowing_boat_tone1", + ["🚣🏼‍♀️"] = "woman_rowing_boat_tone2", + ["🚣🏽‍♀️"] = "woman_rowing_boat_tone3", + ["🚣🏾‍♀️"] = "woman_rowing_boat_tone4", + ["🚣🏿‍♀️"] = "woman_rowing_boat_tone5", + ["🚣‍♂️"] = "man_rowing_boat", + ["🚣🏻‍♂️"] = "man_rowing_boat_tone1", + ["🚣🏼‍♂️"] = "man_rowing_boat_tone2", + ["🚣🏽‍♂️"] = "man_rowing_boat_tone3", + ["🚣🏾‍♂️"] = "man_rowing_boat_tone4", + ["🚣🏿‍♂️"] = "man_rowing_boat_tone5", + ["🧗"] = "person_climbing", + ["🧗🏻"] = "person_climbing_tone1", + ["🧗🏼"] = "person_climbing_tone2", + ["🧗🏽"] = "person_climbing_tone3", + ["🧗🏾"] = "person_climbing_tone4", + ["🧗🏿"] = "person_climbing_tone5", + ["🧗‍♀️"] = "woman_climbing", + ["🧗🏻‍♀️"] = "woman_climbing_tone1", + ["🧗🏼‍♀️"] = "woman_climbing_tone2", + ["🧗🏽‍♀️"] = "woman_climbing_tone3", + ["🧗🏾‍♀️"] = "woman_climbing_tone4", + ["🧗🏿‍♀️"] = "woman_climbing_tone5", + ["🧗‍♂️"] = "man_climbing", + ["🧗🏻‍♂️"] = "man_climbing_tone1", + ["🧗🏼‍♂️"] = "man_climbing_tone2", + ["🧗🏽‍♂️"] = "man_climbing_tone3", + ["🧗🏾‍♂️"] = "man_climbing_tone4", + ["🧗🏿‍♂️"] = "man_climbing_tone5", + ["🚵"] = "person_mountain_biking", + ["🚵🏻"] = "person_mountain_biking_tone1", + ["🚵🏼"] = "person_mountain_biking_tone2", + ["🚵🏽"] = "person_mountain_biking_tone3", + ["🚵🏾"] = "person_mountain_biking_tone4", + ["🚵🏿"] = "person_mountain_biking_tone5", + ["🚵‍♀️"] = "woman_mountain_biking", + ["🚵🏻‍♀️"] = "woman_mountain_biking_tone1", + ["🚵🏼‍♀️"] = "woman_mountain_biking_tone2", + ["🚵🏽‍♀️"] = "woman_mountain_biking_tone3", + ["🚵🏾‍♀️"] = "woman_mountain_biking_tone4", + ["🚵🏿‍♀️"] = "woman_mountain_biking_tone5", + ["🚵‍♂️"] = "man_mountain_biking", + ["🚵🏻‍♂️"] = "man_mountain_biking_tone1", + ["🚵🏼‍♂️"] = "man_mountain_biking_tone2", + ["🚵🏽‍♂️"] = "man_mountain_biking_tone3", + ["🚵🏾‍♂️"] = "man_mountain_biking_tone4", + ["🚵🏿‍♂️"] = "man_mountain_biking_tone5", + ["🚴"] = "person_biking", + ["🚴🏻"] = "person_biking_tone1", + ["🚴🏼"] = "person_biking_tone2", + ["🚴🏽"] = "person_biking_tone3", + ["🚴🏾"] = "person_biking_tone4", + ["🚴🏿"] = "person_biking_tone5", + ["🚴‍♀️"] = "woman_biking", + ["🚴🏻‍♀️"] = "woman_biking_tone1", + ["🚴🏼‍♀️"] = "woman_biking_tone2", + ["🚴🏽‍♀️"] = "woman_biking_tone3", + ["🚴🏾‍♀️"] = "woman_biking_tone4", + ["🚴🏿‍♀️"] = "woman_biking_tone5", + ["🚴‍♂️"] = "man_biking", + ["🚴🏻‍♂️"] = "man_biking_tone1", + ["🚴🏼‍♂️"] = "man_biking_tone2", + ["🚴🏽‍♂️"] = "man_biking_tone3", + ["🚴🏾‍♂️"] = "man_biking_tone4", + ["🚴🏿‍♂️"] = "man_biking_tone5", + ["🏆"] = "trophy", + ["🥇"] = "first_place", + ["🥈"] = "second_place", + ["🥉"] = "third_place", + ["🏅"] = "medal", + ["🎖️"] = "military_medal", + ["🏵️"] = "rosette", + ["🎗️"] = "reminder_ribbon", + ["🎫"] = "ticket", + ["🎟️"] = "tickets", + ["🎪"] = "circus_tent", + ["🤹"] = "person_juggling", + ["🤹🏻"] = "person_juggling_tone1", + ["🤹🏼"] = "person_juggling_tone2", + ["🤹🏽"] = "person_juggling_tone3", + ["🤹🏾"] = "person_juggling_tone4", + ["🤹🏿"] = "person_juggling_tone5", + ["🤹‍♀️"] = "woman_juggling", + ["🤹🏻‍♀️"] = "woman_juggling_tone1", + ["🤹🏼‍♀️"] = "woman_juggling_tone2", + ["🤹🏽‍♀️"] = "woman_juggling_tone3", + ["🤹🏾‍♀️"] = "woman_juggling_tone4", + ["🤹🏿‍♀️"] = "woman_juggling_tone5", + ["🤹‍♂️"] = "man_juggling", + ["🤹🏻‍♂️"] = "man_juggling_tone1", + ["🤹🏼‍♂️"] = "man_juggling_tone2", + ["🤹🏽‍♂️"] = "man_juggling_tone3", + ["🤹🏾‍♂️"] = "man_juggling_tone4", + ["🤹🏿‍♂️"] = "man_juggling_tone5", + ["🎭"] = "performing_arts", + ["🩰"] = "ballet_shoes", + ["🎨"] = "art", + ["🎬"] = "clapper", + ["🎤"] = "microphone", + ["🎧"] = "headphones", + ["🎼"] = "musical_score", + ["🎹"] = "musical_keyboard", + ["🥁"] = "drum", + ["🪘"] = "long_drum", + ["🎷"] = "saxophone", + ["🎺"] = "trumpet", + ["🎸"] = "guitar", + ["🪕"] = "banjo", + ["🎻"] = "violin", + ["🪗"] = "accordion", + ["🎲"] = "game_die", + ["♟️"] = "chess_pawn", + ["🎯"] = "dart", + ["🎳"] = "bowling", + ["🎮"] = "video_game", + ["🎰"] = "slot_machine", + ["🧩"] = "jigsaw", + ["🚗"] = "red_car", + ["🚕"] = "taxi", + ["🚙"] = "blue_car", + ["🛻"] = "pickup_truck", + ["🚌"] = "bus", + ["🚎"] = "trolleybus", + ["🏎️"] = "race_car", + ["🚓"] = "police_car", + ["🚑"] = "ambulance", + ["🚒"] = "fire_engine", + ["🚐"] = "minibus", + ["🚚"] = "truck", + ["🚛"] = "articulated_lorry", + ["🚜"] = "tractor", + ["🦯"] = "probing_cane", + ["🦽"] = "manual_wheelchair", + ["🦼"] = "motorized_wheelchair", + ["🛴"] = "scooter", + ["🚲"] = "bike", + ["🛵"] = "motor_scooter", + ["🏍️"] = "motorcycle", + ["🛺"] = "auto_rickshaw", + ["🚨"] = "rotating_light", + ["🚔"] = "oncoming_police_car", + ["🚍"] = "oncoming_bus", + ["🚘"] = "oncoming_automobile", + ["🚖"] = "oncoming_taxi", + ["🚡"] = "aerial_tramway", + ["🚠"] = "mountain_cableway", + ["🚟"] = "suspension_railway", + ["🚃"] = "railway_car", + ["🚋"] = "train", + ["🚞"] = "mountain_railway", + ["🚝"] = "monorail", + ["🚄"] = "bullettrain_side", + ["🚅"] = "bullettrain_front", + ["🚈"] = "light_rail", + ["🚂"] = "steam_locomotive", + ["🚆"] = "train2", + ["🚇"] = "metro", + ["🚊"] = "tram", + ["🚉"] = "station", + ["✈️"] = "airplane", + ["🛫"] = "airplane_departure", + ["🛬"] = "airplane_arriving", + ["🛩️"] = "airplane_small", + ["💺"] = "seat", + ["🛰️"] = "satellite_orbital", + ["🚀"] = "rocket", + ["🛸"] = "flying_saucer", + ["🚁"] = "helicopter", + ["🛶"] = "canoe", + ["⛵"] = "sailboat", + ["🚤"] = "speedboat", + ["🛥️"] = "motorboat", + ["🛳️"] = "cruise_ship", + ["⛴️"] = "ferry", + ["🚢"] = "ship", + ["⚓"] = "anchor", + ["⛽"] = "fuelpump", + ["🚧"] = "construction", + ["🚦"] = "vertical_traffic_light", + ["🚥"] = "traffic_light", + ["🚏"] = "busstop", + ["🗺️"] = "map", + ["🗿"] = "moyai", + ["🗽"] = "statue_of_liberty", + ["🗼"] = "tokyo_tower", + ["🏰"] = "european_castle", + ["🏯"] = "japanese_castle", + ["🏟️"] = "stadium", + ["🎡"] = "ferris_wheel", + ["🎢"] = "roller_coaster", + ["🎠"] = "carousel_horse", + ["⛲"] = "fountain", + ["⛱️"] = "beach_umbrella", + ["🏖️"] = "beach", + ["🏝️"] = "island", + ["🏜️"] = "desert", + ["🌋"] = "volcano", + ["⛰️"] = "mountain", + ["🏔️"] = "mountain_snow", + ["🗻"] = "mount_fuji", + ["🏕️"] = "camping", + ["⛺"] = "tent", + ["🏠"] = "house", + ["🏡"] = "house_with_garden", + ["🏘️"] = "homes", + ["🏚️"] = "house_abandoned", + ["🛖"] = "hut", + ["🏗️"] = "construction_site", + ["🏭"] = "factory", + ["🏢"] = "office", + ["🏬"] = "department_store", + ["🏣"] = "post_office", + ["🏤"] = "european_post_office", + ["🏥"] = "hospital", + ["🏦"] = "bank", + ["🏨"] = "hotel", + ["🏪"] = "convenience_store", + ["🏫"] = "school", + ["🏩"] = "love_hotel", + ["💒"] = "wedding", + ["🏛️"] = "classical_building", + ["⛪"] = "church", + ["🕌"] = "mosque", + ["🕍"] = "synagogue", + ["🛕"] = "hindu_temple", + ["🕋"] = "kaaba", + ["⛩️"] = "shinto_shrine", + ["🛤️"] = "railway_track", + ["🛣️"] = "motorway", + ["🗾"] = "japan", + ["🎑"] = "rice_scene", + ["🏞️"] = "park", + ["🌅"] = "sunrise", + ["🌄"] = "sunrise_over_mountains", + ["🌠"] = "stars", + ["🎇"] = "sparkler", + ["🎆"] = "fireworks", + ["🌇"] = "city_sunset", + ["🌆"] = "city_dusk", + ["🏙️"] = "cityscape", + ["🌃"] = "night_with_stars", + ["🌌"] = "milky_way", + ["🌉"] = "bridge_at_night", + ["🌁"] = "foggy", + ["⌚"] = "watch", + ["📱"] = "mobile_phone", + ["📲"] = "calling", + ["💻"] = "computer", + ["⌨️"] = "keyboard", + ["🖥️"] = "desktop", + ["🖨️"] = "printer", + ["🖱️"] = "mouse_three_button", + ["🖲️"] = "trackball", + ["🕹️"] = "joystick", + ["🗜️"] = "compression", + ["💽"] = "minidisc", + ["💾"] = "floppy_disk", + ["💿"] = "cd", + ["📀"] = "dvd", + ["📼"] = "vhs", + ["📷"] = "camera", + ["📸"] = "camera_with_flash", + ["📹"] = "video_camera", + ["🎥"] = "movie_camera", + ["📽️"] = "projector", + ["🎞️"] = "film_frames", + ["📞"] = "telephone_receiver", + ["☎️"] = "telephone", + ["📟"] = "pager", + ["📠"] = "fax", + ["📺"] = "tv", + ["📻"] = "radio", + ["🎙️"] = "microphone2", + ["🎚️"] = "level_slider", + ["🎛️"] = "control_knobs", + ["🧭"] = "compass", + ["⏱️"] = "stopwatch", + ["⏲️"] = "timer", + ["⏰"] = "alarm_clock", + ["🕰️"] = "clock", + ["⌛"] = "hourglass", + ["⏳"] = "hourglass_flowing_sand", + ["📡"] = "satellite", + ["🔋"] = "battery", + ["🔌"] = "electric_plug", + ["💡"] = "bulb", + ["🔦"] = "flashlight", + ["🕯️"] = "candle", + ["🪔"] = "diya_lamp", + ["🧯"] = "fire_extinguisher", + ["🛢️"] = "oil", + ["💸"] = "money_with_wings", + ["💵"] = "dollar", + ["💴"] = "yen", + ["💶"] = "euro", + ["💷"] = "pound", + ["🪙"] = "coin", + ["💰"] = "moneybag", + ["💳"] = "credit_card", + ["💎"] = "gem", + ["⚖️"] = "scales", + ["🪜"] = "ladder", + ["🧰"] = "toolbox", + ["🪛"] = "screwdriver", + ["🔧"] = "wrench", + ["🔨"] = "hammer", + ["⚒️"] = "hammer_pick", + ["🛠️"] = "tools", + ["⛏️"] = "pick", + ["🔩"] = "nut_and_bolt", + ["⚙️"] = "gear", + ["🧱"] = "bricks", + ["⛓️"] = "chains", + ["🪝"] = "hook", + ["🪢"] = "knot", + ["🧲"] = "magnet", + ["🔫"] = "gun", + ["💣"] = "bomb", + ["🧨"] = "firecracker", + ["🪓"] = "axe", + ["🪚"] = "carpentry_saw", + ["🔪"] = "knife", + ["🗡️"] = "dagger", + ["⚔️"] = "crossed_swords", + ["🛡️"] = "shield", + ["🚬"] = "smoking", + ["⚰️"] = "coffin", + ["🪦"] = "headstone", + ["⚱️"] = "urn", + ["🏺"] = "amphora", + ["🪄"] = "magic_wand", + ["🔮"] = "crystal_ball", + ["📿"] = "prayer_beads", + ["🧿"] = "nazar_amulet", + ["💈"] = "barber", + ["⚗️"] = "alembic", + ["🔭"] = "telescope", + ["🔬"] = "microscope", + ["🕳️"] = "hole", + ["🪟"] = "window", + ["🩹"] = "adhesive_bandage", + ["🩺"] = "stethoscope", + ["💊"] = "pill", + ["💉"] = "syringe", + ["🩸"] = "drop_of_blood", + ["🧬"] = "dna", + ["🦠"] = "microbe", + ["🧫"] = "petri_dish", + ["🧪"] = "test_tube", + ["🌡️"] = "thermometer", + ["🪤"] = "mouse_trap", + ["🧹"] = "broom", + ["🧺"] = "basket", + ["🪡"] = "sewing_needle", + ["🧻"] = "roll_of_paper", + ["🚽"] = "toilet", + ["🪠"] = "plunger", + ["🪣"] = "bucket", + ["🚰"] = "potable_water", + ["🚿"] = "shower", + ["🛁"] = "bathtub", + ["🛀"] = "bath", + ["🛀🏻"] = "bath_tone1", + ["🛀🏼"] = "bath_tone2", + ["🛀🏽"] = "bath_tone3", + ["🛀🏾"] = "bath_tone4", + ["🛀🏿"] = "bath_tone5", + ["🪥"] = "toothbrush", + ["🧼"] = "soap", + ["🪒"] = "razor", + ["🧽"] = "sponge", + ["🧴"] = "squeeze_bottle", + ["🛎️"] = "bellhop", + ["🔑"] = "key", + ["🗝️"] = "key2", + ["🚪"] = "door", + ["🪑"] = "chair", + ["🪞"] = "mirror", + ["🛋️"] = "couch", + ["🛏️"] = "bed", + ["🛌"] = "sleeping_accommodation", + ["🛌🏻"] = "person_in_bed_tone1", + ["🛌🏼"] = "person_in_bed_tone2", + ["🛌🏽"] = "person_in_bed_tone3", + ["🛌🏾"] = "person_in_bed_tone4", + ["🛌🏿"] = "person_in_bed_tone5", + ["🧸"] = "teddy_bear", + ["🖼️"] = "frame_photo", + ["🛍️"] = "shopping_bags", + ["🛒"] = "shopping_cart", + ["🎁"] = "gift", + ["🎈"] = "balloon", + ["🎏"] = "flags", + ["🎀"] = "ribbon", + ["🎊"] = "confetti_ball", + ["🎉"] = "tada", + ["🪅"] = "piñata", + ["🪆"] = "nesting_dolls", + ["🎎"] = "dolls", + ["🏮"] = "izakaya_lantern", + ["🎐"] = "wind_chime", + ["🧧"] = "red_envelope", + ["✉️"] = "envelope", + ["📩"] = "envelope_with_arrow", + ["📨"] = "incoming_envelope", + ["📧"] = "e_mail", + ["💌"] = "love_letter", + ["📥"] = "inbox_tray", + ["📤"] = "outbox_tray", + ["📦"] = "package", + ["🏷️"] = "label", + ["📪"] = "mailbox_closed", + ["📫"] = "mailbox", + ["📬"] = "mailbox_with_mail", + ["📭"] = "mailbox_with_no_mail", + ["📮"] = "postbox", + ["📯"] = "postal_horn", + ["🪧"] = "placard", + ["📜"] = "scroll", + ["📃"] = "page_with_curl", + ["📄"] = "page_facing_up", + ["📑"] = "bookmark_tabs", + ["🧾"] = "receipt", + ["📊"] = "bar_chart", + ["📈"] = "chart_with_upwards_trend", + ["📉"] = "chart_with_downwards_trend", + ["🗒️"] = "notepad_spiral", + ["🗓️"] = "calendar_spiral", + ["📆"] = "calendar", + ["📅"] = "date", + ["🗑️"] = "wastebasket", + ["📇"] = "card_index", + ["🗃️"] = "card_box", + ["🗳️"] = "ballot_box", + ["🗄️"] = "file_cabinet", + ["📋"] = "clipboard", + ["📁"] = "file_folder", + ["📂"] = "open_file_folder", + ["🗂️"] = "dividers", + ["🗞️"] = "newspaper2", + ["📰"] = "newspaper", + ["📓"] = "notebook", + ["📔"] = "notebook_with_decorative_cover", + ["📒"] = "ledger", + ["📕"] = "closed_book", + ["📗"] = "green_book", + ["📘"] = "blue_book", + ["📙"] = "orange_book", + ["📚"] = "books", + ["📖"] = "book", + ["🔖"] = "bookmark", + ["🧷"] = "safety_pin", + ["🔗"] = "link", + ["📎"] = "paperclip", + ["🖇️"] = "paperclips", + ["📐"] = "triangular_ruler", + ["📏"] = "straight_ruler", + ["🧮"] = "abacus", + ["📌"] = "pushpin", + ["📍"] = "round_pushpin", + ["✂️"] = "scissors", + ["🖊️"] = "pen_ballpoint", + ["🖋️"] = "pen_fountain", + ["✒️"] = "black_nib", + ["🖌️"] = "paintbrush", + ["🖍️"] = "crayon", + ["📝"] = "pencil", + ["✏️"] = "pencil2", + ["🔍"] = "mag", + ["🔎"] = "mag_right", + ["🔏"] = "lock_with_ink_pen", + ["🔐"] = "closed_lock_with_key", + ["🔒"] = "lock", + ["🔓"] = "unlock", + ["❤️"] = "heart", + ["🧡"] = "orange_heart", + ["💛"] = "yellow_heart", + ["💚"] = "green_heart", + ["💙"] = "blue_heart", + ["💜"] = "purple_heart", + ["🖤"] = "black_heart", + ["🤎"] = "brown_heart", + ["🤍"] = "white_heart", + ["💔"] = "broken_heart", + ["❣️"] = "heart_exclamation", + ["💕"] = "two_hearts", + ["💞"] = "revolving_hearts", + ["💓"] = "heartbeat", + ["💗"] = "heartpulse", + ["💖"] = "sparkling_heart", + ["💘"] = "cupid", + ["💝"] = "gift_heart", + ["❤️‍🩹"] = "mending_heart", + ["❤️‍🔥"] = "heart_on_fire", + ["💟"] = "heart_decoration", + ["☮️"] = "peace", + ["✝️"] = "cross", + ["☪️"] = "star_and_crescent", + ["🕉️"] = "om_symbol", + ["☸️"] = "wheel_of_dharma", + ["✡️"] = "star_of_david", + ["🔯"] = "six_pointed_star", + ["🕎"] = "menorah", + ["☯️"] = "yin_yang", + ["☦️"] = "orthodox_cross", + ["🛐"] = "place_of_worship", + ["⛎"] = "ophiuchus", + ["♈"] = "aries", + ["♉"] = "taurus", + ["♊"] = "gemini", + ["♋"] = "cancer", + ["♌"] = "leo", + ["♍"] = "virgo", + ["♎"] = "libra", + ["♏"] = "scorpius", + ["♐"] = "sagittarius", + ["♑"] = "capricorn", + ["♒"] = "aquarius", + ["♓"] = "pisces", + ["🆔"] = "id", + ["⚛️"] = "atom", + ["🉑"] = "accept", + ["☢️"] = "radioactive", + ["☣️"] = "biohazard", + ["📴"] = "mobile_phone_off", + ["📳"] = "vibration_mode", + ["🈶"] = "u6709", + ["🈚"] = "u7121", + ["🈸"] = "u7533", + ["🈺"] = "u55b6", + ["🈷️"] = "u6708", + ["✴️"] = "eight_pointed_black_star", + ["🆚"] = "vs", + ["💮"] = "white_flower", + ["🉐"] = "ideograph_advantage", + ["㊙️"] = "secret", + ["㊗️"] = "congratulations", + ["🈴"] = "u5408", + ["🈵"] = "u6e80", + ["🈹"] = "u5272", + ["🈲"] = "u7981", + ["🅰️"] = "a", + ["🅱️"] = "b", + ["🆎"] = "ab", + ["🆑"] = "cl", + ["🅾️"] = "o2", + ["🆘"] = "sos", + ["❌"] = "x", + ["⭕"] = "o", + ["🛑"] = "octagonal_sign", + ["⛔"] = "no_entry", + ["📛"] = "name_badge", + ["🚫"] = "no_entry_sign", + ["💯"] = "100", + ["💢"] = "anger", + ["♨️"] = "hotsprings", + ["🚷"] = "no_pedestrians", + ["🚯"] = "do_not_litter", + ["🚳"] = "no_bicycles", + ["🚱"] = "non_potable_water", + ["🔞"] = "underage", + ["📵"] = "no_mobile_phones", + ["🚭"] = "no_smoking", + ["❗"] = "exclamation", + ["❕"] = "grey_exclamation", + ["❓"] = "question", + ["❔"] = "grey_question", + ["‼️"] = "bangbang", + ["⁉️"] = "interrobang", + ["🔅"] = "low_brightness", + ["🔆"] = "high_brightness", + ["〽️"] = "part_alternation_mark", + ["⚠️"] = "warning", + ["🚸"] = "children_crossing", + ["🔱"] = "trident", + ["⚜️"] = "fleur_de_lis", + ["🔰"] = "beginner", + ["♻️"] = "recycle", + ["✅"] = "white_check_mark", + ["🈯"] = "u6307", + ["💹"] = "chart", + ["❇️"] = "sparkle", + ["✳️"] = "eight_spoked_asterisk", + ["❎"] = "negative_squared_cross_mark", + ["🌐"] = "globe_with_meridians", + ["💠"] = "diamond_shape_with_a_dot_inside", + ["Ⓜ️"] = "m", + ["🌀"] = "cyclone", + ["💤"] = "zzz", + ["🏧"] = "atm", + ["🚾"] = "wc", + ["♿"] = "wheelchair", + ["🅿️"] = "parking", + ["🈳"] = "u7a7a", + ["🈂️"] = "sa", + ["🛂"] = "passport_control", + ["🛃"] = "customs", + ["🛄"] = "baggage_claim", + ["🛅"] = "left_luggage", + ["🛗"] = "elevator", + ["🚹"] = "mens", + ["🚺"] = "womens", + ["🚼"] = "baby_symbol", + ["🚻"] = "restroom", + ["🚮"] = "put_litter_in_its_place", + ["🎦"] = "cinema", + ["📶"] = "signal_strength", + ["🈁"] = "koko", + ["🔣"] = "symbols", + ["ℹ️"] = "information_source", + ["🔤"] = "abc", + ["🔡"] = "abcd", + ["🔠"] = "capital_abcd", + ["🆖"] = "ng", + ["🆗"] = "ok", + ["🆙"] = "up", + ["🆒"] = "cool", + ["🆕"] = "new", + ["🆓"] = "free", + ["0️⃣"] = "zero", + ["1️⃣"] = "one", + ["2️⃣"] = "two", + ["3️⃣"] = "three", + ["4️⃣"] = "four", + ["5️⃣"] = "five", + ["6️⃣"] = "six", + ["7️⃣"] = "seven", + ["8️⃣"] = "eight", + ["9️⃣"] = "nine", + ["🔟"] = "keycap_ten", + ["🔢"] = "1234", + ["#️⃣"] = "hash", + ["*️⃣"] = "asterisk", + ["⏏️"] = "eject", + ["▶️"] = "arrow_forward", + ["⏸️"] = "pause_button", + ["⏯️"] = "play_pause", + ["⏹️"] = "stop_button", + ["⏺️"] = "record_button", + ["⏭️"] = "track_next", + ["⏮️"] = "track_previous", + ["⏩"] = "fast_forward", + ["⏪"] = "rewind", + ["⏫"] = "arrow_double_up", + ["⏬"] = "arrow_double_down", + ["◀️"] = "arrow_backward", + ["🔼"] = "arrow_up_small", + ["🔽"] = "arrow_down_small", + ["➡️"] = "arrow_right", + ["⬅️"] = "arrow_left", + ["⬆️"] = "arrow_up", + ["⬇️"] = "arrow_down", + ["↗️"] = "arrow_upper_right", + ["↘️"] = "arrow_lower_right", + ["↙️"] = "arrow_lower_left", + ["↖️"] = "arrow_upper_left", + ["↕️"] = "arrow_up_down", + ["↔️"] = "left_right_arrow", + ["↪️"] = "arrow_right_hook", + ["↩️"] = "leftwards_arrow_with_hook", + ["⤴️"] = "arrow_heading_up", + ["⤵️"] = "arrow_heading_down", + ["🔀"] = "twisted_rightwards_arrows", + ["🔁"] = "repeat", + ["🔂"] = "repeat_one", + ["🔄"] = "arrows_counterclockwise", + ["🔃"] = "arrows_clockwise", + ["🎵"] = "musical_note", + ["🎶"] = "notes", + ["➕"] = "heavy_plus_sign", + ["➖"] = "heavy_minus_sign", + ["➗"] = "heavy_division_sign", + ["✖️"] = "heavy_multiplication_x", + ["♾️"] = "infinity", + ["💲"] = "heavy_dollar_sign", + ["💱"] = "currency_exchange", + ["™️"] = "tm", + ["©️"] = "copyright", + ["®️"] = "registered", + ["〰️"] = "wavy_dash", + ["➰"] = "curly_loop", + ["➿"] = "loop", + ["🔚"] = "end", + ["🔙"] = "back", + ["🔛"] = "on", + ["🔝"] = "top", + ["🔜"] = "soon", + ["✔️"] = "heavy_check_mark", + ["☑️"] = "ballot_box_with_check", + ["🔘"] = "radio_button", + ["⚪"] = "white_circle", + ["⚫"] = "black_circle", + ["🔴"] = "red_circle", + ["🔵"] = "blue_circle", + ["🟤"] = "brown_circle", + ["🟣"] = "purple_circle", + ["🟢"] = "green_circle", + ["🟡"] = "yellow_circle", + ["🟠"] = "orange_circle", + ["🔺"] = "small_red_triangle", + ["🔻"] = "small_red_triangle_down", + ["🔸"] = "small_orange_diamond", + ["🔹"] = "small_blue_diamond", + ["🔶"] = "large_orange_diamond", + ["🔷"] = "large_blue_diamond", + ["🔳"] = "white_square_button", + ["🔲"] = "black_square_button", + ["▪️"] = "black_small_square", + ["▫️"] = "white_small_square", + ["◾"] = "black_medium_small_square", + ["◽"] = "white_medium_small_square", + ["◼️"] = "black_medium_square", + ["◻️"] = "white_medium_square", + ["⬛"] = "black_large_square", + ["⬜"] = "white_large_square", + ["🟧"] = "orange_square", + ["🟦"] = "blue_square", + ["🟥"] = "red_square", + ["🟫"] = "brown_square", + ["🟪"] = "purple_square", + ["🟩"] = "green_square", + ["🟨"] = "yellow_square", + ["🔈"] = "speaker", + ["🔇"] = "mute", + ["🔉"] = "sound", + ["🔊"] = "loud_sound", + ["🔔"] = "bell", + ["🔕"] = "no_bell", + ["📣"] = "mega", + ["📢"] = "loudspeaker", + ["🗨️"] = "speech_left", + ["👁‍🗨"] = "eye_in_speech_bubble", + ["💬"] = "speech_balloon", + ["💭"] = "thought_balloon", + ["🗯️"] = "anger_right", + ["♠️"] = "spades", + ["♣️"] = "clubs", + ["♥️"] = "hearts", + ["♦️"] = "diamonds", + ["🃏"] = "black_joker", + ["🎴"] = "flower_playing_cards", + ["🀄"] = "mahjong", + ["🕐"] = "clock1", + ["🕑"] = "clock2", + ["🕒"] = "clock3", + ["🕓"] = "clock4", + ["🕔"] = "clock5", + ["🕕"] = "clock6", + ["🕖"] = "clock7", + ["🕗"] = "clock8", + ["🕘"] = "clock9", + ["🕙"] = "clock10", + ["🕚"] = "clock11", + ["🕛"] = "clock12", + ["🕜"] = "clock130", + ["🕝"] = "clock230", + ["🕞"] = "clock330", + ["🕟"] = "clock430", + ["🕠"] = "clock530", + ["🕡"] = "clock630", + ["🕢"] = "clock730", + ["🕣"] = "clock830", + ["🕤"] = "clock930", + ["🕥"] = "clock1030", + ["🕦"] = "clock1130", + ["🕧"] = "clock1230", + ["♀️"] = "female_sign", + ["♂️"] = "male_sign", + ["⚧"] = "transgender_symbol", + ["⚕️"] = "medical_symbol", + ["🇿"] = "regional_indicator_z", + ["🇾"] = "regional_indicator_y", + ["🇽"] = "regional_indicator_x", + ["🇼"] = "regional_indicator_w", + ["🇻"] = "regional_indicator_v", + ["🇺"] = "regional_indicator_u", + ["🇹"] = "regional_indicator_t", + ["🇸"] = "regional_indicator_s", + ["🇷"] = "regional_indicator_r", + ["🇶"] = "regional_indicator_q", + ["🇵"] = "regional_indicator_p", + ["🇴"] = "regional_indicator_o", + ["🇳"] = "regional_indicator_n", + ["🇲"] = "regional_indicator_m", + ["🇱"] = "regional_indicator_l", + ["🇰"] = "regional_indicator_k", + ["🇯"] = "regional_indicator_j", + ["🇮"] = "regional_indicator_i", + ["🇭"] = "regional_indicator_h", + ["🇬"] = "regional_indicator_g", + ["🇫"] = "regional_indicator_f", + ["🇪"] = "regional_indicator_e", + ["🇩"] = "regional_indicator_d", + ["🇨"] = "regional_indicator_c", + ["🇧"] = "regional_indicator_b", + ["🇦"] = "regional_indicator_a", + ["🏳️"] = "flag_white", + ["🏴"] = "flag_black", + ["🏁"] = "checkered_flag", + ["🚩"] = "triangular_flag_on_post", + ["🏳️‍🌈"] = "rainbow_flag", + ["🏳️‍⚧️"] = "transgender_flag", + ["🏴‍☠️"] = "pirate_flag", + ["🇦🇫"] = "flag_af", + ["🇦🇽"] = "flag_ax", + ["🇦🇱"] = "flag_al", + ["🇩🇿"] = "flag_dz", + ["🇦🇸"] = "flag_as", + ["🇦🇩"] = "flag_ad", + ["🇦🇴"] = "flag_ao", + ["🇦🇮"] = "flag_ai", + ["🇦🇶"] = "flag_aq", + ["🇦🇬"] = "flag_ag", + ["🇦🇷"] = "flag_ar", + ["🇦🇲"] = "flag_am", + ["🇦🇼"] = "flag_aw", + ["🇦🇺"] = "flag_au", + ["🇦🇹"] = "flag_at", + ["🇦🇿"] = "flag_az", + ["🇧🇸"] = "flag_bs", + ["🇧🇭"] = "flag_bh", + ["🇧🇩"] = "flag_bd", + ["🇧🇧"] = "flag_bb", + ["🇧🇾"] = "flag_by", + ["🇧🇪"] = "flag_be", + ["🇧🇿"] = "flag_bz", + ["🇧🇯"] = "flag_bj", + ["🇧🇲"] = "flag_bm", + ["🇧🇹"] = "flag_bt", + ["🇧🇴"] = "flag_bo", + ["🇧🇦"] = "flag_ba", + ["🇧🇼"] = "flag_bw", + ["🇧🇷"] = "flag_br", + ["🇮🇴"] = "flag_io", + ["🇻🇬"] = "flag_vg", + ["🇧🇳"] = "flag_bn", + ["🇧🇬"] = "flag_bg", + ["🇧🇫"] = "flag_bf", + ["🇧🇮"] = "flag_bi", + ["🇰🇭"] = "flag_kh", + ["🇨🇲"] = "flag_cm", + ["🇨🇦"] = "flag_ca", + ["🇮🇨"] = "flag_ic", + ["🇨🇻"] = "flag_cv", + ["🇧🇶"] = "flag_bq", + ["🇰🇾"] = "flag_ky", + ["🇨🇫"] = "flag_cf", + ["🇹🇩"] = "flag_td", + ["🇨🇱"] = "flag_cl", + ["🇨🇳"] = "flag_cn", + ["🇨🇽"] = "flag_cx", + ["🇨🇨"] = "flag_cc", + ["🇨🇴"] = "flag_co", + ["🇰🇲"] = "flag_km", + ["🇨🇬"] = "flag_cg", + ["🇨🇩"] = "flag_cd", + ["🇨🇰"] = "flag_ck", + ["🇨🇷"] = "flag_cr", + ["🇨🇮"] = "flag_ci", + ["🇭🇷"] = "flag_hr", + ["🇨🇺"] = "flag_cu", + ["🇨🇼"] = "flag_cw", + ["🇨🇾"] = "flag_cy", + ["🇨🇿"] = "flag_cz", + ["🇩🇰"] = "flag_dk", + ["🇩🇯"] = "flag_dj", + ["🇩🇲"] = "flag_dm", + ["🇩🇴"] = "flag_do", + ["🇪🇨"] = "flag_ec", + ["🇪🇬"] = "flag_eg", + ["🇸🇻"] = "flag_sv", + ["🇬🇶"] = "flag_gq", + ["🇪🇷"] = "flag_er", + ["🇪🇪"] = "flag_ee", + ["🇪🇹"] = "flag_et", + ["🇪🇺"] = "flag_eu", + ["🇫🇰"] = "flag_fk", + ["🇫🇴"] = "flag_fo", + ["🇫🇯"] = "flag_fj", + ["🇫🇮"] = "flag_fi", + ["🇫🇷"] = "flag_fr", + ["🇬🇫"] = "flag_gf", + ["🇵🇫"] = "flag_pf", + ["🇹🇫"] = "flag_tf", + ["🇬🇦"] = "flag_ga", + ["🇬🇲"] = "flag_gm", + ["🇬🇪"] = "flag_ge", + ["🇩🇪"] = "flag_de", + ["🇬🇭"] = "flag_gh", + ["🇬🇮"] = "flag_gi", + ["🇬🇷"] = "flag_gr", + ["🇬🇱"] = "flag_gl", + ["🇬🇩"] = "flag_gd", + ["🇬🇵"] = "flag_gp", + ["🇬🇺"] = "flag_gu", + ["🇬🇹"] = "flag_gt", + ["🇬🇬"] = "flag_gg", + ["🇬🇳"] = "flag_gn", + ["🇬🇼"] = "flag_gw", + ["🇬🇾"] = "flag_gy", + ["🇭🇹"] = "flag_ht", + ["🇭🇳"] = "flag_hn", + ["🇭🇰"] = "flag_hk", + ["🇭🇺"] = "flag_hu", + ["🇮🇸"] = "flag_is", + ["🇮🇳"] = "flag_in", + ["🇮🇩"] = "flag_id", + ["🇮🇷"] = "flag_ir", + ["🇮🇶"] = "flag_iq", + ["🇮🇪"] = "flag_ie", + ["🇮🇲"] = "flag_im", + ["🇮🇱"] = "flag_il", + ["🇮🇹"] = "flag_it", + ["🇯🇲"] = "flag_jm", + ["🇯🇵"] = "flag_jp", + ["🎌"] = "crossed_flags", + ["🇯🇪"] = "flag_je", + ["🇯🇴"] = "flag_jo", + ["🇰🇿"] = "flag_kz", + ["🇰🇪"] = "flag_ke", + ["🇰🇮"] = "flag_ki", + ["🇽🇰"] = "flag_xk", + ["🇰🇼"] = "flag_kw", + ["🇰🇬"] = "flag_kg", + ["🇱🇦"] = "flag_la", + ["🇱🇻"] = "flag_lv", + ["🇱🇧"] = "flag_lb", + ["🇱🇸"] = "flag_ls", + ["🇱🇷"] = "flag_lr", + ["🇱🇾"] = "flag_ly", + ["🇱🇮"] = "flag_li", + ["🇱🇹"] = "flag_lt", + ["🇱🇺"] = "flag_lu", + ["🇲🇴"] = "flag_mo", + ["🇲🇰"] = "flag_mk", + ["🇲🇬"] = "flag_mg", + ["🇲🇼"] = "flag_mw", + ["🇲🇾"] = "flag_my", + ["🇲🇻"] = "flag_mv", + ["🇲🇱"] = "flag_ml", + ["🇲🇹"] = "flag_mt", + ["🇲🇭"] = "flag_mh", + ["🇲🇶"] = "flag_mq", + ["🇲🇷"] = "flag_mr", + ["🇲🇺"] = "flag_mu", + ["🇾🇹"] = "flag_yt", + ["🇲🇽"] = "flag_mx", + ["🇫🇲"] = "flag_fm", + ["🇲🇩"] = "flag_md", + ["🇲🇨"] = "flag_mc", + ["🇲🇳"] = "flag_mn", + ["🇲🇪"] = "flag_me", + ["🇲🇸"] = "flag_ms", + ["🇲🇦"] = "flag_ma", + ["🇲🇿"] = "flag_mz", + ["🇲🇲"] = "flag_mm", + ["🇳🇦"] = "flag_na", + ["🇳🇷"] = "flag_nr", + ["🇳🇵"] = "flag_np", + ["🇳🇱"] = "flag_nl", + ["🇳🇨"] = "flag_nc", + ["🇳🇿"] = "flag_nz", + ["🇳🇮"] = "flag_ni", + ["🇳🇪"] = "flag_ne", + ["🇳🇬"] = "flag_ng", + ["🇳🇺"] = "flag_nu", + ["🇳🇫"] = "flag_nf", + ["🇰🇵"] = "flag_kp", + ["🇲🇵"] = "flag_mp", + ["🇳🇴"] = "flag_no", + ["🇴🇲"] = "flag_om", + ["🇵🇰"] = "flag_pk", + ["🇵🇼"] = "flag_pw", + ["🇵🇸"] = "flag_ps", + ["🇵🇦"] = "flag_pa", + ["🇵🇬"] = "flag_pg", + ["🇵🇾"] = "flag_py", + ["🇵🇪"] = "flag_pe", + ["🇵🇭"] = "flag_ph", + ["🇵🇳"] = "flag_pn", + ["🇵🇱"] = "flag_pl", + ["🇵🇹"] = "flag_pt", + ["🇵🇷"] = "flag_pr", + ["🇶🇦"] = "flag_qa", + ["🇷🇪"] = "flag_re", + ["🇷🇴"] = "flag_ro", + ["🇷🇺"] = "flag_ru", + ["🇷🇼"] = "flag_rw", + ["🇼🇸"] = "flag_ws", + ["🇸🇲"] = "flag_sm", + ["🇸🇹"] = "flag_st", + ["🇸🇦"] = "flag_sa", + ["🇸🇳"] = "flag_sn", + ["🇷🇸"] = "flag_rs", + ["🇸🇨"] = "flag_sc", + ["🇸🇱"] = "flag_sl", + ["🇸🇬"] = "flag_sg", + ["🇸🇽"] = "flag_sx", + ["🇸🇰"] = "flag_sk", + ["🇸🇮"] = "flag_si", + ["🇬🇸"] = "flag_gs", + ["🇸🇧"] = "flag_sb", + ["🇸🇴"] = "flag_so", + ["🇿🇦"] = "flag_za", + ["🇰🇷"] = "flag_kr", + ["🇸🇸"] = "flag_ss", + ["🇪🇸"] = "flag_es", + ["🇱🇰"] = "flag_lk", + ["🇧🇱"] = "flag_bl", + ["🇸🇭"] = "flag_sh", + ["🇰🇳"] = "flag_kn", + ["🇱🇨"] = "flag_lc", + ["🇵🇲"] = "flag_pm", + ["🇻🇨"] = "flag_vc", + ["🇸🇩"] = "flag_sd", + ["🇸🇷"] = "flag_sr", + ["🇸🇿"] = "flag_sz", + ["🇸🇪"] = "flag_se", + ["🇨🇭"] = "flag_ch", + ["🇸🇾"] = "flag_sy", + ["🇹🇼"] = "flag_tw", + ["🇹🇯"] = "flag_tj", + ["🇹🇿"] = "flag_tz", + ["🇹🇭"] = "flag_th", + ["🇹🇱"] = "flag_tl", + ["🇹🇬"] = "flag_tg", + ["🇹🇰"] = "flag_tk", + ["🇹🇴"] = "flag_to", + ["🇹🇹"] = "flag_tt", + ["🇹🇳"] = "flag_tn", + ["🇹🇷"] = "flag_tr", + ["🇹🇲"] = "flag_tm", + ["🇹🇨"] = "flag_tc", + ["🇻🇮"] = "flag_vi", + ["🇹🇻"] = "flag_tv", + ["🇺🇬"] = "flag_ug", + ["🇺🇦"] = "flag_ua", + ["🇦🇪"] = "flag_ae", + ["🇬🇧"] = "flag_gb", + ["🏴󠁧󠁢󠁥󠁮󠁧󠁿"] = "england", + ["🏴󠁧󠁢󠁳󠁣󠁴󠁿"] = "scotland", + ["🏴󠁧󠁢󠁷󠁬󠁳󠁿"] = "wales", + ["🇺🇸"] = "flag_us", + ["🇺🇾"] = "flag_uy", + ["🇺🇿"] = "flag_uz", + ["🇻🇺"] = "flag_vu", + ["🇻🇦"] = "flag_va", + ["🇻🇪"] = "flag_ve", + ["🇻🇳"] = "flag_vn", + ["🇼🇫"] = "flag_wf", + ["🇪🇭"] = "flag_eh", + ["🇾🇪"] = "flag_ye", + ["🇿🇲"] = "flag_zm", + ["🇿🇼"] = "flag_zw", + ["🇦🇨"] = "flag_ac", + ["🇧🇻"] = "flag_bv", + ["🇨🇵"] = "flag_cp", + ["🇪🇦"] = "flag_ea", + ["🇩🇬"] = "flag_dg", + ["🇭🇲"] = "flag_hm", + ["🇲🇫"] = "flag_mf", + ["🇸🇯"] = "flag_sj", + ["🇹🇦"] = "flag_ta", + ["🇺🇲"] = "flag_um", + ["🇺🇳"] = "united_nations" + }; - private static Dictionary _fromCodes = new(5000, StringComparer.Ordinal) - { - ["grinning"] = "😀", - ["smiley"] = "😃", - ["smile"] = "😄", - ["grin"] = "😁", - ["laughing"] = "😆", - ["satisfied"] = "😆", - ["sweat_smile"] = "😅", - ["joy"] = "😂", - ["rofl"] = "🤣", - ["rolling_on_the_floor_laughing"] = "🤣", - ["relaxed"] = "☺️", - ["blush"] = "😊", - ["innocent"] = "😇", - ["slight_smile"] = "🙂", - ["slightly_smiling_face"] = "🙂", - ["upside_down"] = "🙃", - ["upside_down_face"] = "🙃", - ["wink"] = "😉", - ["relieved"] = "😌", - ["smiling_face_with_tear"] = "🥲", - ["heart_eyes"] = "😍", - ["smiling_face_with_3_hearts"] = "🥰", - ["kissing_heart"] = "😘", - ["kissing"] = "😗", - ["kissing_smiling_eyes"] = "😙", - ["kissing_closed_eyes"] = "😚", - ["yum"] = "😋", - ["stuck_out_tongue"] = "😛", - ["stuck_out_tongue_closed_eyes"] = "😝", - ["stuck_out_tongue_winking_eye"] = "😜", - ["zany_face"] = "🤪", - ["face_with_raised_eyebrow"] = "🤨", - ["face_with_monocle"] = "🧐", - ["nerd"] = "🤓", - ["nerd_face"] = "🤓", - ["sunglasses"] = "😎", - ["star_struck"] = "🤩", - ["partying_face"] = "🥳", - ["smirk"] = "😏", - ["unamused"] = "😒", - ["disappointed"] = "😞", - ["pensive"] = "😔", - ["worried"] = "😟", - ["confused"] = "😕", - ["slight_frown"] = "🙁", - ["slightly_frowning_face"] = "🙁", - ["frowning2"] = "☹️", - ["white_frowning_face"] = "☹️", - ["persevere"] = "😣", - ["confounded"] = "😖", - ["tired_face"] = "😫", - ["weary"] = "😩", - ["pleading_face"] = "🥺", - ["cry"] = "😢", - ["sob"] = "😭", - ["triumph"] = "😤", - ["face_exhaling"] = "😮‍💨", - ["angry"] = "😠", - ["rage"] = "😡", - ["face_with_symbols_over_mouth"] = "🤬", - ["exploding_head"] = "🤯", - ["flushed"] = "😳", - ["face_in_clouds"] = "😶‍🌫️", - ["hot_face"] = "🥵", - ["cold_face"] = "🥶", - ["scream"] = "😱", - ["fearful"] = "😨", - ["cold_sweat"] = "😰", - ["disappointed_relieved"] = "😥", - ["sweat"] = "😓", - ["hugging"] = "🤗", - ["hugging_face"] = "🤗", - ["thinking"] = "🤔", - ["thinking_face"] = "🤔", - ["face_with_hand_over_mouth"] = "🤭", - ["yawning_face"] = "🥱", - ["shushing_face"] = "🤫", - ["lying_face"] = "🤥", - ["liar"] = "🤥", - ["no_mouth"] = "😶", - ["neutral_face"] = "😐", - ["expressionless"] = "😑", - ["grimacing"] = "😬", - ["rolling_eyes"] = "🙄", - ["face_with_rolling_eyes"] = "🙄", - ["hushed"] = "😯", - ["frowning"] = "😦", - ["anguished"] = "😧", - ["open_mouth"] = "😮", - ["astonished"] = "😲", - ["sleeping"] = "😴", - ["drooling_face"] = "🤤", - ["drool"] = "🤤", - ["sleepy"] = "😪", - ["dizzy_face"] = "😵", - ["face_with_spiral_eyes"] = "😵‍💫", - ["zipper_mouth"] = "🤐", - ["zipper_mouth_face"] = "🤐", - ["woozy_face"] = "🥴", - ["nauseated_face"] = "🤢", - ["sick"] = "🤢", - ["face_vomiting"] = "🤮", - ["sneezing_face"] = "🤧", - ["sneeze"] = "🤧", - ["mask"] = "😷", - ["thermometer_face"] = "🤒", - ["face_with_thermometer"] = "🤒", - ["head_bandage"] = "🤕", - ["face_with_head_bandage"] = "🤕", - ["money_mouth"] = "🤑", - ["money_mouth_face"] = "🤑", - ["cowboy"] = "🤠", - ["face_with_cowboy_hat"] = "🤠", - ["disguised_face"] = "🥸", - ["smiling_imp"] = "😈", - ["imp"] = "👿", - ["japanese_ogre"] = "👹", - ["japanese_goblin"] = "👺", - ["clown"] = "🤡", - ["clown_face"] = "🤡", - ["poop"] = "💩", - ["shit"] = "💩", - ["hankey"] = "💩", - ["poo"] = "💩", - ["ghost"] = "👻", - ["skull"] = "💀", - ["skeleton"] = "💀", - ["skull_crossbones"] = "☠️", - ["skull_and_crossbones"] = "☠️", - ["alien"] = "👽", - ["space_invader"] = "👾", - ["robot"] = "🤖", - ["robot_face"] = "🤖", - ["jack_o_lantern"] = "🎃", - ["smiley_cat"] = "😺", - ["smile_cat"] = "😸", - ["joy_cat"] = "😹", - ["heart_eyes_cat"] = "😻", - ["smirk_cat"] = "😼", - ["kissing_cat"] = "😽", - ["scream_cat"] = "🙀", - ["crying_cat_face"] = "😿", - ["pouting_cat"] = "😾", - ["palms_up_together"] = "🤲", - ["palms_up_together_tone1"] = "🤲🏻", - ["palms_up_together_light_skin_tone"] = "🤲🏻", - ["palms_up_together_tone2"] = "🤲🏼", - ["palms_up_together_medium_light_skin_tone"] = "🤲🏼", - ["palms_up_together_tone3"] = "🤲🏽", - ["palms_up_together_medium_skin_tone"] = "🤲🏽", - ["palms_up_together_tone4"] = "🤲🏾", - ["palms_up_together_medium_dark_skin_tone"] = "🤲🏾", - ["palms_up_together_tone5"] = "🤲🏿", - ["palms_up_together_dark_skin_tone"] = "🤲🏿", - ["open_hands"] = "👐", - ["open_hands_tone1"] = "👐🏻", - ["open_hands_tone2"] = "👐🏼", - ["open_hands_tone3"] = "👐🏽", - ["open_hands_tone4"] = "👐🏾", - ["open_hands_tone5"] = "👐🏿", - ["raised_hands"] = "🙌", - ["raised_hands_tone1"] = "🙌🏻", - ["raised_hands_tone2"] = "🙌🏼", - ["raised_hands_tone3"] = "🙌🏽", - ["raised_hands_tone4"] = "🙌🏾", - ["raised_hands_tone5"] = "🙌🏿", - ["clap"] = "👏", - ["clap_tone1"] = "👏🏻", - ["clap_tone2"] = "👏🏼", - ["clap_tone3"] = "👏🏽", - ["clap_tone4"] = "👏🏾", - ["clap_tone5"] = "👏🏿", - ["handshake"] = "🤝", - ["shaking_hands"] = "🤝", - ["thumbsup"] = "👍", - ["+1"] = "👍", - ["thumbup"] = "👍", - ["thumbsup_tone1"] = "👍🏻", - ["+1_tone1"] = "👍🏻", - ["thumbup_tone1"] = "👍🏻", - ["thumbsup_tone2"] = "👍🏼", - ["+1_tone2"] = "👍🏼", - ["thumbup_tone2"] = "👍🏼", - ["thumbsup_tone3"] = "👍🏽", - ["+1_tone3"] = "👍🏽", - ["thumbup_tone3"] = "👍🏽", - ["thumbsup_tone4"] = "👍🏾", - ["+1_tone4"] = "👍🏾", - ["thumbup_tone4"] = "👍🏾", - ["thumbsup_tone5"] = "👍🏿", - ["+1_tone5"] = "👍🏿", - ["thumbup_tone5"] = "👍🏿", - ["thumbsdown"] = "👎", - ["-1"] = "👎", - ["thumbdown"] = "👎", - ["thumbsdown_tone1"] = "👎🏻", - ["_1_tone1"] = "👎🏻", - ["thumbdown_tone1"] = "👎🏻", - ["thumbsdown_tone2"] = "👎🏼", - ["_1_tone2"] = "👎🏼", - ["thumbdown_tone2"] = "👎🏼", - ["thumbsdown_tone3"] = "👎🏽", - ["_1_tone3"] = "👎🏽", - ["thumbdown_tone3"] = "👎🏽", - ["thumbsdown_tone4"] = "👎🏾", - ["_1_tone4"] = "👎🏾", - ["thumbdown_tone4"] = "👎🏾", - ["thumbsdown_tone5"] = "👎🏿", - ["_1_tone5"] = "👎🏿", - ["thumbdown_tone5"] = "👎🏿", - ["punch"] = "👊", - ["punch_tone1"] = "👊🏻", - ["punch_tone2"] = "👊🏼", - ["punch_tone3"] = "👊🏽", - ["punch_tone4"] = "👊🏾", - ["punch_tone5"] = "👊🏿", - ["fist"] = "✊", - ["fist_tone1"] = "✊🏻", - ["fist_tone2"] = "✊🏼", - ["fist_tone3"] = "✊🏽", - ["fist_tone4"] = "✊🏾", - ["fist_tone5"] = "✊🏿", - ["left_facing_fist"] = "🤛", - ["left_fist"] = "🤛", - ["left_facing_fist_tone1"] = "🤛🏻", - ["left_fist_tone1"] = "🤛🏻", - ["left_facing_fist_tone2"] = "🤛🏼", - ["left_fist_tone2"] = "🤛🏼", - ["left_facing_fist_tone3"] = "🤛🏽", - ["left_fist_tone3"] = "🤛🏽", - ["left_facing_fist_tone4"] = "🤛🏾", - ["left_fist_tone4"] = "🤛🏾", - ["left_facing_fist_tone5"] = "🤛🏿", - ["left_fist_tone5"] = "🤛🏿", - ["right_facing_fist"] = "🤜", - ["right_fist"] = "🤜", - ["right_facing_fist_tone1"] = "🤜🏻", - ["right_fist_tone1"] = "🤜🏻", - ["right_facing_fist_tone2"] = "🤜🏼", - ["right_fist_tone2"] = "🤜🏼", - ["right_facing_fist_tone3"] = "🤜🏽", - ["right_fist_tone3"] = "🤜🏽", - ["right_facing_fist_tone4"] = "🤜🏾", - ["right_fist_tone4"] = "🤜🏾", - ["right_facing_fist_tone5"] = "🤜🏿", - ["right_fist_tone5"] = "🤜🏿", - ["fingers_crossed"] = "🤞", - ["hand_with_index_and_middle_finger_crossed"] = "🤞", - ["fingers_crossed_tone1"] = "🤞🏻", - ["hand_with_index_and_middle_fingers_crossed_tone1"] = "🤞🏻", - ["fingers_crossed_tone2"] = "🤞🏼", - ["hand_with_index_and_middle_fingers_crossed_tone2"] = "🤞🏼", - ["fingers_crossed_tone3"] = "🤞🏽", - ["hand_with_index_and_middle_fingers_crossed_tone3"] = "🤞🏽", - ["fingers_crossed_tone4"] = "🤞🏾", - ["hand_with_index_and_middle_fingers_crossed_tone4"] = "🤞🏾", - ["fingers_crossed_tone5"] = "🤞🏿", - ["hand_with_index_and_middle_fingers_crossed_tone5"] = "🤞🏿", - ["v"] = "✌️", - ["v_tone1"] = "✌🏻", - ["v_tone2"] = "✌🏼", - ["v_tone3"] = "✌🏽", - ["v_tone4"] = "✌🏾", - ["v_tone5"] = "✌🏿", - ["love_you_gesture"] = "🤟", - ["love_you_gesture_tone1"] = "🤟🏻", - ["love_you_gesture_light_skin_tone"] = "🤟🏻", - ["love_you_gesture_tone2"] = "🤟🏼", - ["love_you_gesture_medium_light_skin_tone"] = "🤟🏼", - ["love_you_gesture_tone3"] = "🤟🏽", - ["love_you_gesture_medium_skin_tone"] = "🤟🏽", - ["love_you_gesture_tone4"] = "🤟🏾", - ["love_you_gesture_medium_dark_skin_tone"] = "🤟🏾", - ["love_you_gesture_tone5"] = "🤟🏿", - ["love_you_gesture_dark_skin_tone"] = "🤟🏿", - ["metal"] = "🤘", - ["sign_of_the_horns"] = "🤘", - ["metal_tone1"] = "🤘🏻", - ["sign_of_the_horns_tone1"] = "🤘🏻", - ["metal_tone2"] = "🤘🏼", - ["sign_of_the_horns_tone2"] = "🤘🏼", - ["metal_tone3"] = "🤘🏽", - ["sign_of_the_horns_tone3"] = "🤘🏽", - ["metal_tone4"] = "🤘🏾", - ["sign_of_the_horns_tone4"] = "🤘🏾", - ["metal_tone5"] = "🤘🏿", - ["sign_of_the_horns_tone5"] = "🤘🏿", - ["ok_hand"] = "👌", - ["ok_hand_tone1"] = "👌🏻", - ["ok_hand_tone2"] = "👌🏼", - ["ok_hand_tone3"] = "👌🏽", - ["ok_hand_tone4"] = "👌🏾", - ["ok_hand_tone5"] = "👌🏿", - ["pinching_hand"] = "🤏", - ["pinching_hand_tone1"] = "🤏🏻", - ["pinching_hand_light_skin_tone"] = "🤏🏻", - ["pinching_hand_tone2"] = "🤏🏼", - ["pinching_hand_medium_light_skin_tone"] = "🤏🏼", - ["pinching_hand_tone3"] = "🤏🏽", - ["pinching_hand_medium_skin_tone"] = "🤏🏽", - ["pinching_hand_tone4"] = "🤏🏾", - ["pinching_hand_medium_dark_skin_tone"] = "🤏🏾", - ["pinching_hand_tone5"] = "🤏🏿", - ["pinching_hand_dark_skin_tone"] = "🤏🏿", - ["pinched_fingers"] = "🤌", - ["pinched_fingers_tone2"] = "🤌🏼", - ["pinched_fingers_medium_light_skin_tone"] = "🤌🏼", - ["pinched_fingers_tone1"] = "🤌🏻", - ["pinched_fingers_light_skin_tone"] = "🤌🏻", - ["pinched_fingers_tone3"] = "🤌🏽", - ["pinched_fingers_medium_skin_tone"] = "🤌🏽", - ["pinched_fingers_tone4"] = "🤌🏾", - ["pinched_fingers_medium_dark_skin_tone"] = "🤌🏾", - ["pinched_fingers_tone5"] = "🤌🏿", - ["pinched_fingers_dark_skin_tone"] = "🤌🏿", - ["point_left"] = "👈", - ["point_left_tone1"] = "👈🏻", - ["point_left_tone2"] = "👈🏼", - ["point_left_tone3"] = "👈🏽", - ["point_left_tone4"] = "👈🏾", - ["point_left_tone5"] = "👈🏿", - ["point_right"] = "👉", - ["point_right_tone1"] = "👉🏻", - ["point_right_tone2"] = "👉🏼", - ["point_right_tone3"] = "👉🏽", - ["point_right_tone4"] = "👉🏾", - ["point_right_tone5"] = "👉🏿", - ["point_up_2"] = "👆", - ["point_up_2_tone1"] = "👆🏻", - ["point_up_2_tone2"] = "👆🏼", - ["point_up_2_tone3"] = "👆🏽", - ["point_up_2_tone4"] = "👆🏾", - ["point_up_2_tone5"] = "👆🏿", - ["point_down"] = "👇", - ["point_down_tone1"] = "👇🏻", - ["point_down_tone2"] = "👇🏼", - ["point_down_tone3"] = "👇🏽", - ["point_down_tone4"] = "👇🏾", - ["point_down_tone5"] = "👇🏿", - ["point_up"] = "☝️", - ["point_up_tone1"] = "☝🏻", - ["point_up_tone2"] = "☝🏼", - ["point_up_tone3"] = "☝🏽", - ["point_up_tone4"] = "☝🏾", - ["point_up_tone5"] = "☝🏿", - ["raised_hand"] = "✋", - ["raised_hand_tone1"] = "✋🏻", - ["raised_hand_tone2"] = "✋🏼", - ["raised_hand_tone3"] = "✋🏽", - ["raised_hand_tone4"] = "✋🏾", - ["raised_hand_tone5"] = "✋🏿", - ["raised_back_of_hand"] = "🤚", - ["back_of_hand"] = "🤚", - ["raised_back_of_hand_tone1"] = "🤚🏻", - ["back_of_hand_tone1"] = "🤚🏻", - ["raised_back_of_hand_tone2"] = "🤚🏼", - ["back_of_hand_tone2"] = "🤚🏼", - ["raised_back_of_hand_tone3"] = "🤚🏽", - ["back_of_hand_tone3"] = "🤚🏽", - ["raised_back_of_hand_tone4"] = "🤚🏾", - ["back_of_hand_tone4"] = "🤚🏾", - ["raised_back_of_hand_tone5"] = "🤚🏿", - ["back_of_hand_tone5"] = "🤚🏿", - ["hand_splayed"] = "🖐️", - ["raised_hand_with_fingers_splayed"] = "🖐️", - ["hand_splayed_tone1"] = "🖐🏻", - ["raised_hand_with_fingers_splayed_tone1"] = "🖐🏻", - ["hand_splayed_tone2"] = "🖐🏼", - ["raised_hand_with_fingers_splayed_tone2"] = "🖐🏼", - ["hand_splayed_tone3"] = "🖐🏽", - ["raised_hand_with_fingers_splayed_tone3"] = "🖐🏽", - ["hand_splayed_tone4"] = "🖐🏾", - ["raised_hand_with_fingers_splayed_tone4"] = "🖐🏾", - ["hand_splayed_tone5"] = "🖐🏿", - ["raised_hand_with_fingers_splayed_tone5"] = "🖐🏿", - ["vulcan"] = "🖖", - ["raised_hand_with_part_between_middle_and_ring_fingers"] = "🖖", - ["vulcan_tone1"] = "🖖🏻", - ["raised_hand_with_part_between_middle_and_ring_fingers_tone1"] = "🖖🏻", - ["vulcan_tone2"] = "🖖🏼", - ["raised_hand_with_part_between_middle_and_ring_fingers_tone2"] = "🖖🏼", - ["vulcan_tone3"] = "🖖🏽", - ["raised_hand_with_part_between_middle_and_ring_fingers_tone3"] = "🖖🏽", - ["vulcan_tone4"] = "🖖🏾", - ["raised_hand_with_part_between_middle_and_ring_fingers_tone4"] = "🖖🏾", - ["vulcan_tone5"] = "🖖🏿", - ["raised_hand_with_part_between_middle_and_ring_fingers_tone5"] = "🖖🏿", - ["wave"] = "👋", - ["wave_tone1"] = "👋🏻", - ["wave_tone2"] = "👋🏼", - ["wave_tone3"] = "👋🏽", - ["wave_tone4"] = "👋🏾", - ["wave_tone5"] = "👋🏿", - ["call_me"] = "🤙", - ["call_me_hand"] = "🤙", - ["call_me_tone1"] = "🤙🏻", - ["call_me_hand_tone1"] = "🤙🏻", - ["call_me_tone2"] = "🤙🏼", - ["call_me_hand_tone2"] = "🤙🏼", - ["call_me_tone3"] = "🤙🏽", - ["call_me_hand_tone3"] = "🤙🏽", - ["call_me_tone4"] = "🤙🏾", - ["call_me_hand_tone4"] = "🤙🏾", - ["call_me_tone5"] = "🤙🏿", - ["call_me_hand_tone5"] = "🤙🏿", - ["muscle"] = "💪", - ["muscle_tone1"] = "💪🏻", - ["muscle_tone2"] = "💪🏼", - ["muscle_tone3"] = "💪🏽", - ["muscle_tone4"] = "💪🏾", - ["muscle_tone5"] = "💪🏿", - ["mechanical_arm"] = "🦾", - ["middle_finger"] = "🖕", - ["reversed_hand_with_middle_finger_extended"] = "🖕", - ["middle_finger_tone1"] = "🖕🏻", - ["reversed_hand_with_middle_finger_extended_tone1"] = "🖕🏻", - ["middle_finger_tone2"] = "🖕🏼", - ["reversed_hand_with_middle_finger_extended_tone2"] = "🖕🏼", - ["middle_finger_tone3"] = "🖕🏽", - ["reversed_hand_with_middle_finger_extended_tone3"] = "🖕🏽", - ["middle_finger_tone4"] = "🖕🏾", - ["reversed_hand_with_middle_finger_extended_tone4"] = "🖕🏾", - ["middle_finger_tone5"] = "🖕🏿", - ["reversed_hand_with_middle_finger_extended_tone5"] = "🖕🏿", - ["writing_hand"] = "✍️", - ["writing_hand_tone1"] = "✍🏻", - ["writing_hand_tone2"] = "✍🏼", - ["writing_hand_tone3"] = "✍🏽", - ["writing_hand_tone4"] = "✍🏾", - ["writing_hand_tone5"] = "✍🏿", - ["pray"] = "🙏", - ["pray_tone1"] = "🙏🏻", - ["pray_tone2"] = "🙏🏼", - ["pray_tone3"] = "🙏🏽", - ["pray_tone4"] = "🙏🏾", - ["pray_tone5"] = "🙏🏿", - ["foot"] = "🦶", - ["foot_tone1"] = "🦶🏻", - ["foot_light_skin_tone"] = "🦶🏻", - ["foot_tone2"] = "🦶🏼", - ["foot_medium_light_skin_tone"] = "🦶🏼", - ["foot_tone3"] = "🦶🏽", - ["foot_medium_skin_tone"] = "🦶🏽", - ["foot_tone4"] = "🦶🏾", - ["foot_medium_dark_skin_tone"] = "🦶🏾", - ["foot_tone5"] = "🦶🏿", - ["foot_dark_skin_tone"] = "🦶🏿", - ["leg"] = "🦵", - ["leg_tone1"] = "🦵🏻", - ["leg_light_skin_tone"] = "🦵🏻", - ["leg_tone2"] = "🦵🏼", - ["leg_medium_light_skin_tone"] = "🦵🏼", - ["leg_tone3"] = "🦵🏽", - ["leg_medium_skin_tone"] = "🦵🏽", - ["leg_tone4"] = "🦵🏾", - ["leg_medium_dark_skin_tone"] = "🦵🏾", - ["leg_tone5"] = "🦵🏿", - ["leg_dark_skin_tone"] = "🦵🏿", - ["mechanical_leg"] = "🦿", - ["lipstick"] = "💄", - ["kiss"] = "💋", - ["lips"] = "👄", - ["tooth"] = "🦷", - ["tongue"] = "👅", - ["ear"] = "👂", - ["ear_tone1"] = "👂🏻", - ["ear_tone2"] = "👂🏼", - ["ear_tone3"] = "👂🏽", - ["ear_tone4"] = "👂🏾", - ["ear_tone5"] = "👂🏿", - ["ear_with_hearing_aid"] = "🦻", - ["ear_with_hearing_aid_tone1"] = "🦻🏻", - ["ear_with_hearing_aid_light_skin_tone"] = "🦻🏻", - ["ear_with_hearing_aid_tone2"] = "🦻🏼", - ["ear_with_hearing_aid_medium_light_skin_tone"] = "🦻🏼", - ["ear_with_hearing_aid_tone3"] = "🦻🏽", - ["ear_with_hearing_aid_medium_skin_tone"] = "🦻🏽", - ["ear_with_hearing_aid_tone4"] = "🦻🏾", - ["ear_with_hearing_aid_medium_dark_skin_tone"] = "🦻🏾", - ["ear_with_hearing_aid_tone5"] = "🦻🏿", - ["ear_with_hearing_aid_dark_skin_tone"] = "🦻🏿", - ["nose"] = "👃", - ["nose_tone1"] = "👃🏻", - ["nose_tone2"] = "👃🏼", - ["nose_tone3"] = "👃🏽", - ["nose_tone4"] = "👃🏾", - ["nose_tone5"] = "👃🏿", - ["footprints"] = "👣", - ["eye"] = "👁️", - ["eyes"] = "👀", - ["brain"] = "🧠", - ["anatomical_heart"] = "🫀", - ["lungs"] = "🫁", - ["bone"] = "🦴", - ["speaking_head"] = "🗣️", - ["speaking_head_in_silhouette"] = "🗣️", - ["bust_in_silhouette"] = "👤", - ["busts_in_silhouette"] = "👥", - ["people_hugging"] = "🫂", - ["baby"] = "👶", - ["baby_tone1"] = "👶🏻", - ["baby_tone2"] = "👶🏼", - ["baby_tone3"] = "👶🏽", - ["baby_tone4"] = "👶🏾", - ["baby_tone5"] = "👶🏿", - ["girl"] = "👧", - ["girl_tone1"] = "👧🏻", - ["girl_tone2"] = "👧🏼", - ["girl_tone3"] = "👧🏽", - ["girl_tone4"] = "👧🏾", - ["girl_tone5"] = "👧🏿", - ["child"] = "🧒", - ["child_tone1"] = "🧒🏻", - ["child_light_skin_tone"] = "🧒🏻", - ["child_tone2"] = "🧒🏼", - ["child_medium_light_skin_tone"] = "🧒🏼", - ["child_tone3"] = "🧒🏽", - ["child_medium_skin_tone"] = "🧒🏽", - ["child_tone4"] = "🧒🏾", - ["child_medium_dark_skin_tone"] = "🧒🏾", - ["child_tone5"] = "🧒🏿", - ["child_dark_skin_tone"] = "🧒🏿", - ["boy"] = "👦", - ["boy_tone1"] = "👦🏻", - ["boy_tone2"] = "👦🏼", - ["boy_tone3"] = "👦🏽", - ["boy_tone4"] = "👦🏾", - ["boy_tone5"] = "👦🏿", - ["woman"] = "👩", - ["woman_tone1"] = "👩🏻", - ["woman_tone2"] = "👩🏼", - ["woman_tone3"] = "👩🏽", - ["woman_tone4"] = "👩🏾", - ["woman_tone5"] = "👩🏿", - ["adult"] = "🧑", - ["adult_tone1"] = "🧑🏻", - ["adult_light_skin_tone"] = "🧑🏻", - ["adult_tone2"] = "🧑🏼", - ["adult_medium_light_skin_tone"] = "🧑🏼", - ["adult_tone3"] = "🧑🏽", - ["adult_medium_skin_tone"] = "🧑🏽", - ["adult_tone4"] = "🧑🏾", - ["adult_medium_dark_skin_tone"] = "🧑🏾", - ["adult_tone5"] = "🧑🏿", - ["adult_dark_skin_tone"] = "🧑🏿", - ["man"] = "👨", - ["man_tone1"] = "👨🏻", - ["man_tone2"] = "👨🏼", - ["man_tone3"] = "👨🏽", - ["man_tone4"] = "👨🏾", - ["man_tone5"] = "👨🏿", - ["person_curly_hair"] = "🧑‍🦱", - ["person_tone1_curly_hair"] = "🧑🏻‍🦱", - ["person_light_skin_tone_curly_hair"] = "🧑🏻‍🦱", - ["person_tone2_curly_hair"] = "🧑🏼‍🦱", - ["person_medium_light_skin_tone_curly_hair"] = "🧑🏼‍🦱", - ["person_tone3_curly_hair"] = "🧑🏽‍🦱", - ["person_medium_skin_tone_curly_hair"] = "🧑🏽‍🦱", - ["person_tone4_curly_hair"] = "🧑🏾‍🦱", - ["person_medium_dark_skin_tone_curly_hair"] = "🧑🏾‍🦱", - ["person_tone5_curly_hair"] = "🧑🏿‍🦱", - ["person_dark_skin_tone_curly_hair"] = "🧑🏿‍🦱", - ["woman_curly_haired"] = "👩‍🦱", - ["woman_curly_haired_tone1"] = "👩🏻‍🦱", - ["woman_curly_haired_light_skin_tone"] = "👩🏻‍🦱", - ["woman_curly_haired_tone2"] = "👩🏼‍🦱", - ["woman_curly_haired_medium_light_skin_tone"] = "👩🏼‍🦱", - ["woman_curly_haired_tone3"] = "👩🏽‍🦱", - ["woman_curly_haired_medium_skin_tone"] = "👩🏽‍🦱", - ["woman_curly_haired_tone4"] = "👩🏾‍🦱", - ["woman_curly_haired_medium_dark_skin_tone"] = "👩🏾‍🦱", - ["woman_curly_haired_tone5"] = "👩🏿‍🦱", - ["woman_curly_haired_dark_skin_tone"] = "👩🏿‍🦱", - ["man_curly_haired"] = "👨‍🦱", - ["man_curly_haired_tone1"] = "👨🏻‍🦱", - ["man_curly_haired_light_skin_tone"] = "👨🏻‍🦱", - ["man_curly_haired_tone2"] = "👨🏼‍🦱", - ["man_curly_haired_medium_light_skin_tone"] = "👨🏼‍🦱", - ["man_curly_haired_tone3"] = "👨🏽‍🦱", - ["man_curly_haired_medium_skin_tone"] = "👨🏽‍🦱", - ["man_curly_haired_tone4"] = "👨🏾‍🦱", - ["man_curly_haired_medium_dark_skin_tone"] = "👨🏾‍🦱", - ["man_curly_haired_tone5"] = "👨🏿‍🦱", - ["man_curly_haired_dark_skin_tone"] = "👨🏿‍🦱", - ["person_red_hair"] = "🧑‍🦰", - ["person_tone1_red_hair"] = "🧑🏻‍🦰", - ["person_light_skin_tone_red_hair"] = "🧑🏻‍🦰", - ["person_tone2_red_hair"] = "🧑🏼‍🦰", - ["person_medium_light_skin_tone_red_hair"] = "🧑🏼‍🦰", - ["person_tone3_red_hair"] = "🧑🏽‍🦰", - ["person_medium_skin_tone_red_hair"] = "🧑🏽‍🦰", - ["person_tone4_red_hair"] = "🧑🏾‍🦰", - ["person_medium_dark_skin_tone_red_hair"] = "🧑🏾‍🦰", - ["person_tone5_red_hair"] = "🧑🏿‍🦰", - ["person_dark_skin_tone_red_hair"] = "🧑🏿‍🦰", - ["woman_red_haired"] = "👩‍🦰", - ["woman_red_haired_tone1"] = "👩🏻‍🦰", - ["woman_red_haired_light_skin_tone"] = "👩🏻‍🦰", - ["woman_red_haired_tone2"] = "👩🏼‍🦰", - ["woman_red_haired_medium_light_skin_tone"] = "👩🏼‍🦰", - ["woman_red_haired_tone3"] = "👩🏽‍🦰", - ["woman_red_haired_medium_skin_tone"] = "👩🏽‍🦰", - ["woman_red_haired_tone4"] = "👩🏾‍🦰", - ["woman_red_haired_medium_dark_skin_tone"] = "👩🏾‍🦰", - ["woman_red_haired_tone5"] = "👩🏿‍🦰", - ["woman_red_haired_dark_skin_tone"] = "👩🏿‍🦰", - ["man_red_haired"] = "👨‍🦰", - ["man_red_haired_tone1"] = "👨🏻‍🦰", - ["man_red_haired_light_skin_tone"] = "👨🏻‍🦰", - ["man_red_haired_tone2"] = "👨🏼‍🦰", - ["man_red_haired_medium_light_skin_tone"] = "👨🏼‍🦰", - ["man_red_haired_tone3"] = "👨🏽‍🦰", - ["man_red_haired_medium_skin_tone"] = "👨🏽‍🦰", - ["man_red_haired_tone4"] = "👨🏾‍🦰", - ["man_red_haired_medium_dark_skin_tone"] = "👨🏾‍🦰", - ["man_red_haired_tone5"] = "👨🏿‍🦰", - ["man_red_haired_dark_skin_tone"] = "👨🏿‍🦰", - ["blond_haired_woman"] = "👱‍♀️", - ["blond_haired_woman_tone1"] = "👱🏻‍♀️", - ["blond_haired_woman_light_skin_tone"] = "👱🏻‍♀️", - ["blond_haired_woman_tone2"] = "👱🏼‍♀️", - ["blond_haired_woman_medium_light_skin_tone"] = "👱🏼‍♀️", - ["blond_haired_woman_tone3"] = "👱🏽‍♀️", - ["blond_haired_woman_medium_skin_tone"] = "👱🏽‍♀️", - ["blond_haired_woman_tone4"] = "👱🏾‍♀️", - ["blond_haired_woman_medium_dark_skin_tone"] = "👱🏾‍♀️", - ["blond_haired_woman_tone5"] = "👱🏿‍♀️", - ["blond_haired_woman_dark_skin_tone"] = "👱🏿‍♀️", - ["blond_haired_person"] = "👱", - ["person_with_blond_hair"] = "👱", - ["blond_haired_person_tone1"] = "👱🏻", - ["person_with_blond_hair_tone1"] = "👱🏻", - ["blond_haired_person_tone2"] = "👱🏼", - ["person_with_blond_hair_tone2"] = "👱🏼", - ["blond_haired_person_tone3"] = "👱🏽", - ["person_with_blond_hair_tone3"] = "👱🏽", - ["blond_haired_person_tone4"] = "👱🏾", - ["person_with_blond_hair_tone4"] = "👱🏾", - ["blond_haired_person_tone5"] = "👱🏿", - ["person_with_blond_hair_tone5"] = "👱🏿", - ["blond_haired_man"] = "👱‍♂️", - ["blond_haired_man_tone1"] = "👱🏻‍♂️", - ["blond_haired_man_light_skin_tone"] = "👱🏻‍♂️", - ["blond_haired_man_tone2"] = "👱🏼‍♂️", - ["blond_haired_man_medium_light_skin_tone"] = "👱🏼‍♂️", - ["blond_haired_man_tone3"] = "👱🏽‍♂️", - ["blond_haired_man_medium_skin_tone"] = "👱🏽‍♂️", - ["blond_haired_man_tone4"] = "👱🏾‍♂️", - ["blond_haired_man_medium_dark_skin_tone"] = "👱🏾‍♂️", - ["blond_haired_man_tone5"] = "👱🏿‍♂️", - ["blond_haired_man_dark_skin_tone"] = "👱🏿‍♂️", - ["person_white_hair"] = "🧑‍🦳", - ["person_tone1_white_hair"] = "🧑🏻‍🦳", - ["person_light_skin_tone_white_hair"] = "🧑🏻‍🦳", - ["person_tone2_white_hair"] = "🧑🏼‍🦳", - ["person_medium_light_skin_tone_white_hair"] = "🧑🏼‍🦳", - ["person_tone3_white_hair"] = "🧑🏽‍🦳", - ["person_medium_skin_tone_white_hair"] = "🧑🏽‍🦳", - ["person_tone4_white_hair"] = "🧑🏾‍🦳", - ["person_medium_dark_skin_tone_white_hair"] = "🧑🏾‍🦳", - ["person_tone5_white_hair"] = "🧑🏿‍🦳", - ["person_dark_skin_tone_white_hair"] = "🧑🏿‍🦳", - ["woman_white_haired"] = "👩‍🦳", - ["woman_white_haired_tone1"] = "👩🏻‍🦳", - ["woman_white_haired_light_skin_tone"] = "👩🏻‍🦳", - ["woman_white_haired_tone2"] = "👩🏼‍🦳", - ["woman_white_haired_medium_light_skin_tone"] = "👩🏼‍🦳", - ["woman_white_haired_tone3"] = "👩🏽‍🦳", - ["woman_white_haired_medium_skin_tone"] = "👩🏽‍🦳", - ["woman_white_haired_tone4"] = "👩🏾‍🦳", - ["woman_white_haired_medium_dark_skin_tone"] = "👩🏾‍🦳", - ["woman_white_haired_tone5"] = "👩🏿‍🦳", - ["woman_white_haired_dark_skin_tone"] = "👩🏿‍🦳", - ["man_white_haired"] = "👨‍🦳", - ["man_white_haired_tone1"] = "👨🏻‍🦳", - ["man_white_haired_light_skin_tone"] = "👨🏻‍🦳", - ["man_white_haired_tone2"] = "👨🏼‍🦳", - ["man_white_haired_medium_light_skin_tone"] = "👨🏼‍🦳", - ["man_white_haired_tone3"] = "👨🏽‍🦳", - ["man_white_haired_medium_skin_tone"] = "👨🏽‍🦳", - ["man_white_haired_tone4"] = "👨🏾‍🦳", - ["man_white_haired_medium_dark_skin_tone"] = "👨🏾‍🦳", - ["man_white_haired_tone5"] = "👨🏿‍🦳", - ["man_white_haired_dark_skin_tone"] = "👨🏿‍🦳", - ["person_bald"] = "🧑‍🦲", - ["person_tone1_bald"] = "🧑🏻‍🦲", - ["person_light_skin_tone_bald"] = "🧑🏻‍🦲", - ["person_tone2_bald"] = "🧑🏼‍🦲", - ["person_medium_light_skin_tone_bald"] = "🧑🏼‍🦲", - ["person_tone3_bald"] = "🧑🏽‍🦲", - ["person_medium_skin_tone_bald"] = "🧑🏽‍🦲", - ["person_tone4_bald"] = "🧑🏾‍🦲", - ["person_medium_dark_skin_tone_bald"] = "🧑🏾‍🦲", - ["person_tone5_bald"] = "🧑🏿‍🦲", - ["person_dark_skin_tone_bald"] = "🧑🏿‍🦲", - ["woman_bald"] = "👩‍🦲", - ["woman_bald_tone1"] = "👩🏻‍🦲", - ["woman_bald_light_skin_tone"] = "👩🏻‍🦲", - ["woman_bald_tone2"] = "👩🏼‍🦲", - ["woman_bald_medium_light_skin_tone"] = "👩🏼‍🦲", - ["woman_bald_tone3"] = "👩🏽‍🦲", - ["woman_bald_medium_skin_tone"] = "👩🏽‍🦲", - ["woman_bald_tone4"] = "👩🏾‍🦲", - ["woman_bald_medium_dark_skin_tone"] = "👩🏾‍🦲", - ["woman_bald_tone5"] = "👩🏿‍🦲", - ["woman_bald_dark_skin_tone"] = "👩🏿‍🦲", - ["man_bald"] = "👨‍🦲", - ["man_bald_tone1"] = "👨🏻‍🦲", - ["man_bald_light_skin_tone"] = "👨🏻‍🦲", - ["man_bald_tone2"] = "👨🏼‍🦲", - ["man_bald_medium_light_skin_tone"] = "👨🏼‍🦲", - ["man_bald_tone3"] = "👨🏽‍🦲", - ["man_bald_medium_skin_tone"] = "👨🏽‍🦲", - ["man_bald_tone4"] = "👨🏾‍🦲", - ["man_bald_medium_dark_skin_tone"] = "👨🏾‍🦲", - ["man_bald_tone5"] = "👨🏿‍🦲", - ["man_bald_dark_skin_tone"] = "👨🏿‍🦲", - ["bearded_person"] = "🧔", - ["bearded_person_tone1"] = "🧔🏻", - ["bearded_person_light_skin_tone"] = "🧔🏻", - ["bearded_person_tone2"] = "🧔🏼", - ["bearded_person_medium_light_skin_tone"] = "🧔🏼", - ["bearded_person_tone3"] = "🧔🏽", - ["bearded_person_medium_skin_tone"] = "🧔🏽", - ["bearded_person_tone4"] = "🧔🏾", - ["bearded_person_medium_dark_skin_tone"] = "🧔🏾", - ["bearded_person_tone5"] = "🧔🏿", - ["bearded_person_dark_skin_tone"] = "🧔🏿", - ["man_beard"] = "🧔‍♂️", - ["man_tone1_beard"] = "🧔🏻‍♂️", - ["man_light_skin_tone_beard"] = "🧔🏻‍♂️", - ["man_tone2_beard"] = "🧔🏼‍♂️", - ["man_medium_light_skin_tone_beard"] = "🧔🏼‍♂️", - ["man_tone3_beard"] = "🧔🏽‍♂️", - ["man_medium_skin_tone_beard"] = "🧔🏽‍♂️", - ["man_tone4_beard"] = "🧔🏾‍♂️", - ["man_medium_dark_skin_tone_beard"] = "🧔🏾‍♂️", - ["man_tone5_beard"] = "🧔🏿‍♂️", - ["man_dark_skin_tone_beard"] = "🧔🏿‍♂️", - ["woman_beard"] = "🧔‍♀️", - ["woman_tone1_beard"] = "🧔🏻‍♀️", - ["woman_light_skin_tone_beard"] = "🧔🏻‍♀️", - ["woman_tone2_beard"] = "🧔🏼‍♀️", - ["woman_medium_light_skin_tone_beard"] = "🧔🏼‍♀️", - ["woman_tone3_beard"] = "🧔🏽‍♀️", - ["woman_medium_skin_tone_beard"] = "🧔🏽‍♀️", - ["woman_tone4_beard"] = "🧔🏾‍♀️", - ["woman_medium_dark_skin_tone_beard"] = "🧔🏾‍♀️", - ["woman_tone5_beard"] = "🧔🏿‍♀️", - ["woman_dark_skin_tone_beard"] = "🧔🏿‍♀️", - ["older_woman"] = "👵", - ["grandma"] = "👵", - ["older_woman_tone1"] = "👵🏻", - ["grandma_tone1"] = "👵🏻", - ["older_woman_tone2"] = "👵🏼", - ["grandma_tone2"] = "👵🏼", - ["older_woman_tone3"] = "👵🏽", - ["grandma_tone3"] = "👵🏽", - ["older_woman_tone4"] = "👵🏾", - ["grandma_tone4"] = "👵🏾", - ["older_woman_tone5"] = "👵🏿", - ["grandma_tone5"] = "👵🏿", - ["older_adult"] = "🧓", - ["older_adult_tone1"] = "🧓🏻", - ["older_adult_light_skin_tone"] = "🧓🏻", - ["older_adult_tone2"] = "🧓🏼", - ["older_adult_medium_light_skin_tone"] = "🧓🏼", - ["older_adult_tone3"] = "🧓🏽", - ["older_adult_medium_skin_tone"] = "🧓🏽", - ["older_adult_tone4"] = "🧓🏾", - ["older_adult_medium_dark_skin_tone"] = "🧓🏾", - ["older_adult_tone5"] = "🧓🏿", - ["older_adult_dark_skin_tone"] = "🧓🏿", - ["older_man"] = "👴", - ["older_man_tone1"] = "👴🏻", - ["older_man_tone2"] = "👴🏼", - ["older_man_tone3"] = "👴🏽", - ["older_man_tone4"] = "👴🏾", - ["older_man_tone5"] = "👴🏿", - ["man_with_chinese_cap"] = "👲", - ["man_with_gua_pi_mao"] = "👲", - ["man_with_chinese_cap_tone1"] = "👲🏻", - ["man_with_gua_pi_mao_tone1"] = "👲🏻", - ["man_with_chinese_cap_tone2"] = "👲🏼", - ["man_with_gua_pi_mao_tone2"] = "👲🏼", - ["man_with_chinese_cap_tone3"] = "👲🏽", - ["man_with_gua_pi_mao_tone3"] = "👲🏽", - ["man_with_chinese_cap_tone4"] = "👲🏾", - ["man_with_gua_pi_mao_tone4"] = "👲🏾", - ["man_with_chinese_cap_tone5"] = "👲🏿", - ["man_with_gua_pi_mao_tone5"] = "👲🏿", - ["person_wearing_turban"] = "👳", - ["man_with_turban"] = "👳", - ["person_wearing_turban_tone1"] = "👳🏻", - ["man_with_turban_tone1"] = "👳🏻", - ["person_wearing_turban_tone2"] = "👳🏼", - ["man_with_turban_tone2"] = "👳🏼", - ["person_wearing_turban_tone3"] = "👳🏽", - ["man_with_turban_tone3"] = "👳🏽", - ["person_wearing_turban_tone4"] = "👳🏾", - ["man_with_turban_tone4"] = "👳🏾", - ["person_wearing_turban_tone5"] = "👳🏿", - ["man_with_turban_tone5"] = "👳🏿", - ["woman_wearing_turban"] = "👳‍♀️", - ["woman_wearing_turban_tone1"] = "👳🏻‍♀️", - ["woman_wearing_turban_light_skin_tone"] = "👳🏻‍♀️", - ["woman_wearing_turban_tone2"] = "👳🏼‍♀️", - ["woman_wearing_turban_medium_light_skin_tone"] = "👳🏼‍♀️", - ["woman_wearing_turban_tone3"] = "👳🏽‍♀️", - ["woman_wearing_turban_medium_skin_tone"] = "👳🏽‍♀️", - ["woman_wearing_turban_tone4"] = "👳🏾‍♀️", - ["woman_wearing_turban_medium_dark_skin_tone"] = "👳🏾‍♀️", - ["woman_wearing_turban_tone5"] = "👳🏿‍♀️", - ["woman_wearing_turban_dark_skin_tone"] = "👳🏿‍♀️", - ["man_wearing_turban"] = "👳‍♂️", - ["man_wearing_turban_tone1"] = "👳🏻‍♂️", - ["man_wearing_turban_light_skin_tone"] = "👳🏻‍♂️", - ["man_wearing_turban_tone2"] = "👳🏼‍♂️", - ["man_wearing_turban_medium_light_skin_tone"] = "👳🏼‍♂️", - ["man_wearing_turban_tone3"] = "👳🏽‍♂️", - ["man_wearing_turban_medium_skin_tone"] = "👳🏽‍♂️", - ["man_wearing_turban_tone4"] = "👳🏾‍♂️", - ["man_wearing_turban_medium_dark_skin_tone"] = "👳🏾‍♂️", - ["man_wearing_turban_tone5"] = "👳🏿‍♂️", - ["man_wearing_turban_dark_skin_tone"] = "👳🏿‍♂️", - ["woman_with_headscarf"] = "🧕", - ["woman_with_headscarf_tone1"] = "🧕🏻", - ["woman_with_headscarf_light_skin_tone"] = "🧕🏻", - ["woman_with_headscarf_tone2"] = "🧕🏼", - ["woman_with_headscarf_medium_light_skin_tone"] = "🧕🏼", - ["woman_with_headscarf_tone3"] = "🧕🏽", - ["woman_with_headscarf_medium_skin_tone"] = "🧕🏽", - ["woman_with_headscarf_tone4"] = "🧕🏾", - ["woman_with_headscarf_medium_dark_skin_tone"] = "🧕🏾", - ["woman_with_headscarf_tone5"] = "🧕🏿", - ["woman_with_headscarf_dark_skin_tone"] = "🧕🏿", - ["police_officer"] = "👮", - ["cop"] = "👮", - ["police_officer_tone1"] = "👮🏻", - ["cop_tone1"] = "👮🏻", - ["police_officer_tone2"] = "👮🏼", - ["cop_tone2"] = "👮🏼", - ["police_officer_tone3"] = "👮🏽", - ["cop_tone3"] = "👮🏽", - ["police_officer_tone4"] = "👮🏾", - ["cop_tone4"] = "👮🏾", - ["police_officer_tone5"] = "👮🏿", - ["cop_tone5"] = "👮🏿", - ["woman_police_officer"] = "👮‍♀️", - ["woman_police_officer_tone1"] = "👮🏻‍♀️", - ["woman_police_officer_light_skin_tone"] = "👮🏻‍♀️", - ["woman_police_officer_tone2"] = "👮🏼‍♀️", - ["woman_police_officer_medium_light_skin_tone"] = "👮🏼‍♀️", - ["woman_police_officer_tone3"] = "👮🏽‍♀️", - ["woman_police_officer_medium_skin_tone"] = "👮🏽‍♀️", - ["woman_police_officer_tone4"] = "👮🏾‍♀️", - ["woman_police_officer_medium_dark_skin_tone"] = "👮🏾‍♀️", - ["woman_police_officer_tone5"] = "👮🏿‍♀️", - ["woman_police_officer_dark_skin_tone"] = "👮🏿‍♀️", - ["man_police_officer"] = "👮‍♂️", - ["man_police_officer_tone1"] = "👮🏻‍♂️", - ["man_police_officer_light_skin_tone"] = "👮🏻‍♂️", - ["man_police_officer_tone2"] = "👮🏼‍♂️", - ["man_police_officer_medium_light_skin_tone"] = "👮🏼‍♂️", - ["man_police_officer_tone3"] = "👮🏽‍♂️", - ["man_police_officer_medium_skin_tone"] = "👮🏽‍♂️", - ["man_police_officer_tone4"] = "👮🏾‍♂️", - ["man_police_officer_medium_dark_skin_tone"] = "👮🏾‍♂️", - ["man_police_officer_tone5"] = "👮🏿‍♂️", - ["man_police_officer_dark_skin_tone"] = "👮🏿‍♂️", - ["construction_worker"] = "👷", - ["construction_worker_tone1"] = "👷🏻", - ["construction_worker_tone2"] = "👷🏼", - ["construction_worker_tone3"] = "👷🏽", - ["construction_worker_tone4"] = "👷🏾", - ["construction_worker_tone5"] = "👷🏿", - ["woman_construction_worker"] = "👷‍♀️", - ["woman_construction_worker_tone1"] = "👷🏻‍♀️", - ["woman_construction_worker_light_skin_tone"] = "👷🏻‍♀️", - ["woman_construction_worker_tone2"] = "👷🏼‍♀️", - ["woman_construction_worker_medium_light_skin_tone"] = "👷🏼‍♀️", - ["woman_construction_worker_tone3"] = "👷🏽‍♀️", - ["woman_construction_worker_medium_skin_tone"] = "👷🏽‍♀️", - ["woman_construction_worker_tone4"] = "👷🏾‍♀️", - ["woman_construction_worker_medium_dark_skin_tone"] = "👷🏾‍♀️", - ["woman_construction_worker_tone5"] = "👷🏿‍♀️", - ["woman_construction_worker_dark_skin_tone"] = "👷🏿‍♀️", - ["man_construction_worker"] = "👷‍♂️", - ["man_construction_worker_tone1"] = "👷🏻‍♂️", - ["man_construction_worker_light_skin_tone"] = "👷🏻‍♂️", - ["man_construction_worker_tone2"] = "👷🏼‍♂️", - ["man_construction_worker_medium_light_skin_tone"] = "👷🏼‍♂️", - ["man_construction_worker_tone3"] = "👷🏽‍♂️", - ["man_construction_worker_medium_skin_tone"] = "👷🏽‍♂️", - ["man_construction_worker_tone4"] = "👷🏾‍♂️", - ["man_construction_worker_medium_dark_skin_tone"] = "👷🏾‍♂️", - ["man_construction_worker_tone5"] = "👷🏿‍♂️", - ["man_construction_worker_dark_skin_tone"] = "👷🏿‍♂️", - ["guard"] = "💂", - ["guardsman"] = "💂", - ["guard_tone1"] = "💂🏻", - ["guardsman_tone1"] = "💂🏻", - ["guard_tone2"] = "💂🏼", - ["guardsman_tone2"] = "💂🏼", - ["guard_tone3"] = "💂🏽", - ["guardsman_tone3"] = "💂🏽", - ["guard_tone4"] = "💂🏾", - ["guardsman_tone4"] = "💂🏾", - ["guard_tone5"] = "💂🏿", - ["guardsman_tone5"] = "💂🏿", - ["woman_guard"] = "💂‍♀️", - ["woman_guard_tone1"] = "💂🏻‍♀️", - ["woman_guard_light_skin_tone"] = "💂🏻‍♀️", - ["woman_guard_tone2"] = "💂🏼‍♀️", - ["woman_guard_medium_light_skin_tone"] = "💂🏼‍♀️", - ["woman_guard_tone3"] = "💂🏽‍♀️", - ["woman_guard_medium_skin_tone"] = "💂🏽‍♀️", - ["woman_guard_tone4"] = "💂🏾‍♀️", - ["woman_guard_medium_dark_skin_tone"] = "💂🏾‍♀️", - ["woman_guard_tone5"] = "💂🏿‍♀️", - ["woman_guard_dark_skin_tone"] = "💂🏿‍♀️", - ["man_guard"] = "💂‍♂️", - ["man_guard_tone1"] = "💂🏻‍♂️", - ["man_guard_light_skin_tone"] = "💂🏻‍♂️", - ["man_guard_tone2"] = "💂🏼‍♂️", - ["man_guard_medium_light_skin_tone"] = "💂🏼‍♂️", - ["man_guard_tone3"] = "💂🏽‍♂️", - ["man_guard_medium_skin_tone"] = "💂🏽‍♂️", - ["man_guard_tone4"] = "💂🏾‍♂️", - ["man_guard_medium_dark_skin_tone"] = "💂🏾‍♂️", - ["man_guard_tone5"] = "💂🏿‍♂️", - ["man_guard_dark_skin_tone"] = "💂🏿‍♂️", - ["detective"] = "🕵️", - ["spy"] = "🕵️", - ["sleuth_or_spy"] = "🕵️", - ["detective_tone1"] = "🕵🏻", - ["spy_tone1"] = "🕵🏻", - ["sleuth_or_spy_tone1"] = "🕵🏻", - ["detective_tone2"] = "🕵🏼", - ["spy_tone2"] = "🕵🏼", - ["sleuth_or_spy_tone2"] = "🕵🏼", - ["detective_tone3"] = "🕵🏽", - ["spy_tone3"] = "🕵🏽", - ["sleuth_or_spy_tone3"] = "🕵🏽", - ["detective_tone4"] = "🕵🏾", - ["spy_tone4"] = "🕵🏾", - ["sleuth_or_spy_tone4"] = "🕵🏾", - ["detective_tone5"] = "🕵🏿", - ["spy_tone5"] = "🕵🏿", - ["sleuth_or_spy_tone5"] = "🕵🏿", - ["woman_detective"] = "🕵️‍♀️", - ["woman_detective_tone1"] = "🕵🏻‍♀️", - ["woman_detective_light_skin_tone"] = "🕵🏻‍♀️", - ["woman_detective_tone2"] = "🕵🏼‍♀️", - ["woman_detective_medium_light_skin_tone"] = "🕵🏼‍♀️", - ["woman_detective_tone3"] = "🕵🏽‍♀️", - ["woman_detective_medium_skin_tone"] = "🕵🏽‍♀️", - ["woman_detective_tone4"] = "🕵🏾‍♀️", - ["woman_detective_medium_dark_skin_tone"] = "🕵🏾‍♀️", - ["woman_detective_tone5"] = "🕵🏿‍♀️", - ["woman_detective_dark_skin_tone"] = "🕵🏿‍♀️", - ["man_detective"] = "🕵️‍♂️", - ["man_detective_tone1"] = "🕵🏻‍♂️", - ["man_detective_light_skin_tone"] = "🕵🏻‍♂️", - ["man_detective_tone2"] = "🕵🏼‍♂️", - ["man_detective_medium_light_skin_tone"] = "🕵🏼‍♂️", - ["man_detective_tone3"] = "🕵🏽‍♂️", - ["man_detective_medium_skin_tone"] = "🕵🏽‍♂️", - ["man_detective_tone4"] = "🕵🏾‍♂️", - ["man_detective_medium_dark_skin_tone"] = "🕵🏾‍♂️", - ["man_detective_tone5"] = "🕵🏿‍♂️", - ["man_detective_dark_skin_tone"] = "🕵🏿‍♂️", - ["health_worker"] = "🧑‍⚕️", - ["health_worker_tone1"] = "🧑🏻‍⚕️", - ["health_worker_light_skin_tone"] = "🧑🏻‍⚕️", - ["health_worker_tone2"] = "🧑🏼‍⚕️", - ["health_worker_medium_light_skin_tone"] = "🧑🏼‍⚕️", - ["health_worker_tone3"] = "🧑🏽‍⚕️", - ["health_worker_medium_skin_tone"] = "🧑🏽‍⚕️", - ["health_worker_tone4"] = "🧑🏾‍⚕️", - ["health_worker_medium_dark_skin_tone"] = "🧑🏾‍⚕️", - ["health_worker_tone5"] = "🧑🏿‍⚕️", - ["health_worker_dark_skin_tone"] = "🧑🏿‍⚕️", - ["woman_health_worker"] = "👩‍⚕️", - ["woman_health_worker_tone1"] = "👩🏻‍⚕️", - ["woman_health_worker_light_skin_tone"] = "👩🏻‍⚕️", - ["woman_health_worker_tone2"] = "👩🏼‍⚕️", - ["woman_health_worker_medium_light_skin_tone"] = "👩🏼‍⚕️", - ["woman_health_worker_tone3"] = "👩🏽‍⚕️", - ["woman_health_worker_medium_skin_tone"] = "👩🏽‍⚕️", - ["woman_health_worker_tone4"] = "👩🏾‍⚕️", - ["woman_health_worker_medium_dark_skin_tone"] = "👩🏾‍⚕️", - ["woman_health_worker_tone5"] = "👩🏿‍⚕️", - ["woman_health_worker_dark_skin_tone"] = "👩🏿‍⚕️", - ["man_health_worker"] = "👨‍⚕️", - ["man_health_worker_tone1"] = "👨🏻‍⚕️", - ["man_health_worker_light_skin_tone"] = "👨🏻‍⚕️", - ["man_health_worker_tone2"] = "👨🏼‍⚕️", - ["man_health_worker_medium_light_skin_tone"] = "👨🏼‍⚕️", - ["man_health_worker_tone3"] = "👨🏽‍⚕️", - ["man_health_worker_medium_skin_tone"] = "👨🏽‍⚕️", - ["man_health_worker_tone4"] = "👨🏾‍⚕️", - ["man_health_worker_medium_dark_skin_tone"] = "👨🏾‍⚕️", - ["man_health_worker_tone5"] = "👨🏿‍⚕️", - ["man_health_worker_dark_skin_tone"] = "👨🏿‍⚕️", - ["farmer"] = "🧑‍🌾", - ["farmer_tone1"] = "🧑🏻‍🌾", - ["farmer_light_skin_tone"] = "🧑🏻‍🌾", - ["farmer_tone2"] = "🧑🏼‍🌾", - ["farmer_medium_light_skin_tone"] = "🧑🏼‍🌾", - ["farmer_tone3"] = "🧑🏽‍🌾", - ["farmer_medium_skin_tone"] = "🧑🏽‍🌾", - ["farmer_tone4"] = "🧑🏾‍🌾", - ["farmer_medium_dark_skin_tone"] = "🧑🏾‍🌾", - ["farmer_tone5"] = "🧑🏿‍🌾", - ["farmer_dark_skin_tone"] = "🧑🏿‍🌾", - ["woman_farmer"] = "👩‍🌾", - ["woman_farmer_tone1"] = "👩🏻‍🌾", - ["woman_farmer_light_skin_tone"] = "👩🏻‍🌾", - ["woman_farmer_tone2"] = "👩🏼‍🌾", - ["woman_farmer_medium_light_skin_tone"] = "👩🏼‍🌾", - ["woman_farmer_tone3"] = "👩🏽‍🌾", - ["woman_farmer_medium_skin_tone"] = "👩🏽‍🌾", - ["woman_farmer_tone4"] = "👩🏾‍🌾", - ["woman_farmer_medium_dark_skin_tone"] = "👩🏾‍🌾", - ["woman_farmer_tone5"] = "👩🏿‍🌾", - ["woman_farmer_dark_skin_tone"] = "👩🏿‍🌾", - ["man_farmer"] = "👨‍🌾", - ["man_farmer_tone1"] = "👨🏻‍🌾", - ["man_farmer_light_skin_tone"] = "👨🏻‍🌾", - ["man_farmer_tone2"] = "👨🏼‍🌾", - ["man_farmer_medium_light_skin_tone"] = "👨🏼‍🌾", - ["man_farmer_tone3"] = "👨🏽‍🌾", - ["man_farmer_medium_skin_tone"] = "👨🏽‍🌾", - ["man_farmer_tone4"] = "👨🏾‍🌾", - ["man_farmer_medium_dark_skin_tone"] = "👨🏾‍🌾", - ["man_farmer_tone5"] = "👨🏿‍🌾", - ["man_farmer_dark_skin_tone"] = "👨🏿‍🌾", - ["cook"] = "🧑‍🍳", - ["cook_tone1"] = "🧑🏻‍🍳", - ["cook_light_skin_tone"] = "🧑🏻‍🍳", - ["cook_tone2"] = "🧑🏼‍🍳", - ["cook_medium_light_skin_tone"] = "🧑🏼‍🍳", - ["cook_tone3"] = "🧑🏽‍🍳", - ["cook_medium_skin_tone"] = "🧑🏽‍🍳", - ["cook_tone4"] = "🧑🏾‍🍳", - ["cook_medium_dark_skin_tone"] = "🧑🏾‍🍳", - ["cook_tone5"] = "🧑🏿‍🍳", - ["cook_dark_skin_tone"] = "🧑🏿‍🍳", - ["woman_cook"] = "👩‍🍳", - ["woman_cook_tone1"] = "👩🏻‍🍳", - ["woman_cook_light_skin_tone"] = "👩🏻‍🍳", - ["woman_cook_tone2"] = "👩🏼‍🍳", - ["woman_cook_medium_light_skin_tone"] = "👩🏼‍🍳", - ["woman_cook_tone3"] = "👩🏽‍🍳", - ["woman_cook_medium_skin_tone"] = "👩🏽‍🍳", - ["woman_cook_tone4"] = "👩🏾‍🍳", - ["woman_cook_medium_dark_skin_tone"] = "👩🏾‍🍳", - ["woman_cook_tone5"] = "👩🏿‍🍳", - ["woman_cook_dark_skin_tone"] = "👩🏿‍🍳", - ["man_cook"] = "👨‍🍳", - ["man_cook_tone1"] = "👨🏻‍🍳", - ["man_cook_light_skin_tone"] = "👨🏻‍🍳", - ["man_cook_tone2"] = "👨🏼‍🍳", - ["man_cook_medium_light_skin_tone"] = "👨🏼‍🍳", - ["man_cook_tone3"] = "👨🏽‍🍳", - ["man_cook_medium_skin_tone"] = "👨🏽‍🍳", - ["man_cook_tone4"] = "👨🏾‍🍳", - ["man_cook_medium_dark_skin_tone"] = "👨🏾‍🍳", - ["man_cook_tone5"] = "👨🏿‍🍳", - ["man_cook_dark_skin_tone"] = "👨🏿‍🍳", - ["student"] = "🧑‍🎓", - ["student_tone1"] = "🧑🏻‍🎓", - ["student_light_skin_tone"] = "🧑🏻‍🎓", - ["student_tone2"] = "🧑🏼‍🎓", - ["student_medium_light_skin_tone"] = "🧑🏼‍🎓", - ["student_tone3"] = "🧑🏽‍🎓", - ["student_medium_skin_tone"] = "🧑🏽‍🎓", - ["student_tone4"] = "🧑🏾‍🎓", - ["student_medium_dark_skin_tone"] = "🧑🏾‍🎓", - ["student_tone5"] = "🧑🏿‍🎓", - ["student_dark_skin_tone"] = "🧑🏿‍🎓", - ["woman_student"] = "👩‍🎓", - ["woman_student_tone1"] = "👩🏻‍🎓", - ["woman_student_light_skin_tone"] = "👩🏻‍🎓", - ["woman_student_tone2"] = "👩🏼‍🎓", - ["woman_student_medium_light_skin_tone"] = "👩🏼‍🎓", - ["woman_student_tone3"] = "👩🏽‍🎓", - ["woman_student_medium_skin_tone"] = "👩🏽‍🎓", - ["woman_student_tone4"] = "👩🏾‍🎓", - ["woman_student_medium_dark_skin_tone"] = "👩🏾‍🎓", - ["woman_student_tone5"] = "👩🏿‍🎓", - ["woman_student_dark_skin_tone"] = "👩🏿‍🎓", - ["man_student"] = "👨‍🎓", - ["man_student_tone1"] = "👨🏻‍🎓", - ["man_student_light_skin_tone"] = "👨🏻‍🎓", - ["man_student_tone2"] = "👨🏼‍🎓", - ["man_student_medium_light_skin_tone"] = "👨🏼‍🎓", - ["man_student_tone3"] = "👨🏽‍🎓", - ["man_student_medium_skin_tone"] = "👨🏽‍🎓", - ["man_student_tone4"] = "👨🏾‍🎓", - ["man_student_medium_dark_skin_tone"] = "👨🏾‍🎓", - ["man_student_tone5"] = "👨🏿‍🎓", - ["man_student_dark_skin_tone"] = "👨🏿‍🎓", - ["singer"] = "🧑‍🎤", - ["singer_tone1"] = "🧑🏻‍🎤", - ["singer_light_skin_tone"] = "🧑🏻‍🎤", - ["singer_tone2"] = "🧑🏼‍🎤", - ["singer_medium_light_skin_tone"] = "🧑🏼‍🎤", - ["singer_tone3"] = "🧑🏽‍🎤", - ["singer_medium_skin_tone"] = "🧑🏽‍🎤", - ["singer_tone4"] = "🧑🏾‍🎤", - ["singer_medium_dark_skin_tone"] = "🧑🏾‍🎤", - ["singer_tone5"] = "🧑🏿‍🎤", - ["singer_dark_skin_tone"] = "🧑🏿‍🎤", - ["woman_singer"] = "👩‍🎤", - ["woman_singer_tone1"] = "👩🏻‍🎤", - ["woman_singer_light_skin_tone"] = "👩🏻‍🎤", - ["woman_singer_tone2"] = "👩🏼‍🎤", - ["woman_singer_medium_light_skin_tone"] = "👩🏼‍🎤", - ["woman_singer_tone3"] = "👩🏽‍🎤", - ["woman_singer_medium_skin_tone"] = "👩🏽‍🎤", - ["woman_singer_tone4"] = "👩🏾‍🎤", - ["woman_singer_medium_dark_skin_tone"] = "👩🏾‍🎤", - ["woman_singer_tone5"] = "👩🏿‍🎤", - ["woman_singer_dark_skin_tone"] = "👩🏿‍🎤", - ["man_singer"] = "👨‍🎤", - ["man_singer_tone1"] = "👨🏻‍🎤", - ["man_singer_light_skin_tone"] = "👨🏻‍🎤", - ["man_singer_tone2"] = "👨🏼‍🎤", - ["man_singer_medium_light_skin_tone"] = "👨🏼‍🎤", - ["man_singer_tone3"] = "👨🏽‍🎤", - ["man_singer_medium_skin_tone"] = "👨🏽‍🎤", - ["man_singer_tone4"] = "👨🏾‍🎤", - ["man_singer_medium_dark_skin_tone"] = "👨🏾‍🎤", - ["man_singer_tone5"] = "👨🏿‍🎤", - ["man_singer_dark_skin_tone"] = "👨🏿‍🎤", - ["teacher"] = "🧑‍🏫", - ["teacher_tone1"] = "🧑🏻‍🏫", - ["teacher_light_skin_tone"] = "🧑🏻‍🏫", - ["teacher_tone2"] = "🧑🏼‍🏫", - ["teacher_medium_light_skin_tone"] = "🧑🏼‍🏫", - ["teacher_tone3"] = "🧑🏽‍🏫", - ["teacher_medium_skin_tone"] = "🧑🏽‍🏫", - ["teacher_tone4"] = "🧑🏾‍🏫", - ["teacher_medium_dark_skin_tone"] = "🧑🏾‍🏫", - ["teacher_tone5"] = "🧑🏿‍🏫", - ["teacher_dark_skin_tone"] = "🧑🏿‍🏫", - ["woman_teacher"] = "👩‍🏫", - ["woman_teacher_tone1"] = "👩🏻‍🏫", - ["woman_teacher_light_skin_tone"] = "👩🏻‍🏫", - ["woman_teacher_tone2"] = "👩🏼‍🏫", - ["woman_teacher_medium_light_skin_tone"] = "👩🏼‍🏫", - ["woman_teacher_tone3"] = "👩🏽‍🏫", - ["woman_teacher_medium_skin_tone"] = "👩🏽‍🏫", - ["woman_teacher_tone4"] = "👩🏾‍🏫", - ["woman_teacher_medium_dark_skin_tone"] = "👩🏾‍🏫", - ["woman_teacher_tone5"] = "👩🏿‍🏫", - ["woman_teacher_dark_skin_tone"] = "👩🏿‍🏫", - ["man_teacher"] = "👨‍🏫", - ["man_teacher_tone1"] = "👨🏻‍🏫", - ["man_teacher_light_skin_tone"] = "👨🏻‍🏫", - ["man_teacher_tone2"] = "👨🏼‍🏫", - ["man_teacher_medium_light_skin_tone"] = "👨🏼‍🏫", - ["man_teacher_tone3"] = "👨🏽‍🏫", - ["man_teacher_medium_skin_tone"] = "👨🏽‍🏫", - ["man_teacher_tone4"] = "👨🏾‍🏫", - ["man_teacher_medium_dark_skin_tone"] = "👨🏾‍🏫", - ["man_teacher_tone5"] = "👨🏿‍🏫", - ["man_teacher_dark_skin_tone"] = "👨🏿‍🏫", - ["factory_worker"] = "🧑‍🏭", - ["factory_worker_tone1"] = "🧑🏻‍🏭", - ["factory_worker_light_skin_tone"] = "🧑🏻‍🏭", - ["factory_worker_tone2"] = "🧑🏼‍🏭", - ["factory_worker_medium_light_skin_tone"] = "🧑🏼‍🏭", - ["factory_worker_tone3"] = "🧑🏽‍🏭", - ["factory_worker_medium_skin_tone"] = "🧑🏽‍🏭", - ["factory_worker_tone4"] = "🧑🏾‍🏭", - ["factory_worker_medium_dark_skin_tone"] = "🧑🏾‍🏭", - ["factory_worker_tone5"] = "🧑🏿‍🏭", - ["factory_worker_dark_skin_tone"] = "🧑🏿‍🏭", - ["woman_factory_worker"] = "👩‍🏭", - ["woman_factory_worker_tone1"] = "👩🏻‍🏭", - ["woman_factory_worker_light_skin_tone"] = "👩🏻‍🏭", - ["woman_factory_worker_tone2"] = "👩🏼‍🏭", - ["woman_factory_worker_medium_light_skin_tone"] = "👩🏼‍🏭", - ["woman_factory_worker_tone3"] = "👩🏽‍🏭", - ["woman_factory_worker_medium_skin_tone"] = "👩🏽‍🏭", - ["woman_factory_worker_tone4"] = "👩🏾‍🏭", - ["woman_factory_worker_medium_dark_skin_tone"] = "👩🏾‍🏭", - ["woman_factory_worker_tone5"] = "👩🏿‍🏭", - ["woman_factory_worker_dark_skin_tone"] = "👩🏿‍🏭", - ["man_factory_worker"] = "👨‍🏭", - ["man_factory_worker_tone1"] = "👨🏻‍🏭", - ["man_factory_worker_light_skin_tone"] = "👨🏻‍🏭", - ["man_factory_worker_tone2"] = "👨🏼‍🏭", - ["man_factory_worker_medium_light_skin_tone"] = "👨🏼‍🏭", - ["man_factory_worker_tone3"] = "👨🏽‍🏭", - ["man_factory_worker_medium_skin_tone"] = "👨🏽‍🏭", - ["man_factory_worker_tone4"] = "👨🏾‍🏭", - ["man_factory_worker_medium_dark_skin_tone"] = "👨🏾‍🏭", - ["man_factory_worker_tone5"] = "👨🏿‍🏭", - ["man_factory_worker_dark_skin_tone"] = "👨🏿‍🏭", - ["technologist"] = "🧑‍💻", - ["technologist_tone1"] = "🧑🏻‍💻", - ["technologist_light_skin_tone"] = "🧑🏻‍💻", - ["technologist_tone2"] = "🧑🏼‍💻", - ["technologist_medium_light_skin_tone"] = "🧑🏼‍💻", - ["technologist_tone3"] = "🧑🏽‍💻", - ["technologist_medium_skin_tone"] = "🧑🏽‍💻", - ["technologist_tone4"] = "🧑🏾‍💻", - ["technologist_medium_dark_skin_tone"] = "🧑🏾‍💻", - ["technologist_tone5"] = "🧑🏿‍💻", - ["technologist_dark_skin_tone"] = "🧑🏿‍💻", - ["woman_technologist"] = "👩‍💻", - ["woman_technologist_tone1"] = "👩🏻‍💻", - ["woman_technologist_light_skin_tone"] = "👩🏻‍💻", - ["woman_technologist_tone2"] = "👩🏼‍💻", - ["woman_technologist_medium_light_skin_tone"] = "👩🏼‍💻", - ["woman_technologist_tone3"] = "👩🏽‍💻", - ["woman_technologist_medium_skin_tone"] = "👩🏽‍💻", - ["woman_technologist_tone4"] = "👩🏾‍💻", - ["woman_technologist_medium_dark_skin_tone"] = "👩🏾‍💻", - ["woman_technologist_tone5"] = "👩🏿‍💻", - ["woman_technologist_dark_skin_tone"] = "👩🏿‍💻", - ["man_technologist"] = "👨‍💻", - ["man_technologist_tone1"] = "👨🏻‍💻", - ["man_technologist_light_skin_tone"] = "👨🏻‍💻", - ["man_technologist_tone2"] = "👨🏼‍💻", - ["man_technologist_medium_light_skin_tone"] = "👨🏼‍💻", - ["man_technologist_tone3"] = "👨🏽‍💻", - ["man_technologist_medium_skin_tone"] = "👨🏽‍💻", - ["man_technologist_tone4"] = "👨🏾‍💻", - ["man_technologist_medium_dark_skin_tone"] = "👨🏾‍💻", - ["man_technologist_tone5"] = "👨🏿‍💻", - ["man_technologist_dark_skin_tone"] = "👨🏿‍💻", - ["office_worker"] = "🧑‍💼", - ["office_worker_tone1"] = "🧑🏻‍💼", - ["office_worker_light_skin_tone"] = "🧑🏻‍💼", - ["office_worker_tone2"] = "🧑🏼‍💼", - ["office_worker_medium_light_skin_tone"] = "🧑🏼‍💼", - ["office_worker_tone3"] = "🧑🏽‍💼", - ["office_worker_medium_skin_tone"] = "🧑🏽‍💼", - ["office_worker_tone4"] = "🧑🏾‍💼", - ["office_worker_medium_dark_skin_tone"] = "🧑🏾‍💼", - ["office_worker_tone5"] = "🧑🏿‍💼", - ["office_worker_dark_skin_tone"] = "🧑🏿‍💼", - ["woman_office_worker"] = "👩‍💼", - ["woman_office_worker_tone1"] = "👩🏻‍💼", - ["woman_office_worker_light_skin_tone"] = "👩🏻‍💼", - ["woman_office_worker_tone2"] = "👩🏼‍💼", - ["woman_office_worker_medium_light_skin_tone"] = "👩🏼‍💼", - ["woman_office_worker_tone3"] = "👩🏽‍💼", - ["woman_office_worker_medium_skin_tone"] = "👩🏽‍💼", - ["woman_office_worker_tone4"] = "👩🏾‍💼", - ["woman_office_worker_medium_dark_skin_tone"] = "👩🏾‍💼", - ["woman_office_worker_tone5"] = "👩🏿‍💼", - ["woman_office_worker_dark_skin_tone"] = "👩🏿‍💼", - ["man_office_worker"] = "👨‍💼", - ["man_office_worker_tone1"] = "👨🏻‍💼", - ["man_office_worker_light_skin_tone"] = "👨🏻‍💼", - ["man_office_worker_tone2"] = "👨🏼‍💼", - ["man_office_worker_medium_light_skin_tone"] = "👨🏼‍💼", - ["man_office_worker_tone3"] = "👨🏽‍💼", - ["man_office_worker_medium_skin_tone"] = "👨🏽‍💼", - ["man_office_worker_tone4"] = "👨🏾‍💼", - ["man_office_worker_medium_dark_skin_tone"] = "👨🏾‍💼", - ["man_office_worker_tone5"] = "👨🏿‍💼", - ["man_office_worker_dark_skin_tone"] = "👨🏿‍💼", - ["mechanic"] = "🧑‍🔧", - ["mechanic_tone1"] = "🧑🏻‍🔧", - ["mechanic_light_skin_tone"] = "🧑🏻‍🔧", - ["mechanic_tone2"] = "🧑🏼‍🔧", - ["mechanic_medium_light_skin_tone"] = "🧑🏼‍🔧", - ["mechanic_tone3"] = "🧑🏽‍🔧", - ["mechanic_medium_skin_tone"] = "🧑🏽‍🔧", - ["mechanic_tone4"] = "🧑🏾‍🔧", - ["mechanic_medium_dark_skin_tone"] = "🧑🏾‍🔧", - ["mechanic_tone5"] = "🧑🏿‍🔧", - ["mechanic_dark_skin_tone"] = "🧑🏿‍🔧", - ["woman_mechanic"] = "👩‍🔧", - ["woman_mechanic_tone1"] = "👩🏻‍🔧", - ["woman_mechanic_light_skin_tone"] = "👩🏻‍🔧", - ["woman_mechanic_tone2"] = "👩🏼‍🔧", - ["woman_mechanic_medium_light_skin_tone"] = "👩🏼‍🔧", - ["woman_mechanic_tone3"] = "👩🏽‍🔧", - ["woman_mechanic_medium_skin_tone"] = "👩🏽‍🔧", - ["woman_mechanic_tone4"] = "👩🏾‍🔧", - ["woman_mechanic_medium_dark_skin_tone"] = "👩🏾‍🔧", - ["woman_mechanic_tone5"] = "👩🏿‍🔧", - ["woman_mechanic_dark_skin_tone"] = "👩🏿‍🔧", - ["man_mechanic"] = "👨‍🔧", - ["man_mechanic_tone1"] = "👨🏻‍🔧", - ["man_mechanic_light_skin_tone"] = "👨🏻‍🔧", - ["man_mechanic_tone2"] = "👨🏼‍🔧", - ["man_mechanic_medium_light_skin_tone"] = "👨🏼‍🔧", - ["man_mechanic_tone3"] = "👨🏽‍🔧", - ["man_mechanic_medium_skin_tone"] = "👨🏽‍🔧", - ["man_mechanic_tone4"] = "👨🏾‍🔧", - ["man_mechanic_medium_dark_skin_tone"] = "👨🏾‍🔧", - ["man_mechanic_tone5"] = "👨🏿‍🔧", - ["man_mechanic_dark_skin_tone"] = "👨🏿‍🔧", - ["scientist"] = "🧑‍🔬", - ["scientist_tone1"] = "🧑🏻‍🔬", - ["scientist_light_skin_tone"] = "🧑🏻‍🔬", - ["scientist_tone2"] = "🧑🏼‍🔬", - ["scientist_medium_light_skin_tone"] = "🧑🏼‍🔬", - ["scientist_tone3"] = "🧑🏽‍🔬", - ["scientist_medium_skin_tone"] = "🧑🏽‍🔬", - ["scientist_tone4"] = "🧑🏾‍🔬", - ["scientist_medium_dark_skin_tone"] = "🧑🏾‍🔬", - ["scientist_tone5"] = "🧑🏿‍🔬", - ["scientist_dark_skin_tone"] = "🧑🏿‍🔬", - ["woman_scientist"] = "👩‍🔬", - ["woman_scientist_tone1"] = "👩🏻‍🔬", - ["woman_scientist_light_skin_tone"] = "👩🏻‍🔬", - ["woman_scientist_tone2"] = "👩🏼‍🔬", - ["woman_scientist_medium_light_skin_tone"] = "👩🏼‍🔬", - ["woman_scientist_tone3"] = "👩🏽‍🔬", - ["woman_scientist_medium_skin_tone"] = "👩🏽‍🔬", - ["woman_scientist_tone4"] = "👩🏾‍🔬", - ["woman_scientist_medium_dark_skin_tone"] = "👩🏾‍🔬", - ["woman_scientist_tone5"] = "👩🏿‍🔬", - ["woman_scientist_dark_skin_tone"] = "👩🏿‍🔬", - ["man_scientist"] = "👨‍🔬", - ["man_scientist_tone1"] = "👨🏻‍🔬", - ["man_scientist_light_skin_tone"] = "👨🏻‍🔬", - ["man_scientist_tone2"] = "👨🏼‍🔬", - ["man_scientist_medium_light_skin_tone"] = "👨🏼‍🔬", - ["man_scientist_tone3"] = "👨🏽‍🔬", - ["man_scientist_medium_skin_tone"] = "👨🏽‍🔬", - ["man_scientist_tone4"] = "👨🏾‍🔬", - ["man_scientist_medium_dark_skin_tone"] = "👨🏾‍🔬", - ["man_scientist_tone5"] = "👨🏿‍🔬", - ["man_scientist_dark_skin_tone"] = "👨🏿‍🔬", - ["artist"] = "🧑‍🎨", - ["artist_tone1"] = "🧑🏻‍🎨", - ["artist_light_skin_tone"] = "🧑🏻‍🎨", - ["artist_tone2"] = "🧑🏼‍🎨", - ["artist_medium_light_skin_tone"] = "🧑🏼‍🎨", - ["artist_tone3"] = "🧑🏽‍🎨", - ["artist_medium_skin_tone"] = "🧑🏽‍🎨", - ["artist_tone4"] = "🧑🏾‍🎨", - ["artist_medium_dark_skin_tone"] = "🧑🏾‍🎨", - ["artist_tone5"] = "🧑🏿‍🎨", - ["artist_dark_skin_tone"] = "🧑🏿‍🎨", - ["woman_artist"] = "👩‍🎨", - ["woman_artist_tone1"] = "👩🏻‍🎨", - ["woman_artist_light_skin_tone"] = "👩🏻‍🎨", - ["woman_artist_tone2"] = "👩🏼‍🎨", - ["woman_artist_medium_light_skin_tone"] = "👩🏼‍🎨", - ["woman_artist_tone3"] = "👩🏽‍🎨", - ["woman_artist_medium_skin_tone"] = "👩🏽‍🎨", - ["woman_artist_tone4"] = "👩🏾‍🎨", - ["woman_artist_medium_dark_skin_tone"] = "👩🏾‍🎨", - ["woman_artist_tone5"] = "👩🏿‍🎨", - ["woman_artist_dark_skin_tone"] = "👩🏿‍🎨", - ["man_artist"] = "👨‍🎨", - ["man_artist_tone1"] = "👨🏻‍🎨", - ["man_artist_light_skin_tone"] = "👨🏻‍🎨", - ["man_artist_tone2"] = "👨🏼‍🎨", - ["man_artist_medium_light_skin_tone"] = "👨🏼‍🎨", - ["man_artist_tone3"] = "👨🏽‍🎨", - ["man_artist_medium_skin_tone"] = "👨🏽‍🎨", - ["man_artist_tone4"] = "👨🏾‍🎨", - ["man_artist_medium_dark_skin_tone"] = "👨🏾‍🎨", - ["man_artist_tone5"] = "👨🏿‍🎨", - ["man_artist_dark_skin_tone"] = "👨🏿‍🎨", - ["firefighter"] = "🧑‍🚒", - ["firefighter_tone1"] = "🧑🏻‍🚒", - ["firefighter_light_skin_tone"] = "🧑🏻‍🚒", - ["firefighter_tone2"] = "🧑🏼‍🚒", - ["firefighter_medium_light_skin_tone"] = "🧑🏼‍🚒", - ["firefighter_tone3"] = "🧑🏽‍🚒", - ["firefighter_medium_skin_tone"] = "🧑🏽‍🚒", - ["firefighter_tone4"] = "🧑🏾‍🚒", - ["firefighter_medium_dark_skin_tone"] = "🧑🏾‍🚒", - ["firefighter_tone5"] = "🧑🏿‍🚒", - ["firefighter_dark_skin_tone"] = "🧑🏿‍🚒", - ["woman_firefighter"] = "👩‍🚒", - ["woman_firefighter_tone1"] = "👩🏻‍🚒", - ["woman_firefighter_light_skin_tone"] = "👩🏻‍🚒", - ["woman_firefighter_tone2"] = "👩🏼‍🚒", - ["woman_firefighter_medium_light_skin_tone"] = "👩🏼‍🚒", - ["woman_firefighter_tone3"] = "👩🏽‍🚒", - ["woman_firefighter_medium_skin_tone"] = "👩🏽‍🚒", - ["woman_firefighter_tone4"] = "👩🏾‍🚒", - ["woman_firefighter_medium_dark_skin_tone"] = "👩🏾‍🚒", - ["woman_firefighter_tone5"] = "👩🏿‍🚒", - ["woman_firefighter_dark_skin_tone"] = "👩🏿‍🚒", - ["man_firefighter"] = "👨‍🚒", - ["man_firefighter_tone1"] = "👨🏻‍🚒", - ["man_firefighter_light_skin_tone"] = "👨🏻‍🚒", - ["man_firefighter_tone2"] = "👨🏼‍🚒", - ["man_firefighter_medium_light_skin_tone"] = "👨🏼‍🚒", - ["man_firefighter_tone3"] = "👨🏽‍🚒", - ["man_firefighter_medium_skin_tone"] = "👨🏽‍🚒", - ["man_firefighter_tone4"] = "👨🏾‍🚒", - ["man_firefighter_medium_dark_skin_tone"] = "👨🏾‍🚒", - ["man_firefighter_tone5"] = "👨🏿‍🚒", - ["man_firefighter_dark_skin_tone"] = "👨🏿‍🚒", - ["pilot"] = "🧑‍✈️", - ["pilot_tone1"] = "🧑🏻‍✈️", - ["pilot_light_skin_tone"] = "🧑🏻‍✈️", - ["pilot_tone2"] = "🧑🏼‍✈️", - ["pilot_medium_light_skin_tone"] = "🧑🏼‍✈️", - ["pilot_tone3"] = "🧑🏽‍✈️", - ["pilot_medium_skin_tone"] = "🧑🏽‍✈️", - ["pilot_tone4"] = "🧑🏾‍✈️", - ["pilot_medium_dark_skin_tone"] = "🧑🏾‍✈️", - ["pilot_tone5"] = "🧑🏿‍✈️", - ["pilot_dark_skin_tone"] = "🧑🏿‍✈️", - ["woman_pilot"] = "👩‍✈️", - ["woman_pilot_tone1"] = "👩🏻‍✈️", - ["woman_pilot_light_skin_tone"] = "👩🏻‍✈️", - ["woman_pilot_tone2"] = "👩🏼‍✈️", - ["woman_pilot_medium_light_skin_tone"] = "👩🏼‍✈️", - ["woman_pilot_tone3"] = "👩🏽‍✈️", - ["woman_pilot_medium_skin_tone"] = "👩🏽‍✈️", - ["woman_pilot_tone4"] = "👩🏾‍✈️", - ["woman_pilot_medium_dark_skin_tone"] = "👩🏾‍✈️", - ["woman_pilot_tone5"] = "👩🏿‍✈️", - ["woman_pilot_dark_skin_tone"] = "👩🏿‍✈️", - ["man_pilot"] = "👨‍✈️", - ["man_pilot_tone1"] = "👨🏻‍✈️", - ["man_pilot_light_skin_tone"] = "👨🏻‍✈️", - ["man_pilot_tone2"] = "👨🏼‍✈️", - ["man_pilot_medium_light_skin_tone"] = "👨🏼‍✈️", - ["man_pilot_tone3"] = "👨🏽‍✈️", - ["man_pilot_medium_skin_tone"] = "👨🏽‍✈️", - ["man_pilot_tone4"] = "👨🏾‍✈️", - ["man_pilot_medium_dark_skin_tone"] = "👨🏾‍✈️", - ["man_pilot_tone5"] = "👨🏿‍✈️", - ["man_pilot_dark_skin_tone"] = "👨🏿‍✈️", - ["astronaut"] = "🧑‍🚀", - ["astronaut_tone1"] = "🧑🏻‍🚀", - ["astronaut_light_skin_tone"] = "🧑🏻‍🚀", - ["astronaut_tone2"] = "🧑🏼‍🚀", - ["astronaut_medium_light_skin_tone"] = "🧑🏼‍🚀", - ["astronaut_tone3"] = "🧑🏽‍🚀", - ["astronaut_medium_skin_tone"] = "🧑🏽‍🚀", - ["astronaut_tone4"] = "🧑🏾‍🚀", - ["astronaut_medium_dark_skin_tone"] = "🧑🏾‍🚀", - ["astronaut_tone5"] = "🧑🏿‍🚀", - ["astronaut_dark_skin_tone"] = "🧑🏿‍🚀", - ["woman_astronaut"] = "👩‍🚀", - ["woman_astronaut_tone1"] = "👩🏻‍🚀", - ["woman_astronaut_light_skin_tone"] = "👩🏻‍🚀", - ["woman_astronaut_tone2"] = "👩🏼‍🚀", - ["woman_astronaut_medium_light_skin_tone"] = "👩🏼‍🚀", - ["woman_astronaut_tone3"] = "👩🏽‍🚀", - ["woman_astronaut_medium_skin_tone"] = "👩🏽‍🚀", - ["woman_astronaut_tone4"] = "👩🏾‍🚀", - ["woman_astronaut_medium_dark_skin_tone"] = "👩🏾‍🚀", - ["woman_astronaut_tone5"] = "👩🏿‍🚀", - ["woman_astronaut_dark_skin_tone"] = "👩🏿‍🚀", - ["man_astronaut"] = "👨‍🚀", - ["man_astronaut_tone1"] = "👨🏻‍🚀", - ["man_astronaut_light_skin_tone"] = "👨🏻‍🚀", - ["man_astronaut_tone2"] = "👨🏼‍🚀", - ["man_astronaut_medium_light_skin_tone"] = "👨🏼‍🚀", - ["man_astronaut_tone3"] = "👨🏽‍🚀", - ["man_astronaut_medium_skin_tone"] = "👨🏽‍🚀", - ["man_astronaut_tone4"] = "👨🏾‍🚀", - ["man_astronaut_medium_dark_skin_tone"] = "👨🏾‍🚀", - ["man_astronaut_tone5"] = "👨🏿‍🚀", - ["man_astronaut_dark_skin_tone"] = "👨🏿‍🚀", - ["judge"] = "🧑‍⚖️", - ["judge_tone1"] = "🧑🏻‍⚖️", - ["judge_light_skin_tone"] = "🧑🏻‍⚖️", - ["judge_tone2"] = "🧑🏼‍⚖️", - ["judge_medium_light_skin_tone"] = "🧑🏼‍⚖️", - ["judge_tone3"] = "🧑🏽‍⚖️", - ["judge_medium_skin_tone"] = "🧑🏽‍⚖️", - ["judge_tone4"] = "🧑🏾‍⚖️", - ["judge_medium_dark_skin_tone"] = "🧑🏾‍⚖️", - ["judge_tone5"] = "🧑🏿‍⚖️", - ["judge_dark_skin_tone"] = "🧑🏿‍⚖️", - ["woman_judge"] = "👩‍⚖️", - ["woman_judge_tone1"] = "👩🏻‍⚖️", - ["woman_judge_light_skin_tone"] = "👩🏻‍⚖️", - ["woman_judge_tone2"] = "👩🏼‍⚖️", - ["woman_judge_medium_light_skin_tone"] = "👩🏼‍⚖️", - ["woman_judge_tone3"] = "👩🏽‍⚖️", - ["woman_judge_medium_skin_tone"] = "👩🏽‍⚖️", - ["woman_judge_tone4"] = "👩🏾‍⚖️", - ["woman_judge_medium_dark_skin_tone"] = "👩🏾‍⚖️", - ["woman_judge_tone5"] = "👩🏿‍⚖️", - ["woman_judge_dark_skin_tone"] = "👩🏿‍⚖️", - ["man_judge"] = "👨‍⚖️", - ["man_judge_tone1"] = "👨🏻‍⚖️", - ["man_judge_light_skin_tone"] = "👨🏻‍⚖️", - ["man_judge_tone2"] = "👨🏼‍⚖️", - ["man_judge_medium_light_skin_tone"] = "👨🏼‍⚖️", - ["man_judge_tone3"] = "👨🏽‍⚖️", - ["man_judge_medium_skin_tone"] = "👨🏽‍⚖️", - ["man_judge_tone4"] = "👨🏾‍⚖️", - ["man_judge_medium_dark_skin_tone"] = "👨🏾‍⚖️", - ["man_judge_tone5"] = "👨🏿‍⚖️", - ["man_judge_dark_skin_tone"] = "👨🏿‍⚖️", - ["person_with_veil"] = "👰", - ["person_with_veil_tone1"] = "👰🏻", - ["person_with_veil_tone2"] = "👰🏼", - ["person_with_veil_tone3"] = "👰🏽", - ["person_with_veil_tone4"] = "👰🏾", - ["person_with_veil_tone5"] = "👰🏿", - ["woman_with_veil"] = "👰‍♀️", - ["bride_with_veil"] = "👰‍♀️", - ["woman_with_veil_tone1"] = "👰🏻‍♀️", - ["woman_with_veil_light_skin_tone"] = "👰🏻‍♀️", - ["woman_with_veil_tone2"] = "👰🏼‍♀️", - ["woman_with_veil_medium_light_skin_tone"] = "👰🏼‍♀️", - ["woman_with_veil_tone3"] = "👰🏽‍♀️", - ["woman_with_veil_medium_skin_tone"] = "👰🏽‍♀️", - ["woman_with_veil_tone4"] = "👰🏾‍♀️", - ["woman_with_veil_medium_dark_skin_tone"] = "👰🏾‍♀️", - ["woman_with_veil_tone5"] = "👰🏿‍♀️", - ["woman_with_veil_dark_skin_tone"] = "👰🏿‍♀️", - ["man_with_veil"] = "👰‍♂️", - ["man_with_veil_tone1"] = "👰🏻‍♂️", - ["man_with_veil_light_skin_tone"] = "👰🏻‍♂️", - ["man_with_veil_tone2"] = "👰🏼‍♂️", - ["man_with_veil_medium_light_skin_tone"] = "👰🏼‍♂️", - ["man_with_veil_tone3"] = "👰🏽‍♂️", - ["man_with_veil_medium_skin_tone"] = "👰🏽‍♂️", - ["man_with_veil_tone4"] = "👰🏾‍♂️", - ["man_with_veil_medium_dark_skin_tone"] = "👰🏾‍♂️", - ["man_with_veil_tone5"] = "👰🏿‍♂️", - ["man_with_veil_dark_skin_tone"] = "👰🏿‍♂️", - ["person_in_tuxedo"] = "🤵", - ["person_in_tuxedo_tone1"] = "🤵🏻", - ["tuxedo_tone1"] = "🤵🏻", - ["person_in_tuxedo_tone2"] = "🤵🏼", - ["tuxedo_tone2"] = "🤵🏼", - ["person_in_tuxedo_tone3"] = "🤵🏽", - ["tuxedo_tone3"] = "🤵🏽", - ["person_in_tuxedo_tone4"] = "🤵🏾", - ["tuxedo_tone4"] = "🤵🏾", - ["person_in_tuxedo_tone5"] = "🤵🏿", - ["tuxedo_tone5"] = "🤵🏿", - ["woman_in_tuxedo"] = "🤵‍♀️", - ["woman_in_tuxedo_tone1"] = "🤵🏻‍♀️", - ["woman_in_tuxedo_light_skin_tone"] = "🤵🏻‍♀️", - ["woman_in_tuxedo_tone2"] = "🤵🏼‍♀️", - ["woman_in_tuxedo_medium_light_skin_tone"] = "🤵🏼‍♀️", - ["woman_in_tuxedo_tone3"] = "🤵🏽‍♀️", - ["woman_in_tuxedo_medium_skin_tone"] = "🤵🏽‍♀️", - ["woman_in_tuxedo_tone4"] = "🤵🏾‍♀️", - ["woman_in_tuxedo_medium_dark_skin_tone"] = "🤵🏾‍♀️", - ["woman_in_tuxedo_tone5"] = "🤵🏿‍♀️", - ["woman_in_tuxedo_dark_skin_tone"] = "🤵🏿‍♀️", - ["man_in_tuxedo"] = "🤵‍♂️", - ["man_in_tuxedo_tone1"] = "🤵🏻‍♂️", - ["man_in_tuxedo_light_skin_tone"] = "🤵🏻‍♂️", - ["man_in_tuxedo_tone2"] = "🤵🏼‍♂️", - ["man_in_tuxedo_medium_light_skin_tone"] = "🤵🏼‍♂️", - ["man_in_tuxedo_tone3"] = "🤵🏽‍♂️", - ["man_in_tuxedo_medium_skin_tone"] = "🤵🏽‍♂️", - ["man_in_tuxedo_tone4"] = "🤵🏾‍♂️", - ["man_in_tuxedo_medium_dark_skin_tone"] = "🤵🏾‍♂️", - ["man_in_tuxedo_tone5"] = "🤵🏿‍♂️", - ["man_in_tuxedo_dark_skin_tone"] = "🤵🏿‍♂️", - ["princess"] = "👸", - ["princess_tone1"] = "👸🏻", - ["princess_tone2"] = "👸🏼", - ["princess_tone3"] = "👸🏽", - ["princess_tone4"] = "👸🏾", - ["princess_tone5"] = "👸🏿", - ["prince"] = "🤴", - ["prince_tone1"] = "🤴🏻", - ["prince_tone2"] = "🤴🏼", - ["prince_tone3"] = "🤴🏽", - ["prince_tone4"] = "🤴🏾", - ["prince_tone5"] = "🤴🏿", - ["superhero"] = "🦸", - ["superhero_tone1"] = "🦸🏻", - ["superhero_light_skin_tone"] = "🦸🏻", - ["superhero_tone2"] = "🦸🏼", - ["superhero_medium_light_skin_tone"] = "🦸🏼", - ["superhero_tone3"] = "🦸🏽", - ["superhero_medium_skin_tone"] = "🦸🏽", - ["superhero_tone4"] = "🦸🏾", - ["superhero_medium_dark_skin_tone"] = "🦸🏾", - ["superhero_tone5"] = "🦸🏿", - ["superhero_dark_skin_tone"] = "🦸🏿", - ["woman_superhero"] = "🦸‍♀️", - ["woman_superhero_tone1"] = "🦸🏻‍♀️", - ["woman_superhero_light_skin_tone"] = "🦸🏻‍♀️", - ["woman_superhero_tone2"] = "🦸🏼‍♀️", - ["woman_superhero_medium_light_skin_tone"] = "🦸🏼‍♀️", - ["woman_superhero_tone3"] = "🦸🏽‍♀️", - ["woman_superhero_medium_skin_tone"] = "🦸🏽‍♀️", - ["woman_superhero_tone4"] = "🦸🏾‍♀️", - ["woman_superhero_medium_dark_skin_tone"] = "🦸🏾‍♀️", - ["woman_superhero_tone5"] = "🦸🏿‍♀️", - ["woman_superhero_dark_skin_tone"] = "🦸🏿‍♀️", - ["man_superhero"] = "🦸‍♂️", - ["man_superhero_tone1"] = "🦸🏻‍♂️", - ["man_superhero_light_skin_tone"] = "🦸🏻‍♂️", - ["man_superhero_tone2"] = "🦸🏼‍♂️", - ["man_superhero_medium_light_skin_tone"] = "🦸🏼‍♂️", - ["man_superhero_tone3"] = "🦸🏽‍♂️", - ["man_superhero_medium_skin_tone"] = "🦸🏽‍♂️", - ["man_superhero_tone4"] = "🦸🏾‍♂️", - ["man_superhero_medium_dark_skin_tone"] = "🦸🏾‍♂️", - ["man_superhero_tone5"] = "🦸🏿‍♂️", - ["man_superhero_dark_skin_tone"] = "🦸🏿‍♂️", - ["supervillain"] = "🦹", - ["supervillain_tone1"] = "🦹🏻", - ["supervillain_light_skin_tone"] = "🦹🏻", - ["supervillain_tone2"] = "🦹🏼", - ["supervillain_medium_light_skin_tone"] = "🦹🏼", - ["supervillain_tone3"] = "🦹🏽", - ["supervillain_medium_skin_tone"] = "🦹🏽", - ["supervillain_tone4"] = "🦹🏾", - ["supervillain_medium_dark_skin_tone"] = "🦹🏾", - ["supervillain_tone5"] = "🦹🏿", - ["supervillain_dark_skin_tone"] = "🦹🏿", - ["woman_supervillain"] = "🦹‍♀️", - ["woman_supervillain_tone1"] = "🦹🏻‍♀️", - ["woman_supervillain_light_skin_tone"] = "🦹🏻‍♀️", - ["woman_supervillain_tone2"] = "🦹🏼‍♀️", - ["woman_supervillain_medium_light_skin_tone"] = "🦹🏼‍♀️", - ["woman_supervillain_tone3"] = "🦹🏽‍♀️", - ["woman_supervillain_medium_skin_tone"] = "🦹🏽‍♀️", - ["woman_supervillain_tone4"] = "🦹🏾‍♀️", - ["woman_supervillain_medium_dark_skin_tone"] = "🦹🏾‍♀️", - ["woman_supervillain_tone5"] = "🦹🏿‍♀️", - ["woman_supervillain_dark_skin_tone"] = "🦹🏿‍♀️", - ["man_supervillain"] = "🦹‍♂️", - ["man_supervillain_tone1"] = "🦹🏻‍♂️", - ["man_supervillain_light_skin_tone"] = "🦹🏻‍♂️", - ["man_supervillain_tone2"] = "🦹🏼‍♂️", - ["man_supervillain_medium_light_skin_tone"] = "🦹🏼‍♂️", - ["man_supervillain_tone3"] = "🦹🏽‍♂️", - ["man_supervillain_medium_skin_tone"] = "🦹🏽‍♂️", - ["man_supervillain_tone4"] = "🦹🏾‍♂️", - ["man_supervillain_medium_dark_skin_tone"] = "🦹🏾‍♂️", - ["man_supervillain_tone5"] = "🦹🏿‍♂️", - ["man_supervillain_dark_skin_tone"] = "🦹🏿‍♂️", - ["ninja"] = "🥷", - ["ninja_tone1"] = "🥷🏻", - ["ninja_light_skin_tone"] = "🥷🏻", - ["ninja_tone2"] = "🥷🏼", - ["ninja_medium_light_skin_tone"] = "🥷🏼", - ["ninja_tone3"] = "🥷🏽", - ["ninja_medium_skin_tone"] = "🥷🏽", - ["ninja_tone4"] = "🥷🏾", - ["ninja_medium_dark_skin_tone"] = "🥷🏾", - ["ninja_tone5"] = "🥷🏿", - ["ninja_dark_skin_tone"] = "🥷🏿", - ["mx_claus"] = "🧑‍🎄", - ["mx_claus_tone1"] = "🧑🏻‍🎄", - ["mx_claus_light_skin_tone"] = "🧑🏻‍🎄", - ["mx_claus_tone2"] = "🧑🏼‍🎄", - ["mx_claus_medium_light_skin_tone"] = "🧑🏼‍🎄", - ["mx_claus_tone3"] = "🧑🏽‍🎄", - ["mx_claus_medium_skin_tone"] = "🧑🏽‍🎄", - ["mx_claus_tone4"] = "🧑🏾‍🎄", - ["mx_claus_medium_dark_skin_tone"] = "🧑🏾‍🎄", - ["mx_claus_tone5"] = "🧑🏿‍🎄", - ["mx_claus_dark_skin_tone"] = "🧑🏿‍🎄", - ["mrs_claus"] = "🤶", - ["mother_christmas"] = "🤶", - ["mrs_claus_tone1"] = "🤶🏻", - ["mother_christmas_tone1"] = "🤶🏻", - ["mrs_claus_tone2"] = "🤶🏼", - ["mother_christmas_tone2"] = "🤶🏼", - ["mrs_claus_tone3"] = "🤶🏽", - ["mother_christmas_tone3"] = "🤶🏽", - ["mrs_claus_tone4"] = "🤶🏾", - ["mother_christmas_tone4"] = "🤶🏾", - ["mrs_claus_tone5"] = "🤶🏿", - ["mother_christmas_tone5"] = "🤶🏿", - ["santa"] = "🎅", - ["santa_tone1"] = "🎅🏻", - ["santa_tone2"] = "🎅🏼", - ["santa_tone3"] = "🎅🏽", - ["santa_tone4"] = "🎅🏾", - ["santa_tone5"] = "🎅🏿", - ["mage"] = "🧙", - ["mage_tone1"] = "🧙🏻", - ["mage_light_skin_tone"] = "🧙🏻", - ["mage_tone2"] = "🧙🏼", - ["mage_medium_light_skin_tone"] = "🧙🏼", - ["mage_tone3"] = "🧙🏽", - ["mage_medium_skin_tone"] = "🧙🏽", - ["mage_tone4"] = "🧙🏾", - ["mage_medium_dark_skin_tone"] = "🧙🏾", - ["mage_tone5"] = "🧙🏿", - ["mage_dark_skin_tone"] = "🧙🏿", - ["woman_mage"] = "🧙‍♀️", - ["woman_mage_tone1"] = "🧙🏻‍♀️", - ["woman_mage_light_skin_tone"] = "🧙🏻‍♀️", - ["woman_mage_tone2"] = "🧙🏼‍♀️", - ["woman_mage_medium_light_skin_tone"] = "🧙🏼‍♀️", - ["woman_mage_tone3"] = "🧙🏽‍♀️", - ["woman_mage_medium_skin_tone"] = "🧙🏽‍♀️", - ["woman_mage_tone4"] = "🧙🏾‍♀️", - ["woman_mage_medium_dark_skin_tone"] = "🧙🏾‍♀️", - ["woman_mage_tone5"] = "🧙🏿‍♀️", - ["woman_mage_dark_skin_tone"] = "🧙🏿‍♀️", - ["man_mage"] = "🧙‍♂️", - ["man_mage_tone1"] = "🧙🏻‍♂️", - ["man_mage_light_skin_tone"] = "🧙🏻‍♂️", - ["man_mage_tone2"] = "🧙🏼‍♂️", - ["man_mage_medium_light_skin_tone"] = "🧙🏼‍♂️", - ["man_mage_tone3"] = "🧙🏽‍♂️", - ["man_mage_medium_skin_tone"] = "🧙🏽‍♂️", - ["man_mage_tone4"] = "🧙🏾‍♂️", - ["man_mage_medium_dark_skin_tone"] = "🧙🏾‍♂️", - ["man_mage_tone5"] = "🧙🏿‍♂️", - ["man_mage_dark_skin_tone"] = "🧙🏿‍♂️", - ["elf"] = "🧝", - ["elf_tone1"] = "🧝🏻", - ["elf_light_skin_tone"] = "🧝🏻", - ["elf_tone2"] = "🧝🏼", - ["elf_medium_light_skin_tone"] = "🧝🏼", - ["elf_tone3"] = "🧝🏽", - ["elf_medium_skin_tone"] = "🧝🏽", - ["elf_tone4"] = "🧝🏾", - ["elf_medium_dark_skin_tone"] = "🧝🏾", - ["elf_tone5"] = "🧝🏿", - ["elf_dark_skin_tone"] = "🧝🏿", - ["woman_elf"] = "🧝‍♀️", - ["woman_elf_tone1"] = "🧝🏻‍♀️", - ["woman_elf_light_skin_tone"] = "🧝🏻‍♀️", - ["woman_elf_tone2"] = "🧝🏼‍♀️", - ["woman_elf_medium_light_skin_tone"] = "🧝🏼‍♀️", - ["woman_elf_tone3"] = "🧝🏽‍♀️", - ["woman_elf_medium_skin_tone"] = "🧝🏽‍♀️", - ["woman_elf_tone4"] = "🧝🏾‍♀️", - ["woman_elf_medium_dark_skin_tone"] = "🧝🏾‍♀️", - ["woman_elf_tone5"] = "🧝🏿‍♀️", - ["woman_elf_dark_skin_tone"] = "🧝🏿‍♀️", - ["man_elf"] = "🧝‍♂️", - ["man_elf_tone1"] = "🧝🏻‍♂️", - ["man_elf_light_skin_tone"] = "🧝🏻‍♂️", - ["man_elf_tone2"] = "🧝🏼‍♂️", - ["man_elf_medium_light_skin_tone"] = "🧝🏼‍♂️", - ["man_elf_tone3"] = "🧝🏽‍♂️", - ["man_elf_medium_skin_tone"] = "🧝🏽‍♂️", - ["man_elf_tone4"] = "🧝🏾‍♂️", - ["man_elf_medium_dark_skin_tone"] = "🧝🏾‍♂️", - ["man_elf_tone5"] = "🧝🏿‍♂️", - ["man_elf_dark_skin_tone"] = "🧝🏿‍♂️", - ["vampire"] = "🧛", - ["vampire_tone1"] = "🧛🏻", - ["vampire_light_skin_tone"] = "🧛🏻", - ["vampire_tone2"] = "🧛🏼", - ["vampire_medium_light_skin_tone"] = "🧛🏼", - ["vampire_tone3"] = "🧛🏽", - ["vampire_medium_skin_tone"] = "🧛🏽", - ["vampire_tone4"] = "🧛🏾", - ["vampire_medium_dark_skin_tone"] = "🧛🏾", - ["vampire_tone5"] = "🧛🏿", - ["vampire_dark_skin_tone"] = "🧛🏿", - ["woman_vampire"] = "🧛‍♀️", - ["woman_vampire_tone1"] = "🧛🏻‍♀️", - ["woman_vampire_light_skin_tone"] = "🧛🏻‍♀️", - ["woman_vampire_tone2"] = "🧛🏼‍♀️", - ["woman_vampire_medium_light_skin_tone"] = "🧛🏼‍♀️", - ["woman_vampire_tone3"] = "🧛🏽‍♀️", - ["woman_vampire_medium_skin_tone"] = "🧛🏽‍♀️", - ["woman_vampire_tone4"] = "🧛🏾‍♀️", - ["woman_vampire_medium_dark_skin_tone"] = "🧛🏾‍♀️", - ["woman_vampire_tone5"] = "🧛🏿‍♀️", - ["woman_vampire_dark_skin_tone"] = "🧛🏿‍♀️", - ["man_vampire"] = "🧛‍♂️", - ["man_vampire_tone1"] = "🧛🏻‍♂️", - ["man_vampire_light_skin_tone"] = "🧛🏻‍♂️", - ["man_vampire_tone2"] = "🧛🏼‍♂️", - ["man_vampire_medium_light_skin_tone"] = "🧛🏼‍♂️", - ["man_vampire_tone3"] = "🧛🏽‍♂️", - ["man_vampire_medium_skin_tone"] = "🧛🏽‍♂️", - ["man_vampire_tone4"] = "🧛🏾‍♂️", - ["man_vampire_medium_dark_skin_tone"] = "🧛🏾‍♂️", - ["man_vampire_tone5"] = "🧛🏿‍♂️", - ["man_vampire_dark_skin_tone"] = "🧛🏿‍♂️", - ["zombie"] = "🧟", - ["woman_zombie"] = "🧟‍♀️", - ["man_zombie"] = "🧟‍♂️", - ["genie"] = "🧞", - ["woman_genie"] = "🧞‍♀️", - ["man_genie"] = "🧞‍♂️", - ["merperson"] = "🧜", - ["merperson_tone1"] = "🧜🏻", - ["merperson_light_skin_tone"] = "🧜🏻", - ["merperson_tone2"] = "🧜🏼", - ["merperson_medium_light_skin_tone"] = "🧜🏼", - ["merperson_tone3"] = "🧜🏽", - ["merperson_medium_skin_tone"] = "🧜🏽", - ["merperson_tone4"] = "🧜🏾", - ["merperson_medium_dark_skin_tone"] = "🧜🏾", - ["merperson_tone5"] = "🧜🏿", - ["merperson_dark_skin_tone"] = "🧜🏿", - ["mermaid"] = "🧜‍♀️", - ["mermaid_tone1"] = "🧜🏻‍♀️", - ["mermaid_light_skin_tone"] = "🧜🏻‍♀️", - ["mermaid_tone2"] = "🧜🏼‍♀️", - ["mermaid_medium_light_skin_tone"] = "🧜🏼‍♀️", - ["mermaid_tone3"] = "🧜🏽‍♀️", - ["mermaid_medium_skin_tone"] = "🧜🏽‍♀️", - ["mermaid_tone4"] = "🧜🏾‍♀️", - ["mermaid_medium_dark_skin_tone"] = "🧜🏾‍♀️", - ["mermaid_tone5"] = "🧜🏿‍♀️", - ["mermaid_dark_skin_tone"] = "🧜🏿‍♀️", - ["merman"] = "🧜‍♂️", - ["merman_tone1"] = "🧜🏻‍♂️", - ["merman_light_skin_tone"] = "🧜🏻‍♂️", - ["merman_tone2"] = "🧜🏼‍♂️", - ["merman_medium_light_skin_tone"] = "🧜🏼‍♂️", - ["merman_tone3"] = "🧜🏽‍♂️", - ["merman_medium_skin_tone"] = "🧜🏽‍♂️", - ["merman_tone4"] = "🧜🏾‍♂️", - ["merman_medium_dark_skin_tone"] = "🧜🏾‍♂️", - ["merman_tone5"] = "🧜🏿‍♂️", - ["merman_dark_skin_tone"] = "🧜🏿‍♂️", - ["fairy"] = "🧚", - ["fairy_tone1"] = "🧚🏻", - ["fairy_light_skin_tone"] = "🧚🏻", - ["fairy_tone2"] = "🧚🏼", - ["fairy_medium_light_skin_tone"] = "🧚🏼", - ["fairy_tone3"] = "🧚🏽", - ["fairy_medium_skin_tone"] = "🧚🏽", - ["fairy_tone4"] = "🧚🏾", - ["fairy_medium_dark_skin_tone"] = "🧚🏾", - ["fairy_tone5"] = "🧚🏿", - ["fairy_dark_skin_tone"] = "🧚🏿", - ["woman_fairy"] = "🧚‍♀️", - ["woman_fairy_tone1"] = "🧚🏻‍♀️", - ["woman_fairy_light_skin_tone"] = "🧚🏻‍♀️", - ["woman_fairy_tone2"] = "🧚🏼‍♀️", - ["woman_fairy_medium_light_skin_tone"] = "🧚🏼‍♀️", - ["woman_fairy_tone3"] = "🧚🏽‍♀️", - ["woman_fairy_medium_skin_tone"] = "🧚🏽‍♀️", - ["woman_fairy_tone4"] = "🧚🏾‍♀️", - ["woman_fairy_medium_dark_skin_tone"] = "🧚🏾‍♀️", - ["woman_fairy_tone5"] = "🧚🏿‍♀️", - ["woman_fairy_dark_skin_tone"] = "🧚🏿‍♀️", - ["man_fairy"] = "🧚‍♂️", - ["man_fairy_tone1"] = "🧚🏻‍♂️", - ["man_fairy_light_skin_tone"] = "🧚🏻‍♂️", - ["man_fairy_tone2"] = "🧚🏼‍♂️", - ["man_fairy_medium_light_skin_tone"] = "🧚🏼‍♂️", - ["man_fairy_tone3"] = "🧚🏽‍♂️", - ["man_fairy_medium_skin_tone"] = "🧚🏽‍♂️", - ["man_fairy_tone4"] = "🧚🏾‍♂️", - ["man_fairy_medium_dark_skin_tone"] = "🧚🏾‍♂️", - ["man_fairy_tone5"] = "🧚🏿‍♂️", - ["man_fairy_dark_skin_tone"] = "🧚🏿‍♂️", - ["angel"] = "👼", - ["angel_tone1"] = "👼🏻", - ["angel_tone2"] = "👼🏼", - ["angel_tone3"] = "👼🏽", - ["angel_tone4"] = "👼🏾", - ["angel_tone5"] = "👼🏿", - ["pregnant_woman"] = "🤰", - ["expecting_woman"] = "🤰", - ["pregnant_woman_tone1"] = "🤰🏻", - ["expecting_woman_tone1"] = "🤰🏻", - ["pregnant_woman_tone2"] = "🤰🏼", - ["expecting_woman_tone2"] = "🤰🏼", - ["pregnant_woman_tone3"] = "🤰🏽", - ["expecting_woman_tone3"] = "🤰🏽", - ["pregnant_woman_tone4"] = "🤰🏾", - ["expecting_woman_tone4"] = "🤰🏾", - ["pregnant_woman_tone5"] = "🤰🏿", - ["expecting_woman_tone5"] = "🤰🏿", - ["breast_feeding"] = "🤱", - ["breast_feeding_tone1"] = "🤱🏻", - ["breast_feeding_light_skin_tone"] = "🤱🏻", - ["breast_feeding_tone2"] = "🤱🏼", - ["breast_feeding_medium_light_skin_tone"] = "🤱🏼", - ["breast_feeding_tone3"] = "🤱🏽", - ["breast_feeding_medium_skin_tone"] = "🤱🏽", - ["breast_feeding_tone4"] = "🤱🏾", - ["breast_feeding_medium_dark_skin_tone"] = "🤱🏾", - ["breast_feeding_tone5"] = "🤱🏿", - ["breast_feeding_dark_skin_tone"] = "🤱🏿", - ["person_feeding_baby"] = "🧑‍🍼", - ["person_feeding_baby_tone1"] = "🧑🏻‍🍼", - ["person_feeding_baby_light_skin_tone"] = "🧑🏻‍🍼", - ["person_feeding_baby_tone2"] = "🧑🏼‍🍼", - ["person_feeding_baby_medium_light_skin_tone"] = "🧑🏼‍🍼", - ["person_feeding_baby_tone3"] = "🧑🏽‍🍼", - ["person_feeding_baby_medium_skin_tone"] = "🧑🏽‍🍼", - ["person_feeding_baby_tone4"] = "🧑🏾‍🍼", - ["person_feeding_baby_medium_dark_skin_tone"] = "🧑🏾‍🍼", - ["person_feeding_baby_tone5"] = "🧑🏿‍🍼", - ["person_feeding_baby_dark_skin_tone"] = "🧑🏿‍🍼", - ["woman_feeding_baby"] = "👩‍🍼", - ["woman_feeding_baby_tone1"] = "👩🏻‍🍼", - ["woman_feeding_baby_light_skin_tone"] = "👩🏻‍🍼", - ["woman_feeding_baby_tone2"] = "👩🏼‍🍼", - ["woman_feeding_baby_medium_light_skin_tone"] = "👩🏼‍🍼", - ["woman_feeding_baby_tone3"] = "👩🏽‍🍼", - ["woman_feeding_baby_medium_skin_tone"] = "👩🏽‍🍼", - ["woman_feeding_baby_tone4"] = "👩🏾‍🍼", - ["woman_feeding_baby_medium_dark_skin_tone"] = "👩🏾‍🍼", - ["woman_feeding_baby_tone5"] = "👩🏿‍🍼", - ["woman_feeding_baby_dark_skin_tone"] = "👩🏿‍🍼", - ["man_feeding_baby"] = "👨‍🍼", - ["man_feeding_baby_tone1"] = "👨🏻‍🍼", - ["man_feeding_baby_light_skin_tone"] = "👨🏻‍🍼", - ["man_feeding_baby_tone2"] = "👨🏼‍🍼", - ["man_feeding_baby_medium_light_skin_tone"] = "👨🏼‍🍼", - ["man_feeding_baby_tone3"] = "👨🏽‍🍼", - ["man_feeding_baby_medium_skin_tone"] = "👨🏽‍🍼", - ["man_feeding_baby_tone4"] = "👨🏾‍🍼", - ["man_feeding_baby_medium_dark_skin_tone"] = "👨🏾‍🍼", - ["man_feeding_baby_tone5"] = "👨🏿‍🍼", - ["man_feeding_baby_dark_skin_tone"] = "👨🏿‍🍼", - ["person_bowing"] = "🙇", - ["bow"] = "🙇", - ["person_bowing_tone1"] = "🙇🏻", - ["bow_tone1"] = "🙇🏻", - ["person_bowing_tone2"] = "🙇🏼", - ["bow_tone2"] = "🙇🏼", - ["person_bowing_tone3"] = "🙇🏽", - ["bow_tone3"] = "🙇🏽", - ["person_bowing_tone4"] = "🙇🏾", - ["bow_tone4"] = "🙇🏾", - ["person_bowing_tone5"] = "🙇🏿", - ["bow_tone5"] = "🙇🏿", - ["woman_bowing"] = "🙇‍♀️", - ["woman_bowing_tone1"] = "🙇🏻‍♀️", - ["woman_bowing_light_skin_tone"] = "🙇🏻‍♀️", - ["woman_bowing_tone2"] = "🙇🏼‍♀️", - ["woman_bowing_medium_light_skin_tone"] = "🙇🏼‍♀️", - ["woman_bowing_tone3"] = "🙇🏽‍♀️", - ["woman_bowing_medium_skin_tone"] = "🙇🏽‍♀️", - ["woman_bowing_tone4"] = "🙇🏾‍♀️", - ["woman_bowing_medium_dark_skin_tone"] = "🙇🏾‍♀️", - ["woman_bowing_tone5"] = "🙇🏿‍♀️", - ["woman_bowing_dark_skin_tone"] = "🙇🏿‍♀️", - ["man_bowing"] = "🙇‍♂️", - ["man_bowing_tone1"] = "🙇🏻‍♂️", - ["man_bowing_light_skin_tone"] = "🙇🏻‍♂️", - ["man_bowing_tone2"] = "🙇🏼‍♂️", - ["man_bowing_medium_light_skin_tone"] = "🙇🏼‍♂️", - ["man_bowing_tone3"] = "🙇🏽‍♂️", - ["man_bowing_medium_skin_tone"] = "🙇🏽‍♂️", - ["man_bowing_tone4"] = "🙇🏾‍♂️", - ["man_bowing_medium_dark_skin_tone"] = "🙇🏾‍♂️", - ["man_bowing_tone5"] = "🙇🏿‍♂️", - ["man_bowing_dark_skin_tone"] = "🙇🏿‍♂️", - ["person_tipping_hand"] = "💁", - ["information_desk_person"] = "💁", - ["person_tipping_hand_tone1"] = "💁🏻", - ["information_desk_person_tone1"] = "💁🏻", - ["person_tipping_hand_tone2"] = "💁🏼", - ["information_desk_person_tone2"] = "💁🏼", - ["person_tipping_hand_tone3"] = "💁🏽", - ["information_desk_person_tone3"] = "💁🏽", - ["person_tipping_hand_tone4"] = "💁🏾", - ["information_desk_person_tone4"] = "💁🏾", - ["person_tipping_hand_tone5"] = "💁🏿", - ["information_desk_person_tone5"] = "💁🏿", - ["woman_tipping_hand"] = "💁‍♀️", - ["woman_tipping_hand_tone1"] = "💁🏻‍♀️", - ["woman_tipping_hand_light_skin_tone"] = "💁🏻‍♀️", - ["woman_tipping_hand_tone2"] = "💁🏼‍♀️", - ["woman_tipping_hand_medium_light_skin_tone"] = "💁🏼‍♀️", - ["woman_tipping_hand_tone3"] = "💁🏽‍♀️", - ["woman_tipping_hand_medium_skin_tone"] = "💁🏽‍♀️", - ["woman_tipping_hand_tone4"] = "💁🏾‍♀️", - ["woman_tipping_hand_medium_dark_skin_tone"] = "💁🏾‍♀️", - ["woman_tipping_hand_tone5"] = "💁🏿‍♀️", - ["woman_tipping_hand_dark_skin_tone"] = "💁🏿‍♀️", - ["man_tipping_hand"] = "💁‍♂️", - ["man_tipping_hand_tone1"] = "💁🏻‍♂️", - ["man_tipping_hand_light_skin_tone"] = "💁🏻‍♂️", - ["man_tipping_hand_tone2"] = "💁🏼‍♂️", - ["man_tipping_hand_medium_light_skin_tone"] = "💁🏼‍♂️", - ["man_tipping_hand_tone3"] = "💁🏽‍♂️", - ["man_tipping_hand_medium_skin_tone"] = "💁🏽‍♂️", - ["man_tipping_hand_tone4"] = "💁🏾‍♂️", - ["man_tipping_hand_medium_dark_skin_tone"] = "💁🏾‍♂️", - ["man_tipping_hand_tone5"] = "💁🏿‍♂️", - ["man_tipping_hand_dark_skin_tone"] = "💁🏿‍♂️", - ["person_gesturing_no"] = "🙅", - ["no_good"] = "🙅", - ["person_gesturing_no_tone1"] = "🙅🏻", - ["no_good_tone1"] = "🙅🏻", - ["person_gesturing_no_tone2"] = "🙅🏼", - ["no_good_tone2"] = "🙅🏼", - ["person_gesturing_no_tone3"] = "🙅🏽", - ["no_good_tone3"] = "🙅🏽", - ["person_gesturing_no_tone4"] = "🙅🏾", - ["no_good_tone4"] = "🙅🏾", - ["person_gesturing_no_tone5"] = "🙅🏿", - ["no_good_tone5"] = "🙅🏿", - ["woman_gesturing_no"] = "🙅‍♀️", - ["woman_gesturing_no_tone1"] = "🙅🏻‍♀️", - ["woman_gesturing_no_light_skin_tone"] = "🙅🏻‍♀️", - ["woman_gesturing_no_tone2"] = "🙅🏼‍♀️", - ["woman_gesturing_no_medium_light_skin_tone"] = "🙅🏼‍♀️", - ["woman_gesturing_no_tone3"] = "🙅🏽‍♀️", - ["woman_gesturing_no_medium_skin_tone"] = "🙅🏽‍♀️", - ["woman_gesturing_no_tone4"] = "🙅🏾‍♀️", - ["woman_gesturing_no_medium_dark_skin_tone"] = "🙅🏾‍♀️", - ["woman_gesturing_no_tone5"] = "🙅🏿‍♀️", - ["woman_gesturing_no_dark_skin_tone"] = "🙅🏿‍♀️", - ["man_gesturing_no"] = "🙅‍♂️", - ["man_gesturing_no_tone1"] = "🙅🏻‍♂️", - ["man_gesturing_no_light_skin_tone"] = "🙅🏻‍♂️", - ["man_gesturing_no_tone2"] = "🙅🏼‍♂️", - ["man_gesturing_no_medium_light_skin_tone"] = "🙅🏼‍♂️", - ["man_gesturing_no_tone3"] = "🙅🏽‍♂️", - ["man_gesturing_no_medium_skin_tone"] = "🙅🏽‍♂️", - ["man_gesturing_no_tone4"] = "🙅🏾‍♂️", - ["man_gesturing_no_medium_dark_skin_tone"] = "🙅🏾‍♂️", - ["man_gesturing_no_tone5"] = "🙅🏿‍♂️", - ["man_gesturing_no_dark_skin_tone"] = "🙅🏿‍♂️", - ["person_gesturing_ok"] = "🙆", - ["ok_woman"] = "🙆", - ["person_gesturing_ok_tone1"] = "🙆🏻", - ["ok_woman_tone1"] = "🙆🏻", - ["person_gesturing_ok_tone2"] = "🙆🏼", - ["ok_woman_tone2"] = "🙆🏼", - ["person_gesturing_ok_tone3"] = "🙆🏽", - ["ok_woman_tone3"] = "🙆🏽", - ["person_gesturing_ok_tone4"] = "🙆🏾", - ["ok_woman_tone4"] = "🙆🏾", - ["person_gesturing_ok_tone5"] = "🙆🏿", - ["ok_woman_tone5"] = "🙆🏿", - ["woman_gesturing_ok"] = "🙆‍♀️", - ["woman_gesturing_ok_tone1"] = "🙆🏻‍♀️", - ["woman_gesturing_ok_light_skin_tone"] = "🙆🏻‍♀️", - ["woman_gesturing_ok_tone2"] = "🙆🏼‍♀️", - ["woman_gesturing_ok_medium_light_skin_tone"] = "🙆🏼‍♀️", - ["woman_gesturing_ok_tone3"] = "🙆🏽‍♀️", - ["woman_gesturing_ok_medium_skin_tone"] = "🙆🏽‍♀️", - ["woman_gesturing_ok_tone4"] = "🙆🏾‍♀️", - ["woman_gesturing_ok_medium_dark_skin_tone"] = "🙆🏾‍♀️", - ["woman_gesturing_ok_tone5"] = "🙆🏿‍♀️", - ["woman_gesturing_ok_dark_skin_tone"] = "🙆🏿‍♀️", - ["man_gesturing_ok"] = "🙆‍♂️", - ["man_gesturing_ok_tone1"] = "🙆🏻‍♂️", - ["man_gesturing_ok_light_skin_tone"] = "🙆🏻‍♂️", - ["man_gesturing_ok_tone2"] = "🙆🏼‍♂️", - ["man_gesturing_ok_medium_light_skin_tone"] = "🙆🏼‍♂️", - ["man_gesturing_ok_tone3"] = "🙆🏽‍♂️", - ["man_gesturing_ok_medium_skin_tone"] = "🙆🏽‍♂️", - ["man_gesturing_ok_tone4"] = "🙆🏾‍♂️", - ["man_gesturing_ok_medium_dark_skin_tone"] = "🙆🏾‍♂️", - ["man_gesturing_ok_tone5"] = "🙆🏿‍♂️", - ["man_gesturing_ok_dark_skin_tone"] = "🙆🏿‍♂️", - ["person_raising_hand"] = "🙋", - ["raising_hand"] = "🙋", - ["person_raising_hand_tone1"] = "🙋🏻", - ["raising_hand_tone1"] = "🙋🏻", - ["person_raising_hand_tone2"] = "🙋🏼", - ["raising_hand_tone2"] = "🙋🏼", - ["person_raising_hand_tone3"] = "🙋🏽", - ["raising_hand_tone3"] = "🙋🏽", - ["person_raising_hand_tone4"] = "🙋🏾", - ["raising_hand_tone4"] = "🙋🏾", - ["person_raising_hand_tone5"] = "🙋🏿", - ["raising_hand_tone5"] = "🙋🏿", - ["woman_raising_hand"] = "🙋‍♀️", - ["woman_raising_hand_tone1"] = "🙋🏻‍♀️", - ["woman_raising_hand_light_skin_tone"] = "🙋🏻‍♀️", - ["woman_raising_hand_tone2"] = "🙋🏼‍♀️", - ["woman_raising_hand_medium_light_skin_tone"] = "🙋🏼‍♀️", - ["woman_raising_hand_tone3"] = "🙋🏽‍♀️", - ["woman_raising_hand_medium_skin_tone"] = "🙋🏽‍♀️", - ["woman_raising_hand_tone4"] = "🙋🏾‍♀️", - ["woman_raising_hand_medium_dark_skin_tone"] = "🙋🏾‍♀️", - ["woman_raising_hand_tone5"] = "🙋🏿‍♀️", - ["woman_raising_hand_dark_skin_tone"] = "🙋🏿‍♀️", - ["man_raising_hand"] = "🙋‍♂️", - ["man_raising_hand_tone1"] = "🙋🏻‍♂️", - ["man_raising_hand_light_skin_tone"] = "🙋🏻‍♂️", - ["man_raising_hand_tone2"] = "🙋🏼‍♂️", - ["man_raising_hand_medium_light_skin_tone"] = "🙋🏼‍♂️", - ["man_raising_hand_tone3"] = "🙋🏽‍♂️", - ["man_raising_hand_medium_skin_tone"] = "🙋🏽‍♂️", - ["man_raising_hand_tone4"] = "🙋🏾‍♂️", - ["man_raising_hand_medium_dark_skin_tone"] = "🙋🏾‍♂️", - ["man_raising_hand_tone5"] = "🙋🏿‍♂️", - ["man_raising_hand_dark_skin_tone"] = "🙋🏿‍♂️", - ["deaf_person"] = "🧏", - ["deaf_person_tone1"] = "🧏🏻", - ["deaf_person_light_skin_tone"] = "🧏🏻", - ["deaf_person_tone2"] = "🧏🏼", - ["deaf_person_medium_light_skin_tone"] = "🧏🏼", - ["deaf_person_tone3"] = "🧏🏽", - ["deaf_person_medium_skin_tone"] = "🧏🏽", - ["deaf_person_tone4"] = "🧏🏾", - ["deaf_person_medium_dark_skin_tone"] = "🧏🏾", - ["deaf_person_tone5"] = "🧏🏿", - ["deaf_person_dark_skin_tone"] = "🧏🏿", - ["deaf_woman"] = "🧏‍♀️", - ["deaf_woman_tone1"] = "🧏🏻‍♀️", - ["deaf_woman_light_skin_tone"] = "🧏🏻‍♀️", - ["deaf_woman_tone2"] = "🧏🏼‍♀️", - ["deaf_woman_medium_light_skin_tone"] = "🧏🏼‍♀️", - ["deaf_woman_tone3"] = "🧏🏽‍♀️", - ["deaf_woman_medium_skin_tone"] = "🧏🏽‍♀️", - ["deaf_woman_tone4"] = "🧏🏾‍♀️", - ["deaf_woman_medium_dark_skin_tone"] = "🧏🏾‍♀️", - ["deaf_woman_tone5"] = "🧏🏿‍♀️", - ["deaf_woman_dark_skin_tone"] = "🧏🏿‍♀️", - ["deaf_man"] = "🧏‍♂️", - ["deaf_man_tone1"] = "🧏🏻‍♂️", - ["deaf_man_light_skin_tone"] = "🧏🏻‍♂️", - ["deaf_man_tone2"] = "🧏🏼‍♂️", - ["deaf_man_medium_light_skin_tone"] = "🧏🏼‍♂️", - ["deaf_man_tone3"] = "🧏🏽‍♂️", - ["deaf_man_medium_skin_tone"] = "🧏🏽‍♂️", - ["deaf_man_tone4"] = "🧏🏾‍♂️", - ["deaf_man_medium_dark_skin_tone"] = "🧏🏾‍♂️", - ["deaf_man_tone5"] = "🧏🏿‍♂️", - ["deaf_man_dark_skin_tone"] = "🧏🏿‍♂️", - ["person_facepalming"] = "🤦", - ["face_palm"] = "🤦", - ["facepalm"] = "🤦", - ["person_facepalming_tone1"] = "🤦🏻", - ["face_palm_tone1"] = "🤦🏻", - ["facepalm_tone1"] = "🤦🏻", - ["person_facepalming_tone2"] = "🤦🏼", - ["face_palm_tone2"] = "🤦🏼", - ["facepalm_tone2"] = "🤦🏼", - ["person_facepalming_tone3"] = "🤦🏽", - ["face_palm_tone3"] = "🤦🏽", - ["facepalm_tone3"] = "🤦🏽", - ["person_facepalming_tone4"] = "🤦🏾", - ["face_palm_tone4"] = "🤦🏾", - ["facepalm_tone4"] = "🤦🏾", - ["person_facepalming_tone5"] = "🤦🏿", - ["face_palm_tone5"] = "🤦🏿", - ["facepalm_tone5"] = "🤦🏿", - ["woman_facepalming"] = "🤦‍♀️", - ["woman_facepalming_tone1"] = "🤦🏻‍♀️", - ["woman_facepalming_light_skin_tone"] = "🤦🏻‍♀️", - ["woman_facepalming_tone2"] = "🤦🏼‍♀️", - ["woman_facepalming_medium_light_skin_tone"] = "🤦🏼‍♀️", - ["woman_facepalming_tone3"] = "🤦🏽‍♀️", - ["woman_facepalming_medium_skin_tone"] = "🤦🏽‍♀️", - ["woman_facepalming_tone4"] = "🤦🏾‍♀️", - ["woman_facepalming_medium_dark_skin_tone"] = "🤦🏾‍♀️", - ["woman_facepalming_tone5"] = "🤦🏿‍♀️", - ["woman_facepalming_dark_skin_tone"] = "🤦🏿‍♀️", - ["man_facepalming"] = "🤦‍♂️", - ["man_facepalming_tone1"] = "🤦🏻‍♂️", - ["man_facepalming_light_skin_tone"] = "🤦🏻‍♂️", - ["man_facepalming_tone2"] = "🤦🏼‍♂️", - ["man_facepalming_medium_light_skin_tone"] = "🤦🏼‍♂️", - ["man_facepalming_tone3"] = "🤦🏽‍♂️", - ["man_facepalming_medium_skin_tone"] = "🤦🏽‍♂️", - ["man_facepalming_tone4"] = "🤦🏾‍♂️", - ["man_facepalming_medium_dark_skin_tone"] = "🤦🏾‍♂️", - ["man_facepalming_tone5"] = "🤦🏿‍♂️", - ["man_facepalming_dark_skin_tone"] = "🤦🏿‍♂️", - ["person_shrugging"] = "🤷", - ["shrug"] = "🤷", - ["person_shrugging_tone1"] = "🤷🏻", - ["shrug_tone1"] = "🤷🏻", - ["person_shrugging_tone2"] = "🤷🏼", - ["shrug_tone2"] = "🤷🏼", - ["person_shrugging_tone3"] = "🤷🏽", - ["shrug_tone3"] = "🤷🏽", - ["person_shrugging_tone4"] = "🤷🏾", - ["shrug_tone4"] = "🤷🏾", - ["person_shrugging_tone5"] = "🤷🏿", - ["shrug_tone5"] = "🤷🏿", - ["woman_shrugging"] = "🤷‍♀️", - ["woman_shrugging_tone1"] = "🤷🏻‍♀️", - ["woman_shrugging_light_skin_tone"] = "🤷🏻‍♀️", - ["woman_shrugging_tone2"] = "🤷🏼‍♀️", - ["woman_shrugging_medium_light_skin_tone"] = "🤷🏼‍♀️", - ["woman_shrugging_tone3"] = "🤷🏽‍♀️", - ["woman_shrugging_medium_skin_tone"] = "🤷🏽‍♀️", - ["woman_shrugging_tone4"] = "🤷🏾‍♀️", - ["woman_shrugging_medium_dark_skin_tone"] = "🤷🏾‍♀️", - ["woman_shrugging_tone5"] = "🤷🏿‍♀️", - ["woman_shrugging_dark_skin_tone"] = "🤷🏿‍♀️", - ["man_shrugging"] = "🤷‍♂️", - ["man_shrugging_tone1"] = "🤷🏻‍♂️", - ["man_shrugging_light_skin_tone"] = "🤷🏻‍♂️", - ["man_shrugging_tone2"] = "🤷🏼‍♂️", - ["man_shrugging_medium_light_skin_tone"] = "🤷🏼‍♂️", - ["man_shrugging_tone3"] = "🤷🏽‍♂️", - ["man_shrugging_medium_skin_tone"] = "🤷🏽‍♂️", - ["man_shrugging_tone4"] = "🤷🏾‍♂️", - ["man_shrugging_medium_dark_skin_tone"] = "🤷🏾‍♂️", - ["man_shrugging_tone5"] = "🤷🏿‍♂️", - ["man_shrugging_dark_skin_tone"] = "🤷🏿‍♂️", - ["person_pouting"] = "🙎", - ["person_with_pouting_face"] = "🙎", - ["person_pouting_tone1"] = "🙎🏻", - ["person_with_pouting_face_tone1"] = "🙎🏻", - ["person_pouting_tone2"] = "🙎🏼", - ["person_with_pouting_face_tone2"] = "🙎🏼", - ["person_pouting_tone3"] = "🙎🏽", - ["person_with_pouting_face_tone3"] = "🙎🏽", - ["person_pouting_tone4"] = "🙎🏾", - ["person_with_pouting_face_tone4"] = "🙎🏾", - ["person_pouting_tone5"] = "🙎🏿", - ["person_with_pouting_face_tone5"] = "🙎🏿", - ["woman_pouting"] = "🙎‍♀️", - ["woman_pouting_tone1"] = "🙎🏻‍♀️", - ["woman_pouting_light_skin_tone"] = "🙎🏻‍♀️", - ["woman_pouting_tone2"] = "🙎🏼‍♀️", - ["woman_pouting_medium_light_skin_tone"] = "🙎🏼‍♀️", - ["woman_pouting_tone3"] = "🙎🏽‍♀️", - ["woman_pouting_medium_skin_tone"] = "🙎🏽‍♀️", - ["woman_pouting_tone4"] = "🙎🏾‍♀️", - ["woman_pouting_medium_dark_skin_tone"] = "🙎🏾‍♀️", - ["woman_pouting_tone5"] = "🙎🏿‍♀️", - ["woman_pouting_dark_skin_tone"] = "🙎🏿‍♀️", - ["man_pouting"] = "🙎‍♂️", - ["man_pouting_tone1"] = "🙎🏻‍♂️", - ["man_pouting_light_skin_tone"] = "🙎🏻‍♂️", - ["man_pouting_tone2"] = "🙎🏼‍♂️", - ["man_pouting_medium_light_skin_tone"] = "🙎🏼‍♂️", - ["man_pouting_tone3"] = "🙎🏽‍♂️", - ["man_pouting_medium_skin_tone"] = "🙎🏽‍♂️", - ["man_pouting_tone4"] = "🙎🏾‍♂️", - ["man_pouting_medium_dark_skin_tone"] = "🙎🏾‍♂️", - ["man_pouting_tone5"] = "🙎🏿‍♂️", - ["man_pouting_dark_skin_tone"] = "🙎🏿‍♂️", - ["person_frowning"] = "🙍", - ["person_frowning_tone1"] = "🙍🏻", - ["person_frowning_tone2"] = "🙍🏼", - ["person_frowning_tone3"] = "🙍🏽", - ["person_frowning_tone4"] = "🙍🏾", - ["person_frowning_tone5"] = "🙍🏿", - ["woman_frowning"] = "🙍‍♀️", - ["woman_frowning_tone1"] = "🙍🏻‍♀️", - ["woman_frowning_light_skin_tone"] = "🙍🏻‍♀️", - ["woman_frowning_tone2"] = "🙍🏼‍♀️", - ["woman_frowning_medium_light_skin_tone"] = "🙍🏼‍♀️", - ["woman_frowning_tone3"] = "🙍🏽‍♀️", - ["woman_frowning_medium_skin_tone"] = "🙍🏽‍♀️", - ["woman_frowning_tone4"] = "🙍🏾‍♀️", - ["woman_frowning_medium_dark_skin_tone"] = "🙍🏾‍♀️", - ["woman_frowning_tone5"] = "🙍🏿‍♀️", - ["woman_frowning_dark_skin_tone"] = "🙍🏿‍♀️", - ["man_frowning"] = "🙍‍♂️", - ["man_frowning_tone1"] = "🙍🏻‍♂️", - ["man_frowning_light_skin_tone"] = "🙍🏻‍♂️", - ["man_frowning_tone2"] = "🙍🏼‍♂️", - ["man_frowning_medium_light_skin_tone"] = "🙍🏼‍♂️", - ["man_frowning_tone3"] = "🙍🏽‍♂️", - ["man_frowning_medium_skin_tone"] = "🙍🏽‍♂️", - ["man_frowning_tone4"] = "🙍🏾‍♂️", - ["man_frowning_medium_dark_skin_tone"] = "🙍🏾‍♂️", - ["man_frowning_tone5"] = "🙍🏿‍♂️", - ["man_frowning_dark_skin_tone"] = "🙍🏿‍♂️", - ["person_getting_haircut"] = "💇", - ["haircut"] = "💇", - ["person_getting_haircut_tone1"] = "💇🏻", - ["haircut_tone1"] = "💇🏻", - ["person_getting_haircut_tone2"] = "💇🏼", - ["haircut_tone2"] = "💇🏼", - ["person_getting_haircut_tone3"] = "💇🏽", - ["haircut_tone3"] = "💇🏽", - ["person_getting_haircut_tone4"] = "💇🏾", - ["haircut_tone4"] = "💇🏾", - ["person_getting_haircut_tone5"] = "💇🏿", - ["haircut_tone5"] = "💇🏿", - ["woman_getting_haircut"] = "💇‍♀️", - ["woman_getting_haircut_tone1"] = "💇🏻‍♀️", - ["woman_getting_haircut_light_skin_tone"] = "💇🏻‍♀️", - ["woman_getting_haircut_tone2"] = "💇🏼‍♀️", - ["woman_getting_haircut_medium_light_skin_tone"] = "💇🏼‍♀️", - ["woman_getting_haircut_tone3"] = "💇🏽‍♀️", - ["woman_getting_haircut_medium_skin_tone"] = "💇🏽‍♀️", - ["woman_getting_haircut_tone4"] = "💇🏾‍♀️", - ["woman_getting_haircut_medium_dark_skin_tone"] = "💇🏾‍♀️", - ["woman_getting_haircut_tone5"] = "💇🏿‍♀️", - ["woman_getting_haircut_dark_skin_tone"] = "💇🏿‍♀️", - ["man_getting_haircut"] = "💇‍♂️", - ["man_getting_haircut_tone1"] = "💇🏻‍♂️", - ["man_getting_haircut_light_skin_tone"] = "💇🏻‍♂️", - ["man_getting_haircut_tone2"] = "💇🏼‍♂️", - ["man_getting_haircut_medium_light_skin_tone"] = "💇🏼‍♂️", - ["man_getting_haircut_tone3"] = "💇🏽‍♂️", - ["man_getting_haircut_medium_skin_tone"] = "💇🏽‍♂️", - ["man_getting_haircut_tone4"] = "💇🏾‍♂️", - ["man_getting_haircut_medium_dark_skin_tone"] = "💇🏾‍♂️", - ["man_getting_haircut_tone5"] = "💇🏿‍♂️", - ["man_getting_haircut_dark_skin_tone"] = "💇🏿‍♂️", - ["person_getting_massage"] = "💆", - ["massage"] = "💆", - ["person_getting_massage_tone1"] = "💆🏻", - ["massage_tone1"] = "💆🏻", - ["person_getting_massage_tone2"] = "💆🏼", - ["massage_tone2"] = "💆🏼", - ["person_getting_massage_tone3"] = "💆🏽", - ["massage_tone3"] = "💆🏽", - ["person_getting_massage_tone4"] = "💆🏾", - ["massage_tone4"] = "💆🏾", - ["person_getting_massage_tone5"] = "💆🏿", - ["massage_tone5"] = "💆🏿", - ["woman_getting_face_massage"] = "💆‍♀️", - ["woman_getting_face_massage_tone1"] = "💆🏻‍♀️", - ["woman_getting_face_massage_light_skin_tone"] = "💆🏻‍♀️", - ["woman_getting_face_massage_tone2"] = "💆🏼‍♀️", - ["woman_getting_face_massage_medium_light_skin_tone"] = "💆🏼‍♀️", - ["woman_getting_face_massage_tone3"] = "💆🏽‍♀️", - ["woman_getting_face_massage_medium_skin_tone"] = "💆🏽‍♀️", - ["woman_getting_face_massage_tone4"] = "💆🏾‍♀️", - ["woman_getting_face_massage_medium_dark_skin_tone"] = "💆🏾‍♀️", - ["woman_getting_face_massage_tone5"] = "💆🏿‍♀️", - ["woman_getting_face_massage_dark_skin_tone"] = "💆🏿‍♀️", - ["man_getting_face_massage"] = "💆‍♂️", - ["man_getting_face_massage_tone1"] = "💆🏻‍♂️", - ["man_getting_face_massage_light_skin_tone"] = "💆🏻‍♂️", - ["man_getting_face_massage_tone2"] = "💆🏼‍♂️", - ["man_getting_face_massage_medium_light_skin_tone"] = "💆🏼‍♂️", - ["man_getting_face_massage_tone3"] = "💆🏽‍♂️", - ["man_getting_face_massage_medium_skin_tone"] = "💆🏽‍♂️", - ["man_getting_face_massage_tone4"] = "💆🏾‍♂️", - ["man_getting_face_massage_medium_dark_skin_tone"] = "💆🏾‍♂️", - ["man_getting_face_massage_tone5"] = "💆🏿‍♂️", - ["man_getting_face_massage_dark_skin_tone"] = "💆🏿‍♂️", - ["person_in_steamy_room"] = "🧖", - ["person_in_steamy_room_tone1"] = "🧖🏻", - ["person_in_steamy_room_light_skin_tone"] = "🧖🏻", - ["person_in_steamy_room_tone2"] = "🧖🏼", - ["person_in_steamy_room_medium_light_skin_tone"] = "🧖🏼", - ["person_in_steamy_room_tone3"] = "🧖🏽", - ["person_in_steamy_room_medium_skin_tone"] = "🧖🏽", - ["person_in_steamy_room_tone4"] = "🧖🏾", - ["person_in_steamy_room_medium_dark_skin_tone"] = "🧖🏾", - ["person_in_steamy_room_tone5"] = "🧖🏿", - ["person_in_steamy_room_dark_skin_tone"] = "🧖🏿", - ["woman_in_steamy_room"] = "🧖‍♀️", - ["woman_in_steamy_room_tone1"] = "🧖🏻‍♀️", - ["woman_in_steamy_room_light_skin_tone"] = "🧖🏻‍♀️", - ["woman_in_steamy_room_tone2"] = "🧖🏼‍♀️", - ["woman_in_steamy_room_medium_light_skin_tone"] = "🧖🏼‍♀️", - ["woman_in_steamy_room_tone3"] = "🧖🏽‍♀️", - ["woman_in_steamy_room_medium_skin_tone"] = "🧖🏽‍♀️", - ["woman_in_steamy_room_tone4"] = "🧖🏾‍♀️", - ["woman_in_steamy_room_medium_dark_skin_tone"] = "🧖🏾‍♀️", - ["woman_in_steamy_room_tone5"] = "🧖🏿‍♀️", - ["woman_in_steamy_room_dark_skin_tone"] = "🧖🏿‍♀️", - ["man_in_steamy_room"] = "🧖‍♂️", - ["man_in_steamy_room_tone1"] = "🧖🏻‍♂️", - ["man_in_steamy_room_light_skin_tone"] = "🧖🏻‍♂️", - ["man_in_steamy_room_tone2"] = "🧖🏼‍♂️", - ["man_in_steamy_room_medium_light_skin_tone"] = "🧖🏼‍♂️", - ["man_in_steamy_room_tone3"] = "🧖🏽‍♂️", - ["man_in_steamy_room_medium_skin_tone"] = "🧖🏽‍♂️", - ["man_in_steamy_room_tone4"] = "🧖🏾‍♂️", - ["man_in_steamy_room_medium_dark_skin_tone"] = "🧖🏾‍♂️", - ["man_in_steamy_room_tone5"] = "🧖🏿‍♂️", - ["man_in_steamy_room_dark_skin_tone"] = "🧖🏿‍♂️", - ["nail_care"] = "💅", - ["nail_care_tone1"] = "💅🏻", - ["nail_care_tone2"] = "💅🏼", - ["nail_care_tone3"] = "💅🏽", - ["nail_care_tone4"] = "💅🏾", - ["nail_care_tone5"] = "💅🏿", - ["selfie"] = "🤳", - ["selfie_tone1"] = "🤳🏻", - ["selfie_tone2"] = "🤳🏼", - ["selfie_tone3"] = "🤳🏽", - ["selfie_tone4"] = "🤳🏾", - ["selfie_tone5"] = "🤳🏿", - ["dancer"] = "💃", - ["dancer_tone1"] = "💃🏻", - ["dancer_tone2"] = "💃🏼", - ["dancer_tone3"] = "💃🏽", - ["dancer_tone4"] = "💃🏾", - ["dancer_tone5"] = "💃🏿", - ["man_dancing"] = "🕺", - ["male_dancer"] = "🕺", - ["man_dancing_tone1"] = "🕺🏻", - ["male_dancer_tone1"] = "🕺🏻", - ["man_dancing_tone2"] = "🕺🏼", - ["male_dancer_tone2"] = "🕺🏼", - ["man_dancing_tone3"] = "🕺🏽", - ["male_dancer_tone3"] = "🕺🏽", - ["man_dancing_tone5"] = "🕺🏿", - ["male_dancer_tone5"] = "🕺🏿", - ["man_dancing_tone4"] = "🕺🏾", - ["male_dancer_tone4"] = "🕺🏾", - ["people_with_bunny_ears_partying"] = "👯", - ["dancers"] = "👯", - ["women_with_bunny_ears_partying"] = "👯‍♀️", - ["men_with_bunny_ears_partying"] = "👯‍♂️", - ["levitate"] = "🕴️", - ["man_in_business_suit_levitating"] = "🕴️", - ["levitate_tone1"] = "🕴🏻", - ["man_in_business_suit_levitating_tone1"] = "🕴🏻", - ["man_in_business_suit_levitating_light_skin_tone"] = "🕴🏻", - ["levitate_tone2"] = "🕴🏼", - ["man_in_business_suit_levitating_tone2"] = "🕴🏼", - ["man_in_business_suit_levitating_medium_light_skin_tone"] = "🕴🏼", - ["levitate_tone3"] = "🕴🏽", - ["man_in_business_suit_levitating_tone3"] = "🕴🏽", - ["man_in_business_suit_levitating_medium_skin_tone"] = "🕴🏽", - ["levitate_tone4"] = "🕴🏾", - ["man_in_business_suit_levitating_tone4"] = "🕴🏾", - ["man_in_business_suit_levitating_medium_dark_skin_tone"] = "🕴🏾", - ["levitate_tone5"] = "🕴🏿", - ["man_in_business_suit_levitating_tone5"] = "🕴🏿", - ["man_in_business_suit_levitating_dark_skin_tone"] = "🕴🏿", - ["person_in_manual_wheelchair"] = "🧑‍🦽", - ["person_in_manual_wheelchair_tone1"] = "🧑🏻‍🦽", - ["person_in_manual_wheelchair_light_skin_tone"] = "🧑🏻‍🦽", - ["person_in_manual_wheelchair_tone2"] = "🧑🏼‍🦽", - ["person_in_manual_wheelchair_medium_light_skin_tone"] = "🧑🏼‍🦽", - ["person_in_manual_wheelchair_tone3"] = "🧑🏽‍🦽", - ["person_in_manual_wheelchair_medium_skin_tone"] = "🧑🏽‍🦽", - ["person_in_manual_wheelchair_tone4"] = "🧑🏾‍🦽", - ["person_in_manual_wheelchair_medium_dark_skin_tone"] = "🧑🏾‍🦽", - ["person_in_manual_wheelchair_tone5"] = "🧑🏿‍🦽", - ["person_in_manual_wheelchair_dark_skin_tone"] = "🧑🏿‍🦽", - ["woman_in_manual_wheelchair"] = "👩‍🦽", - ["woman_in_manual_wheelchair_tone1"] = "👩🏻‍🦽", - ["woman_in_manual_wheelchair_light_skin_tone"] = "👩🏻‍🦽", - ["woman_in_manual_wheelchair_tone2"] = "👩🏼‍🦽", - ["woman_in_manual_wheelchair_medium_light_skin_tone"] = "👩🏼‍🦽", - ["woman_in_manual_wheelchair_tone3"] = "👩🏽‍🦽", - ["woman_in_manual_wheelchair_medium_skin_tone"] = "👩🏽‍🦽", - ["woman_in_manual_wheelchair_tone4"] = "👩🏾‍🦽", - ["woman_in_manual_wheelchair_medium_dark_skin_tone"] = "👩🏾‍🦽", - ["woman_in_manual_wheelchair_tone5"] = "👩🏿‍🦽", - ["woman_in_manual_wheelchair_dark_skin_tone"] = "👩🏿‍🦽", - ["man_in_manual_wheelchair"] = "👨‍🦽", - ["man_in_manual_wheelchair_tone1"] = "👨🏻‍🦽", - ["man_in_manual_wheelchair_light_skin_tone"] = "👨🏻‍🦽", - ["man_in_manual_wheelchair_tone2"] = "👨🏼‍🦽", - ["man_in_manual_wheelchair_medium_light_skin_tone"] = "👨🏼‍🦽", - ["man_in_manual_wheelchair_tone3"] = "👨🏽‍🦽", - ["man_in_manual_wheelchair_medium_skin_tone"] = "👨🏽‍🦽", - ["man_in_manual_wheelchair_tone4"] = "👨🏾‍🦽", - ["man_in_manual_wheelchair_medium_dark_skin_tone"] = "👨🏾‍🦽", - ["man_in_manual_wheelchair_tone5"] = "👨🏿‍🦽", - ["man_in_manual_wheelchair_dark_skin_tone"] = "👨🏿‍🦽", - ["person_in_motorized_wheelchair"] = "🧑‍🦼", - ["person_in_motorized_wheelchair_tone1"] = "🧑🏻‍🦼", - ["person_in_motorized_wheelchair_light_skin_tone"] = "🧑🏻‍🦼", - ["person_in_motorized_wheelchair_tone2"] = "🧑🏼‍🦼", - ["person_in_motorized_wheelchair_medium_light_skin_tone"] = "🧑🏼‍🦼", - ["person_in_motorized_wheelchair_tone3"] = "🧑🏽‍🦼", - ["person_in_motorized_wheelchair_medium_skin_tone"] = "🧑🏽‍🦼", - ["person_in_motorized_wheelchair_tone4"] = "🧑🏾‍🦼", - ["person_in_motorized_wheelchair_medium_dark_skin_tone"] = "🧑🏾‍🦼", - ["person_in_motorized_wheelchair_tone5"] = "🧑🏿‍🦼", - ["person_in_motorized_wheelchair_dark_skin_tone"] = "🧑🏿‍🦼", - ["woman_in_motorized_wheelchair"] = "👩‍🦼", - ["woman_in_motorized_wheelchair_tone1"] = "👩🏻‍🦼", - ["woman_in_motorized_wheelchair_light_skin_tone"] = "👩🏻‍🦼", - ["woman_in_motorized_wheelchair_tone2"] = "👩🏼‍🦼", - ["woman_in_motorized_wheelchair_medium_light_skin_tone"] = "👩🏼‍🦼", - ["woman_in_motorized_wheelchair_tone3"] = "👩🏽‍🦼", - ["woman_in_motorized_wheelchair_medium_skin_tone"] = "👩🏽‍🦼", - ["woman_in_motorized_wheelchair_tone4"] = "👩🏾‍🦼", - ["woman_in_motorized_wheelchair_medium_dark_skin_tone"] = "👩🏾‍🦼", - ["woman_in_motorized_wheelchair_tone5"] = "👩🏿‍🦼", - ["woman_in_motorized_wheelchair_dark_skin_tone"] = "👩🏿‍🦼", - ["man_in_motorized_wheelchair"] = "👨‍🦼", - ["man_in_motorized_wheelchair_tone1"] = "👨🏻‍🦼", - ["man_in_motorized_wheelchair_light_skin_tone"] = "👨🏻‍🦼", - ["man_in_motorized_wheelchair_tone2"] = "👨🏼‍🦼", - ["man_in_motorized_wheelchair_medium_light_skin_tone"] = "👨🏼‍🦼", - ["man_in_motorized_wheelchair_tone3"] = "👨🏽‍🦼", - ["man_in_motorized_wheelchair_medium_skin_tone"] = "👨🏽‍🦼", - ["man_in_motorized_wheelchair_tone4"] = "👨🏾‍🦼", - ["man_in_motorized_wheelchair_medium_dark_skin_tone"] = "👨🏾‍🦼", - ["man_in_motorized_wheelchair_tone5"] = "👨🏿‍🦼", - ["man_in_motorized_wheelchair_dark_skin_tone"] = "👨🏿‍🦼", - ["person_walking"] = "🚶", - ["walking"] = "🚶", - ["person_walking_tone1"] = "🚶🏻", - ["walking_tone1"] = "🚶🏻", - ["person_walking_tone2"] = "🚶🏼", - ["walking_tone2"] = "🚶🏼", - ["person_walking_tone3"] = "🚶🏽", - ["walking_tone3"] = "🚶🏽", - ["person_walking_tone4"] = "🚶🏾", - ["walking_tone4"] = "🚶🏾", - ["person_walking_tone5"] = "🚶🏿", - ["walking_tone5"] = "🚶🏿", - ["woman_walking"] = "🚶‍♀️", - ["woman_walking_tone1"] = "🚶🏻‍♀️", - ["woman_walking_light_skin_tone"] = "🚶🏻‍♀️", - ["woman_walking_tone2"] = "🚶🏼‍♀️", - ["woman_walking_medium_light_skin_tone"] = "🚶🏼‍♀️", - ["woman_walking_tone3"] = "🚶🏽‍♀️", - ["woman_walking_medium_skin_tone"] = "🚶🏽‍♀️", - ["woman_walking_tone4"] = "🚶🏾‍♀️", - ["woman_walking_medium_dark_skin_tone"] = "🚶🏾‍♀️", - ["woman_walking_tone5"] = "🚶🏿‍♀️", - ["woman_walking_dark_skin_tone"] = "🚶🏿‍♀️", - ["man_walking"] = "🚶‍♂️", - ["man_walking_tone1"] = "🚶🏻‍♂️", - ["man_walking_light_skin_tone"] = "🚶🏻‍♂️", - ["man_walking_tone2"] = "🚶🏼‍♂️", - ["man_walking_medium_light_skin_tone"] = "🚶🏼‍♂️", - ["man_walking_tone3"] = "🚶🏽‍♂️", - ["man_walking_medium_skin_tone"] = "🚶🏽‍♂️", - ["man_walking_tone4"] = "🚶🏾‍♂️", - ["man_walking_medium_dark_skin_tone"] = "🚶🏾‍♂️", - ["man_walking_tone5"] = "🚶🏿‍♂️", - ["man_walking_dark_skin_tone"] = "🚶🏿‍♂️", - ["person_with_probing_cane"] = "🧑‍🦯", - ["person_with_probing_cane_tone1"] = "🧑🏻‍🦯", - ["person_with_probing_cane_light_skin_tone"] = "🧑🏻‍🦯", - ["person_with_probing_cane_tone2"] = "🧑🏼‍🦯", - ["person_with_probing_cane_medium_light_skin_tone"] = "🧑🏼‍🦯", - ["person_with_probing_cane_tone3"] = "🧑🏽‍🦯", - ["person_with_probing_cane_medium_skin_tone"] = "🧑🏽‍🦯", - ["person_with_probing_cane_tone4"] = "🧑🏾‍🦯", - ["person_with_probing_cane_medium_dark_skin_tone"] = "🧑🏾‍🦯", - ["person_with_probing_cane_tone5"] = "🧑🏿‍🦯", - ["person_with_probing_cane_dark_skin_tone"] = "🧑🏿‍🦯", - ["woman_with_probing_cane"] = "👩‍🦯", - ["woman_with_probing_cane_tone1"] = "👩🏻‍🦯", - ["woman_with_probing_cane_light_skin_tone"] = "👩🏻‍🦯", - ["woman_with_probing_cane_tone2"] = "👩🏼‍🦯", - ["woman_with_probing_cane_medium_light_skin_tone"] = "👩🏼‍🦯", - ["woman_with_probing_cane_tone3"] = "👩🏽‍🦯", - ["woman_with_probing_cane_medium_skin_tone"] = "👩🏽‍🦯", - ["woman_with_probing_cane_tone4"] = "👩🏾‍🦯", - ["woman_with_probing_cane_medium_dark_skin_tone"] = "👩🏾‍🦯", - ["woman_with_probing_cane_tone5"] = "👩🏿‍🦯", - ["woman_with_probing_cane_dark_skin_tone"] = "👩🏿‍🦯", - ["man_with_probing_cane"] = "👨‍🦯", - ["man_with_probing_cane_tone1"] = "👨🏻‍🦯", - ["man_with_probing_cane_light_skin_tone"] = "👨🏻‍🦯", - ["man_with_probing_cane_tone3"] = "👨🏽‍🦯", - ["man_with_probing_cane_medium_skin_tone"] = "👨🏽‍🦯", - ["man_with_probing_cane_tone2"] = "👨🏼‍🦯", - ["man_with_probing_cane_medium_light_skin_tone"] = "👨🏼‍🦯", - ["man_with_probing_cane_tone4"] = "👨🏾‍🦯", - ["man_with_probing_cane_medium_dark_skin_tone"] = "👨🏾‍🦯", - ["man_with_probing_cane_tone5"] = "👨🏿‍🦯", - ["man_with_probing_cane_dark_skin_tone"] = "👨🏿‍🦯", - ["person_kneeling"] = "🧎", - ["person_kneeling_tone1"] = "🧎🏻", - ["person_kneeling_light_skin_tone"] = "🧎🏻", - ["person_kneeling_tone2"] = "🧎🏼", - ["person_kneeling_medium_light_skin_tone"] = "🧎🏼", - ["person_kneeling_tone3"] = "🧎🏽", - ["person_kneeling_medium_skin_tone"] = "🧎🏽", - ["person_kneeling_tone4"] = "🧎🏾", - ["person_kneeling_medium_dark_skin_tone"] = "🧎🏾", - ["person_kneeling_tone5"] = "🧎🏿", - ["person_kneeling_dark_skin_tone"] = "🧎🏿", - ["woman_kneeling"] = "🧎‍♀️", - ["woman_kneeling_tone1"] = "🧎🏻‍♀️", - ["woman_kneeling_light_skin_tone"] = "🧎🏻‍♀️", - ["woman_kneeling_tone2"] = "🧎🏼‍♀️", - ["woman_kneeling_medium_light_skin_tone"] = "🧎🏼‍♀️", - ["woman_kneeling_tone3"] = "🧎🏽‍♀️", - ["woman_kneeling_medium_skin_tone"] = "🧎🏽‍♀️", - ["woman_kneeling_tone4"] = "🧎🏾‍♀️", - ["woman_kneeling_medium_dark_skin_tone"] = "🧎🏾‍♀️", - ["woman_kneeling_tone5"] = "🧎🏿‍♀️", - ["woman_kneeling_dark_skin_tone"] = "🧎🏿‍♀️", - ["man_kneeling"] = "🧎‍♂️", - ["man_kneeling_tone1"] = "🧎🏻‍♂️", - ["man_kneeling_light_skin_tone"] = "🧎🏻‍♂️", - ["man_kneeling_tone2"] = "🧎🏼‍♂️", - ["man_kneeling_medium_light_skin_tone"] = "🧎🏼‍♂️", - ["man_kneeling_tone3"] = "🧎🏽‍♂️", - ["man_kneeling_medium_skin_tone"] = "🧎🏽‍♂️", - ["man_kneeling_tone4"] = "🧎🏾‍♂️", - ["man_kneeling_medium_dark_skin_tone"] = "🧎🏾‍♂️", - ["man_kneeling_tone5"] = "🧎🏿‍♂️", - ["man_kneeling_dark_skin_tone"] = "🧎🏿‍♂️", - ["person_running"] = "🏃", - ["runner"] = "🏃", - ["person_running_tone1"] = "🏃🏻", - ["runner_tone1"] = "🏃🏻", - ["person_running_tone2"] = "🏃🏼", - ["runner_tone2"] = "🏃🏼", - ["person_running_tone3"] = "🏃🏽", - ["runner_tone3"] = "🏃🏽", - ["person_running_tone4"] = "🏃🏾", - ["runner_tone4"] = "🏃🏾", - ["person_running_tone5"] = "🏃🏿", - ["runner_tone5"] = "🏃🏿", - ["woman_running"] = "🏃‍♀️", - ["woman_running_tone1"] = "🏃🏻‍♀️", - ["woman_running_light_skin_tone"] = "🏃🏻‍♀️", - ["woman_running_tone2"] = "🏃🏼‍♀️", - ["woman_running_medium_light_skin_tone"] = "🏃🏼‍♀️", - ["woman_running_tone3"] = "🏃🏽‍♀️", - ["woman_running_medium_skin_tone"] = "🏃🏽‍♀️", - ["woman_running_tone4"] = "🏃🏾‍♀️", - ["woman_running_medium_dark_skin_tone"] = "🏃🏾‍♀️", - ["woman_running_tone5"] = "🏃🏿‍♀️", - ["woman_running_dark_skin_tone"] = "🏃🏿‍♀️", - ["man_running"] = "🏃‍♂️", - ["man_running_tone1"] = "🏃🏻‍♂️", - ["man_running_light_skin_tone"] = "🏃🏻‍♂️", - ["man_running_tone2"] = "🏃🏼‍♂️", - ["man_running_medium_light_skin_tone"] = "🏃🏼‍♂️", - ["man_running_tone3"] = "🏃🏽‍♂️", - ["man_running_medium_skin_tone"] = "🏃🏽‍♂️", - ["man_running_tone4"] = "🏃🏾‍♂️", - ["man_running_medium_dark_skin_tone"] = "🏃🏾‍♂️", - ["man_running_tone5"] = "🏃🏿‍♂️", - ["man_running_dark_skin_tone"] = "🏃🏿‍♂️", - ["person_standing"] = "🧍", - ["person_standing_tone1"] = "🧍🏻", - ["person_standing_light_skin_tone"] = "🧍🏻", - ["person_standing_tone2"] = "🧍🏼", - ["person_standing_medium_light_skin_tone"] = "🧍🏼", - ["person_standing_tone3"] = "🧍🏽", - ["person_standing_medium_skin_tone"] = "🧍🏽", - ["person_standing_tone4"] = "🧍🏾", - ["person_standing_medium_dark_skin_tone"] = "🧍🏾", - ["person_standing_tone5"] = "🧍🏿", - ["person_standing_dark_skin_tone"] = "🧍🏿", - ["woman_standing"] = "🧍‍♀️", - ["woman_standing_tone1"] = "🧍🏻‍♀️", - ["woman_standing_light_skin_tone"] = "🧍🏻‍♀️", - ["woman_standing_tone2"] = "🧍🏼‍♀️", - ["woman_standing_medium_light_skin_tone"] = "🧍🏼‍♀️", - ["woman_standing_tone3"] = "🧍🏽‍♀️", - ["woman_standing_medium_skin_tone"] = "🧍🏽‍♀️", - ["woman_standing_tone4"] = "🧍🏾‍♀️", - ["woman_standing_medium_dark_skin_tone"] = "🧍🏾‍♀️", - ["woman_standing_tone5"] = "🧍🏿‍♀️", - ["woman_standing_dark_skin_tone"] = "🧍🏿‍♀️", - ["man_standing"] = "🧍‍♂️", - ["man_standing_tone1"] = "🧍🏻‍♂️", - ["man_standing_light_skin_tone"] = "🧍🏻‍♂️", - ["man_standing_tone2"] = "🧍🏼‍♂️", - ["man_standing_medium_light_skin_tone"] = "🧍🏼‍♂️", - ["man_standing_tone3"] = "🧍🏽‍♂️", - ["man_standing_medium_skin_tone"] = "🧍🏽‍♂️", - ["man_standing_tone4"] = "🧍🏾‍♂️", - ["man_standing_medium_dark_skin_tone"] = "🧍🏾‍♂️", - ["man_standing_tone5"] = "🧍🏿‍♂️", - ["man_standing_dark_skin_tone"] = "🧍🏿‍♂️", - ["people_holding_hands"] = "🧑‍🤝‍🧑", - ["people_holding_hands_tone1"] = "🧑🏻‍🤝‍🧑🏻", - ["people_holding_hands_light_skin_tone"] = "🧑🏻‍🤝‍🧑🏻", - ["people_holding_hands_tone1_tone2"] = "🧑🏻‍🤝‍🧑🏼", - ["people_holding_hands_light_skin_tone_medium_light_skin_tone"] = "🧑🏻‍🤝‍🧑🏼", - ["people_holding_hands_tone1_tone3"] = "🧑🏻‍🤝‍🧑🏽", - ["people_holding_hands_light_skin_tone_medium_skin_tone"] = "🧑🏻‍🤝‍🧑🏽", - ["people_holding_hands_tone1_tone4"] = "🧑🏻‍🤝‍🧑🏾", - ["people_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "🧑🏻‍🤝‍🧑🏾", - ["people_holding_hands_tone1_tone5"] = "🧑🏻‍🤝‍🧑🏿", - ["people_holding_hands_light_skin_tone_dark_skin_tone"] = "🧑🏻‍🤝‍🧑🏿", - ["people_holding_hands_tone2_tone1"] = "🧑🏼‍🤝‍🧑🏻", - ["people_holding_hands_medium_light_skin_tone_light_skin_tone"] = "🧑🏼‍🤝‍🧑🏻", - ["people_holding_hands_tone2"] = "🧑🏼‍🤝‍🧑🏼", - ["people_holding_hands_medium_light_skin_tone"] = "🧑🏼‍🤝‍🧑🏼", - ["people_holding_hands_tone2_tone3"] = "🧑🏼‍🤝‍🧑🏽", - ["people_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "🧑🏼‍🤝‍🧑🏽", - ["people_holding_hands_tone2_tone4"] = "🧑🏼‍🤝‍🧑🏾", - ["people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "🧑🏼‍🤝‍🧑🏾", - ["people_holding_hands_tone2_tone5"] = "🧑🏼‍🤝‍🧑🏿", - ["people_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "🧑🏼‍🤝‍🧑🏿", - ["people_holding_hands_tone3_tone1"] = "🧑🏽‍🤝‍🧑🏻", - ["people_holding_hands_medium_skin_tone_light_skin_tone"] = "🧑🏽‍🤝‍🧑🏻", - ["people_holding_hands_tone3_tone2"] = "🧑🏽‍🤝‍🧑🏼", - ["people_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "🧑🏽‍🤝‍🧑🏼", - ["people_holding_hands_tone3"] = "🧑🏽‍🤝‍🧑🏽", - ["people_holding_hands_medium_skin_tone"] = "🧑🏽‍🤝‍🧑🏽", - ["people_holding_hands_tone3_tone4"] = "🧑🏽‍🤝‍🧑🏾", - ["people_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "🧑🏽‍🤝‍🧑🏾", - ["people_holding_hands_tone3_tone5"] = "🧑🏽‍🤝‍🧑🏿", - ["people_holding_hands_medium_skin_tone_dark_skin_tone"] = "🧑🏽‍🤝‍🧑🏿", - ["people_holding_hands_tone4_tone1"] = "🧑🏾‍🤝‍🧑🏻", - ["people_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "🧑🏾‍🤝‍🧑🏻", - ["people_holding_hands_tone4_tone2"] = "🧑🏾‍🤝‍🧑🏼", - ["people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "🧑🏾‍🤝‍🧑🏼", - ["people_holding_hands_tone4_tone3"] = "🧑🏾‍🤝‍🧑🏽", - ["people_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "🧑🏾‍🤝‍🧑🏽", - ["people_holding_hands_tone4"] = "🧑🏾‍🤝‍🧑🏾", - ["people_holding_hands_medium_dark_skin_tone"] = "🧑🏾‍🤝‍🧑🏾", - ["people_holding_hands_tone4_tone5"] = "🧑🏾‍🤝‍🧑🏿", - ["people_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "🧑🏾‍🤝‍🧑🏿", - ["people_holding_hands_tone5_tone1"] = "🧑🏿‍🤝‍🧑🏻", - ["people_holding_hands_dark_skin_tone_light_skin_tone"] = "🧑🏿‍🤝‍🧑🏻", - ["people_holding_hands_tone5_tone2"] = "🧑🏿‍🤝‍🧑🏼", - ["people_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "🧑🏿‍🤝‍🧑🏼", - ["people_holding_hands_tone5_tone3"] = "🧑🏿‍🤝‍🧑🏽", - ["people_holding_hands_dark_skin_tone_medium_skin_tone"] = "🧑🏿‍🤝‍🧑🏽", - ["people_holding_hands_tone5_tone4"] = "🧑🏿‍🤝‍🧑🏾", - ["people_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "🧑🏿‍🤝‍🧑🏾", - ["people_holding_hands_tone5"] = "🧑🏿‍🤝‍🧑🏿", - ["people_holding_hands_dark_skin_tone"] = "🧑🏿‍🤝‍🧑🏿", - ["couple"] = "👫", - ["woman_and_man_holding_hands_tone1"] = "👫🏻", - ["woman_and_man_holding_hands_light_skin_tone"] = "👫🏻", - ["woman_and_man_holding_hands_tone1_tone2"] = "👩🏻‍🤝‍👨🏼", - ["woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍🤝‍👨🏼", - ["woman_and_man_holding_hands_tone1_tone3"] = "👩🏻‍🤝‍👨🏽", - ["woman_and_man_holding_hands_light_skin_tone_medium_skin_tone"] = "👩🏻‍🤝‍👨🏽", - ["woman_and_man_holding_hands_tone1_tone4"] = "👩🏻‍🤝‍👨🏾", - ["woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍🤝‍👨🏾", - ["woman_and_man_holding_hands_tone1_tone5"] = "👩🏻‍🤝‍👨🏿", - ["woman_and_man_holding_hands_light_skin_tone_dark_skin_tone"] = "👩🏻‍🤝‍👨🏿", - ["woman_and_man_holding_hands_tone2_tone1"] = "👩🏼‍🤝‍👨🏻", - ["woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍🤝‍👨🏻", - ["woman_and_man_holding_hands_tone2"] = "👫🏼", - ["woman_and_man_holding_hands_medium_light_skin_tone"] = "👫🏼", - ["woman_and_man_holding_hands_tone2_tone3"] = "👩🏼‍🤝‍👨🏽", - ["woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍🤝‍👨🏽", - ["woman_and_man_holding_hands_tone2_tone4"] = "👩🏼‍🤝‍👨🏾", - ["woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍🤝‍👨🏾", - ["woman_and_man_holding_hands_tone2_tone5"] = "👩🏼‍🤝‍👨🏿", - ["woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍🤝‍👨🏿", - ["woman_and_man_holding_hands_tone3_tone1"] = "👩🏽‍🤝‍👨🏻", - ["woman_and_man_holding_hands_medium_skin_tone_light_skin_tone"] = "👩🏽‍🤝‍👨🏻", - ["woman_and_man_holding_hands_tone3_tone2"] = "👩🏽‍🤝‍👨🏼", - ["woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍🤝‍👨🏼", - ["woman_and_man_holding_hands_tone3"] = "👫🏽", - ["woman_and_man_holding_hands_medium_skin_tone"] = "👫🏽", - ["woman_and_man_holding_hands_tone3_tone4"] = "👩🏽‍🤝‍👨🏾", - ["woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍🤝‍👨🏾", - ["woman_and_man_holding_hands_tone3_tone5"] = "👩🏽‍🤝‍👨🏿", - ["woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone"] = "👩🏽‍🤝‍👨🏿", - ["woman_and_man_holding_hands_tone4_tone1"] = "👩🏾‍🤝‍👨🏻", - ["woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍🤝‍👨🏻", - ["woman_and_man_holding_hands_tone4_tone2"] = "👩🏾‍🤝‍👨🏼", - ["woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍🤝‍👨🏼", - ["woman_and_man_holding_hands_tone4_tone3"] = "👩🏾‍🤝‍👨🏽", - ["woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍🤝‍👨🏽", - ["woman_and_man_holding_hands_tone4"] = "👫🏾", - ["woman_and_man_holding_hands_medium_dark_skin_tone"] = "👫🏾", - ["woman_and_man_holding_hands_tone4_tone5"] = "👩🏾‍🤝‍👨🏿", - ["woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍🤝‍👨🏿", - ["woman_and_man_holding_hands_tone5_tone1"] = "👩🏿‍🤝‍👨🏻", - ["woman_and_man_holding_hands_dark_skin_tone_light_skin_tone"] = "👩🏿‍🤝‍👨🏻", - ["woman_and_man_holding_hands_tone5_tone2"] = "👩🏿‍🤝‍👨🏼", - ["woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍🤝‍👨🏼", - ["woman_and_man_holding_hands_tone5_tone3"] = "👩🏿‍🤝‍👨🏽", - ["woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone"] = "👩🏿‍🤝‍👨🏽", - ["woman_and_man_holding_hands_tone5_tone4"] = "👩🏿‍🤝‍👨🏾", - ["woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍🤝‍👨🏾", - ["woman_and_man_holding_hands_tone5"] = "👫🏿", - ["woman_and_man_holding_hands_dark_skin_tone"] = "👫🏿", - ["two_women_holding_hands"] = "👭", - ["women_holding_hands_tone1"] = "👭🏻", - ["women_holding_hands_light_skin_tone"] = "👭🏻", - ["women_holding_hands_tone1_tone2"] = "👩🏻‍🤝‍👩🏼", - ["women_holding_hands_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍🤝‍👩🏼", - ["women_holding_hands_tone1_tone3"] = "👩🏻‍🤝‍👩🏽", - ["women_holding_hands_light_skin_tone_medium_skin_tone"] = "👩🏻‍🤝‍👩🏽", - ["women_holding_hands_tone1_tone4"] = "👩🏻‍🤝‍👩🏾", - ["women_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍🤝‍👩🏾", - ["women_holding_hands_tone1_tone5"] = "👩🏻‍🤝‍👩🏿", - ["women_holding_hands_light_skin_tone_dark_skin_tone"] = "👩🏻‍🤝‍👩🏿", - ["women_holding_hands_tone2_tone1"] = "👩🏼‍🤝‍👩🏻", - ["women_holding_hands_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍🤝‍👩🏻", - ["women_holding_hands_tone2"] = "👭🏼", - ["women_holding_hands_medium_light_skin_tone"] = "👭🏼", - ["women_holding_hands_tone2_tone3"] = "👩🏼‍🤝‍👩🏽", - ["women_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍🤝‍👩🏽", - ["women_holding_hands_tone2_tone4"] = "👩🏼‍🤝‍👩🏾", - ["women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍🤝‍👩🏾", - ["women_holding_hands_tone2_tone5"] = "👩🏼‍🤝‍👩🏿", - ["women_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍🤝‍👩🏿", - ["women_holding_hands_tone3_tone1"] = "👩🏽‍🤝‍👩🏻", - ["women_holding_hands_medium_skin_tone_light_skin_tone"] = "👩🏽‍🤝‍👩🏻", - ["women_holding_hands_tone3_tone2"] = "👩🏽‍🤝‍👩🏼", - ["women_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍🤝‍👩🏼", - ["women_holding_hands_tone3"] = "👭🏽", - ["women_holding_hands_medium_skin_tone"] = "👭🏽", - ["women_holding_hands_tone3_tone4"] = "👩🏽‍🤝‍👩🏾", - ["women_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍🤝‍👩🏾", - ["women_holding_hands_tone3_tone5"] = "👩🏽‍🤝‍👩🏿", - ["women_holding_hands_medium_skin_tone_dark_skin_tone"] = "👩🏽‍🤝‍👩🏿", - ["women_holding_hands_tone4_tone1"] = "👩🏾‍🤝‍👩🏻", - ["women_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍🤝‍👩🏻", - ["women_holding_hands_tone4_tone2"] = "👩🏾‍🤝‍👩🏼", - ["women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍🤝‍👩🏼", - ["women_holding_hands_tone4_tone3"] = "👩🏾‍🤝‍👩🏽", - ["women_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍🤝‍👩🏽", - ["women_holding_hands_tone4"] = "👭🏾", - ["women_holding_hands_medium_dark_skin_tone"] = "👭🏾", - ["women_holding_hands_tone4_tone5"] = "👩🏾‍🤝‍👩🏿", - ["women_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍🤝‍👩🏿", - ["women_holding_hands_tone5_tone1"] = "👩🏿‍🤝‍👩🏻", - ["women_holding_hands_dark_skin_tone_light_skin_tone"] = "👩🏿‍🤝‍👩🏻", - ["women_holding_hands_tone5_tone2"] = "👩🏿‍🤝‍👩🏼", - ["women_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍🤝‍👩🏼", - ["women_holding_hands_tone5_tone3"] = "👩🏿‍🤝‍👩🏽", - ["women_holding_hands_dark_skin_tone_medium_skin_tone"] = "👩🏿‍🤝‍👩🏽", - ["women_holding_hands_tone5_tone4"] = "👩🏿‍🤝‍👩🏾", - ["women_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍🤝‍👩🏾", - ["women_holding_hands_tone5"] = "👭🏿", - ["women_holding_hands_dark_skin_tone"] = "👭🏿", - ["two_men_holding_hands"] = "👬", - ["men_holding_hands_tone1"] = "👬🏻", - ["men_holding_hands_light_skin_tone"] = "👬🏻", - ["men_holding_hands_tone1_tone2"] = "👨🏻‍🤝‍👨🏼", - ["men_holding_hands_light_skin_tone_medium_light_skin_tone"] = "👨🏻‍🤝‍👨🏼", - ["men_holding_hands_tone1_tone3"] = "👨🏻‍🤝‍👨🏽", - ["men_holding_hands_light_skin_tone_medium_skin_tone"] = "👨🏻‍🤝‍👨🏽", - ["men_holding_hands_tone1_tone4"] = "👨🏻‍🤝‍👨🏾", - ["men_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "👨🏻‍🤝‍👨🏾", - ["men_holding_hands_tone1_tone5"] = "👨🏻‍🤝‍👨🏿", - ["men_holding_hands_light_skin_tone_dark_skin_tone"] = "👨🏻‍🤝‍👨🏿", - ["men_holding_hands_tone2_tone1"] = "👨🏼‍🤝‍👨🏻", - ["men_holding_hands_medium_light_skin_tone_light_skin_tone"] = "👨🏼‍🤝‍👨🏻", - ["men_holding_hands_tone2"] = "👬🏼", - ["men_holding_hands_medium_light_skin_tone"] = "👬🏼", - ["men_holding_hands_tone2_tone3"] = "👨🏼‍🤝‍👨🏽", - ["men_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "👨🏼‍🤝‍👨🏽", - ["men_holding_hands_tone2_tone4"] = "👨🏼‍🤝‍👨🏾", - ["men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "👨🏼‍🤝‍👨🏾", - ["men_holding_hands_tone2_tone5"] = "👨🏼‍🤝‍👨🏿", - ["men_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "👨🏼‍🤝‍👨🏿", - ["men_holding_hands_tone3_tone1"] = "👨🏽‍🤝‍👨🏻", - ["men_holding_hands_medium_skin_tone_light_skin_tone"] = "👨🏽‍🤝‍👨🏻", - ["men_holding_hands_tone3_tone2"] = "👨🏽‍🤝‍👨🏼", - ["men_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "👨🏽‍🤝‍👨🏼", - ["men_holding_hands_tone3"] = "👬🏽", - ["men_holding_hands_medium_skin_tone"] = "👬🏽", - ["men_holding_hands_tone3_tone4"] = "👨🏽‍🤝‍👨🏾", - ["men_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "👨🏽‍🤝‍👨🏾", - ["men_holding_hands_tone3_tone5"] = "👨🏽‍🤝‍👨🏿", - ["men_holding_hands_medium_skin_tone_dark_skin_tone"] = "👨🏽‍🤝‍👨🏿", - ["men_holding_hands_tone4_tone1"] = "👨🏾‍🤝‍👨🏻", - ["men_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "👨🏾‍🤝‍👨🏻", - ["men_holding_hands_tone4_tone2"] = "👨🏾‍🤝‍👨🏼", - ["men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "👨🏾‍🤝‍👨🏼", - ["men_holding_hands_tone4_tone3"] = "👨🏾‍🤝‍👨🏽", - ["men_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "👨🏾‍🤝‍👨🏽", - ["men_holding_hands_tone4"] = "👬🏾", - ["men_holding_hands_medium_dark_skin_tone"] = "👬🏾", - ["men_holding_hands_tone4_tone5"] = "👨🏾‍🤝‍👨🏿", - ["men_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "👨🏾‍🤝‍👨🏿", - ["men_holding_hands_tone5_tone1"] = "👨🏿‍🤝‍👨🏻", - ["men_holding_hands_dark_skin_tone_light_skin_tone"] = "👨🏿‍🤝‍👨🏻", - ["men_holding_hands_tone5_tone2"] = "👨🏿‍🤝‍👨🏼", - ["men_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "👨🏿‍🤝‍👨🏼", - ["men_holding_hands_tone5_tone3"] = "👨🏿‍🤝‍👨🏽", - ["men_holding_hands_dark_skin_tone_medium_skin_tone"] = "👨🏿‍🤝‍👨🏽", - ["men_holding_hands_tone5_tone4"] = "👨🏿‍🤝‍👨🏾", - ["men_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "👨🏿‍🤝‍👨🏾", - ["men_holding_hands_tone5"] = "👬🏿", - ["men_holding_hands_dark_skin_tone"] = "👬🏿", - ["couple_with_heart"] = "💑", - ["couple_with_heart_tone1"] = "💑🏻", - ["couple_with_heart_light_skin_tone"] = "💑🏻", - ["couple_with_heart_person_person_tone1_tone2"] = "🧑🏻‍❤️‍🧑🏼", - ["couple_with_heart_person_person_light_skin_tone_medium_light_skin_tone"] = "🧑🏻‍❤️‍🧑🏼", - ["couple_with_heart_person_person_tone1_tone3"] = "🧑🏻‍❤️‍🧑🏽", - ["couple_with_heart_person_person_light_skin_tone_medium_skin_tone"] = "🧑🏻‍❤️‍🧑🏽", - ["couple_with_heart_person_person_tone1_tone4"] = "🧑🏻‍❤️‍🧑🏾", - ["couple_with_heart_person_person_light_skin_tone_medium_dark_skin_tone"] = "🧑🏻‍❤️‍🧑🏾", - ["couple_with_heart_person_person_tone1_tone5"] = "🧑🏻‍❤️‍🧑🏿", - ["couple_with_heart_person_person_light_skin_tone_dark_skin_tone"] = "🧑🏻‍❤️‍🧑🏿", - ["couple_with_heart_person_person_tone2_tone1"] = "🧑🏼‍❤️‍🧑🏻", - ["couple_with_heart_person_person_medium_light_skin_tone_light_skin_tone"] = "🧑🏼‍❤️‍🧑🏻", - ["couple_with_heart_tone2"] = "💑🏼", - ["couple_with_heart_medium_light_skin_tone"] = "💑🏼", - ["couple_with_heart_person_person_tone2_tone3"] = "🧑🏼‍❤️‍🧑🏽", - ["couple_with_heart_person_person_medium_light_skin_tone_medium_skin_tone"] = "🧑🏼‍❤️‍🧑🏽", - ["couple_with_heart_person_person_tone2_tone4"] = "🧑🏼‍❤️‍🧑🏾", - ["couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone"] = "🧑🏼‍❤️‍🧑🏾", - ["couple_with_heart_person_person_tone2_tone5"] = "🧑🏼‍❤️‍🧑🏿", - ["couple_with_heart_person_person_medium_light_skin_tone_dark_skin_tone"] = "🧑🏼‍❤️‍🧑🏿", - ["couple_with_heart_person_person_tone3_tone1"] = "🧑🏽‍❤️‍🧑🏻", - ["couple_with_heart_person_person_medium_skin_tone_light_skin_tone"] = "🧑🏽‍❤️‍🧑🏻", - ["couple_with_heart_person_person_tone3_tone2"] = "🧑🏽‍❤️‍🧑🏼", - ["couple_with_heart_person_person_medium_skin_tone_medium_light_skin_tone"] = "🧑🏽‍❤️‍🧑🏼", - ["couple_with_heart_tone3"] = "💑🏽", - ["couple_with_heart_medium_skin_tone"] = "💑🏽", - ["couple_with_heart_person_person_tone3_tone4"] = "🧑🏽‍❤️‍🧑🏾", - ["couple_with_heart_person_person_medium_skin_tone_medium_dark_skin_tone"] = "🧑🏽‍❤️‍🧑🏾", - ["couple_with_heart_person_person_tone3_tone5"] = "🧑🏽‍❤️‍🧑🏿", - ["couple_with_heart_person_person_medium_skin_tone_dark_skin_tone"] = "🧑🏽‍❤️‍🧑🏿", - ["couple_with_heart_person_person_tone4_tone1"] = "🧑🏾‍❤️‍🧑🏻", - ["couple_with_heart_person_person_medium_dark_skin_tone_light_skin_tone"] = "🧑🏾‍❤️‍🧑🏻", - ["couple_with_heart_person_person_tone4_tone2"] = "🧑🏾‍❤️‍🧑🏼", - ["couple_with_heart_person_person_medium_dark_skin_tone_medium_light_skin_tone"] = "🧑🏾‍❤️‍🧑🏼", - ["couple_with_heart_person_person_tone4_tone3"] = "🧑🏾‍❤️‍🧑🏽", - ["couple_with_heart_person_person_medium_dark_skin_tone_medium_skin_tone"] = "🧑🏾‍❤️‍🧑🏽", - ["couple_with_heart_tone4"] = "💑🏾", - ["couple_with_heart_medium_dark_skin_tone"] = "💑🏾", - ["couple_with_heart_person_person_tone4_tone5"] = "🧑🏾‍❤️‍🧑🏿", - ["couple_with_heart_person_person_medium_dark_skin_tone_dark_skin_tone"] = "🧑🏾‍❤️‍🧑🏿", - ["couple_with_heart_person_person_tone5_tone1"] = "🧑🏿‍❤️‍🧑🏻", - ["couple_with_heart_person_person_dark_skin_tone_light_skin_tone"] = "🧑🏿‍❤️‍🧑🏻", - ["couple_with_heart_person_person_tone5_tone2"] = "🧑🏿‍❤️‍🧑🏼", - ["couple_with_heart_person_person_dark_skin_tone_medium_light_skin_tone"] = "🧑🏿‍❤️‍🧑🏼", - ["couple_with_heart_person_person_tone5_tone3"] = "🧑🏿‍❤️‍🧑🏽", - ["couple_with_heart_person_person_dark_skin_tone_medium_skin_tone"] = "🧑🏿‍❤️‍🧑🏽", - ["couple_with_heart_person_person_tone5_tone4"] = "🧑🏿‍❤️‍🧑🏾", - ["couple_with_heart_person_person_dark_skin_tone_medium_dark_skin_tone"] = "🧑🏿‍❤️‍🧑🏾", - ["couple_with_heart_tone5"] = "💑🏿", - ["couple_with_heart_dark_skin_tone"] = "💑🏿", - ["couple_with_heart_woman_man"] = "👩‍❤️‍👨", - ["couple_with_heart_woman_man_tone1"] = "👩🏻‍❤️‍👨🏻", - ["couple_with_heart_woman_man_light_skin_tone"] = "👩🏻‍❤️‍👨🏻", - ["couple_with_heart_woman_man_tone1_tone2"] = "👩🏻‍❤️‍👨🏼", - ["couple_with_heart_woman_man_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍👨🏼", - ["couple_with_heart_woman_man_tone1_tone3"] = "👩🏻‍❤️‍👨🏽", - ["couple_with_heart_woman_man_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍👨🏽", - ["couple_with_heart_woman_man_tone1_tone4"] = "👩🏻‍❤️‍👨🏾", - ["couple_with_heart_woman_man_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍👨🏾", - ["couple_with_heart_woman_man_tone1_tone5"] = "👩🏻‍❤️‍👨🏿", - ["couple_with_heart_woman_man_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍👨🏿", - ["couple_with_heart_woman_man_tone2_tone1"] = "👩🏼‍❤️‍👨🏻", - ["couple_with_heart_woman_man_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍👨🏻", - ["couple_with_heart_woman_man_tone2"] = "👩🏼‍❤️‍👨🏼", - ["couple_with_heart_woman_man_medium_light_skin_tone"] = "👩🏼‍❤️‍👨🏼", - ["couple_with_heart_woman_man_tone2_tone3"] = "👩🏼‍❤️‍👨🏽", - ["couple_with_heart_woman_man_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍👨🏽", - ["couple_with_heart_woman_man_tone2_tone4"] = "👩🏼‍❤️‍👨🏾", - ["couple_with_heart_woman_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍👨🏾", - ["couple_with_heart_woman_man_tone2_tone5"] = "👩🏼‍❤️‍👨🏿", - ["couple_with_heart_woman_man_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍👨🏿", - ["couple_with_heart_woman_man_tone3_tone1"] = "👩🏽‍❤️‍👨🏻", - ["couple_with_heart_woman_man_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍👨🏻", - ["couple_with_heart_woman_man_tone3_tone2"] = "👩🏽‍❤️‍👨🏼", - ["couple_with_heart_woman_man_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍👨🏼", - ["couple_with_heart_woman_man_tone3"] = "👩🏽‍❤️‍👨🏽", - ["couple_with_heart_woman_man_medium_skin_tone"] = "👩🏽‍❤️‍👨🏽", - ["couple_with_heart_woman_man_tone3_tone4"] = "👩🏽‍❤️‍👨🏾", - ["couple_with_heart_woman_man_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍👨🏾", - ["couple_with_heart_woman_man_tone3_tone5"] = "👩🏽‍❤️‍👨🏿", - ["couple_with_heart_woman_man_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍👨🏿", - ["couple_with_heart_woman_man_tone4_tone1"] = "👩🏾‍❤️‍👨🏻", - ["couple_with_heart_woman_man_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍👨🏻", - ["couple_with_heart_woman_man_tone4_tone2"] = "👩🏾‍❤️‍👨🏼", - ["couple_with_heart_woman_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍👨🏼", - ["couple_with_heart_woman_man_tone4_tone3"] = "👩🏾‍❤️‍👨🏽", - ["couple_with_heart_woman_man_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍👨🏽", - ["couple_with_heart_woman_man_tone4"] = "👩🏾‍❤️‍👨🏾", - ["couple_with_heart_woman_man_medium_dark_skin_tone"] = "👩🏾‍❤️‍👨🏾", - ["couple_with_heart_woman_man_tone4_tone5"] = "👩🏾‍❤️‍👨🏿", - ["couple_with_heart_woman_man_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍👨🏿", - ["couple_with_heart_woman_man_tone5_tone1"] = "👩🏿‍❤️‍👨🏻", - ["couple_with_heart_woman_man_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍👨🏻", - ["couple_with_heart_woman_man_tone5_tone2"] = "👩🏿‍❤️‍👨🏼", - ["couple_with_heart_woman_man_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍👨🏼", - ["couple_with_heart_woman_man_tone5_tone3"] = "👩🏿‍❤️‍👨🏽", - ["couple_with_heart_woman_man_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍👨🏽", - ["couple_with_heart_woman_man_tone5_tone4"] = "👩🏿‍❤️‍👨🏾", - ["couple_with_heart_woman_man_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍👨🏾", - ["couple_with_heart_woman_man_tone5"] = "👩🏿‍❤️‍👨🏿", - ["couple_with_heart_woman_man_dark_skin_tone"] = "👩🏿‍❤️‍👨🏿", - ["couple_ww"] = "👩‍❤️‍👩", - ["couple_with_heart_ww"] = "👩‍❤️‍👩", - ["couple_with_heart_woman_woman_tone1"] = "👩🏻‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_light_skin_tone"] = "👩🏻‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_tone1_tone2"] = "👩🏻‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_tone1_tone3"] = "👩🏻‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_tone1_tone4"] = "👩🏻‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_tone1_tone5"] = "👩🏻‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_tone2_tone1"] = "👩🏼‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_tone2"] = "👩🏼‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_medium_light_skin_tone"] = "👩🏼‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_tone2_tone3"] = "👩🏼‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_tone2_tone4"] = "👩🏼‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_tone2_tone5"] = "👩🏼‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_tone3_tone1"] = "👩🏽‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_tone3_tone2"] = "👩🏽‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_tone3"] = "👩🏽‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_medium_skin_tone"] = "👩🏽‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_tone3_tone4"] = "👩🏽‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_tone3_tone5"] = "👩🏽‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_tone4_tone1"] = "👩🏾‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_tone4_tone2"] = "👩🏾‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_tone4_tone3"] = "👩🏾‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_tone4"] = "👩🏾‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_medium_dark_skin_tone"] = "👩🏾‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_tone4_tone5"] = "👩🏾‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_tone5_tone1"] = "👩🏿‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍👩🏻", - ["couple_with_heart_woman_woman_tone5_tone2"] = "👩🏿‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍👩🏼", - ["couple_with_heart_woman_woman_tone5_tone3"] = "👩🏿‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍👩🏽", - ["couple_with_heart_woman_woman_tone5_tone4"] = "👩🏿‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍👩🏾", - ["couple_with_heart_woman_woman_tone5"] = "👩🏿‍❤️‍👩🏿", - ["couple_with_heart_woman_woman_dark_skin_tone"] = "👩🏿‍❤️‍👩🏿", - ["couple_mm"] = "👨‍❤️‍👨", - ["couple_with_heart_mm"] = "👨‍❤️‍👨", - ["couple_with_heart_man_man_tone1"] = "👨🏻‍❤️‍👨🏻", - ["couple_with_heart_man_man_light_skin_tone"] = "👨🏻‍❤️‍👨🏻", - ["couple_with_heart_man_man_tone1_tone2"] = "👨🏻‍❤️‍👨🏼", - ["couple_with_heart_man_man_light_skin_tone_medium_light_skin_tone"] = "👨🏻‍❤️‍👨🏼", - ["couple_with_heart_man_man_tone1_tone3"] = "👨🏻‍❤️‍👨🏽", - ["couple_with_heart_man_man_light_skin_tone_medium_skin_tone"] = "👨🏻‍❤️‍👨🏽", - ["couple_with_heart_man_man_tone1_tone4"] = "👨🏻‍❤️‍👨🏾", - ["couple_with_heart_man_man_light_skin_tone_medium_dark_skin_tone"] = "👨🏻‍❤️‍👨🏾", - ["couple_with_heart_man_man_tone1_tone5"] = "👨🏻‍❤️‍👨🏿", - ["couple_with_heart_man_man_light_skin_tone_dark_skin_tone"] = "👨🏻‍❤️‍👨🏿", - ["couple_with_heart_man_man_tone2_tone1"] = "👨🏼‍❤️‍👨🏻", - ["couple_with_heart_man_man_medium_light_skin_tone_light_skin_tone"] = "👨🏼‍❤️‍👨🏻", - ["couple_with_heart_man_man_tone2"] = "👨🏼‍❤️‍👨🏼", - ["couple_with_heart_man_man_medium_light_skin_tone"] = "👨🏼‍❤️‍👨🏼", - ["couple_with_heart_man_man_tone2_tone3"] = "👨🏼‍❤️‍👨🏽", - ["couple_with_heart_man_man_medium_light_skin_tone_medium_skin_tone"] = "👨🏼‍❤️‍👨🏽", - ["couple_with_heart_man_man_tone2_tone4"] = "👨🏼‍❤️‍👨🏾", - ["couple_with_heart_man_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👨🏼‍❤️‍👨🏾", - ["couple_with_heart_man_man_tone2_tone5"] = "👨🏼‍❤️‍👨🏿", - ["couple_with_heart_man_man_medium_light_skin_tone_dark_skin_tone"] = "👨🏼‍❤️‍👨🏿", - ["couple_with_heart_man_man_tone3_tone1"] = "👨🏽‍❤️‍👨🏻", - ["couple_with_heart_man_man_medium_skin_tone_light_skin_tone"] = "👨🏽‍❤️‍👨🏻", - ["couple_with_heart_man_man_tone3_tone2"] = "👨🏽‍❤️‍👨🏼", - ["couple_with_heart_man_man_medium_skin_tone_medium_light_skin_tone"] = "👨🏽‍❤️‍👨🏼", - ["couple_with_heart_man_man_tone3"] = "👨🏽‍❤️‍👨🏽", - ["couple_with_heart_man_man_medium_skin_tone"] = "👨🏽‍❤️‍👨🏽", - ["couple_with_heart_man_man_tone3_tone4"] = "👨🏽‍❤️‍👨🏾", - ["couple_with_heart_man_man_medium_skin_tone_medium_dark_skin_tone"] = "👨🏽‍❤️‍👨🏾", - ["couple_with_heart_man_man_tone3_tone5"] = "👨🏽‍❤️‍👨🏿", - ["couple_with_heart_man_man_medium_skin_tone_dark_skin_tone"] = "👨🏽‍❤️‍👨🏿", - ["couple_with_heart_man_man_tone4_tone1"] = "👨🏾‍❤️‍👨🏻", - ["couple_with_heart_man_man_medium_dark_skin_tone_light_skin_tone"] = "👨🏾‍❤️‍👨🏻", - ["couple_with_heart_man_man_tone4_tone2"] = "👨🏾‍❤️‍👨🏼", - ["couple_with_heart_man_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👨🏾‍❤️‍👨🏼", - ["couple_with_heart_man_man_tone4_tone3"] = "👨🏾‍❤️‍👨🏽", - ["couple_with_heart_man_man_medium_dark_skin_tone_medium_skin_tone"] = "👨🏾‍❤️‍👨🏽", - ["couple_with_heart_man_man_tone4"] = "👨🏾‍❤️‍👨🏾", - ["couple_with_heart_man_man_medium_dark_skin_tone"] = "👨🏾‍❤️‍👨🏾", - ["couple_with_heart_man_man_tone4_tone5"] = "👨🏾‍❤️‍👨🏿", - ["couple_with_heart_man_man_medium_dark_skin_tone_dark_skin_tone"] = "👨🏾‍❤️‍👨🏿", - ["couple_with_heart_man_man_tone5_tone1"] = "👨🏿‍❤️‍👨🏻", - ["couple_with_heart_man_man_dark_skin_tone_light_skin_tone"] = "👨🏿‍❤️‍👨🏻", - ["couple_with_heart_man_man_tone5_tone2"] = "👨🏿‍❤️‍👨🏼", - ["couple_with_heart_man_man_dark_skin_tone_medium_light_skin_tone"] = "👨🏿‍❤️‍👨🏼", - ["couple_with_heart_man_man_tone5_tone3"] = "👨🏿‍❤️‍👨🏽", - ["couple_with_heart_man_man_dark_skin_tone_medium_skin_tone"] = "👨🏿‍❤️‍👨🏽", - ["couple_with_heart_man_man_tone5_tone4"] = "👨🏿‍❤️‍👨🏾", - ["couple_with_heart_man_man_dark_skin_tone_medium_dark_skin_tone"] = "👨🏿‍❤️‍👨🏾", - ["couple_with_heart_man_man_tone5"] = "👨🏿‍❤️‍👨🏿", - ["couple_with_heart_man_man_dark_skin_tone"] = "👨🏿‍❤️‍👨🏿", - ["couplekiss"] = "💏", - ["kiss_person_person_tone5_tone4"] = "🧑🏿‍❤️‍💋‍🧑🏾", - ["kiss_person_person_dark_skin_tone_medium_dark_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏾", - ["kiss_tone1"] = "💏🏻", - ["kiss_light_skin_tone"] = "💏🏻", - ["kiss_person_person_tone1_tone2"] = "🧑🏻‍❤️‍💋‍🧑🏼", - ["kiss_person_person_light_skin_tone_medium_light_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏼", - ["kiss_person_person_tone1_tone3"] = "🧑🏻‍❤️‍💋‍🧑🏽", - ["kiss_person_person_light_skin_tone_medium_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏽", - ["kiss_person_person_tone1_tone4"] = "🧑🏻‍❤️‍💋‍🧑🏾", - ["kiss_person_person_light_skin_tone_medium_dark_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏾", - ["kiss_person_person_tone1_tone5"] = "🧑🏻‍❤️‍💋‍🧑🏿", - ["kiss_person_person_light_skin_tone_dark_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏿", - ["kiss_person_person_tone2_tone1"] = "🧑🏼‍❤️‍💋‍🧑🏻", - ["kiss_person_person_medium_light_skin_tone_light_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏻", - ["kiss_tone2"] = "💏🏼", - ["kiss_medium_light_skin_tone"] = "💏🏼", - ["kiss_person_person_tone2_tone3"] = "🧑🏼‍❤️‍💋‍🧑🏽", - ["kiss_person_person_medium_light_skin_tone_medium_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏽", - ["kiss_person_person_tone2_tone4"] = "🧑🏼‍❤️‍💋‍🧑🏾", - ["kiss_person_person_medium_light_skin_tone_medium_dark_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏾", - ["kiss_person_person_tone2_tone5"] = "🧑🏼‍❤️‍💋‍🧑🏿", - ["kiss_person_person_medium_light_skin_tone_dark_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏿", - ["kiss_person_person_tone3_tone1"] = "🧑🏽‍❤️‍💋‍🧑🏻", - ["kiss_person_person_medium_skin_tone_light_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏻", - ["kiss_person_person_tone3_tone2"] = "🧑🏽‍❤️‍💋‍🧑🏼", - ["kiss_person_person_medium_skin_tone_medium_light_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏼", - ["kiss_tone3"] = "💏🏽", - ["kiss_medium_skin_tone"] = "💏🏽", - ["kiss_person_person_tone3_tone4"] = "🧑🏽‍❤️‍💋‍🧑🏾", - ["kiss_person_person_medium_skin_tone_medium_dark_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏾", - ["kiss_person_person_tone3_tone5"] = "🧑🏽‍❤️‍💋‍🧑🏿", - ["kiss_person_person_medium_skin_tone_dark_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏿", - ["kiss_person_person_tone4_tone1"] = "🧑🏾‍❤️‍💋‍🧑🏻", - ["kiss_person_person_medium_dark_skin_tone_light_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏻", - ["kiss_person_person_tone4_tone2"] = "🧑🏾‍❤️‍💋‍🧑🏼", - ["kiss_person_person_medium_dark_skin_tone_medium_light_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏼", - ["kiss_person_person_tone4_tone3"] = "🧑🏾‍❤️‍💋‍🧑🏽", - ["kiss_person_person_medium_dark_skin_tone_medium_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏽", - ["kiss_tone4"] = "💏🏾", - ["kiss_medium_dark_skin_tone"] = "💏🏾", - ["kiss_person_person_tone4_tone5"] = "🧑🏾‍❤️‍💋‍🧑🏿", - ["kiss_person_person_medium_dark_skin_tone_dark_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏿", - ["kiss_person_person_tone5_tone1"] = "🧑🏿‍❤️‍💋‍🧑🏻", - ["kiss_person_person_dark_skin_tone_light_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏻", - ["kiss_person_person_tone5_tone2"] = "🧑🏿‍❤️‍💋‍🧑🏼", - ["kiss_person_person_dark_skin_tone_medium_light_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏼", - ["kiss_person_person_tone5_tone3"] = "🧑🏿‍❤️‍💋‍🧑🏽", - ["kiss_person_person_dark_skin_tone_medium_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏽", - ["kiss_tone5"] = "💏🏿", - ["kiss_dark_skin_tone"] = "💏🏿", - ["kiss_woman_man"] = "👩‍❤️‍💋‍👨", - ["kiss_woman_man_tone1"] = "👩🏻‍❤️‍💋‍👨🏻", - ["kiss_woman_man_light_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏻", - ["kiss_woman_man_tone1_tone2"] = "👩🏻‍❤️‍💋‍👨🏼", - ["kiss_woman_man_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏼", - ["kiss_woman_man_tone1_tone3"] = "👩🏻‍❤️‍💋‍👨🏽", - ["kiss_woman_man_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏽", - ["kiss_woman_man_tone1_tone4"] = "👩🏻‍❤️‍💋‍👨🏾", - ["kiss_woman_man_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏾", - ["kiss_woman_man_tone1_tone5"] = "👩🏻‍❤️‍💋‍👨🏿", - ["kiss_woman_man_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏿", - ["kiss_woman_man_tone2_tone1"] = "👩🏼‍❤️‍💋‍👨🏻", - ["kiss_woman_man_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏻", - ["kiss_woman_man_tone2"] = "👩🏼‍❤️‍💋‍👨🏼", - ["kiss_woman_man_medium_light_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏼", - ["kiss_woman_man_tone2_tone3"] = "👩🏼‍❤️‍💋‍👨🏽", - ["kiss_woman_man_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏽", - ["kiss_woman_man_tone2_tone4"] = "👩🏼‍❤️‍💋‍👨🏾", - ["kiss_woman_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏾", - ["kiss_woman_man_tone2_tone5"] = "👩🏼‍❤️‍💋‍👨🏿", - ["kiss_woman_man_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏿", - ["kiss_woman_man_tone3_tone1"] = "👩🏽‍❤️‍💋‍👨🏻", - ["kiss_woman_man_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏻", - ["kiss_woman_man_tone3_tone2"] = "👩🏽‍❤️‍💋‍👨🏼", - ["kiss_woman_man_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏼", - ["kiss_woman_man_tone3"] = "👩🏽‍❤️‍💋‍👨🏽", - ["kiss_woman_man_medium_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏽", - ["kiss_woman_man_tone3_tone4"] = "👩🏽‍❤️‍💋‍👨🏾", - ["kiss_woman_man_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏾", - ["kiss_woman_man_tone3_tone5"] = "👩🏽‍❤️‍💋‍👨🏿", - ["kiss_woman_man_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏿", - ["kiss_woman_man_tone4_tone1"] = "👩🏾‍❤️‍💋‍👨🏻", - ["kiss_woman_man_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏻", - ["kiss_woman_man_tone4_tone2"] = "👩🏾‍❤️‍💋‍👨🏼", - ["kiss_woman_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏼", - ["kiss_woman_man_tone4_tone3"] = "👩🏾‍❤️‍💋‍👨🏽", - ["kiss_woman_man_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏽", - ["kiss_woman_man_tone4"] = "👩🏾‍❤️‍💋‍👨🏾", - ["kiss_woman_man_medium_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏾", - ["kiss_woman_man_tone4_tone5"] = "👩🏾‍❤️‍💋‍👨🏿", - ["kiss_woman_man_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏿", - ["kiss_woman_man_tone5_tone1"] = "👩🏿‍❤️‍💋‍👨🏻", - ["kiss_woman_man_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏻", - ["kiss_woman_man_tone5_tone2"] = "👩🏿‍❤️‍💋‍👨🏼", - ["kiss_woman_man_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏼", - ["kiss_woman_man_tone5_tone3"] = "👩🏿‍❤️‍💋‍👨🏽", - ["kiss_woman_man_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏽", - ["kiss_woman_man_tone5_tone4"] = "👩🏿‍❤️‍💋‍👨🏾", - ["kiss_woman_man_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏾", - ["kiss_woman_man_tone5"] = "👩🏿‍❤️‍💋‍👨🏿", - ["kiss_woman_man_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏿", - ["kiss_ww"] = "👩‍❤️‍💋‍👩", - ["couplekiss_ww"] = "👩‍❤️‍💋‍👩", - ["kiss_woman_woman_tone1"] = "👩🏻‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_light_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_tone1_tone2"] = "👩🏻‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_tone1_tone3"] = "👩🏻‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_tone1_tone4"] = "👩🏻‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_tone1_tone5"] = "👩🏻‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_tone2_tone1"] = "👩🏼‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_tone2"] = "👩🏼‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_medium_light_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_tone2_tone3"] = "👩🏼‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_tone2_tone4"] = "👩🏼‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_tone2_tone5"] = "👩🏼‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_tone3_tone1"] = "👩🏽‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_tone3_tone2"] = "👩🏽‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_tone3"] = "👩🏽‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_medium_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_tone3_tone4"] = "👩🏽‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_tone3_tone5"] = "👩🏽‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_tone4_tone1"] = "👩🏾‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_tone4_tone2"] = "👩🏾‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_tone4_tone3"] = "👩🏾‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_tone4"] = "👩🏾‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_medium_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_tone4_tone5"] = "👩🏾‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_tone5_tone1"] = "👩🏿‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏻", - ["kiss_woman_woman_tone5_tone2"] = "👩🏿‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏼", - ["kiss_woman_woman_tone5_tone3"] = "👩🏿‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏽", - ["kiss_woman_woman_tone5_tone4"] = "👩🏿‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏾", - ["kiss_woman_woman_tone5"] = "👩🏿‍❤️‍💋‍👩🏿", - ["kiss_woman_woman_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏿", - ["kiss_mm"] = "👨‍❤️‍💋‍👨", - ["couplekiss_mm"] = "👨‍❤️‍💋‍👨", - ["kiss_man_man_tone1"] = "👨🏻‍❤️‍💋‍👨🏻", - ["kiss_man_man_light_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏻", - ["kiss_man_man_tone1_tone2"] = "👨🏻‍❤️‍💋‍👨🏼", - ["kiss_man_man_light_skin_tone_medium_light_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏼", - ["kiss_man_man_tone1_tone3"] = "👨🏻‍❤️‍💋‍👨🏽", - ["kiss_man_man_light_skin_tone_medium_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏽", - ["kiss_man_man_tone1_tone4"] = "👨🏻‍❤️‍💋‍👨🏾", - ["kiss_man_man_light_skin_tone_medium_dark_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏾", - ["kiss_man_man_tone1_tone5"] = "👨🏻‍❤️‍💋‍👨🏿", - ["kiss_man_man_light_skin_tone_dark_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏿", - ["kiss_man_man_tone2_tone1"] = "👨🏼‍❤️‍💋‍👨🏻", - ["kiss_man_man_medium_light_skin_tone_light_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏻", - ["kiss_man_man_tone2"] = "👨🏼‍❤️‍💋‍👨🏼", - ["kiss_man_man_medium_light_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏼", - ["kiss_man_man_tone2_tone3"] = "👨🏼‍❤️‍💋‍👨🏽", - ["kiss_man_man_medium_light_skin_tone_medium_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏽", - ["kiss_man_man_tone2_tone4"] = "👨🏼‍❤️‍💋‍👨🏾", - ["kiss_man_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏾", - ["kiss_man_man_tone2_tone5"] = "👨🏼‍❤️‍💋‍👨🏿", - ["kiss_man_man_medium_light_skin_tone_dark_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏿", - ["kiss_man_man_tone3_tone1"] = "👨🏽‍❤️‍💋‍👨🏻", - ["kiss_man_man_medium_skin_tone_light_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏻", - ["kiss_man_man_tone3_tone2"] = "👨🏽‍❤️‍💋‍👨🏼", - ["kiss_man_man_medium_skin_tone_medium_light_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏼", - ["kiss_man_man_tone3"] = "👨🏽‍❤️‍💋‍👨🏽", - ["kiss_man_man_medium_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏽", - ["kiss_man_man_tone3_tone4"] = "👨🏽‍❤️‍💋‍👨🏾", - ["kiss_man_man_medium_skin_tone_medium_dark_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏾", - ["kiss_man_man_tone3_tone5"] = "👨🏽‍❤️‍💋‍👨🏿", - ["kiss_man_man_medium_skin_tone_dark_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏿", - ["kiss_man_man_tone4_tone1"] = "👨🏾‍❤️‍💋‍👨🏻", - ["kiss_man_man_medium_dark_skin_tone_light_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏻", - ["kiss_man_man_tone4_tone2"] = "👨🏾‍❤️‍💋‍👨🏼", - ["kiss_man_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏼", - ["kiss_man_man_tone4_tone3"] = "👨🏾‍❤️‍💋‍👨🏽", - ["kiss_man_man_medium_dark_skin_tone_medium_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏽", - ["kiss_man_man_tone4"] = "👨🏾‍❤️‍💋‍👨🏾", - ["kiss_man_man_medium_dark_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏾", - ["kiss_man_man_tone4_tone5"] = "👨🏾‍❤️‍💋‍👨🏿", - ["kiss_man_man_medium_dark_skin_tone_dark_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏿", - ["kiss_man_man_tone5_tone1"] = "👨🏿‍❤️‍💋‍👨🏻", - ["kiss_man_man_dark_skin_tone_light_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏻", - ["kiss_man_man_tone5_tone2"] = "👨🏿‍❤️‍💋‍👨🏼", - ["kiss_man_man_dark_skin_tone_medium_light_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏼", - ["kiss_man_man_tone5_tone3"] = "👨🏿‍❤️‍💋‍👨🏽", - ["kiss_man_man_dark_skin_tone_medium_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏽", - ["kiss_man_man_tone5_tone4"] = "👨🏿‍❤️‍💋‍👨🏾", - ["kiss_man_man_dark_skin_tone_medium_dark_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏾", - ["kiss_man_man_tone5"] = "👨🏿‍❤️‍💋‍👨🏿", - ["kiss_man_man_dark_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏿", - ["family"] = "👪", - ["family_man_woman_boy"] = "👨‍👩‍👦", - ["family_mwg"] = "👨‍👩‍👧", - ["family_mwgb"] = "👨‍👩‍👧‍👦", - ["family_mwbb"] = "👨‍👩‍👦‍👦", - ["family_mwgg"] = "👨‍👩‍👧‍👧", - ["family_wwb"] = "👩‍👩‍👦", - ["family_wwg"] = "👩‍👩‍👧", - ["family_wwgb"] = "👩‍👩‍👧‍👦", - ["family_wwbb"] = "👩‍👩‍👦‍👦", - ["family_wwgg"] = "👩‍👩‍👧‍👧", - ["family_mmb"] = "👨‍👨‍👦", - ["family_mmg"] = "👨‍👨‍👧", - ["family_mmgb"] = "👨‍👨‍👧‍👦", - ["family_mmbb"] = "👨‍👨‍👦‍👦", - ["family_mmgg"] = "👨‍👨‍👧‍👧", - ["family_woman_boy"] = "👩‍👦", - ["family_woman_girl"] = "👩‍👧", - ["family_woman_girl_boy"] = "👩‍👧‍👦", - ["family_woman_boy_boy"] = "👩‍👦‍👦", - ["family_woman_girl_girl"] = "👩‍👧‍👧", - ["family_man_boy"] = "👨‍👦", - ["family_man_girl"] = "👨‍👧", - ["family_man_girl_boy"] = "👨‍👧‍👦", - ["family_man_boy_boy"] = "👨‍👦‍👦", - ["family_man_girl_girl"] = "👨‍👧‍👧", - ["yarn"] = "🧶", - ["thread"] = "🧵", - ["coat"] = "🧥", - ["lab_coat"] = "🥼", - ["safety_vest"] = "🦺", - ["womans_clothes"] = "👚", - ["shirt"] = "👕", - ["jeans"] = "👖", - ["briefs"] = "🩲", - ["shorts"] = "🩳", - ["necktie"] = "👔", - ["dress"] = "👗", - ["bikini"] = "👙", - ["one_piece_swimsuit"] = "🩱", - ["kimono"] = "👘", - ["sari"] = "🥻", - ["womans_flat_shoe"] = "🥿", - ["high_heel"] = "👠", - ["sandal"] = "👡", - ["boot"] = "👢", - ["mans_shoe"] = "👞", - ["athletic_shoe"] = "👟", - ["hiking_boot"] = "🥾", - ["thong_sandal"] = "🩴", - ["socks"] = "🧦", - ["gloves"] = "🧤", - ["scarf"] = "🧣", - ["tophat"] = "🎩", - ["billed_cap"] = "🧢", - ["womans_hat"] = "👒", - ["mortar_board"] = "🎓", - ["helmet_with_cross"] = "⛑️", - ["helmet_with_white_cross"] = "⛑️", - ["military_helmet"] = "🪖", - ["crown"] = "👑", - ["ring"] = "💍", - ["pouch"] = "👝", - ["purse"] = "👛", - ["handbag"] = "👜", - ["briefcase"] = "💼", - ["school_satchel"] = "🎒", - ["luggage"] = "🧳", - ["eyeglasses"] = "👓", - ["dark_sunglasses"] = "🕶️", - ["goggles"] = "🥽", - ["closed_umbrella"] = "🌂", - ["dog"] = "🐶", - ["cat"] = "🐱", - ["mouse"] = "🐭", - ["hamster"] = "🐹", - ["rabbit"] = "🐰", - ["fox"] = "🦊", - ["fox_face"] = "🦊", - ["bear"] = "🐻", - ["panda_face"] = "🐼", - ["polar_bear"] = "🐻‍❄️", - ["koala"] = "🐨", - ["tiger"] = "🐯", - ["lion_face"] = "🦁", - ["lion"] = "🦁", - ["cow"] = "🐮", - ["pig"] = "🐷", - ["pig_nose"] = "🐽", - ["frog"] = "🐸", - ["monkey_face"] = "🐵", - ["see_no_evil"] = "🙈", - ["hear_no_evil"] = "🙉", - ["speak_no_evil"] = "🙊", - ["monkey"] = "🐒", - ["chicken"] = "🐔", - ["penguin"] = "🐧", - ["bird"] = "🐦", - ["baby_chick"] = "🐤", - ["hatching_chick"] = "🐣", - ["hatched_chick"] = "🐥", - ["duck"] = "🦆", - ["dodo"] = "🦤", - ["eagle"] = "🦅", - ["owl"] = "🦉", - ["bat"] = "🦇", - ["wolf"] = "🐺", - ["boar"] = "🐗", - ["horse"] = "🐴", - ["unicorn"] = "🦄", - ["unicorn_face"] = "🦄", - ["bee"] = "🐝", - ["bug"] = "🐛", - ["butterfly"] = "🦋", - ["snail"] = "🐌", - ["worm"] = "🪱", - ["lady_beetle"] = "🐞", - ["ant"] = "🐜", - ["fly"] = "🪰", - ["mosquito"] = "🦟", - ["cockroach"] = "🪳", - ["beetle"] = "🪲", - ["cricket"] = "🦗", - ["spider"] = "🕷️", - ["spider_web"] = "🕸️", - ["scorpion"] = "🦂", - ["turtle"] = "🐢", - ["snake"] = "🐍", - ["lizard"] = "🦎", - ["t_rex"] = "🦖", - ["sauropod"] = "🦕", - ["octopus"] = "🐙", - ["squid"] = "🦑", - ["shrimp"] = "🦐", - ["lobster"] = "🦞", - ["crab"] = "🦀", - ["blowfish"] = "🐡", - ["tropical_fish"] = "🐠", - ["fish"] = "🐟", - ["seal"] = "🦭", - ["dolphin"] = "🐬", - ["whale"] = "🐳", - ["whale2"] = "🐋", - ["shark"] = "🦈", - ["crocodile"] = "🐊", - ["tiger2"] = "🐅", - ["leopard"] = "🐆", - ["zebra"] = "🦓", - ["gorilla"] = "🦍", - ["orangutan"] = "🦧", - ["elephant"] = "🐘", - ["mammoth"] = "🦣", - ["bison"] = "🦬", - ["hippopotamus"] = "🦛", - ["rhino"] = "🦏", - ["rhinoceros"] = "🦏", - ["dromedary_camel"] = "🐪", - ["camel"] = "🐫", - ["giraffe"] = "🦒", - ["kangaroo"] = "🦘", - ["water_buffalo"] = "🐃", - ["ox"] = "🐂", - ["cow2"] = "🐄", - ["racehorse"] = "🐎", - ["pig2"] = "🐖", - ["ram"] = "🐏", - ["sheep"] = "🐑", - ["llama"] = "🦙", - ["goat"] = "🐐", - ["deer"] = "🦌", - ["dog2"] = "🐕", - ["poodle"] = "🐩", - ["guide_dog"] = "🦮", - ["service_dog"] = "🐕‍🦺", - ["cat2"] = "🐈", - ["black_cat"] = "🐈‍⬛", - ["rooster"] = "🐓", - ["turkey"] = "🦃", - ["peacock"] = "🦚", - ["parrot"] = "🦜", - ["swan"] = "🦢", - ["flamingo"] = "🦩", - ["dove"] = "🕊️", - ["dove_of_peace"] = "🕊️", - ["rabbit2"] = "🐇", - ["raccoon"] = "🦝", - ["skunk"] = "🦨", - ["badger"] = "🦡", - ["beaver"] = "🦫", - ["otter"] = "🦦", - ["sloth"] = "🦥", - ["mouse2"] = "🐁", - ["rat"] = "🐀", - ["chipmunk"] = "🐿️", - ["hedgehog"] = "🦔", - ["feet"] = "🐾", - ["paw_prints"] = "🐾", - ["dragon"] = "🐉", - ["dragon_face"] = "🐲", - ["cactus"] = "🌵", - ["christmas_tree"] = "🎄", - ["evergreen_tree"] = "🌲", - ["deciduous_tree"] = "🌳", - ["palm_tree"] = "🌴", - ["seedling"] = "🌱", - ["herb"] = "🌿", - ["shamrock"] = "☘️", - ["four_leaf_clover"] = "🍀", - ["bamboo"] = "🎍", - ["tanabata_tree"] = "🎋", - ["leaves"] = "🍃", - ["fallen_leaf"] = "🍂", - ["maple_leaf"] = "🍁", - ["feather"] = "🪶", - ["mushroom"] = "🍄", - ["shell"] = "🐚", - ["rock"] = "🪨", - ["wood"] = "🪵", - ["ear_of_rice"] = "🌾", - ["potted_plant"] = "🪴", - ["bouquet"] = "💐", - ["tulip"] = "🌷", - ["rose"] = "🌹", - ["wilted_rose"] = "🥀", - ["wilted_flower"] = "🥀", - ["hibiscus"] = "🌺", - ["cherry_blossom"] = "🌸", - ["blossom"] = "🌼", - ["sunflower"] = "🌻", - ["sun_with_face"] = "🌞", - ["full_moon_with_face"] = "🌝", - ["first_quarter_moon_with_face"] = "🌛", - ["last_quarter_moon_with_face"] = "🌜", - ["new_moon_with_face"] = "🌚", - ["full_moon"] = "🌕", - ["waning_gibbous_moon"] = "🌖", - ["last_quarter_moon"] = "🌗", - ["waning_crescent_moon"] = "🌘", - ["new_moon"] = "🌑", - ["waxing_crescent_moon"] = "🌒", - ["first_quarter_moon"] = "🌓", - ["waxing_gibbous_moon"] = "🌔", - ["crescent_moon"] = "🌙", - ["earth_americas"] = "🌎", - ["earth_africa"] = "🌍", - ["earth_asia"] = "🌏", - ["ringed_planet"] = "🪐", - ["dizzy"] = "💫", - ["star"] = "⭐", - ["star2"] = "🌟", - ["sparkles"] = "✨", - ["zap"] = "⚡", - ["comet"] = "☄️", - ["boom"] = "💥", - ["fire"] = "🔥", - ["flame"] = "🔥", - ["cloud_tornado"] = "🌪️", - ["cloud_with_tornado"] = "🌪️", - ["rainbow"] = "🌈", - ["sunny"] = "☀️", - ["white_sun_small_cloud"] = "🌤️", - ["white_sun_with_small_cloud"] = "🌤️", - ["partly_sunny"] = "⛅", - ["white_sun_cloud"] = "🌥️", - ["white_sun_behind_cloud"] = "🌥️", - ["cloud"] = "☁️", - ["white_sun_rain_cloud"] = "🌦️", - ["white_sun_behind_cloud_with_rain"] = "🌦️", - ["cloud_rain"] = "🌧️", - ["cloud_with_rain"] = "🌧️", - ["thunder_cloud_rain"] = "⛈️", - ["thunder_cloud_and_rain"] = "⛈️", - ["cloud_lightning"] = "🌩️", - ["cloud_with_lightning"] = "🌩️", - ["cloud_snow"] = "🌨️", - ["cloud_with_snow"] = "🌨️", - ["snowflake"] = "❄️", - ["snowman2"] = "☃️", - ["snowman"] = "⛄", - ["wind_blowing_face"] = "🌬️", - ["dash"] = "💨", - ["droplet"] = "💧", - ["sweat_drops"] = "💦", - ["umbrella"] = "☔", - ["umbrella2"] = "☂️", - ["ocean"] = "🌊", - ["fog"] = "🌫️", - ["green_apple"] = "🍏", - ["apple"] = "🍎", - ["pear"] = "🍐", - ["tangerine"] = "🍊", - ["lemon"] = "🍋", - ["banana"] = "🍌", - ["watermelon"] = "🍉", - ["grapes"] = "🍇", - ["blueberries"] = "🫐", - ["strawberry"] = "🍓", - ["melon"] = "🍈", - ["cherries"] = "🍒", - ["peach"] = "🍑", - ["mango"] = "🥭", - ["pineapple"] = "🍍", - ["coconut"] = "🥥", - ["kiwi"] = "🥝", - ["kiwifruit"] = "🥝", - ["tomato"] = "🍅", - ["eggplant"] = "🍆", - ["avocado"] = "🥑", - ["olive"] = "🫒", - ["broccoli"] = "🥦", - ["leafy_green"] = "🥬", - ["bell_pepper"] = "🫑", - ["cucumber"] = "🥒", - ["hot_pepper"] = "🌶️", - ["corn"] = "🌽", - ["carrot"] = "🥕", - ["garlic"] = "🧄", - ["onion"] = "🧅", - ["potato"] = "🥔", - ["sweet_potato"] = "🍠", - ["croissant"] = "🥐", - ["bagel"] = "🥯", - ["bread"] = "🍞", - ["french_bread"] = "🥖", - ["baguette_bread"] = "🥖", - ["flatbread"] = "🫓", - ["pretzel"] = "🥨", - ["cheese"] = "🧀", - ["cheese_wedge"] = "🧀", - ["egg"] = "🥚", - ["cooking"] = "🍳", - ["butter"] = "🧈", - ["pancakes"] = "🥞", - ["waffle"] = "🧇", - ["bacon"] = "🥓", - ["cut_of_meat"] = "🥩", - ["poultry_leg"] = "🍗", - ["meat_on_bone"] = "🍖", - ["hotdog"] = "🌭", - ["hot_dog"] = "🌭", - ["hamburger"] = "🍔", - ["fries"] = "🍟", - ["pizza"] = "🍕", - ["sandwich"] = "🥪", - ["stuffed_flatbread"] = "🥙", - ["stuffed_pita"] = "🥙", - ["falafel"] = "🧆", - ["taco"] = "🌮", - ["burrito"] = "🌯", - ["tamale"] = "🫔", - ["salad"] = "🥗", - ["green_salad"] = "🥗", - ["shallow_pan_of_food"] = "🥘", - ["paella"] = "🥘", - ["fondue"] = "🫕", - ["canned_food"] = "🥫", - ["spaghetti"] = "🍝", - ["ramen"] = "🍜", - ["stew"] = "🍲", - ["curry"] = "🍛", - ["sushi"] = "🍣", - ["bento"] = "🍱", - ["dumpling"] = "🥟", - ["oyster"] = "🦪", - ["fried_shrimp"] = "🍤", - ["rice_ball"] = "🍙", - ["rice"] = "🍚", - ["rice_cracker"] = "🍘", - ["fish_cake"] = "🍥", - ["fortune_cookie"] = "🥠", - ["moon_cake"] = "🥮", - ["oden"] = "🍢", - ["dango"] = "🍡", - ["shaved_ice"] = "🍧", - ["ice_cream"] = "🍨", - ["icecream"] = "🍦", - ["pie"] = "🥧", - ["cupcake"] = "🧁", - ["cake"] = "🍰", - ["birthday"] = "🎂", - ["custard"] = "🍮", - ["pudding"] = "🍮", - ["flan"] = "🍮", - ["lollipop"] = "🍭", - ["candy"] = "🍬", - ["chocolate_bar"] = "🍫", - ["popcorn"] = "🍿", - ["doughnut"] = "🍩", - ["cookie"] = "🍪", - ["chestnut"] = "🌰", - ["peanuts"] = "🥜", - ["shelled_peanut"] = "🥜", - ["honey_pot"] = "🍯", - ["milk"] = "🥛", - ["glass_of_milk"] = "🥛", - ["baby_bottle"] = "🍼", - ["coffee"] = "☕", - ["tea"] = "🍵", - ["teapot"] = "🫖", - ["mate"] = "🧉", - ["bubble_tea"] = "🧋", - ["beverage_box"] = "🧃", - ["cup_with_straw"] = "🥤", - ["sake"] = "🍶", - ["beer"] = "🍺", - ["beers"] = "🍻", - ["champagne_glass"] = "🥂", - ["clinking_glass"] = "🥂", - ["wine_glass"] = "🍷", - ["tumbler_glass"] = "🥃", - ["whisky"] = "🥃", - ["cocktail"] = "🍸", - ["tropical_drink"] = "🍹", - ["champagne"] = "🍾", - ["bottle_with_popping_cork"] = "🍾", - ["ice_cube"] = "🧊", - ["spoon"] = "🥄", - ["fork_and_knife"] = "🍴", - ["fork_knife_plate"] = "🍽️", - ["fork_and_knife_with_plate"] = "🍽️", - ["bowl_with_spoon"] = "🥣", - ["takeout_box"] = "🥡", - ["chopsticks"] = "🥢", - ["salt"] = "🧂", - ["soccer"] = "⚽", - ["basketball"] = "🏀", - ["football"] = "🏈", - ["baseball"] = "⚾", - ["softball"] = "🥎", - ["tennis"] = "🎾", - ["volleyball"] = "🏐", - ["rugby_football"] = "🏉", - ["flying_disc"] = "🥏", - ["boomerang"] = "🪃", - ["8ball"] = "🎱", - ["yo_yo"] = "🪀", - ["ping_pong"] = "🏓", - ["table_tennis"] = "🏓", - ["badminton"] = "🏸", - ["hockey"] = "🏒", - ["field_hockey"] = "🏑", - ["lacrosse"] = "🥍", - ["cricket_game"] = "🏏", - ["cricket_bat_ball"] = "🏏", - ["goal"] = "🥅", - ["goal_net"] = "🥅", - ["golf"] = "⛳", - ["kite"] = "🪁", - ["bow_and_arrow"] = "🏹", - ["archery"] = "🏹", - ["fishing_pole_and_fish"] = "🎣", - ["diving_mask"] = "🤿", - ["boxing_glove"] = "🥊", - ["boxing_gloves"] = "🥊", - ["martial_arts_uniform"] = "🥋", - ["karate_uniform"] = "🥋", - ["running_shirt_with_sash"] = "🎽", - ["skateboard"] = "🛹", - ["roller_skate"] = "🛼", - ["sled"] = "🛷", - ["ice_skate"] = "⛸️", - ["curling_stone"] = "🥌", - ["ski"] = "🎿", - ["skier"] = "⛷️", - ["snowboarder"] = "🏂", - ["snowboarder_tone1"] = "🏂🏻", - ["snowboarder_light_skin_tone"] = "🏂🏻", - ["snowboarder_tone2"] = "🏂🏼", - ["snowboarder_medium_light_skin_tone"] = "🏂🏼", - ["snowboarder_tone3"] = "🏂🏽", - ["snowboarder_medium_skin_tone"] = "🏂🏽", - ["snowboarder_tone4"] = "🏂🏾", - ["snowboarder_medium_dark_skin_tone"] = "🏂🏾", - ["snowboarder_tone5"] = "🏂🏿", - ["snowboarder_dark_skin_tone"] = "🏂🏿", - ["parachute"] = "🪂", - ["person_lifting_weights"] = "🏋️", - ["lifter"] = "🏋️", - ["weight_lifter"] = "🏋️", - ["person_lifting_weights_tone1"] = "🏋🏻", - ["lifter_tone1"] = "🏋🏻", - ["weight_lifter_tone1"] = "🏋🏻", - ["person_lifting_weights_tone2"] = "🏋🏼", - ["lifter_tone2"] = "🏋🏼", - ["weight_lifter_tone2"] = "🏋🏼", - ["person_lifting_weights_tone3"] = "🏋🏽", - ["lifter_tone3"] = "🏋🏽", - ["weight_lifter_tone3"] = "🏋🏽", - ["person_lifting_weights_tone4"] = "🏋🏾", - ["lifter_tone4"] = "🏋🏾", - ["weight_lifter_tone4"] = "🏋🏾", - ["person_lifting_weights_tone5"] = "🏋🏿", - ["lifter_tone5"] = "🏋🏿", - ["weight_lifter_tone5"] = "🏋🏿", - ["woman_lifting_weights"] = "🏋️‍♀️", - ["woman_lifting_weights_tone1"] = "🏋🏻‍♀️", - ["woman_lifting_weights_light_skin_tone"] = "🏋🏻‍♀️", - ["woman_lifting_weights_tone2"] = "🏋🏼‍♀️", - ["woman_lifting_weights_medium_light_skin_tone"] = "🏋🏼‍♀️", - ["woman_lifting_weights_tone3"] = "🏋🏽‍♀️", - ["woman_lifting_weights_medium_skin_tone"] = "🏋🏽‍♀️", - ["woman_lifting_weights_tone4"] = "🏋🏾‍♀️", - ["woman_lifting_weights_medium_dark_skin_tone"] = "🏋🏾‍♀️", - ["woman_lifting_weights_tone5"] = "🏋🏿‍♀️", - ["woman_lifting_weights_dark_skin_tone"] = "🏋🏿‍♀️", - ["man_lifting_weights"] = "🏋️‍♂️", - ["man_lifting_weights_tone1"] = "🏋🏻‍♂️", - ["man_lifting_weights_light_skin_tone"] = "🏋🏻‍♂️", - ["man_lifting_weights_tone2"] = "🏋🏼‍♂️", - ["man_lifting_weights_medium_light_skin_tone"] = "🏋🏼‍♂️", - ["man_lifting_weights_tone3"] = "🏋🏽‍♂️", - ["man_lifting_weights_medium_skin_tone"] = "🏋🏽‍♂️", - ["man_lifting_weights_tone4"] = "🏋🏾‍♂️", - ["man_lifting_weights_medium_dark_skin_tone"] = "🏋🏾‍♂️", - ["man_lifting_weights_tone5"] = "🏋🏿‍♂️", - ["man_lifting_weights_dark_skin_tone"] = "🏋🏿‍♂️", - ["people_wrestling"] = "🤼", - ["wrestlers"] = "🤼", - ["wrestling"] = "🤼", - ["women_wrestling"] = "🤼‍♀️", - ["men_wrestling"] = "🤼‍♂️", - ["person_doing_cartwheel"] = "🤸", - ["cartwheel"] = "🤸", - ["person_doing_cartwheel_tone1"] = "🤸🏻", - ["cartwheel_tone1"] = "🤸🏻", - ["person_doing_cartwheel_tone2"] = "🤸🏼", - ["cartwheel_tone2"] = "🤸🏼", - ["person_doing_cartwheel_tone3"] = "🤸🏽", - ["cartwheel_tone3"] = "🤸🏽", - ["person_doing_cartwheel_tone4"] = "🤸🏾", - ["cartwheel_tone4"] = "🤸🏾", - ["person_doing_cartwheel_tone5"] = "🤸🏿", - ["cartwheel_tone5"] = "🤸🏿", - ["woman_cartwheeling"] = "🤸‍♀️", - ["woman_cartwheeling_tone1"] = "🤸🏻‍♀️", - ["woman_cartwheeling_light_skin_tone"] = "🤸🏻‍♀️", - ["woman_cartwheeling_tone2"] = "🤸🏼‍♀️", - ["woman_cartwheeling_medium_light_skin_tone"] = "🤸🏼‍♀️", - ["woman_cartwheeling_tone3"] = "🤸🏽‍♀️", - ["woman_cartwheeling_medium_skin_tone"] = "🤸🏽‍♀️", - ["woman_cartwheeling_tone4"] = "🤸🏾‍♀️", - ["woman_cartwheeling_medium_dark_skin_tone"] = "🤸🏾‍♀️", - ["woman_cartwheeling_tone5"] = "🤸🏿‍♀️", - ["woman_cartwheeling_dark_skin_tone"] = "🤸🏿‍♀️", - ["man_cartwheeling"] = "🤸‍♂️", - ["man_cartwheeling_tone1"] = "🤸🏻‍♂️", - ["man_cartwheeling_light_skin_tone"] = "🤸🏻‍♂️", - ["man_cartwheeling_tone2"] = "🤸🏼‍♂️", - ["man_cartwheeling_medium_light_skin_tone"] = "🤸🏼‍♂️", - ["man_cartwheeling_tone3"] = "🤸🏽‍♂️", - ["man_cartwheeling_medium_skin_tone"] = "🤸🏽‍♂️", - ["man_cartwheeling_tone4"] = "🤸🏾‍♂️", - ["man_cartwheeling_medium_dark_skin_tone"] = "🤸🏾‍♂️", - ["man_cartwheeling_tone5"] = "🤸🏿‍♂️", - ["man_cartwheeling_dark_skin_tone"] = "🤸🏿‍♂️", - ["person_bouncing_ball"] = "⛹️", - ["basketball_player"] = "⛹️", - ["person_with_ball"] = "⛹️", - ["person_bouncing_ball_tone1"] = "⛹🏻", - ["basketball_player_tone1"] = "⛹🏻", - ["person_with_ball_tone1"] = "⛹🏻", - ["person_bouncing_ball_tone2"] = "⛹🏼", - ["basketball_player_tone2"] = "⛹🏼", - ["person_with_ball_tone2"] = "⛹🏼", - ["person_bouncing_ball_tone3"] = "⛹🏽", - ["basketball_player_tone3"] = "⛹🏽", - ["person_with_ball_tone3"] = "⛹🏽", - ["person_bouncing_ball_tone4"] = "⛹🏾", - ["basketball_player_tone4"] = "⛹🏾", - ["person_with_ball_tone4"] = "⛹🏾", - ["person_bouncing_ball_tone5"] = "⛹🏿", - ["basketball_player_tone5"] = "⛹🏿", - ["person_with_ball_tone5"] = "⛹🏿", - ["woman_bouncing_ball"] = "⛹️‍♀️", - ["woman_bouncing_ball_tone1"] = "⛹🏻‍♀️", - ["woman_bouncing_ball_light_skin_tone"] = "⛹🏻‍♀️", - ["woman_bouncing_ball_tone2"] = "⛹🏼‍♀️", - ["woman_bouncing_ball_medium_light_skin_tone"] = "⛹🏼‍♀️", - ["woman_bouncing_ball_tone3"] = "⛹🏽‍♀️", - ["woman_bouncing_ball_medium_skin_tone"] = "⛹🏽‍♀️", - ["woman_bouncing_ball_tone4"] = "⛹🏾‍♀️", - ["woman_bouncing_ball_medium_dark_skin_tone"] = "⛹🏾‍♀️", - ["woman_bouncing_ball_tone5"] = "⛹🏿‍♀️", - ["woman_bouncing_ball_dark_skin_tone"] = "⛹🏿‍♀️", - ["man_bouncing_ball"] = "⛹️‍♂️", - ["man_bouncing_ball_tone1"] = "⛹🏻‍♂️", - ["man_bouncing_ball_light_skin_tone"] = "⛹🏻‍♂️", - ["man_bouncing_ball_tone2"] = "⛹🏼‍♂️", - ["man_bouncing_ball_medium_light_skin_tone"] = "⛹🏼‍♂️", - ["man_bouncing_ball_tone3"] = "⛹🏽‍♂️", - ["man_bouncing_ball_medium_skin_tone"] = "⛹🏽‍♂️", - ["man_bouncing_ball_tone4"] = "⛹🏾‍♂️", - ["man_bouncing_ball_medium_dark_skin_tone"] = "⛹🏾‍♂️", - ["man_bouncing_ball_tone5"] = "⛹🏿‍♂️", - ["man_bouncing_ball_dark_skin_tone"] = "⛹🏿‍♂️", - ["person_fencing"] = "🤺", - ["fencer"] = "🤺", - ["fencing"] = "🤺", - ["person_playing_handball"] = "🤾", - ["handball"] = "🤾", - ["person_playing_handball_tone1"] = "🤾🏻", - ["handball_tone1"] = "🤾🏻", - ["person_playing_handball_tone2"] = "🤾🏼", - ["handball_tone2"] = "🤾🏼", - ["person_playing_handball_tone3"] = "🤾🏽", - ["handball_tone3"] = "🤾🏽", - ["person_playing_handball_tone4"] = "🤾🏾", - ["handball_tone4"] = "🤾🏾", - ["person_playing_handball_tone5"] = "🤾🏿", - ["handball_tone5"] = "🤾🏿", - ["woman_playing_handball"] = "🤾‍♀️", - ["woman_playing_handball_tone1"] = "🤾🏻‍♀️", - ["woman_playing_handball_light_skin_tone"] = "🤾🏻‍♀️", - ["woman_playing_handball_tone2"] = "🤾🏼‍♀️", - ["woman_playing_handball_medium_light_skin_tone"] = "🤾🏼‍♀️", - ["woman_playing_handball_tone3"] = "🤾🏽‍♀️", - ["woman_playing_handball_medium_skin_tone"] = "🤾🏽‍♀️", - ["woman_playing_handball_tone4"] = "🤾🏾‍♀️", - ["woman_playing_handball_medium_dark_skin_tone"] = "🤾🏾‍♀️", - ["woman_playing_handball_tone5"] = "🤾🏿‍♀️", - ["woman_playing_handball_dark_skin_tone"] = "🤾🏿‍♀️", - ["man_playing_handball"] = "🤾‍♂️", - ["man_playing_handball_tone1"] = "🤾🏻‍♂️", - ["man_playing_handball_light_skin_tone"] = "🤾🏻‍♂️", - ["man_playing_handball_tone2"] = "🤾🏼‍♂️", - ["man_playing_handball_medium_light_skin_tone"] = "🤾🏼‍♂️", - ["man_playing_handball_tone3"] = "🤾🏽‍♂️", - ["man_playing_handball_medium_skin_tone"] = "🤾🏽‍♂️", - ["man_playing_handball_tone4"] = "🤾🏾‍♂️", - ["man_playing_handball_medium_dark_skin_tone"] = "🤾🏾‍♂️", - ["man_playing_handball_tone5"] = "🤾🏿‍♂️", - ["man_playing_handball_dark_skin_tone"] = "🤾🏿‍♂️", - ["person_golfing"] = "🏌️", - ["golfer"] = "🏌️", - ["person_golfing_tone1"] = "🏌🏻", - ["person_golfing_light_skin_tone"] = "🏌🏻", - ["person_golfing_tone2"] = "🏌🏼", - ["person_golfing_medium_light_skin_tone"] = "🏌🏼", - ["person_golfing_tone3"] = "🏌🏽", - ["person_golfing_medium_skin_tone"] = "🏌🏽", - ["person_golfing_tone4"] = "🏌🏾", - ["person_golfing_medium_dark_skin_tone"] = "🏌🏾", - ["person_golfing_tone5"] = "🏌🏿", - ["person_golfing_dark_skin_tone"] = "🏌🏿", - ["woman_golfing"] = "🏌️‍♀️", - ["woman_golfing_tone1"] = "🏌🏻‍♀️", - ["woman_golfing_light_skin_tone"] = "🏌🏻‍♀️", - ["woman_golfing_tone2"] = "🏌🏼‍♀️", - ["woman_golfing_medium_light_skin_tone"] = "🏌🏼‍♀️", - ["woman_golfing_tone3"] = "🏌🏽‍♀️", - ["woman_golfing_medium_skin_tone"] = "🏌🏽‍♀️", - ["woman_golfing_tone4"] = "🏌🏾‍♀️", - ["woman_golfing_medium_dark_skin_tone"] = "🏌🏾‍♀️", - ["woman_golfing_tone5"] = "🏌🏿‍♀️", - ["woman_golfing_dark_skin_tone"] = "🏌🏿‍♀️", - ["man_golfing"] = "🏌️‍♂️", - ["man_golfing_tone1"] = "🏌🏻‍♂️", - ["man_golfing_light_skin_tone"] = "🏌🏻‍♂️", - ["man_golfing_tone2"] = "🏌🏼‍♂️", - ["man_golfing_medium_light_skin_tone"] = "🏌🏼‍♂️", - ["man_golfing_tone3"] = "🏌🏽‍♂️", - ["man_golfing_medium_skin_tone"] = "🏌🏽‍♂️", - ["man_golfing_tone4"] = "🏌🏾‍♂️", - ["man_golfing_medium_dark_skin_tone"] = "🏌🏾‍♂️", - ["man_golfing_tone5"] = "🏌🏿‍♂️", - ["man_golfing_dark_skin_tone"] = "🏌🏿‍♂️", - ["horse_racing"] = "🏇", - ["horse_racing_tone1"] = "🏇🏻", - ["horse_racing_tone2"] = "🏇🏼", - ["horse_racing_tone3"] = "🏇🏽", - ["horse_racing_tone4"] = "🏇🏾", - ["horse_racing_tone5"] = "🏇🏿", - ["person_in_lotus_position"] = "🧘", - ["person_in_lotus_position_tone1"] = "🧘🏻", - ["person_in_lotus_position_light_skin_tone"] = "🧘🏻", - ["person_in_lotus_position_tone2"] = "🧘🏼", - ["person_in_lotus_position_medium_light_skin_tone"] = "🧘🏼", - ["person_in_lotus_position_tone3"] = "🧘🏽", - ["person_in_lotus_position_medium_skin_tone"] = "🧘🏽", - ["person_in_lotus_position_tone4"] = "🧘🏾", - ["person_in_lotus_position_medium_dark_skin_tone"] = "🧘🏾", - ["person_in_lotus_position_tone5"] = "🧘🏿", - ["person_in_lotus_position_dark_skin_tone"] = "🧘🏿", - ["woman_in_lotus_position"] = "🧘‍♀️", - ["woman_in_lotus_position_tone1"] = "🧘🏻‍♀️", - ["woman_in_lotus_position_light_skin_tone"] = "🧘🏻‍♀️", - ["woman_in_lotus_position_tone2"] = "🧘🏼‍♀️", - ["woman_in_lotus_position_medium_light_skin_tone"] = "🧘🏼‍♀️", - ["woman_in_lotus_position_tone3"] = "🧘🏽‍♀️", - ["woman_in_lotus_position_medium_skin_tone"] = "🧘🏽‍♀️", - ["woman_in_lotus_position_tone4"] = "🧘🏾‍♀️", - ["woman_in_lotus_position_medium_dark_skin_tone"] = "🧘🏾‍♀️", - ["woman_in_lotus_position_tone5"] = "🧘🏿‍♀️", - ["woman_in_lotus_position_dark_skin_tone"] = "🧘🏿‍♀️", - ["man_in_lotus_position"] = "🧘‍♂️", - ["man_in_lotus_position_tone1"] = "🧘🏻‍♂️", - ["man_in_lotus_position_light_skin_tone"] = "🧘🏻‍♂️", - ["man_in_lotus_position_tone2"] = "🧘🏼‍♂️", - ["man_in_lotus_position_medium_light_skin_tone"] = "🧘🏼‍♂️", - ["man_in_lotus_position_tone3"] = "🧘🏽‍♂️", - ["man_in_lotus_position_medium_skin_tone"] = "🧘🏽‍♂️", - ["man_in_lotus_position_tone4"] = "🧘🏾‍♂️", - ["man_in_lotus_position_medium_dark_skin_tone"] = "🧘🏾‍♂️", - ["man_in_lotus_position_tone5"] = "🧘🏿‍♂️", - ["man_in_lotus_position_dark_skin_tone"] = "🧘🏿‍♂️", - ["person_surfing"] = "🏄", - ["surfer"] = "🏄", - ["person_surfing_tone1"] = "🏄🏻", - ["surfer_tone1"] = "🏄🏻", - ["person_surfing_tone2"] = "🏄🏼", - ["surfer_tone2"] = "🏄🏼", - ["person_surfing_tone3"] = "🏄🏽", - ["surfer_tone3"] = "🏄🏽", - ["person_surfing_tone4"] = "🏄🏾", - ["surfer_tone4"] = "🏄🏾", - ["person_surfing_tone5"] = "🏄🏿", - ["surfer_tone5"] = "🏄🏿", - ["woman_surfing"] = "🏄‍♀️", - ["woman_surfing_tone1"] = "🏄🏻‍♀️", - ["woman_surfing_light_skin_tone"] = "🏄🏻‍♀️", - ["woman_surfing_tone2"] = "🏄🏼‍♀️", - ["woman_surfing_medium_light_skin_tone"] = "🏄🏼‍♀️", - ["woman_surfing_tone3"] = "🏄🏽‍♀️", - ["woman_surfing_medium_skin_tone"] = "🏄🏽‍♀️", - ["woman_surfing_tone4"] = "🏄🏾‍♀️", - ["woman_surfing_medium_dark_skin_tone"] = "🏄🏾‍♀️", - ["woman_surfing_tone5"] = "🏄🏿‍♀️", - ["woman_surfing_dark_skin_tone"] = "🏄🏿‍♀️", - ["man_surfing"] = "🏄‍♂️", - ["man_surfing_tone1"] = "🏄🏻‍♂️", - ["man_surfing_light_skin_tone"] = "🏄🏻‍♂️", - ["man_surfing_tone2"] = "🏄🏼‍♂️", - ["man_surfing_medium_light_skin_tone"] = "🏄🏼‍♂️", - ["man_surfing_tone3"] = "🏄🏽‍♂️", - ["man_surfing_medium_skin_tone"] = "🏄🏽‍♂️", - ["man_surfing_tone4"] = "🏄🏾‍♂️", - ["man_surfing_medium_dark_skin_tone"] = "🏄🏾‍♂️", - ["man_surfing_tone5"] = "🏄🏿‍♂️", - ["man_surfing_dark_skin_tone"] = "🏄🏿‍♂️", - ["person_swimming"] = "🏊", - ["swimmer"] = "🏊", - ["person_swimming_tone1"] = "🏊🏻", - ["swimmer_tone1"] = "🏊🏻", - ["person_swimming_tone2"] = "🏊🏼", - ["swimmer_tone2"] = "🏊🏼", - ["person_swimming_tone3"] = "🏊🏽", - ["swimmer_tone3"] = "🏊🏽", - ["person_swimming_tone4"] = "🏊🏾", - ["swimmer_tone4"] = "🏊🏾", - ["person_swimming_tone5"] = "🏊🏿", - ["swimmer_tone5"] = "🏊🏿", - ["woman_swimming"] = "🏊‍♀️", - ["woman_swimming_tone1"] = "🏊🏻‍♀️", - ["woman_swimming_light_skin_tone"] = "🏊🏻‍♀️", - ["woman_swimming_tone2"] = "🏊🏼‍♀️", - ["woman_swimming_medium_light_skin_tone"] = "🏊🏼‍♀️", - ["woman_swimming_tone3"] = "🏊🏽‍♀️", - ["woman_swimming_medium_skin_tone"] = "🏊🏽‍♀️", - ["woman_swimming_tone4"] = "🏊🏾‍♀️", - ["woman_swimming_medium_dark_skin_tone"] = "🏊🏾‍♀️", - ["woman_swimming_tone5"] = "🏊🏿‍♀️", - ["woman_swimming_dark_skin_tone"] = "🏊🏿‍♀️", - ["man_swimming"] = "🏊‍♂️", - ["man_swimming_tone1"] = "🏊🏻‍♂️", - ["man_swimming_light_skin_tone"] = "🏊🏻‍♂️", - ["man_swimming_tone2"] = "🏊🏼‍♂️", - ["man_swimming_medium_light_skin_tone"] = "🏊🏼‍♂️", - ["man_swimming_tone3"] = "🏊🏽‍♂️", - ["man_swimming_medium_skin_tone"] = "🏊🏽‍♂️", - ["man_swimming_tone4"] = "🏊🏾‍♂️", - ["man_swimming_medium_dark_skin_tone"] = "🏊🏾‍♂️", - ["man_swimming_tone5"] = "🏊🏿‍♂️", - ["man_swimming_dark_skin_tone"] = "🏊🏿‍♂️", - ["person_playing_water_polo"] = "🤽", - ["water_polo"] = "🤽", - ["person_playing_water_polo_tone1"] = "🤽🏻", - ["water_polo_tone1"] = "🤽🏻", - ["person_playing_water_polo_tone2"] = "🤽🏼", - ["water_polo_tone2"] = "🤽🏼", - ["person_playing_water_polo_tone3"] = "🤽🏽", - ["water_polo_tone3"] = "🤽🏽", - ["person_playing_water_polo_tone4"] = "🤽🏾", - ["water_polo_tone4"] = "🤽🏾", - ["person_playing_water_polo_tone5"] = "🤽🏿", - ["water_polo_tone5"] = "🤽🏿", - ["woman_playing_water_polo"] = "🤽‍♀️", - ["woman_playing_water_polo_tone1"] = "🤽🏻‍♀️", - ["woman_playing_water_polo_light_skin_tone"] = "🤽🏻‍♀️", - ["woman_playing_water_polo_tone2"] = "🤽🏼‍♀️", - ["woman_playing_water_polo_medium_light_skin_tone"] = "🤽🏼‍♀️", - ["woman_playing_water_polo_tone3"] = "🤽🏽‍♀️", - ["woman_playing_water_polo_medium_skin_tone"] = "🤽🏽‍♀️", - ["woman_playing_water_polo_tone4"] = "🤽🏾‍♀️", - ["woman_playing_water_polo_medium_dark_skin_tone"] = "🤽🏾‍♀️", - ["woman_playing_water_polo_tone5"] = "🤽🏿‍♀️", - ["woman_playing_water_polo_dark_skin_tone"] = "🤽🏿‍♀️", - ["man_playing_water_polo"] = "🤽‍♂️", - ["man_playing_water_polo_tone1"] = "🤽🏻‍♂️", - ["man_playing_water_polo_light_skin_tone"] = "🤽🏻‍♂️", - ["man_playing_water_polo_tone2"] = "🤽🏼‍♂️", - ["man_playing_water_polo_medium_light_skin_tone"] = "🤽🏼‍♂️", - ["man_playing_water_polo_tone3"] = "🤽🏽‍♂️", - ["man_playing_water_polo_medium_skin_tone"] = "🤽🏽‍♂️", - ["man_playing_water_polo_tone4"] = "🤽🏾‍♂️", - ["man_playing_water_polo_medium_dark_skin_tone"] = "🤽🏾‍♂️", - ["man_playing_water_polo_tone5"] = "🤽🏿‍♂️", - ["man_playing_water_polo_dark_skin_tone"] = "🤽🏿‍♂️", - ["person_rowing_boat"] = "🚣", - ["rowboat"] = "🚣", - ["person_rowing_boat_tone1"] = "🚣🏻", - ["rowboat_tone1"] = "🚣🏻", - ["person_rowing_boat_tone2"] = "🚣🏼", - ["rowboat_tone2"] = "🚣🏼", - ["person_rowing_boat_tone3"] = "🚣🏽", - ["rowboat_tone3"] = "🚣🏽", - ["person_rowing_boat_tone4"] = "🚣🏾", - ["rowboat_tone4"] = "🚣🏾", - ["person_rowing_boat_tone5"] = "🚣🏿", - ["rowboat_tone5"] = "🚣🏿", - ["woman_rowing_boat"] = "🚣‍♀️", - ["woman_rowing_boat_tone1"] = "🚣🏻‍♀️", - ["woman_rowing_boat_light_skin_tone"] = "🚣🏻‍♀️", - ["woman_rowing_boat_tone2"] = "🚣🏼‍♀️", - ["woman_rowing_boat_medium_light_skin_tone"] = "🚣🏼‍♀️", - ["woman_rowing_boat_tone3"] = "🚣🏽‍♀️", - ["woman_rowing_boat_medium_skin_tone"] = "🚣🏽‍♀️", - ["woman_rowing_boat_tone4"] = "🚣🏾‍♀️", - ["woman_rowing_boat_medium_dark_skin_tone"] = "🚣🏾‍♀️", - ["woman_rowing_boat_tone5"] = "🚣🏿‍♀️", - ["woman_rowing_boat_dark_skin_tone"] = "🚣🏿‍♀️", - ["man_rowing_boat"] = "🚣‍♂️", - ["man_rowing_boat_tone1"] = "🚣🏻‍♂️", - ["man_rowing_boat_light_skin_tone"] = "🚣🏻‍♂️", - ["man_rowing_boat_tone2"] = "🚣🏼‍♂️", - ["man_rowing_boat_medium_light_skin_tone"] = "🚣🏼‍♂️", - ["man_rowing_boat_tone3"] = "🚣🏽‍♂️", - ["man_rowing_boat_medium_skin_tone"] = "🚣🏽‍♂️", - ["man_rowing_boat_tone4"] = "🚣🏾‍♂️", - ["man_rowing_boat_medium_dark_skin_tone"] = "🚣🏾‍♂️", - ["man_rowing_boat_tone5"] = "🚣🏿‍♂️", - ["man_rowing_boat_dark_skin_tone"] = "🚣🏿‍♂️", - ["person_climbing"] = "🧗", - ["person_climbing_tone1"] = "🧗🏻", - ["person_climbing_light_skin_tone"] = "🧗🏻", - ["person_climbing_tone2"] = "🧗🏼", - ["person_climbing_medium_light_skin_tone"] = "🧗🏼", - ["person_climbing_tone3"] = "🧗🏽", - ["person_climbing_medium_skin_tone"] = "🧗🏽", - ["person_climbing_tone4"] = "🧗🏾", - ["person_climbing_medium_dark_skin_tone"] = "🧗🏾", - ["person_climbing_tone5"] = "🧗🏿", - ["person_climbing_dark_skin_tone"] = "🧗🏿", - ["woman_climbing"] = "🧗‍♀️", - ["woman_climbing_tone1"] = "🧗🏻‍♀️", - ["woman_climbing_light_skin_tone"] = "🧗🏻‍♀️", - ["woman_climbing_tone2"] = "🧗🏼‍♀️", - ["woman_climbing_medium_light_skin_tone"] = "🧗🏼‍♀️", - ["woman_climbing_tone3"] = "🧗🏽‍♀️", - ["woman_climbing_medium_skin_tone"] = "🧗🏽‍♀️", - ["woman_climbing_tone4"] = "🧗🏾‍♀️", - ["woman_climbing_medium_dark_skin_tone"] = "🧗🏾‍♀️", - ["woman_climbing_tone5"] = "🧗🏿‍♀️", - ["woman_climbing_dark_skin_tone"] = "🧗🏿‍♀️", - ["man_climbing"] = "🧗‍♂️", - ["man_climbing_tone1"] = "🧗🏻‍♂️", - ["man_climbing_light_skin_tone"] = "🧗🏻‍♂️", - ["man_climbing_tone2"] = "🧗🏼‍♂️", - ["man_climbing_medium_light_skin_tone"] = "🧗🏼‍♂️", - ["man_climbing_tone3"] = "🧗🏽‍♂️", - ["man_climbing_medium_skin_tone"] = "🧗🏽‍♂️", - ["man_climbing_tone4"] = "🧗🏾‍♂️", - ["man_climbing_medium_dark_skin_tone"] = "🧗🏾‍♂️", - ["man_climbing_tone5"] = "🧗🏿‍♂️", - ["man_climbing_dark_skin_tone"] = "🧗🏿‍♂️", - ["person_mountain_biking"] = "🚵", - ["mountain_bicyclist"] = "🚵", - ["person_mountain_biking_tone1"] = "🚵🏻", - ["mountain_bicyclist_tone1"] = "🚵🏻", - ["person_mountain_biking_tone2"] = "🚵🏼", - ["mountain_bicyclist_tone2"] = "🚵🏼", - ["person_mountain_biking_tone3"] = "🚵🏽", - ["mountain_bicyclist_tone3"] = "🚵🏽", - ["person_mountain_biking_tone4"] = "🚵🏾", - ["mountain_bicyclist_tone4"] = "🚵🏾", - ["person_mountain_biking_tone5"] = "🚵🏿", - ["mountain_bicyclist_tone5"] = "🚵🏿", - ["woman_mountain_biking"] = "🚵‍♀️", - ["woman_mountain_biking_tone1"] = "🚵🏻‍♀️", - ["woman_mountain_biking_light_skin_tone"] = "🚵🏻‍♀️", - ["woman_mountain_biking_tone2"] = "🚵🏼‍♀️", - ["woman_mountain_biking_medium_light_skin_tone"] = "🚵🏼‍♀️", - ["woman_mountain_biking_tone3"] = "🚵🏽‍♀️", - ["woman_mountain_biking_medium_skin_tone"] = "🚵🏽‍♀️", - ["woman_mountain_biking_tone4"] = "🚵🏾‍♀️", - ["woman_mountain_biking_medium_dark_skin_tone"] = "🚵🏾‍♀️", - ["woman_mountain_biking_tone5"] = "🚵🏿‍♀️", - ["woman_mountain_biking_dark_skin_tone"] = "🚵🏿‍♀️", - ["man_mountain_biking"] = "🚵‍♂️", - ["man_mountain_biking_tone1"] = "🚵🏻‍♂️", - ["man_mountain_biking_light_skin_tone"] = "🚵🏻‍♂️", - ["man_mountain_biking_tone2"] = "🚵🏼‍♂️", - ["man_mountain_biking_medium_light_skin_tone"] = "🚵🏼‍♂️", - ["man_mountain_biking_tone3"] = "🚵🏽‍♂️", - ["man_mountain_biking_medium_skin_tone"] = "🚵🏽‍♂️", - ["man_mountain_biking_tone4"] = "🚵🏾‍♂️", - ["man_mountain_biking_medium_dark_skin_tone"] = "🚵🏾‍♂️", - ["man_mountain_biking_tone5"] = "🚵🏿‍♂️", - ["man_mountain_biking_dark_skin_tone"] = "🚵🏿‍♂️", - ["person_biking"] = "🚴", - ["bicyclist"] = "🚴", - ["person_biking_tone1"] = "🚴🏻", - ["bicyclist_tone1"] = "🚴🏻", - ["person_biking_tone2"] = "🚴🏼", - ["bicyclist_tone2"] = "🚴🏼", - ["person_biking_tone3"] = "🚴🏽", - ["bicyclist_tone3"] = "🚴🏽", - ["person_biking_tone4"] = "🚴🏾", - ["bicyclist_tone4"] = "🚴🏾", - ["person_biking_tone5"] = "🚴🏿", - ["bicyclist_tone5"] = "🚴🏿", - ["woman_biking"] = "🚴‍♀️", - ["woman_biking_tone1"] = "🚴🏻‍♀️", - ["woman_biking_light_skin_tone"] = "🚴🏻‍♀️", - ["woman_biking_tone2"] = "🚴🏼‍♀️", - ["woman_biking_medium_light_skin_tone"] = "🚴🏼‍♀️", - ["woman_biking_tone3"] = "🚴🏽‍♀️", - ["woman_biking_medium_skin_tone"] = "🚴🏽‍♀️", - ["woman_biking_tone4"] = "🚴🏾‍♀️", - ["woman_biking_medium_dark_skin_tone"] = "🚴🏾‍♀️", - ["woman_biking_tone5"] = "🚴🏿‍♀️", - ["woman_biking_dark_skin_tone"] = "🚴🏿‍♀️", - ["man_biking"] = "🚴‍♂️", - ["man_biking_tone1"] = "🚴🏻‍♂️", - ["man_biking_light_skin_tone"] = "🚴🏻‍♂️", - ["man_biking_tone2"] = "🚴🏼‍♂️", - ["man_biking_medium_light_skin_tone"] = "🚴🏼‍♂️", - ["man_biking_tone3"] = "🚴🏽‍♂️", - ["man_biking_medium_skin_tone"] = "🚴🏽‍♂️", - ["man_biking_tone4"] = "🚴🏾‍♂️", - ["man_biking_medium_dark_skin_tone"] = "🚴🏾‍♂️", - ["man_biking_tone5"] = "🚴🏿‍♂️", - ["man_biking_dark_skin_tone"] = "🚴🏿‍♂️", - ["trophy"] = "🏆", - ["first_place"] = "🥇", - ["first_place_medal"] = "🥇", - ["second_place"] = "🥈", - ["second_place_medal"] = "🥈", - ["third_place"] = "🥉", - ["third_place_medal"] = "🥉", - ["medal"] = "🏅", - ["sports_medal"] = "🏅", - ["military_medal"] = "🎖️", - ["rosette"] = "🏵️", - ["reminder_ribbon"] = "🎗️", - ["ticket"] = "🎫", - ["tickets"] = "🎟️", - ["admission_tickets"] = "🎟️", - ["circus_tent"] = "🎪", - ["person_juggling"] = "🤹", - ["juggling"] = "🤹", - ["juggler"] = "🤹", - ["person_juggling_tone1"] = "🤹🏻", - ["juggling_tone1"] = "🤹🏻", - ["juggler_tone1"] = "🤹🏻", - ["person_juggling_tone2"] = "🤹🏼", - ["juggling_tone2"] = "🤹🏼", - ["juggler_tone2"] = "🤹🏼", - ["person_juggling_tone3"] = "🤹🏽", - ["juggling_tone3"] = "🤹🏽", - ["juggler_tone3"] = "🤹🏽", - ["person_juggling_tone4"] = "🤹🏾", - ["juggling_tone4"] = "🤹🏾", - ["juggler_tone4"] = "🤹🏾", - ["person_juggling_tone5"] = "🤹🏿", - ["juggling_tone5"] = "🤹🏿", - ["juggler_tone5"] = "🤹🏿", - ["woman_juggling"] = "🤹‍♀️", - ["woman_juggling_tone1"] = "🤹🏻‍♀️", - ["woman_juggling_light_skin_tone"] = "🤹🏻‍♀️", - ["woman_juggling_tone2"] = "🤹🏼‍♀️", - ["woman_juggling_medium_light_skin_tone"] = "🤹🏼‍♀️", - ["woman_juggling_tone3"] = "🤹🏽‍♀️", - ["woman_juggling_medium_skin_tone"] = "🤹🏽‍♀️", - ["woman_juggling_tone4"] = "🤹🏾‍♀️", - ["woman_juggling_medium_dark_skin_tone"] = "🤹🏾‍♀️", - ["woman_juggling_tone5"] = "🤹🏿‍♀️", - ["woman_juggling_dark_skin_tone"] = "🤹🏿‍♀️", - ["man_juggling"] = "🤹‍♂️", - ["man_juggling_tone1"] = "🤹🏻‍♂️", - ["man_juggling_light_skin_tone"] = "🤹🏻‍♂️", - ["man_juggling_tone2"] = "🤹🏼‍♂️", - ["man_juggling_medium_light_skin_tone"] = "🤹🏼‍♂️", - ["man_juggling_tone3"] = "🤹🏽‍♂️", - ["man_juggling_medium_skin_tone"] = "🤹🏽‍♂️", - ["man_juggling_tone4"] = "🤹🏾‍♂️", - ["man_juggling_medium_dark_skin_tone"] = "🤹🏾‍♂️", - ["man_juggling_tone5"] = "🤹🏿‍♂️", - ["man_juggling_dark_skin_tone"] = "🤹🏿‍♂️", - ["performing_arts"] = "🎭", - ["ballet_shoes"] = "🩰", - ["art"] = "🎨", - ["clapper"] = "🎬", - ["microphone"] = "🎤", - ["headphones"] = "🎧", - ["musical_score"] = "🎼", - ["musical_keyboard"] = "🎹", - ["drum"] = "🥁", - ["drum_with_drumsticks"] = "🥁", - ["long_drum"] = "🪘", - ["saxophone"] = "🎷", - ["trumpet"] = "🎺", - ["guitar"] = "🎸", - ["banjo"] = "🪕", - ["violin"] = "🎻", - ["accordion"] = "🪗", - ["game_die"] = "🎲", - ["chess_pawn"] = "♟️", - ["dart"] = "🎯", - ["bowling"] = "🎳", - ["video_game"] = "🎮", - ["slot_machine"] = "🎰", - ["jigsaw"] = "🧩", - ["red_car"] = "🚗", - ["taxi"] = "🚕", - ["blue_car"] = "🚙", - ["pickup_truck"] = "🛻", - ["bus"] = "🚌", - ["trolleybus"] = "🚎", - ["race_car"] = "🏎️", - ["racing_car"] = "🏎️", - ["police_car"] = "🚓", - ["ambulance"] = "🚑", - ["fire_engine"] = "🚒", - ["minibus"] = "🚐", - ["truck"] = "🚚", - ["articulated_lorry"] = "🚛", - ["tractor"] = "🚜", - ["probing_cane"] = "🦯", - ["manual_wheelchair"] = "🦽", - ["motorized_wheelchair"] = "🦼", - ["scooter"] = "🛴", - ["bike"] = "🚲", - ["motor_scooter"] = "🛵", - ["motorbike"] = "🛵", - ["motorcycle"] = "🏍️", - ["racing_motorcycle"] = "🏍️", - ["auto_rickshaw"] = "🛺", - ["rotating_light"] = "🚨", - ["oncoming_police_car"] = "🚔", - ["oncoming_bus"] = "🚍", - ["oncoming_automobile"] = "🚘", - ["oncoming_taxi"] = "🚖", - ["aerial_tramway"] = "🚡", - ["mountain_cableway"] = "🚠", - ["suspension_railway"] = "🚟", - ["railway_car"] = "🚃", - ["train"] = "🚋", - ["mountain_railway"] = "🚞", - ["monorail"] = "🚝", - ["bullettrain_side"] = "🚄", - ["bullettrain_front"] = "🚅", - ["light_rail"] = "🚈", - ["steam_locomotive"] = "🚂", - ["train2"] = "🚆", - ["metro"] = "🚇", - ["tram"] = "🚊", - ["station"] = "🚉", - ["airplane"] = "✈️", - ["airplane_departure"] = "🛫", - ["airplane_arriving"] = "🛬", - ["airplane_small"] = "🛩️", - ["small_airplane"] = "🛩️", - ["seat"] = "💺", - ["satellite_orbital"] = "🛰️", - ["rocket"] = "🚀", - ["flying_saucer"] = "🛸", - ["helicopter"] = "🚁", - ["canoe"] = "🛶", - ["kayak"] = "🛶", - ["sailboat"] = "⛵", - ["speedboat"] = "🚤", - ["motorboat"] = "🛥️", - ["cruise_ship"] = "🛳️", - ["passenger_ship"] = "🛳️", - ["ferry"] = "⛴️", - ["ship"] = "🚢", - ["anchor"] = "⚓", - ["fuelpump"] = "⛽", - ["construction"] = "🚧", - ["vertical_traffic_light"] = "🚦", - ["traffic_light"] = "🚥", - ["busstop"] = "🚏", - ["map"] = "🗺️", - ["world_map"] = "🗺️", - ["moyai"] = "🗿", - ["statue_of_liberty"] = "🗽", - ["tokyo_tower"] = "🗼", - ["european_castle"] = "🏰", - ["japanese_castle"] = "🏯", - ["stadium"] = "🏟️", - ["ferris_wheel"] = "🎡", - ["roller_coaster"] = "🎢", - ["carousel_horse"] = "🎠", - ["fountain"] = "⛲", - ["beach_umbrella"] = "⛱️", - ["umbrella_on_ground"] = "⛱️", - ["beach"] = "🏖️", - ["beach_with_umbrella"] = "🏖️", - ["island"] = "🏝️", - ["desert_island"] = "🏝️", - ["desert"] = "🏜️", - ["volcano"] = "🌋", - ["mountain"] = "⛰️", - ["mountain_snow"] = "🏔️", - ["snow_capped_mountain"] = "🏔️", - ["mount_fuji"] = "🗻", - ["camping"] = "🏕️", - ["tent"] = "⛺", - ["house"] = "🏠", - ["house_with_garden"] = "🏡", - ["homes"] = "🏘️", - ["house_buildings"] = "🏘️", - ["house_abandoned"] = "🏚️", - ["derelict_house_building"] = "🏚️", - ["hut"] = "🛖", - ["construction_site"] = "🏗️", - ["building_construction"] = "🏗️", - ["factory"] = "🏭", - ["office"] = "🏢", - ["department_store"] = "🏬", - ["post_office"] = "🏣", - ["european_post_office"] = "🏤", - ["hospital"] = "🏥", - ["bank"] = "🏦", - ["hotel"] = "🏨", - ["convenience_store"] = "🏪", - ["school"] = "🏫", - ["love_hotel"] = "🏩", - ["wedding"] = "💒", - ["classical_building"] = "🏛️", - ["church"] = "⛪", - ["mosque"] = "🕌", - ["synagogue"] = "🕍", - ["hindu_temple"] = "🛕", - ["kaaba"] = "🕋", - ["shinto_shrine"] = "⛩️", - ["railway_track"] = "🛤️", - ["railroad_track"] = "🛤️", - ["motorway"] = "🛣️", - ["japan"] = "🗾", - ["rice_scene"] = "🎑", - ["park"] = "🏞️", - ["national_park"] = "🏞️", - ["sunrise"] = "🌅", - ["sunrise_over_mountains"] = "🌄", - ["stars"] = "🌠", - ["sparkler"] = "🎇", - ["fireworks"] = "🎆", - ["city_sunset"] = "🌇", - ["city_sunrise"] = "🌇", - ["city_dusk"] = "🌆", - ["cityscape"] = "🏙️", - ["night_with_stars"] = "🌃", - ["milky_way"] = "🌌", - ["bridge_at_night"] = "🌉", - ["foggy"] = "🌁", - ["watch"] = "⌚", - ["mobile_phone"] = "📱", - ["iphone"] = "📱", - ["calling"] = "📲", - ["computer"] = "💻", - ["keyboard"] = "⌨️", - ["desktop"] = "🖥️", - ["desktop_computer"] = "🖥️", - ["printer"] = "🖨️", - ["mouse_three_button"] = "🖱️", - ["three_button_mouse"] = "🖱️", - ["trackball"] = "🖲️", - ["joystick"] = "🕹️", - ["compression"] = "🗜️", - ["minidisc"] = "💽", - ["floppy_disk"] = "💾", - ["cd"] = "💿", - ["dvd"] = "📀", - ["vhs"] = "📼", - ["camera"] = "📷", - ["camera_with_flash"] = "📸", - ["video_camera"] = "📹", - ["movie_camera"] = "🎥", - ["projector"] = "📽️", - ["film_projector"] = "📽️", - ["film_frames"] = "🎞️", - ["telephone_receiver"] = "📞", - ["telephone"] = "☎️", - ["pager"] = "📟", - ["fax"] = "📠", - ["tv"] = "📺", - ["radio"] = "📻", - ["microphone2"] = "🎙️", - ["studio_microphone"] = "🎙️", - ["level_slider"] = "🎚️", - ["control_knobs"] = "🎛️", - ["compass"] = "🧭", - ["stopwatch"] = "⏱️", - ["timer"] = "⏲️", - ["timer_clock"] = "⏲️", - ["alarm_clock"] = "⏰", - ["clock"] = "🕰️", - ["mantlepiece_clock"] = "🕰️", - ["hourglass"] = "⌛", - ["hourglass_flowing_sand"] = "⏳", - ["satellite"] = "📡", - ["battery"] = "🔋", - ["electric_plug"] = "🔌", - ["bulb"] = "💡", - ["flashlight"] = "🔦", - ["candle"] = "🕯️", - ["diya_lamp"] = "🪔", - ["fire_extinguisher"] = "🧯", - ["oil"] = "🛢️", - ["oil_drum"] = "🛢️", - ["money_with_wings"] = "💸", - ["dollar"] = "💵", - ["yen"] = "💴", - ["euro"] = "💶", - ["pound"] = "💷", - ["coin"] = "🪙", - ["moneybag"] = "💰", - ["credit_card"] = "💳", - ["gem"] = "💎", - ["scales"] = "⚖️", - ["ladder"] = "🪜", - ["toolbox"] = "🧰", - ["screwdriver"] = "🪛", - ["wrench"] = "🔧", - ["hammer"] = "🔨", - ["hammer_pick"] = "⚒️", - ["hammer_and_pick"] = "⚒️", - ["tools"] = "🛠️", - ["hammer_and_wrench"] = "🛠️", - ["pick"] = "⛏️", - ["nut_and_bolt"] = "🔩", - ["gear"] = "⚙️", - ["bricks"] = "🧱", - ["chains"] = "⛓️", - ["hook"] = "🪝", - ["knot"] = "🪢", - ["magnet"] = "🧲", - ["gun"] = "🔫", - ["bomb"] = "💣", - ["firecracker"] = "🧨", - ["axe"] = "🪓", - ["carpentry_saw"] = "🪚", - ["knife"] = "🔪", - ["dagger"] = "🗡️", - ["dagger_knife"] = "🗡️", - ["crossed_swords"] = "⚔️", - ["shield"] = "🛡️", - ["smoking"] = "🚬", - ["coffin"] = "⚰️", - ["headstone"] = "🪦", - ["urn"] = "⚱️", - ["funeral_urn"] = "⚱️", - ["amphora"] = "🏺", - ["magic_wand"] = "🪄", - ["crystal_ball"] = "🔮", - ["prayer_beads"] = "📿", - ["nazar_amulet"] = "🧿", - ["barber"] = "💈", - ["alembic"] = "⚗️", - ["telescope"] = "🔭", - ["microscope"] = "🔬", - ["hole"] = "🕳️", - ["window"] = "🪟", - ["adhesive_bandage"] = "🩹", - ["stethoscope"] = "🩺", - ["pill"] = "💊", - ["syringe"] = "💉", - ["drop_of_blood"] = "🩸", - ["dna"] = "🧬", - ["microbe"] = "🦠", - ["petri_dish"] = "🧫", - ["test_tube"] = "🧪", - ["thermometer"] = "🌡️", - ["mouse_trap"] = "🪤", - ["broom"] = "🧹", - ["basket"] = "🧺", - ["sewing_needle"] = "🪡", - ["roll_of_paper"] = "🧻", - ["toilet"] = "🚽", - ["plunger"] = "🪠", - ["bucket"] = "🪣", - ["potable_water"] = "🚰", - ["shower"] = "🚿", - ["bathtub"] = "🛁", - ["bath"] = "🛀", - ["bath_tone1"] = "🛀🏻", - ["bath_tone2"] = "🛀🏼", - ["bath_tone3"] = "🛀🏽", - ["bath_tone4"] = "🛀🏾", - ["bath_tone5"] = "🛀🏿", - ["toothbrush"] = "🪥", - ["soap"] = "🧼", - ["razor"] = "🪒", - ["sponge"] = "🧽", - ["squeeze_bottle"] = "🧴", - ["bellhop"] = "🛎️", - ["bellhop_bell"] = "🛎️", - ["key"] = "🔑", - ["key2"] = "🗝️", - ["old_key"] = "🗝️", - ["door"] = "🚪", - ["chair"] = "🪑", - ["mirror"] = "🪞", - ["couch"] = "🛋️", - ["couch_and_lamp"] = "🛋️", - ["bed"] = "🛏️", - ["sleeping_accommodation"] = "🛌", - ["person_in_bed_tone1"] = "🛌🏻", - ["person_in_bed_light_skin_tone"] = "🛌🏻", - ["person_in_bed_tone2"] = "🛌🏼", - ["person_in_bed_medium_light_skin_tone"] = "🛌🏼", - ["person_in_bed_tone3"] = "🛌🏽", - ["person_in_bed_medium_skin_tone"] = "🛌🏽", - ["person_in_bed_tone4"] = "🛌🏾", - ["person_in_bed_medium_dark_skin_tone"] = "🛌🏾", - ["person_in_bed_tone5"] = "🛌🏿", - ["person_in_bed_dark_skin_tone"] = "🛌🏿", - ["teddy_bear"] = "🧸", - ["frame_photo"] = "🖼️", - ["frame_with_picture"] = "🖼️", - ["shopping_bags"] = "🛍️", - ["shopping_cart"] = "🛒", - ["shopping_trolley"] = "🛒", - ["gift"] = "🎁", - ["balloon"] = "🎈", - ["flags"] = "🎏", - ["ribbon"] = "🎀", - ["confetti_ball"] = "🎊", - ["tada"] = "🎉", - ["piñata"] = "🪅", - ["nesting_dolls"] = "🪆", - ["dolls"] = "🎎", - ["izakaya_lantern"] = "🏮", - ["wind_chime"] = "🎐", - ["red_envelope"] = "🧧", - ["envelope"] = "✉️", - ["envelope_with_arrow"] = "📩", - ["incoming_envelope"] = "📨", - ["e_mail"] = "📧", - ["email"] = "📧", - ["love_letter"] = "💌", - ["inbox_tray"] = "📥", - ["outbox_tray"] = "📤", - ["package"] = "📦", - ["label"] = "🏷️", - ["mailbox_closed"] = "📪", - ["mailbox"] = "📫", - ["mailbox_with_mail"] = "📬", - ["mailbox_with_no_mail"] = "📭", - ["postbox"] = "📮", - ["postal_horn"] = "📯", - ["placard"] = "🪧", - ["scroll"] = "📜", - ["page_with_curl"] = "📃", - ["page_facing_up"] = "📄", - ["bookmark_tabs"] = "📑", - ["receipt"] = "🧾", - ["bar_chart"] = "📊", - ["chart_with_upwards_trend"] = "📈", - ["chart_with_downwards_trend"] = "📉", - ["notepad_spiral"] = "🗒️", - ["spiral_note_pad"] = "🗒️", - ["calendar_spiral"] = "🗓️", - ["spiral_calendar_pad"] = "🗓️", - ["calendar"] = "📆", - ["date"] = "📅", - ["wastebasket"] = "🗑️", - ["card_index"] = "📇", - ["card_box"] = "🗃️", - ["card_file_box"] = "🗃️", - ["ballot_box"] = "🗳️", - ["ballot_box_with_ballot"] = "🗳️", - ["file_cabinet"] = "🗄️", - ["clipboard"] = "📋", - ["file_folder"] = "📁", - ["open_file_folder"] = "📂", - ["dividers"] = "🗂️", - ["card_index_dividers"] = "🗂️", - ["newspaper2"] = "🗞️", - ["rolled_up_newspaper"] = "🗞️", - ["newspaper"] = "📰", - ["notebook"] = "📓", - ["notebook_with_decorative_cover"] = "📔", - ["ledger"] = "📒", - ["closed_book"] = "📕", - ["green_book"] = "📗", - ["blue_book"] = "📘", - ["orange_book"] = "📙", - ["books"] = "📚", - ["book"] = "📖", - ["bookmark"] = "🔖", - ["safety_pin"] = "🧷", - ["link"] = "🔗", - ["paperclip"] = "📎", - ["paperclips"] = "🖇️", - ["linked_paperclips"] = "🖇️", - ["triangular_ruler"] = "📐", - ["straight_ruler"] = "📏", - ["abacus"] = "🧮", - ["pushpin"] = "📌", - ["round_pushpin"] = "📍", - ["scissors"] = "✂️", - ["pen_ballpoint"] = "🖊️", - ["lower_left_ballpoint_pen"] = "🖊️", - ["pen_fountain"] = "🖋️", - ["lower_left_fountain_pen"] = "🖋️", - ["black_nib"] = "✒️", - ["paintbrush"] = "🖌️", - ["lower_left_paintbrush"] = "🖌️", - ["crayon"] = "🖍️", - ["lower_left_crayon"] = "🖍️", - ["pencil"] = "📝", - ["memo"] = "📝", - ["pencil2"] = "✏️", - ["mag"] = "🔍", - ["mag_right"] = "🔎", - ["lock_with_ink_pen"] = "🔏", - ["closed_lock_with_key"] = "🔐", - ["lock"] = "🔒", - ["unlock"] = "🔓", - ["heart"] = "❤️", - ["orange_heart"] = "🧡", - ["yellow_heart"] = "💛", - ["green_heart"] = "💚", - ["blue_heart"] = "💙", - ["purple_heart"] = "💜", - ["black_heart"] = "🖤", - ["brown_heart"] = "🤎", - ["white_heart"] = "🤍", - ["broken_heart"] = "💔", - ["heart_exclamation"] = "❣️", - ["heavy_heart_exclamation_mark_ornament"] = "❣️", - ["two_hearts"] = "💕", - ["revolving_hearts"] = "💞", - ["heartbeat"] = "💓", - ["heartpulse"] = "💗", - ["sparkling_heart"] = "💖", - ["cupid"] = "💘", - ["gift_heart"] = "💝", - ["mending_heart"] = "❤️‍🩹", - ["heart_on_fire"] = "❤️‍🔥", - ["heart_decoration"] = "💟", - ["peace"] = "☮️", - ["peace_symbol"] = "☮️", - ["cross"] = "✝️", - ["latin_cross"] = "✝️", - ["star_and_crescent"] = "☪️", - ["om_symbol"] = "🕉️", - ["wheel_of_dharma"] = "☸️", - ["star_of_david"] = "✡️", - ["six_pointed_star"] = "🔯", - ["menorah"] = "🕎", - ["yin_yang"] = "☯️", - ["orthodox_cross"] = "☦️", - ["place_of_worship"] = "🛐", - ["worship_symbol"] = "🛐", - ["ophiuchus"] = "⛎", - ["aries"] = "♈", - ["taurus"] = "♉", - ["gemini"] = "♊", - ["cancer"] = "♋", - ["leo"] = "♌", - ["virgo"] = "♍", - ["libra"] = "♎", - ["scorpius"] = "♏", - ["sagittarius"] = "♐", - ["capricorn"] = "♑", - ["aquarius"] = "♒", - ["pisces"] = "♓", - ["id"] = "🆔", - ["atom"] = "⚛️", - ["atom_symbol"] = "⚛️", - ["accept"] = "🉑", - ["radioactive"] = "☢️", - ["radioactive_sign"] = "☢️", - ["biohazard"] = "☣️", - ["biohazard_sign"] = "☣️", - ["mobile_phone_off"] = "📴", - ["vibration_mode"] = "📳", - ["u6709"] = "🈶", - ["u7121"] = "🈚", - ["u7533"] = "🈸", - ["u55b6"] = "🈺", - ["u6708"] = "🈷️", - ["eight_pointed_black_star"] = "✴️", - ["vs"] = "🆚", - ["white_flower"] = "💮", - ["ideograph_advantage"] = "🉐", - ["secret"] = "㊙️", - ["congratulations"] = "㊗️", - ["u5408"] = "🈴", - ["u6e80"] = "🈵", - ["u5272"] = "🈹", - ["u7981"] = "🈲", - ["a"] = "🅰️", - ["b"] = "🅱️", - ["ab"] = "🆎", - ["cl"] = "🆑", - ["o2"] = "🅾️", - ["sos"] = "🆘", - ["x"] = "❌", - ["o"] = "⭕", - ["octagonal_sign"] = "🛑", - ["stop_sign"] = "🛑", - ["no_entry"] = "⛔", - ["name_badge"] = "📛", - ["no_entry_sign"] = "🚫", - ["100"] = "💯", - ["anger"] = "💢", - ["hotsprings"] = "♨️", - ["no_pedestrians"] = "🚷", - ["do_not_litter"] = "🚯", - ["no_bicycles"] = "🚳", - ["non_potable_water"] = "🚱", - ["underage"] = "🔞", - ["no_mobile_phones"] = "📵", - ["no_smoking"] = "🚭", - ["exclamation"] = "❗", - ["grey_exclamation"] = "❕", - ["question"] = "❓", - ["grey_question"] = "❔", - ["bangbang"] = "‼️", - ["interrobang"] = "⁉️", - ["low_brightness"] = "🔅", - ["high_brightness"] = "🔆", - ["part_alternation_mark"] = "〽️", - ["warning"] = "⚠️", - ["children_crossing"] = "🚸", - ["trident"] = "🔱", - ["fleur_de_lis"] = "⚜️", - ["beginner"] = "🔰", - ["recycle"] = "♻️", - ["white_check_mark"] = "✅", - ["u6307"] = "🈯", - ["chart"] = "💹", - ["sparkle"] = "❇️", - ["eight_spoked_asterisk"] = "✳️", - ["negative_squared_cross_mark"] = "❎", - ["globe_with_meridians"] = "🌐", - ["diamond_shape_with_a_dot_inside"] = "💠", - ["m"] = "Ⓜ️", - ["cyclone"] = "🌀", - ["zzz"] = "💤", - ["atm"] = "🏧", - ["wc"] = "🚾", - ["wheelchair"] = "♿", - ["parking"] = "🅿️", - ["u7a7a"] = "🈳", - ["sa"] = "🈂️", - ["passport_control"] = "🛂", - ["customs"] = "🛃", - ["baggage_claim"] = "🛄", - ["left_luggage"] = "🛅", - ["elevator"] = "🛗", - ["mens"] = "🚹", - ["womens"] = "🚺", - ["baby_symbol"] = "🚼", - ["restroom"] = "🚻", - ["put_litter_in_its_place"] = "🚮", - ["cinema"] = "🎦", - ["signal_strength"] = "📶", - ["koko"] = "🈁", - ["symbols"] = "🔣", - ["information_source"] = "ℹ️", - ["abc"] = "🔤", - ["abcd"] = "🔡", - ["capital_abcd"] = "🔠", - ["ng"] = "🆖", - ["ok"] = "🆗", - ["up"] = "🆙", - ["cool"] = "🆒", - ["new"] = "🆕", - ["free"] = "🆓", - ["zero"] = "0️⃣", - ["one"] = "1️⃣", - ["two"] = "2️⃣", - ["three"] = "3️⃣", - ["four"] = "4️⃣", - ["five"] = "5️⃣", - ["six"] = "6️⃣", - ["seven"] = "7️⃣", - ["eight"] = "8️⃣", - ["nine"] = "9️⃣", - ["keycap_ten"] = "🔟", - ["1234"] = "🔢", - ["hash"] = "#️⃣", - ["asterisk"] = "*️⃣", - ["keycap_asterisk"] = "*️⃣", - ["eject"] = "⏏️", - ["eject_symbol"] = "⏏️", - ["arrow_forward"] = "▶️", - ["pause_button"] = "⏸️", - ["double_vertical_bar"] = "⏸️", - ["play_pause"] = "⏯️", - ["stop_button"] = "⏹️", - ["record_button"] = "⏺️", - ["track_next"] = "⏭️", - ["next_track"] = "⏭️", - ["track_previous"] = "⏮️", - ["previous_track"] = "⏮️", - ["fast_forward"] = "⏩", - ["rewind"] = "⏪", - ["arrow_double_up"] = "⏫", - ["arrow_double_down"] = "⏬", - ["arrow_backward"] = "◀️", - ["arrow_up_small"] = "🔼", - ["arrow_down_small"] = "🔽", - ["arrow_right"] = "➡️", - ["arrow_left"] = "⬅️", - ["arrow_up"] = "⬆️", - ["arrow_down"] = "⬇️", - ["arrow_upper_right"] = "↗️", - ["arrow_lower_right"] = "↘️", - ["arrow_lower_left"] = "↙️", - ["arrow_upper_left"] = "↖️", - ["arrow_up_down"] = "↕️", - ["left_right_arrow"] = "↔️", - ["arrow_right_hook"] = "↪️", - ["leftwards_arrow_with_hook"] = "↩️", - ["arrow_heading_up"] = "⤴️", - ["arrow_heading_down"] = "⤵️", - ["twisted_rightwards_arrows"] = "🔀", - ["repeat"] = "🔁", - ["repeat_one"] = "🔂", - ["arrows_counterclockwise"] = "🔄", - ["arrows_clockwise"] = "🔃", - ["musical_note"] = "🎵", - ["notes"] = "🎶", - ["heavy_plus_sign"] = "➕", - ["heavy_minus_sign"] = "➖", - ["heavy_division_sign"] = "➗", - ["heavy_multiplication_x"] = "✖️", - ["infinity"] = "♾️", - ["heavy_dollar_sign"] = "💲", - ["currency_exchange"] = "💱", - ["tm"] = "™️", - ["copyright"] = "©️", - ["registered"] = "®️", - ["wavy_dash"] = "〰️", - ["curly_loop"] = "➰", - ["loop"] = "➿", - ["end"] = "🔚", - ["back"] = "🔙", - ["on"] = "🔛", - ["top"] = "🔝", - ["soon"] = "🔜", - ["heavy_check_mark"] = "✔️", - ["ballot_box_with_check"] = "☑️", - ["radio_button"] = "🔘", - ["white_circle"] = "⚪", - ["black_circle"] = "⚫", - ["red_circle"] = "🔴", - ["blue_circle"] = "🔵", - ["brown_circle"] = "🟤", - ["purple_circle"] = "🟣", - ["green_circle"] = "🟢", - ["yellow_circle"] = "🟡", - ["orange_circle"] = "🟠", - ["small_red_triangle"] = "🔺", - ["small_red_triangle_down"] = "🔻", - ["small_orange_diamond"] = "🔸", - ["small_blue_diamond"] = "🔹", - ["large_orange_diamond"] = "🔶", - ["large_blue_diamond"] = "🔷", - ["white_square_button"] = "🔳", - ["black_square_button"] = "🔲", - ["black_small_square"] = "▪️", - ["white_small_square"] = "▫️", - ["black_medium_small_square"] = "◾", - ["white_medium_small_square"] = "◽", - ["black_medium_square"] = "◼️", - ["white_medium_square"] = "◻️", - ["black_large_square"] = "⬛", - ["white_large_square"] = "⬜", - ["orange_square"] = "🟧", - ["blue_square"] = "🟦", - ["red_square"] = "🟥", - ["brown_square"] = "🟫", - ["purple_square"] = "🟪", - ["green_square"] = "🟩", - ["yellow_square"] = "🟨", - ["speaker"] = "🔈", - ["mute"] = "🔇", - ["sound"] = "🔉", - ["loud_sound"] = "🔊", - ["bell"] = "🔔", - ["no_bell"] = "🔕", - ["mega"] = "📣", - ["loudspeaker"] = "📢", - ["speech_left"] = "🗨️", - ["left_speech_bubble"] = "🗨️", - ["eye_in_speech_bubble"] = "👁‍🗨", - ["speech_balloon"] = "💬", - ["thought_balloon"] = "💭", - ["anger_right"] = "🗯️", - ["right_anger_bubble"] = "🗯️", - ["spades"] = "♠️", - ["clubs"] = "♣️", - ["hearts"] = "♥️", - ["diamonds"] = "♦️", - ["black_joker"] = "🃏", - ["flower_playing_cards"] = "🎴", - ["mahjong"] = "🀄", - ["clock1"] = "🕐", - ["clock2"] = "🕑", - ["clock3"] = "🕒", - ["clock4"] = "🕓", - ["clock5"] = "🕔", - ["clock6"] = "🕕", - ["clock7"] = "🕖", - ["clock8"] = "🕗", - ["clock9"] = "🕘", - ["clock10"] = "🕙", - ["clock11"] = "🕚", - ["clock12"] = "🕛", - ["clock130"] = "🕜", - ["clock230"] = "🕝", - ["clock330"] = "🕞", - ["clock430"] = "🕟", - ["clock530"] = "🕠", - ["clock630"] = "🕡", - ["clock730"] = "🕢", - ["clock830"] = "🕣", - ["clock930"] = "🕤", - ["clock1030"] = "🕥", - ["clock1130"] = "🕦", - ["clock1230"] = "🕧", - ["female_sign"] = "♀️", - ["male_sign"] = "♂️", - ["transgender_symbol"] = "⚧", - ["medical_symbol"] = "⚕️", - ["regional_indicator_z"] = "🇿", - ["regional_indicator_y"] = "🇾", - ["regional_indicator_x"] = "🇽", - ["regional_indicator_w"] = "🇼", - ["regional_indicator_v"] = "🇻", - ["regional_indicator_u"] = "🇺", - ["regional_indicator_t"] = "🇹", - ["regional_indicator_s"] = "🇸", - ["regional_indicator_r"] = "🇷", - ["regional_indicator_q"] = "🇶", - ["regional_indicator_p"] = "🇵", - ["regional_indicator_o"] = "🇴", - ["regional_indicator_n"] = "🇳", - ["regional_indicator_m"] = "🇲", - ["regional_indicator_l"] = "🇱", - ["regional_indicator_k"] = "🇰", - ["regional_indicator_j"] = "🇯", - ["regional_indicator_i"] = "🇮", - ["regional_indicator_h"] = "🇭", - ["regional_indicator_g"] = "🇬", - ["regional_indicator_f"] = "🇫", - ["regional_indicator_e"] = "🇪", - ["regional_indicator_d"] = "🇩", - ["regional_indicator_c"] = "🇨", - ["regional_indicator_b"] = "🇧", - ["regional_indicator_a"] = "🇦", - ["flag_white"] = "🏳️", - ["flag_black"] = "🏴", - ["checkered_flag"] = "🏁", - ["triangular_flag_on_post"] = "🚩", - ["rainbow_flag"] = "🏳️‍🌈", - ["gay_pride_flag"] = "🏳️‍🌈", - ["transgender_flag"] = "🏳️‍⚧️", - ["pirate_flag"] = "🏴‍☠️", - ["flag_af"] = "🇦🇫", - ["flag_ax"] = "🇦🇽", - ["flag_al"] = "🇦🇱", - ["flag_dz"] = "🇩🇿", - ["flag_as"] = "🇦🇸", - ["flag_ad"] = "🇦🇩", - ["flag_ao"] = "🇦🇴", - ["flag_ai"] = "🇦🇮", - ["flag_aq"] = "🇦🇶", - ["flag_ag"] = "🇦🇬", - ["flag_ar"] = "🇦🇷", - ["flag_am"] = "🇦🇲", - ["flag_aw"] = "🇦🇼", - ["flag_au"] = "🇦🇺", - ["flag_at"] = "🇦🇹", - ["flag_az"] = "🇦🇿", - ["flag_bs"] = "🇧🇸", - ["flag_bh"] = "🇧🇭", - ["flag_bd"] = "🇧🇩", - ["flag_bb"] = "🇧🇧", - ["flag_by"] = "🇧🇾", - ["flag_be"] = "🇧🇪", - ["flag_bz"] = "🇧🇿", - ["flag_bj"] = "🇧🇯", - ["flag_bm"] = "🇧🇲", - ["flag_bt"] = "🇧🇹", - ["flag_bo"] = "🇧🇴", - ["flag_ba"] = "🇧🇦", - ["flag_bw"] = "🇧🇼", - ["flag_br"] = "🇧🇷", - ["flag_io"] = "🇮🇴", - ["flag_vg"] = "🇻🇬", - ["flag_bn"] = "🇧🇳", - ["flag_bg"] = "🇧🇬", - ["flag_bf"] = "🇧🇫", - ["flag_bi"] = "🇧🇮", - ["flag_kh"] = "🇰🇭", - ["flag_cm"] = "🇨🇲", - ["flag_ca"] = "🇨🇦", - ["flag_ic"] = "🇮🇨", - ["flag_cv"] = "🇨🇻", - ["flag_bq"] = "🇧🇶", - ["flag_ky"] = "🇰🇾", - ["flag_cf"] = "🇨🇫", - ["flag_td"] = "🇹🇩", - ["flag_cl"] = "🇨🇱", - ["flag_cn"] = "🇨🇳", - ["flag_cx"] = "🇨🇽", - ["flag_cc"] = "🇨🇨", - ["flag_co"] = "🇨🇴", - ["flag_km"] = "🇰🇲", - ["flag_cg"] = "🇨🇬", - ["flag_cd"] = "🇨🇩", - ["flag_ck"] = "🇨🇰", - ["flag_cr"] = "🇨🇷", - ["flag_ci"] = "🇨🇮", - ["flag_hr"] = "🇭🇷", - ["flag_cu"] = "🇨🇺", - ["flag_cw"] = "🇨🇼", - ["flag_cy"] = "🇨🇾", - ["flag_cz"] = "🇨🇿", - ["flag_dk"] = "🇩🇰", - ["flag_dj"] = "🇩🇯", - ["flag_dm"] = "🇩🇲", - ["flag_do"] = "🇩🇴", - ["flag_ec"] = "🇪🇨", - ["flag_eg"] = "🇪🇬", - ["flag_sv"] = "🇸🇻", - ["flag_gq"] = "🇬🇶", - ["flag_er"] = "🇪🇷", - ["flag_ee"] = "🇪🇪", - ["flag_et"] = "🇪🇹", - ["flag_eu"] = "🇪🇺", - ["flag_fk"] = "🇫🇰", - ["flag_fo"] = "🇫🇴", - ["flag_fj"] = "🇫🇯", - ["flag_fi"] = "🇫🇮", - ["flag_fr"] = "🇫🇷", - ["flag_gf"] = "🇬🇫", - ["flag_pf"] = "🇵🇫", - ["flag_tf"] = "🇹🇫", - ["flag_ga"] = "🇬🇦", - ["flag_gm"] = "🇬🇲", - ["flag_ge"] = "🇬🇪", - ["flag_de"] = "🇩🇪", - ["flag_gh"] = "🇬🇭", - ["flag_gi"] = "🇬🇮", - ["flag_gr"] = "🇬🇷", - ["flag_gl"] = "🇬🇱", - ["flag_gd"] = "🇬🇩", - ["flag_gp"] = "🇬🇵", - ["flag_gu"] = "🇬🇺", - ["flag_gt"] = "🇬🇹", - ["flag_gg"] = "🇬🇬", - ["flag_gn"] = "🇬🇳", - ["flag_gw"] = "🇬🇼", - ["flag_gy"] = "🇬🇾", - ["flag_ht"] = "🇭🇹", - ["flag_hn"] = "🇭🇳", - ["flag_hk"] = "🇭🇰", - ["flag_hu"] = "🇭🇺", - ["flag_is"] = "🇮🇸", - ["flag_in"] = "🇮🇳", - ["flag_id"] = "🇮🇩", - ["flag_ir"] = "🇮🇷", - ["flag_iq"] = "🇮🇶", - ["flag_ie"] = "🇮🇪", - ["flag_im"] = "🇮🇲", - ["flag_il"] = "🇮🇱", - ["flag_it"] = "🇮🇹", - ["flag_jm"] = "🇯🇲", - ["flag_jp"] = "🇯🇵", - ["crossed_flags"] = "🎌", - ["flag_je"] = "🇯🇪", - ["flag_jo"] = "🇯🇴", - ["flag_kz"] = "🇰🇿", - ["flag_ke"] = "🇰🇪", - ["flag_ki"] = "🇰🇮", - ["flag_xk"] = "🇽🇰", - ["flag_kw"] = "🇰🇼", - ["flag_kg"] = "🇰🇬", - ["flag_la"] = "🇱🇦", - ["flag_lv"] = "🇱🇻", - ["flag_lb"] = "🇱🇧", - ["flag_ls"] = "🇱🇸", - ["flag_lr"] = "🇱🇷", - ["flag_ly"] = "🇱🇾", - ["flag_li"] = "🇱🇮", - ["flag_lt"] = "🇱🇹", - ["flag_lu"] = "🇱🇺", - ["flag_mo"] = "🇲🇴", - ["flag_mk"] = "🇲🇰", - ["flag_mg"] = "🇲🇬", - ["flag_mw"] = "🇲🇼", - ["flag_my"] = "🇲🇾", - ["flag_mv"] = "🇲🇻", - ["flag_ml"] = "🇲🇱", - ["flag_mt"] = "🇲🇹", - ["flag_mh"] = "🇲🇭", - ["flag_mq"] = "🇲🇶", - ["flag_mr"] = "🇲🇷", - ["flag_mu"] = "🇲🇺", - ["flag_yt"] = "🇾🇹", - ["flag_mx"] = "🇲🇽", - ["flag_fm"] = "🇫🇲", - ["flag_md"] = "🇲🇩", - ["flag_mc"] = "🇲🇨", - ["flag_mn"] = "🇲🇳", - ["flag_me"] = "🇲🇪", - ["flag_ms"] = "🇲🇸", - ["flag_ma"] = "🇲🇦", - ["flag_mz"] = "🇲🇿", - ["flag_mm"] = "🇲🇲", - ["flag_na"] = "🇳🇦", - ["flag_nr"] = "🇳🇷", - ["flag_np"] = "🇳🇵", - ["flag_nl"] = "🇳🇱", - ["flag_nc"] = "🇳🇨", - ["flag_nz"] = "🇳🇿", - ["flag_ni"] = "🇳🇮", - ["flag_ne"] = "🇳🇪", - ["flag_ng"] = "🇳🇬", - ["flag_nu"] = "🇳🇺", - ["flag_nf"] = "🇳🇫", - ["flag_kp"] = "🇰🇵", - ["flag_mp"] = "🇲🇵", - ["flag_no"] = "🇳🇴", - ["flag_om"] = "🇴🇲", - ["flag_pk"] = "🇵🇰", - ["flag_pw"] = "🇵🇼", - ["flag_ps"] = "🇵🇸", - ["flag_pa"] = "🇵🇦", - ["flag_pg"] = "🇵🇬", - ["flag_py"] = "🇵🇾", - ["flag_pe"] = "🇵🇪", - ["flag_ph"] = "🇵🇭", - ["flag_pn"] = "🇵🇳", - ["flag_pl"] = "🇵🇱", - ["flag_pt"] = "🇵🇹", - ["flag_pr"] = "🇵🇷", - ["flag_qa"] = "🇶🇦", - ["flag_re"] = "🇷🇪", - ["flag_ro"] = "🇷🇴", - ["flag_ru"] = "🇷🇺", - ["flag_rw"] = "🇷🇼", - ["flag_ws"] = "🇼🇸", - ["flag_sm"] = "🇸🇲", - ["flag_st"] = "🇸🇹", - ["flag_sa"] = "🇸🇦", - ["flag_sn"] = "🇸🇳", - ["flag_rs"] = "🇷🇸", - ["flag_sc"] = "🇸🇨", - ["flag_sl"] = "🇸🇱", - ["flag_sg"] = "🇸🇬", - ["flag_sx"] = "🇸🇽", - ["flag_sk"] = "🇸🇰", - ["flag_si"] = "🇸🇮", - ["flag_gs"] = "🇬🇸", - ["flag_sb"] = "🇸🇧", - ["flag_so"] = "🇸🇴", - ["flag_za"] = "🇿🇦", - ["flag_kr"] = "🇰🇷", - ["flag_ss"] = "🇸🇸", - ["flag_es"] = "🇪🇸", - ["flag_lk"] = "🇱🇰", - ["flag_bl"] = "🇧🇱", - ["flag_sh"] = "🇸🇭", - ["flag_kn"] = "🇰🇳", - ["flag_lc"] = "🇱🇨", - ["flag_pm"] = "🇵🇲", - ["flag_vc"] = "🇻🇨", - ["flag_sd"] = "🇸🇩", - ["flag_sr"] = "🇸🇷", - ["flag_sz"] = "🇸🇿", - ["flag_se"] = "🇸🇪", - ["flag_ch"] = "🇨🇭", - ["flag_sy"] = "🇸🇾", - ["flag_tw"] = "🇹🇼", - ["flag_tj"] = "🇹🇯", - ["flag_tz"] = "🇹🇿", - ["flag_th"] = "🇹🇭", - ["flag_tl"] = "🇹🇱", - ["flag_tg"] = "🇹🇬", - ["flag_tk"] = "🇹🇰", - ["flag_to"] = "🇹🇴", - ["flag_tt"] = "🇹🇹", - ["flag_tn"] = "🇹🇳", - ["flag_tr"] = "🇹🇷", - ["flag_tm"] = "🇹🇲", - ["flag_tc"] = "🇹🇨", - ["flag_vi"] = "🇻🇮", - ["flag_tv"] = "🇹🇻", - ["flag_ug"] = "🇺🇬", - ["flag_ua"] = "🇺🇦", - ["flag_ae"] = "🇦🇪", - ["flag_gb"] = "🇬🇧", - ["england"] = "🏴󠁧󠁢󠁥󠁮󠁧󠁿", - ["scotland"] = "🏴󠁧󠁢󠁳󠁣󠁴󠁿", - ["wales"] = "🏴󠁧󠁢󠁷󠁬󠁳󠁿", - ["flag_us"] = "🇺🇸", - ["flag_uy"] = "🇺🇾", - ["flag_uz"] = "🇺🇿", - ["flag_vu"] = "🇻🇺", - ["flag_va"] = "🇻🇦", - ["flag_ve"] = "🇻🇪", - ["flag_vn"] = "🇻🇳", - ["flag_wf"] = "🇼🇫", - ["flag_eh"] = "🇪🇭", - ["flag_ye"] = "🇾🇪", - ["flag_zm"] = "🇿🇲", - ["flag_zw"] = "🇿🇼", - ["flag_ac"] = "🇦🇨", - ["flag_bv"] = "🇧🇻", - ["flag_cp"] = "🇨🇵", - ["flag_ea"] = "🇪🇦", - ["flag_dg"] = "🇩🇬", - ["flag_hm"] = "🇭🇲", - ["flag_mf"] = "🇲🇫", - ["flag_sj"] = "🇸🇯", - ["flag_ta"] = "🇹🇦", - ["flag_um"] = "🇺🇲", - ["united_nations"] = "🇺🇳" - }; + private static Dictionary _fromCodes = new(5000, StringComparer.Ordinal) + { + ["grinning"] = "😀", + ["smiley"] = "😃", + ["smile"] = "😄", + ["grin"] = "😁", + ["laughing"] = "😆", + ["satisfied"] = "😆", + ["sweat_smile"] = "😅", + ["joy"] = "😂", + ["rofl"] = "🤣", + ["rolling_on_the_floor_laughing"] = "🤣", + ["relaxed"] = "☺️", + ["blush"] = "😊", + ["innocent"] = "😇", + ["slight_smile"] = "🙂", + ["slightly_smiling_face"] = "🙂", + ["upside_down"] = "🙃", + ["upside_down_face"] = "🙃", + ["wink"] = "😉", + ["relieved"] = "😌", + ["smiling_face_with_tear"] = "🥲", + ["heart_eyes"] = "😍", + ["smiling_face_with_3_hearts"] = "🥰", + ["kissing_heart"] = "😘", + ["kissing"] = "😗", + ["kissing_smiling_eyes"] = "😙", + ["kissing_closed_eyes"] = "😚", + ["yum"] = "😋", + ["stuck_out_tongue"] = "😛", + ["stuck_out_tongue_closed_eyes"] = "😝", + ["stuck_out_tongue_winking_eye"] = "😜", + ["zany_face"] = "🤪", + ["face_with_raised_eyebrow"] = "🤨", + ["face_with_monocle"] = "🧐", + ["nerd"] = "🤓", + ["nerd_face"] = "🤓", + ["sunglasses"] = "😎", + ["star_struck"] = "🤩", + ["partying_face"] = "🥳", + ["smirk"] = "😏", + ["unamused"] = "😒", + ["disappointed"] = "😞", + ["pensive"] = "😔", + ["worried"] = "😟", + ["confused"] = "😕", + ["slight_frown"] = "🙁", + ["slightly_frowning_face"] = "🙁", + ["frowning2"] = "☹️", + ["white_frowning_face"] = "☹️", + ["persevere"] = "😣", + ["confounded"] = "😖", + ["tired_face"] = "😫", + ["weary"] = "😩", + ["pleading_face"] = "🥺", + ["cry"] = "😢", + ["sob"] = "😭", + ["triumph"] = "😤", + ["face_exhaling"] = "😮‍💨", + ["angry"] = "😠", + ["rage"] = "😡", + ["face_with_symbols_over_mouth"] = "🤬", + ["exploding_head"] = "🤯", + ["flushed"] = "😳", + ["face_in_clouds"] = "😶‍🌫️", + ["hot_face"] = "🥵", + ["cold_face"] = "🥶", + ["scream"] = "😱", + ["fearful"] = "😨", + ["cold_sweat"] = "😰", + ["disappointed_relieved"] = "😥", + ["sweat"] = "😓", + ["hugging"] = "🤗", + ["hugging_face"] = "🤗", + ["thinking"] = "🤔", + ["thinking_face"] = "🤔", + ["face_with_hand_over_mouth"] = "🤭", + ["yawning_face"] = "🥱", + ["shushing_face"] = "🤫", + ["lying_face"] = "🤥", + ["liar"] = "🤥", + ["no_mouth"] = "😶", + ["neutral_face"] = "😐", + ["expressionless"] = "😑", + ["grimacing"] = "😬", + ["rolling_eyes"] = "🙄", + ["face_with_rolling_eyes"] = "🙄", + ["hushed"] = "😯", + ["frowning"] = "😦", + ["anguished"] = "😧", + ["open_mouth"] = "😮", + ["astonished"] = "😲", + ["sleeping"] = "😴", + ["drooling_face"] = "🤤", + ["drool"] = "🤤", + ["sleepy"] = "😪", + ["dizzy_face"] = "😵", + ["face_with_spiral_eyes"] = "😵‍💫", + ["zipper_mouth"] = "🤐", + ["zipper_mouth_face"] = "🤐", + ["woozy_face"] = "🥴", + ["nauseated_face"] = "🤢", + ["sick"] = "🤢", + ["face_vomiting"] = "🤮", + ["sneezing_face"] = "🤧", + ["sneeze"] = "🤧", + ["mask"] = "😷", + ["thermometer_face"] = "🤒", + ["face_with_thermometer"] = "🤒", + ["head_bandage"] = "🤕", + ["face_with_head_bandage"] = "🤕", + ["money_mouth"] = "🤑", + ["money_mouth_face"] = "🤑", + ["cowboy"] = "🤠", + ["face_with_cowboy_hat"] = "🤠", + ["disguised_face"] = "🥸", + ["smiling_imp"] = "😈", + ["imp"] = "👿", + ["japanese_ogre"] = "👹", + ["japanese_goblin"] = "👺", + ["clown"] = "🤡", + ["clown_face"] = "🤡", + ["poop"] = "💩", + ["shit"] = "💩", + ["hankey"] = "💩", + ["poo"] = "💩", + ["ghost"] = "👻", + ["skull"] = "💀", + ["skeleton"] = "💀", + ["skull_crossbones"] = "☠️", + ["skull_and_crossbones"] = "☠️", + ["alien"] = "👽", + ["space_invader"] = "👾", + ["robot"] = "🤖", + ["robot_face"] = "🤖", + ["jack_o_lantern"] = "🎃", + ["smiley_cat"] = "😺", + ["smile_cat"] = "😸", + ["joy_cat"] = "😹", + ["heart_eyes_cat"] = "😻", + ["smirk_cat"] = "😼", + ["kissing_cat"] = "😽", + ["scream_cat"] = "🙀", + ["crying_cat_face"] = "😿", + ["pouting_cat"] = "😾", + ["palms_up_together"] = "🤲", + ["palms_up_together_tone1"] = "🤲🏻", + ["palms_up_together_light_skin_tone"] = "🤲🏻", + ["palms_up_together_tone2"] = "🤲🏼", + ["palms_up_together_medium_light_skin_tone"] = "🤲🏼", + ["palms_up_together_tone3"] = "🤲🏽", + ["palms_up_together_medium_skin_tone"] = "🤲🏽", + ["palms_up_together_tone4"] = "🤲🏾", + ["palms_up_together_medium_dark_skin_tone"] = "🤲🏾", + ["palms_up_together_tone5"] = "🤲🏿", + ["palms_up_together_dark_skin_tone"] = "🤲🏿", + ["open_hands"] = "👐", + ["open_hands_tone1"] = "👐🏻", + ["open_hands_tone2"] = "👐🏼", + ["open_hands_tone3"] = "👐🏽", + ["open_hands_tone4"] = "👐🏾", + ["open_hands_tone5"] = "👐🏿", + ["raised_hands"] = "🙌", + ["raised_hands_tone1"] = "🙌🏻", + ["raised_hands_tone2"] = "🙌🏼", + ["raised_hands_tone3"] = "🙌🏽", + ["raised_hands_tone4"] = "🙌🏾", + ["raised_hands_tone5"] = "🙌🏿", + ["clap"] = "👏", + ["clap_tone1"] = "👏🏻", + ["clap_tone2"] = "👏🏼", + ["clap_tone3"] = "👏🏽", + ["clap_tone4"] = "👏🏾", + ["clap_tone5"] = "👏🏿", + ["handshake"] = "🤝", + ["shaking_hands"] = "🤝", + ["thumbsup"] = "👍", + ["+1"] = "👍", + ["thumbup"] = "👍", + ["thumbsup_tone1"] = "👍🏻", + ["+1_tone1"] = "👍🏻", + ["thumbup_tone1"] = "👍🏻", + ["thumbsup_tone2"] = "👍🏼", + ["+1_tone2"] = "👍🏼", + ["thumbup_tone2"] = "👍🏼", + ["thumbsup_tone3"] = "👍🏽", + ["+1_tone3"] = "👍🏽", + ["thumbup_tone3"] = "👍🏽", + ["thumbsup_tone4"] = "👍🏾", + ["+1_tone4"] = "👍🏾", + ["thumbup_tone4"] = "👍🏾", + ["thumbsup_tone5"] = "👍🏿", + ["+1_tone5"] = "👍🏿", + ["thumbup_tone5"] = "👍🏿", + ["thumbsdown"] = "👎", + ["-1"] = "👎", + ["thumbdown"] = "👎", + ["thumbsdown_tone1"] = "👎🏻", + ["_1_tone1"] = "👎🏻", + ["thumbdown_tone1"] = "👎🏻", + ["thumbsdown_tone2"] = "👎🏼", + ["_1_tone2"] = "👎🏼", + ["thumbdown_tone2"] = "👎🏼", + ["thumbsdown_tone3"] = "👎🏽", + ["_1_tone3"] = "👎🏽", + ["thumbdown_tone3"] = "👎🏽", + ["thumbsdown_tone4"] = "👎🏾", + ["_1_tone4"] = "👎🏾", + ["thumbdown_tone4"] = "👎🏾", + ["thumbsdown_tone5"] = "👎🏿", + ["_1_tone5"] = "👎🏿", + ["thumbdown_tone5"] = "👎🏿", + ["punch"] = "👊", + ["punch_tone1"] = "👊🏻", + ["punch_tone2"] = "👊🏼", + ["punch_tone3"] = "👊🏽", + ["punch_tone4"] = "👊🏾", + ["punch_tone5"] = "👊🏿", + ["fist"] = "✊", + ["fist_tone1"] = "✊🏻", + ["fist_tone2"] = "✊🏼", + ["fist_tone3"] = "✊🏽", + ["fist_tone4"] = "✊🏾", + ["fist_tone5"] = "✊🏿", + ["left_facing_fist"] = "🤛", + ["left_fist"] = "🤛", + ["left_facing_fist_tone1"] = "🤛🏻", + ["left_fist_tone1"] = "🤛🏻", + ["left_facing_fist_tone2"] = "🤛🏼", + ["left_fist_tone2"] = "🤛🏼", + ["left_facing_fist_tone3"] = "🤛🏽", + ["left_fist_tone3"] = "🤛🏽", + ["left_facing_fist_tone4"] = "🤛🏾", + ["left_fist_tone4"] = "🤛🏾", + ["left_facing_fist_tone5"] = "🤛🏿", + ["left_fist_tone5"] = "🤛🏿", + ["right_facing_fist"] = "🤜", + ["right_fist"] = "🤜", + ["right_facing_fist_tone1"] = "🤜🏻", + ["right_fist_tone1"] = "🤜🏻", + ["right_facing_fist_tone2"] = "🤜🏼", + ["right_fist_tone2"] = "🤜🏼", + ["right_facing_fist_tone3"] = "🤜🏽", + ["right_fist_tone3"] = "🤜🏽", + ["right_facing_fist_tone4"] = "🤜🏾", + ["right_fist_tone4"] = "🤜🏾", + ["right_facing_fist_tone5"] = "🤜🏿", + ["right_fist_tone5"] = "🤜🏿", + ["fingers_crossed"] = "🤞", + ["hand_with_index_and_middle_finger_crossed"] = "🤞", + ["fingers_crossed_tone1"] = "🤞🏻", + ["hand_with_index_and_middle_fingers_crossed_tone1"] = "🤞🏻", + ["fingers_crossed_tone2"] = "🤞🏼", + ["hand_with_index_and_middle_fingers_crossed_tone2"] = "🤞🏼", + ["fingers_crossed_tone3"] = "🤞🏽", + ["hand_with_index_and_middle_fingers_crossed_tone3"] = "🤞🏽", + ["fingers_crossed_tone4"] = "🤞🏾", + ["hand_with_index_and_middle_fingers_crossed_tone4"] = "🤞🏾", + ["fingers_crossed_tone5"] = "🤞🏿", + ["hand_with_index_and_middle_fingers_crossed_tone5"] = "🤞🏿", + ["v"] = "✌️", + ["v_tone1"] = "✌🏻", + ["v_tone2"] = "✌🏼", + ["v_tone3"] = "✌🏽", + ["v_tone4"] = "✌🏾", + ["v_tone5"] = "✌🏿", + ["love_you_gesture"] = "🤟", + ["love_you_gesture_tone1"] = "🤟🏻", + ["love_you_gesture_light_skin_tone"] = "🤟🏻", + ["love_you_gesture_tone2"] = "🤟🏼", + ["love_you_gesture_medium_light_skin_tone"] = "🤟🏼", + ["love_you_gesture_tone3"] = "🤟🏽", + ["love_you_gesture_medium_skin_tone"] = "🤟🏽", + ["love_you_gesture_tone4"] = "🤟🏾", + ["love_you_gesture_medium_dark_skin_tone"] = "🤟🏾", + ["love_you_gesture_tone5"] = "🤟🏿", + ["love_you_gesture_dark_skin_tone"] = "🤟🏿", + ["metal"] = "🤘", + ["sign_of_the_horns"] = "🤘", + ["metal_tone1"] = "🤘🏻", + ["sign_of_the_horns_tone1"] = "🤘🏻", + ["metal_tone2"] = "🤘🏼", + ["sign_of_the_horns_tone2"] = "🤘🏼", + ["metal_tone3"] = "🤘🏽", + ["sign_of_the_horns_tone3"] = "🤘🏽", + ["metal_tone4"] = "🤘🏾", + ["sign_of_the_horns_tone4"] = "🤘🏾", + ["metal_tone5"] = "🤘🏿", + ["sign_of_the_horns_tone5"] = "🤘🏿", + ["ok_hand"] = "👌", + ["ok_hand_tone1"] = "👌🏻", + ["ok_hand_tone2"] = "👌🏼", + ["ok_hand_tone3"] = "👌🏽", + ["ok_hand_tone4"] = "👌🏾", + ["ok_hand_tone5"] = "👌🏿", + ["pinching_hand"] = "🤏", + ["pinching_hand_tone1"] = "🤏🏻", + ["pinching_hand_light_skin_tone"] = "🤏🏻", + ["pinching_hand_tone2"] = "🤏🏼", + ["pinching_hand_medium_light_skin_tone"] = "🤏🏼", + ["pinching_hand_tone3"] = "🤏🏽", + ["pinching_hand_medium_skin_tone"] = "🤏🏽", + ["pinching_hand_tone4"] = "🤏🏾", + ["pinching_hand_medium_dark_skin_tone"] = "🤏🏾", + ["pinching_hand_tone5"] = "🤏🏿", + ["pinching_hand_dark_skin_tone"] = "🤏🏿", + ["pinched_fingers"] = "🤌", + ["pinched_fingers_tone2"] = "🤌🏼", + ["pinched_fingers_medium_light_skin_tone"] = "🤌🏼", + ["pinched_fingers_tone1"] = "🤌🏻", + ["pinched_fingers_light_skin_tone"] = "🤌🏻", + ["pinched_fingers_tone3"] = "🤌🏽", + ["pinched_fingers_medium_skin_tone"] = "🤌🏽", + ["pinched_fingers_tone4"] = "🤌🏾", + ["pinched_fingers_medium_dark_skin_tone"] = "🤌🏾", + ["pinched_fingers_tone5"] = "🤌🏿", + ["pinched_fingers_dark_skin_tone"] = "🤌🏿", + ["point_left"] = "👈", + ["point_left_tone1"] = "👈🏻", + ["point_left_tone2"] = "👈🏼", + ["point_left_tone3"] = "👈🏽", + ["point_left_tone4"] = "👈🏾", + ["point_left_tone5"] = "👈🏿", + ["point_right"] = "👉", + ["point_right_tone1"] = "👉🏻", + ["point_right_tone2"] = "👉🏼", + ["point_right_tone3"] = "👉🏽", + ["point_right_tone4"] = "👉🏾", + ["point_right_tone5"] = "👉🏿", + ["point_up_2"] = "👆", + ["point_up_2_tone1"] = "👆🏻", + ["point_up_2_tone2"] = "👆🏼", + ["point_up_2_tone3"] = "👆🏽", + ["point_up_2_tone4"] = "👆🏾", + ["point_up_2_tone5"] = "👆🏿", + ["point_down"] = "👇", + ["point_down_tone1"] = "👇🏻", + ["point_down_tone2"] = "👇🏼", + ["point_down_tone3"] = "👇🏽", + ["point_down_tone4"] = "👇🏾", + ["point_down_tone5"] = "👇🏿", + ["point_up"] = "☝️", + ["point_up_tone1"] = "☝🏻", + ["point_up_tone2"] = "☝🏼", + ["point_up_tone3"] = "☝🏽", + ["point_up_tone4"] = "☝🏾", + ["point_up_tone5"] = "☝🏿", + ["raised_hand"] = "✋", + ["raised_hand_tone1"] = "✋🏻", + ["raised_hand_tone2"] = "✋🏼", + ["raised_hand_tone3"] = "✋🏽", + ["raised_hand_tone4"] = "✋🏾", + ["raised_hand_tone5"] = "✋🏿", + ["raised_back_of_hand"] = "🤚", + ["back_of_hand"] = "🤚", + ["raised_back_of_hand_tone1"] = "🤚🏻", + ["back_of_hand_tone1"] = "🤚🏻", + ["raised_back_of_hand_tone2"] = "🤚🏼", + ["back_of_hand_tone2"] = "🤚🏼", + ["raised_back_of_hand_tone3"] = "🤚🏽", + ["back_of_hand_tone3"] = "🤚🏽", + ["raised_back_of_hand_tone4"] = "🤚🏾", + ["back_of_hand_tone4"] = "🤚🏾", + ["raised_back_of_hand_tone5"] = "🤚🏿", + ["back_of_hand_tone5"] = "🤚🏿", + ["hand_splayed"] = "🖐️", + ["raised_hand_with_fingers_splayed"] = "🖐️", + ["hand_splayed_tone1"] = "🖐🏻", + ["raised_hand_with_fingers_splayed_tone1"] = "🖐🏻", + ["hand_splayed_tone2"] = "🖐🏼", + ["raised_hand_with_fingers_splayed_tone2"] = "🖐🏼", + ["hand_splayed_tone3"] = "🖐🏽", + ["raised_hand_with_fingers_splayed_tone3"] = "🖐🏽", + ["hand_splayed_tone4"] = "🖐🏾", + ["raised_hand_with_fingers_splayed_tone4"] = "🖐🏾", + ["hand_splayed_tone5"] = "🖐🏿", + ["raised_hand_with_fingers_splayed_tone5"] = "🖐🏿", + ["vulcan"] = "🖖", + ["raised_hand_with_part_between_middle_and_ring_fingers"] = "🖖", + ["vulcan_tone1"] = "🖖🏻", + ["raised_hand_with_part_between_middle_and_ring_fingers_tone1"] = "🖖🏻", + ["vulcan_tone2"] = "🖖🏼", + ["raised_hand_with_part_between_middle_and_ring_fingers_tone2"] = "🖖🏼", + ["vulcan_tone3"] = "🖖🏽", + ["raised_hand_with_part_between_middle_and_ring_fingers_tone3"] = "🖖🏽", + ["vulcan_tone4"] = "🖖🏾", + ["raised_hand_with_part_between_middle_and_ring_fingers_tone4"] = "🖖🏾", + ["vulcan_tone5"] = "🖖🏿", + ["raised_hand_with_part_between_middle_and_ring_fingers_tone5"] = "🖖🏿", + ["wave"] = "👋", + ["wave_tone1"] = "👋🏻", + ["wave_tone2"] = "👋🏼", + ["wave_tone3"] = "👋🏽", + ["wave_tone4"] = "👋🏾", + ["wave_tone5"] = "👋🏿", + ["call_me"] = "🤙", + ["call_me_hand"] = "🤙", + ["call_me_tone1"] = "🤙🏻", + ["call_me_hand_tone1"] = "🤙🏻", + ["call_me_tone2"] = "🤙🏼", + ["call_me_hand_tone2"] = "🤙🏼", + ["call_me_tone3"] = "🤙🏽", + ["call_me_hand_tone3"] = "🤙🏽", + ["call_me_tone4"] = "🤙🏾", + ["call_me_hand_tone4"] = "🤙🏾", + ["call_me_tone5"] = "🤙🏿", + ["call_me_hand_tone5"] = "🤙🏿", + ["muscle"] = "💪", + ["muscle_tone1"] = "💪🏻", + ["muscle_tone2"] = "💪🏼", + ["muscle_tone3"] = "💪🏽", + ["muscle_tone4"] = "💪🏾", + ["muscle_tone5"] = "💪🏿", + ["mechanical_arm"] = "🦾", + ["middle_finger"] = "🖕", + ["reversed_hand_with_middle_finger_extended"] = "🖕", + ["middle_finger_tone1"] = "🖕🏻", + ["reversed_hand_with_middle_finger_extended_tone1"] = "🖕🏻", + ["middle_finger_tone2"] = "🖕🏼", + ["reversed_hand_with_middle_finger_extended_tone2"] = "🖕🏼", + ["middle_finger_tone3"] = "🖕🏽", + ["reversed_hand_with_middle_finger_extended_tone3"] = "🖕🏽", + ["middle_finger_tone4"] = "🖕🏾", + ["reversed_hand_with_middle_finger_extended_tone4"] = "🖕🏾", + ["middle_finger_tone5"] = "🖕🏿", + ["reversed_hand_with_middle_finger_extended_tone5"] = "🖕🏿", + ["writing_hand"] = "✍️", + ["writing_hand_tone1"] = "✍🏻", + ["writing_hand_tone2"] = "✍🏼", + ["writing_hand_tone3"] = "✍🏽", + ["writing_hand_tone4"] = "✍🏾", + ["writing_hand_tone5"] = "✍🏿", + ["pray"] = "🙏", + ["pray_tone1"] = "🙏🏻", + ["pray_tone2"] = "🙏🏼", + ["pray_tone3"] = "🙏🏽", + ["pray_tone4"] = "🙏🏾", + ["pray_tone5"] = "🙏🏿", + ["foot"] = "🦶", + ["foot_tone1"] = "🦶🏻", + ["foot_light_skin_tone"] = "🦶🏻", + ["foot_tone2"] = "🦶🏼", + ["foot_medium_light_skin_tone"] = "🦶🏼", + ["foot_tone3"] = "🦶🏽", + ["foot_medium_skin_tone"] = "🦶🏽", + ["foot_tone4"] = "🦶🏾", + ["foot_medium_dark_skin_tone"] = "🦶🏾", + ["foot_tone5"] = "🦶🏿", + ["foot_dark_skin_tone"] = "🦶🏿", + ["leg"] = "🦵", + ["leg_tone1"] = "🦵🏻", + ["leg_light_skin_tone"] = "🦵🏻", + ["leg_tone2"] = "🦵🏼", + ["leg_medium_light_skin_tone"] = "🦵🏼", + ["leg_tone3"] = "🦵🏽", + ["leg_medium_skin_tone"] = "🦵🏽", + ["leg_tone4"] = "🦵🏾", + ["leg_medium_dark_skin_tone"] = "🦵🏾", + ["leg_tone5"] = "🦵🏿", + ["leg_dark_skin_tone"] = "🦵🏿", + ["mechanical_leg"] = "🦿", + ["lipstick"] = "💄", + ["kiss"] = "💋", + ["lips"] = "👄", + ["tooth"] = "🦷", + ["tongue"] = "👅", + ["ear"] = "👂", + ["ear_tone1"] = "👂🏻", + ["ear_tone2"] = "👂🏼", + ["ear_tone3"] = "👂🏽", + ["ear_tone4"] = "👂🏾", + ["ear_tone5"] = "👂🏿", + ["ear_with_hearing_aid"] = "🦻", + ["ear_with_hearing_aid_tone1"] = "🦻🏻", + ["ear_with_hearing_aid_light_skin_tone"] = "🦻🏻", + ["ear_with_hearing_aid_tone2"] = "🦻🏼", + ["ear_with_hearing_aid_medium_light_skin_tone"] = "🦻🏼", + ["ear_with_hearing_aid_tone3"] = "🦻🏽", + ["ear_with_hearing_aid_medium_skin_tone"] = "🦻🏽", + ["ear_with_hearing_aid_tone4"] = "🦻🏾", + ["ear_with_hearing_aid_medium_dark_skin_tone"] = "🦻🏾", + ["ear_with_hearing_aid_tone5"] = "🦻🏿", + ["ear_with_hearing_aid_dark_skin_tone"] = "🦻🏿", + ["nose"] = "👃", + ["nose_tone1"] = "👃🏻", + ["nose_tone2"] = "👃🏼", + ["nose_tone3"] = "👃🏽", + ["nose_tone4"] = "👃🏾", + ["nose_tone5"] = "👃🏿", + ["footprints"] = "👣", + ["eye"] = "👁️", + ["eyes"] = "👀", + ["brain"] = "🧠", + ["anatomical_heart"] = "🫀", + ["lungs"] = "🫁", + ["bone"] = "🦴", + ["speaking_head"] = "🗣️", + ["speaking_head_in_silhouette"] = "🗣️", + ["bust_in_silhouette"] = "👤", + ["busts_in_silhouette"] = "👥", + ["people_hugging"] = "🫂", + ["baby"] = "👶", + ["baby_tone1"] = "👶🏻", + ["baby_tone2"] = "👶🏼", + ["baby_tone3"] = "👶🏽", + ["baby_tone4"] = "👶🏾", + ["baby_tone5"] = "👶🏿", + ["girl"] = "👧", + ["girl_tone1"] = "👧🏻", + ["girl_tone2"] = "👧🏼", + ["girl_tone3"] = "👧🏽", + ["girl_tone4"] = "👧🏾", + ["girl_tone5"] = "👧🏿", + ["child"] = "🧒", + ["child_tone1"] = "🧒🏻", + ["child_light_skin_tone"] = "🧒🏻", + ["child_tone2"] = "🧒🏼", + ["child_medium_light_skin_tone"] = "🧒🏼", + ["child_tone3"] = "🧒🏽", + ["child_medium_skin_tone"] = "🧒🏽", + ["child_tone4"] = "🧒🏾", + ["child_medium_dark_skin_tone"] = "🧒🏾", + ["child_tone5"] = "🧒🏿", + ["child_dark_skin_tone"] = "🧒🏿", + ["boy"] = "👦", + ["boy_tone1"] = "👦🏻", + ["boy_tone2"] = "👦🏼", + ["boy_tone3"] = "👦🏽", + ["boy_tone4"] = "👦🏾", + ["boy_tone5"] = "👦🏿", + ["woman"] = "👩", + ["woman_tone1"] = "👩🏻", + ["woman_tone2"] = "👩🏼", + ["woman_tone3"] = "👩🏽", + ["woman_tone4"] = "👩🏾", + ["woman_tone5"] = "👩🏿", + ["adult"] = "🧑", + ["adult_tone1"] = "🧑🏻", + ["adult_light_skin_tone"] = "🧑🏻", + ["adult_tone2"] = "🧑🏼", + ["adult_medium_light_skin_tone"] = "🧑🏼", + ["adult_tone3"] = "🧑🏽", + ["adult_medium_skin_tone"] = "🧑🏽", + ["adult_tone4"] = "🧑🏾", + ["adult_medium_dark_skin_tone"] = "🧑🏾", + ["adult_tone5"] = "🧑🏿", + ["adult_dark_skin_tone"] = "🧑🏿", + ["man"] = "👨", + ["man_tone1"] = "👨🏻", + ["man_tone2"] = "👨🏼", + ["man_tone3"] = "👨🏽", + ["man_tone4"] = "👨🏾", + ["man_tone5"] = "👨🏿", + ["person_curly_hair"] = "🧑‍🦱", + ["person_tone1_curly_hair"] = "🧑🏻‍🦱", + ["person_light_skin_tone_curly_hair"] = "🧑🏻‍🦱", + ["person_tone2_curly_hair"] = "🧑🏼‍🦱", + ["person_medium_light_skin_tone_curly_hair"] = "🧑🏼‍🦱", + ["person_tone3_curly_hair"] = "🧑🏽‍🦱", + ["person_medium_skin_tone_curly_hair"] = "🧑🏽‍🦱", + ["person_tone4_curly_hair"] = "🧑🏾‍🦱", + ["person_medium_dark_skin_tone_curly_hair"] = "🧑🏾‍🦱", + ["person_tone5_curly_hair"] = "🧑🏿‍🦱", + ["person_dark_skin_tone_curly_hair"] = "🧑🏿‍🦱", + ["woman_curly_haired"] = "👩‍🦱", + ["woman_curly_haired_tone1"] = "👩🏻‍🦱", + ["woman_curly_haired_light_skin_tone"] = "👩🏻‍🦱", + ["woman_curly_haired_tone2"] = "👩🏼‍🦱", + ["woman_curly_haired_medium_light_skin_tone"] = "👩🏼‍🦱", + ["woman_curly_haired_tone3"] = "👩🏽‍🦱", + ["woman_curly_haired_medium_skin_tone"] = "👩🏽‍🦱", + ["woman_curly_haired_tone4"] = "👩🏾‍🦱", + ["woman_curly_haired_medium_dark_skin_tone"] = "👩🏾‍🦱", + ["woman_curly_haired_tone5"] = "👩🏿‍🦱", + ["woman_curly_haired_dark_skin_tone"] = "👩🏿‍🦱", + ["man_curly_haired"] = "👨‍🦱", + ["man_curly_haired_tone1"] = "👨🏻‍🦱", + ["man_curly_haired_light_skin_tone"] = "👨🏻‍🦱", + ["man_curly_haired_tone2"] = "👨🏼‍🦱", + ["man_curly_haired_medium_light_skin_tone"] = "👨🏼‍🦱", + ["man_curly_haired_tone3"] = "👨🏽‍🦱", + ["man_curly_haired_medium_skin_tone"] = "👨🏽‍🦱", + ["man_curly_haired_tone4"] = "👨🏾‍🦱", + ["man_curly_haired_medium_dark_skin_tone"] = "👨🏾‍🦱", + ["man_curly_haired_tone5"] = "👨🏿‍🦱", + ["man_curly_haired_dark_skin_tone"] = "👨🏿‍🦱", + ["person_red_hair"] = "🧑‍🦰", + ["person_tone1_red_hair"] = "🧑🏻‍🦰", + ["person_light_skin_tone_red_hair"] = "🧑🏻‍🦰", + ["person_tone2_red_hair"] = "🧑🏼‍🦰", + ["person_medium_light_skin_tone_red_hair"] = "🧑🏼‍🦰", + ["person_tone3_red_hair"] = "🧑🏽‍🦰", + ["person_medium_skin_tone_red_hair"] = "🧑🏽‍🦰", + ["person_tone4_red_hair"] = "🧑🏾‍🦰", + ["person_medium_dark_skin_tone_red_hair"] = "🧑🏾‍🦰", + ["person_tone5_red_hair"] = "🧑🏿‍🦰", + ["person_dark_skin_tone_red_hair"] = "🧑🏿‍🦰", + ["woman_red_haired"] = "👩‍🦰", + ["woman_red_haired_tone1"] = "👩🏻‍🦰", + ["woman_red_haired_light_skin_tone"] = "👩🏻‍🦰", + ["woman_red_haired_tone2"] = "👩🏼‍🦰", + ["woman_red_haired_medium_light_skin_tone"] = "👩🏼‍🦰", + ["woman_red_haired_tone3"] = "👩🏽‍🦰", + ["woman_red_haired_medium_skin_tone"] = "👩🏽‍🦰", + ["woman_red_haired_tone4"] = "👩🏾‍🦰", + ["woman_red_haired_medium_dark_skin_tone"] = "👩🏾‍🦰", + ["woman_red_haired_tone5"] = "👩🏿‍🦰", + ["woman_red_haired_dark_skin_tone"] = "👩🏿‍🦰", + ["man_red_haired"] = "👨‍🦰", + ["man_red_haired_tone1"] = "👨🏻‍🦰", + ["man_red_haired_light_skin_tone"] = "👨🏻‍🦰", + ["man_red_haired_tone2"] = "👨🏼‍🦰", + ["man_red_haired_medium_light_skin_tone"] = "👨🏼‍🦰", + ["man_red_haired_tone3"] = "👨🏽‍🦰", + ["man_red_haired_medium_skin_tone"] = "👨🏽‍🦰", + ["man_red_haired_tone4"] = "👨🏾‍🦰", + ["man_red_haired_medium_dark_skin_tone"] = "👨🏾‍🦰", + ["man_red_haired_tone5"] = "👨🏿‍🦰", + ["man_red_haired_dark_skin_tone"] = "👨🏿‍🦰", + ["blond_haired_woman"] = "👱‍♀️", + ["blond_haired_woman_tone1"] = "👱🏻‍♀️", + ["blond_haired_woman_light_skin_tone"] = "👱🏻‍♀️", + ["blond_haired_woman_tone2"] = "👱🏼‍♀️", + ["blond_haired_woman_medium_light_skin_tone"] = "👱🏼‍♀️", + ["blond_haired_woman_tone3"] = "👱🏽‍♀️", + ["blond_haired_woman_medium_skin_tone"] = "👱🏽‍♀️", + ["blond_haired_woman_tone4"] = "👱🏾‍♀️", + ["blond_haired_woman_medium_dark_skin_tone"] = "👱🏾‍♀️", + ["blond_haired_woman_tone5"] = "👱🏿‍♀️", + ["blond_haired_woman_dark_skin_tone"] = "👱🏿‍♀️", + ["blond_haired_person"] = "👱", + ["person_with_blond_hair"] = "👱", + ["blond_haired_person_tone1"] = "👱🏻", + ["person_with_blond_hair_tone1"] = "👱🏻", + ["blond_haired_person_tone2"] = "👱🏼", + ["person_with_blond_hair_tone2"] = "👱🏼", + ["blond_haired_person_tone3"] = "👱🏽", + ["person_with_blond_hair_tone3"] = "👱🏽", + ["blond_haired_person_tone4"] = "👱🏾", + ["person_with_blond_hair_tone4"] = "👱🏾", + ["blond_haired_person_tone5"] = "👱🏿", + ["person_with_blond_hair_tone5"] = "👱🏿", + ["blond_haired_man"] = "👱‍♂️", + ["blond_haired_man_tone1"] = "👱🏻‍♂️", + ["blond_haired_man_light_skin_tone"] = "👱🏻‍♂️", + ["blond_haired_man_tone2"] = "👱🏼‍♂️", + ["blond_haired_man_medium_light_skin_tone"] = "👱🏼‍♂️", + ["blond_haired_man_tone3"] = "👱🏽‍♂️", + ["blond_haired_man_medium_skin_tone"] = "👱🏽‍♂️", + ["blond_haired_man_tone4"] = "👱🏾‍♂️", + ["blond_haired_man_medium_dark_skin_tone"] = "👱🏾‍♂️", + ["blond_haired_man_tone5"] = "👱🏿‍♂️", + ["blond_haired_man_dark_skin_tone"] = "👱🏿‍♂️", + ["person_white_hair"] = "🧑‍🦳", + ["person_tone1_white_hair"] = "🧑🏻‍🦳", + ["person_light_skin_tone_white_hair"] = "🧑🏻‍🦳", + ["person_tone2_white_hair"] = "🧑🏼‍🦳", + ["person_medium_light_skin_tone_white_hair"] = "🧑🏼‍🦳", + ["person_tone3_white_hair"] = "🧑🏽‍🦳", + ["person_medium_skin_tone_white_hair"] = "🧑🏽‍🦳", + ["person_tone4_white_hair"] = "🧑🏾‍🦳", + ["person_medium_dark_skin_tone_white_hair"] = "🧑🏾‍🦳", + ["person_tone5_white_hair"] = "🧑🏿‍🦳", + ["person_dark_skin_tone_white_hair"] = "🧑🏿‍🦳", + ["woman_white_haired"] = "👩‍🦳", + ["woman_white_haired_tone1"] = "👩🏻‍🦳", + ["woman_white_haired_light_skin_tone"] = "👩🏻‍🦳", + ["woman_white_haired_tone2"] = "👩🏼‍🦳", + ["woman_white_haired_medium_light_skin_tone"] = "👩🏼‍🦳", + ["woman_white_haired_tone3"] = "👩🏽‍🦳", + ["woman_white_haired_medium_skin_tone"] = "👩🏽‍🦳", + ["woman_white_haired_tone4"] = "👩🏾‍🦳", + ["woman_white_haired_medium_dark_skin_tone"] = "👩🏾‍🦳", + ["woman_white_haired_tone5"] = "👩🏿‍🦳", + ["woman_white_haired_dark_skin_tone"] = "👩🏿‍🦳", + ["man_white_haired"] = "👨‍🦳", + ["man_white_haired_tone1"] = "👨🏻‍🦳", + ["man_white_haired_light_skin_tone"] = "👨🏻‍🦳", + ["man_white_haired_tone2"] = "👨🏼‍🦳", + ["man_white_haired_medium_light_skin_tone"] = "👨🏼‍🦳", + ["man_white_haired_tone3"] = "👨🏽‍🦳", + ["man_white_haired_medium_skin_tone"] = "👨🏽‍🦳", + ["man_white_haired_tone4"] = "👨🏾‍🦳", + ["man_white_haired_medium_dark_skin_tone"] = "👨🏾‍🦳", + ["man_white_haired_tone5"] = "👨🏿‍🦳", + ["man_white_haired_dark_skin_tone"] = "👨🏿‍🦳", + ["person_bald"] = "🧑‍🦲", + ["person_tone1_bald"] = "🧑🏻‍🦲", + ["person_light_skin_tone_bald"] = "🧑🏻‍🦲", + ["person_tone2_bald"] = "🧑🏼‍🦲", + ["person_medium_light_skin_tone_bald"] = "🧑🏼‍🦲", + ["person_tone3_bald"] = "🧑🏽‍🦲", + ["person_medium_skin_tone_bald"] = "🧑🏽‍🦲", + ["person_tone4_bald"] = "🧑🏾‍🦲", + ["person_medium_dark_skin_tone_bald"] = "🧑🏾‍🦲", + ["person_tone5_bald"] = "🧑🏿‍🦲", + ["person_dark_skin_tone_bald"] = "🧑🏿‍🦲", + ["woman_bald"] = "👩‍🦲", + ["woman_bald_tone1"] = "👩🏻‍🦲", + ["woman_bald_light_skin_tone"] = "👩🏻‍🦲", + ["woman_bald_tone2"] = "👩🏼‍🦲", + ["woman_bald_medium_light_skin_tone"] = "👩🏼‍🦲", + ["woman_bald_tone3"] = "👩🏽‍🦲", + ["woman_bald_medium_skin_tone"] = "👩🏽‍🦲", + ["woman_bald_tone4"] = "👩🏾‍🦲", + ["woman_bald_medium_dark_skin_tone"] = "👩🏾‍🦲", + ["woman_bald_tone5"] = "👩🏿‍🦲", + ["woman_bald_dark_skin_tone"] = "👩🏿‍🦲", + ["man_bald"] = "👨‍🦲", + ["man_bald_tone1"] = "👨🏻‍🦲", + ["man_bald_light_skin_tone"] = "👨🏻‍🦲", + ["man_bald_tone2"] = "👨🏼‍🦲", + ["man_bald_medium_light_skin_tone"] = "👨🏼‍🦲", + ["man_bald_tone3"] = "👨🏽‍🦲", + ["man_bald_medium_skin_tone"] = "👨🏽‍🦲", + ["man_bald_tone4"] = "👨🏾‍🦲", + ["man_bald_medium_dark_skin_tone"] = "👨🏾‍🦲", + ["man_bald_tone5"] = "👨🏿‍🦲", + ["man_bald_dark_skin_tone"] = "👨🏿‍🦲", + ["bearded_person"] = "🧔", + ["bearded_person_tone1"] = "🧔🏻", + ["bearded_person_light_skin_tone"] = "🧔🏻", + ["bearded_person_tone2"] = "🧔🏼", + ["bearded_person_medium_light_skin_tone"] = "🧔🏼", + ["bearded_person_tone3"] = "🧔🏽", + ["bearded_person_medium_skin_tone"] = "🧔🏽", + ["bearded_person_tone4"] = "🧔🏾", + ["bearded_person_medium_dark_skin_tone"] = "🧔🏾", + ["bearded_person_tone5"] = "🧔🏿", + ["bearded_person_dark_skin_tone"] = "🧔🏿", + ["man_beard"] = "🧔‍♂️", + ["man_tone1_beard"] = "🧔🏻‍♂️", + ["man_light_skin_tone_beard"] = "🧔🏻‍♂️", + ["man_tone2_beard"] = "🧔🏼‍♂️", + ["man_medium_light_skin_tone_beard"] = "🧔🏼‍♂️", + ["man_tone3_beard"] = "🧔🏽‍♂️", + ["man_medium_skin_tone_beard"] = "🧔🏽‍♂️", + ["man_tone4_beard"] = "🧔🏾‍♂️", + ["man_medium_dark_skin_tone_beard"] = "🧔🏾‍♂️", + ["man_tone5_beard"] = "🧔🏿‍♂️", + ["man_dark_skin_tone_beard"] = "🧔🏿‍♂️", + ["woman_beard"] = "🧔‍♀️", + ["woman_tone1_beard"] = "🧔🏻‍♀️", + ["woman_light_skin_tone_beard"] = "🧔🏻‍♀️", + ["woman_tone2_beard"] = "🧔🏼‍♀️", + ["woman_medium_light_skin_tone_beard"] = "🧔🏼‍♀️", + ["woman_tone3_beard"] = "🧔🏽‍♀️", + ["woman_medium_skin_tone_beard"] = "🧔🏽‍♀️", + ["woman_tone4_beard"] = "🧔🏾‍♀️", + ["woman_medium_dark_skin_tone_beard"] = "🧔🏾‍♀️", + ["woman_tone5_beard"] = "🧔🏿‍♀️", + ["woman_dark_skin_tone_beard"] = "🧔🏿‍♀️", + ["older_woman"] = "👵", + ["grandma"] = "👵", + ["older_woman_tone1"] = "👵🏻", + ["grandma_tone1"] = "👵🏻", + ["older_woman_tone2"] = "👵🏼", + ["grandma_tone2"] = "👵🏼", + ["older_woman_tone3"] = "👵🏽", + ["grandma_tone3"] = "👵🏽", + ["older_woman_tone4"] = "👵🏾", + ["grandma_tone4"] = "👵🏾", + ["older_woman_tone5"] = "👵🏿", + ["grandma_tone5"] = "👵🏿", + ["older_adult"] = "🧓", + ["older_adult_tone1"] = "🧓🏻", + ["older_adult_light_skin_tone"] = "🧓🏻", + ["older_adult_tone2"] = "🧓🏼", + ["older_adult_medium_light_skin_tone"] = "🧓🏼", + ["older_adult_tone3"] = "🧓🏽", + ["older_adult_medium_skin_tone"] = "🧓🏽", + ["older_adult_tone4"] = "🧓🏾", + ["older_adult_medium_dark_skin_tone"] = "🧓🏾", + ["older_adult_tone5"] = "🧓🏿", + ["older_adult_dark_skin_tone"] = "🧓🏿", + ["older_man"] = "👴", + ["older_man_tone1"] = "👴🏻", + ["older_man_tone2"] = "👴🏼", + ["older_man_tone3"] = "👴🏽", + ["older_man_tone4"] = "👴🏾", + ["older_man_tone5"] = "👴🏿", + ["man_with_chinese_cap"] = "👲", + ["man_with_gua_pi_mao"] = "👲", + ["man_with_chinese_cap_tone1"] = "👲🏻", + ["man_with_gua_pi_mao_tone1"] = "👲🏻", + ["man_with_chinese_cap_tone2"] = "👲🏼", + ["man_with_gua_pi_mao_tone2"] = "👲🏼", + ["man_with_chinese_cap_tone3"] = "👲🏽", + ["man_with_gua_pi_mao_tone3"] = "👲🏽", + ["man_with_chinese_cap_tone4"] = "👲🏾", + ["man_with_gua_pi_mao_tone4"] = "👲🏾", + ["man_with_chinese_cap_tone5"] = "👲🏿", + ["man_with_gua_pi_mao_tone5"] = "👲🏿", + ["person_wearing_turban"] = "👳", + ["man_with_turban"] = "👳", + ["person_wearing_turban_tone1"] = "👳🏻", + ["man_with_turban_tone1"] = "👳🏻", + ["person_wearing_turban_tone2"] = "👳🏼", + ["man_with_turban_tone2"] = "👳🏼", + ["person_wearing_turban_tone3"] = "👳🏽", + ["man_with_turban_tone3"] = "👳🏽", + ["person_wearing_turban_tone4"] = "👳🏾", + ["man_with_turban_tone4"] = "👳🏾", + ["person_wearing_turban_tone5"] = "👳🏿", + ["man_with_turban_tone5"] = "👳🏿", + ["woman_wearing_turban"] = "👳‍♀️", + ["woman_wearing_turban_tone1"] = "👳🏻‍♀️", + ["woman_wearing_turban_light_skin_tone"] = "👳🏻‍♀️", + ["woman_wearing_turban_tone2"] = "👳🏼‍♀️", + ["woman_wearing_turban_medium_light_skin_tone"] = "👳🏼‍♀️", + ["woman_wearing_turban_tone3"] = "👳🏽‍♀️", + ["woman_wearing_turban_medium_skin_tone"] = "👳🏽‍♀️", + ["woman_wearing_turban_tone4"] = "👳🏾‍♀️", + ["woman_wearing_turban_medium_dark_skin_tone"] = "👳🏾‍♀️", + ["woman_wearing_turban_tone5"] = "👳🏿‍♀️", + ["woman_wearing_turban_dark_skin_tone"] = "👳🏿‍♀️", + ["man_wearing_turban"] = "👳‍♂️", + ["man_wearing_turban_tone1"] = "👳🏻‍♂️", + ["man_wearing_turban_light_skin_tone"] = "👳🏻‍♂️", + ["man_wearing_turban_tone2"] = "👳🏼‍♂️", + ["man_wearing_turban_medium_light_skin_tone"] = "👳🏼‍♂️", + ["man_wearing_turban_tone3"] = "👳🏽‍♂️", + ["man_wearing_turban_medium_skin_tone"] = "👳🏽‍♂️", + ["man_wearing_turban_tone4"] = "👳🏾‍♂️", + ["man_wearing_turban_medium_dark_skin_tone"] = "👳🏾‍♂️", + ["man_wearing_turban_tone5"] = "👳🏿‍♂️", + ["man_wearing_turban_dark_skin_tone"] = "👳🏿‍♂️", + ["woman_with_headscarf"] = "🧕", + ["woman_with_headscarf_tone1"] = "🧕🏻", + ["woman_with_headscarf_light_skin_tone"] = "🧕🏻", + ["woman_with_headscarf_tone2"] = "🧕🏼", + ["woman_with_headscarf_medium_light_skin_tone"] = "🧕🏼", + ["woman_with_headscarf_tone3"] = "🧕🏽", + ["woman_with_headscarf_medium_skin_tone"] = "🧕🏽", + ["woman_with_headscarf_tone4"] = "🧕🏾", + ["woman_with_headscarf_medium_dark_skin_tone"] = "🧕🏾", + ["woman_with_headscarf_tone5"] = "🧕🏿", + ["woman_with_headscarf_dark_skin_tone"] = "🧕🏿", + ["police_officer"] = "👮", + ["cop"] = "👮", + ["police_officer_tone1"] = "👮🏻", + ["cop_tone1"] = "👮🏻", + ["police_officer_tone2"] = "👮🏼", + ["cop_tone2"] = "👮🏼", + ["police_officer_tone3"] = "👮🏽", + ["cop_tone3"] = "👮🏽", + ["police_officer_tone4"] = "👮🏾", + ["cop_tone4"] = "👮🏾", + ["police_officer_tone5"] = "👮🏿", + ["cop_tone5"] = "👮🏿", + ["woman_police_officer"] = "👮‍♀️", + ["woman_police_officer_tone1"] = "👮🏻‍♀️", + ["woman_police_officer_light_skin_tone"] = "👮🏻‍♀️", + ["woman_police_officer_tone2"] = "👮🏼‍♀️", + ["woman_police_officer_medium_light_skin_tone"] = "👮🏼‍♀️", + ["woman_police_officer_tone3"] = "👮🏽‍♀️", + ["woman_police_officer_medium_skin_tone"] = "👮🏽‍♀️", + ["woman_police_officer_tone4"] = "👮🏾‍♀️", + ["woman_police_officer_medium_dark_skin_tone"] = "👮🏾‍♀️", + ["woman_police_officer_tone5"] = "👮🏿‍♀️", + ["woman_police_officer_dark_skin_tone"] = "👮🏿‍♀️", + ["man_police_officer"] = "👮‍♂️", + ["man_police_officer_tone1"] = "👮🏻‍♂️", + ["man_police_officer_light_skin_tone"] = "👮🏻‍♂️", + ["man_police_officer_tone2"] = "👮🏼‍♂️", + ["man_police_officer_medium_light_skin_tone"] = "👮🏼‍♂️", + ["man_police_officer_tone3"] = "👮🏽‍♂️", + ["man_police_officer_medium_skin_tone"] = "👮🏽‍♂️", + ["man_police_officer_tone4"] = "👮🏾‍♂️", + ["man_police_officer_medium_dark_skin_tone"] = "👮🏾‍♂️", + ["man_police_officer_tone5"] = "👮🏿‍♂️", + ["man_police_officer_dark_skin_tone"] = "👮🏿‍♂️", + ["construction_worker"] = "👷", + ["construction_worker_tone1"] = "👷🏻", + ["construction_worker_tone2"] = "👷🏼", + ["construction_worker_tone3"] = "👷🏽", + ["construction_worker_tone4"] = "👷🏾", + ["construction_worker_tone5"] = "👷🏿", + ["woman_construction_worker"] = "👷‍♀️", + ["woman_construction_worker_tone1"] = "👷🏻‍♀️", + ["woman_construction_worker_light_skin_tone"] = "👷🏻‍♀️", + ["woman_construction_worker_tone2"] = "👷🏼‍♀️", + ["woman_construction_worker_medium_light_skin_tone"] = "👷🏼‍♀️", + ["woman_construction_worker_tone3"] = "👷🏽‍♀️", + ["woman_construction_worker_medium_skin_tone"] = "👷🏽‍♀️", + ["woman_construction_worker_tone4"] = "👷🏾‍♀️", + ["woman_construction_worker_medium_dark_skin_tone"] = "👷🏾‍♀️", + ["woman_construction_worker_tone5"] = "👷🏿‍♀️", + ["woman_construction_worker_dark_skin_tone"] = "👷🏿‍♀️", + ["man_construction_worker"] = "👷‍♂️", + ["man_construction_worker_tone1"] = "👷🏻‍♂️", + ["man_construction_worker_light_skin_tone"] = "👷🏻‍♂️", + ["man_construction_worker_tone2"] = "👷🏼‍♂️", + ["man_construction_worker_medium_light_skin_tone"] = "👷🏼‍♂️", + ["man_construction_worker_tone3"] = "👷🏽‍♂️", + ["man_construction_worker_medium_skin_tone"] = "👷🏽‍♂️", + ["man_construction_worker_tone4"] = "👷🏾‍♂️", + ["man_construction_worker_medium_dark_skin_tone"] = "👷🏾‍♂️", + ["man_construction_worker_tone5"] = "👷🏿‍♂️", + ["man_construction_worker_dark_skin_tone"] = "👷🏿‍♂️", + ["guard"] = "💂", + ["guardsman"] = "💂", + ["guard_tone1"] = "💂🏻", + ["guardsman_tone1"] = "💂🏻", + ["guard_tone2"] = "💂🏼", + ["guardsman_tone2"] = "💂🏼", + ["guard_tone3"] = "💂🏽", + ["guardsman_tone3"] = "💂🏽", + ["guard_tone4"] = "💂🏾", + ["guardsman_tone4"] = "💂🏾", + ["guard_tone5"] = "💂🏿", + ["guardsman_tone5"] = "💂🏿", + ["woman_guard"] = "💂‍♀️", + ["woman_guard_tone1"] = "💂🏻‍♀️", + ["woman_guard_light_skin_tone"] = "💂🏻‍♀️", + ["woman_guard_tone2"] = "💂🏼‍♀️", + ["woman_guard_medium_light_skin_tone"] = "💂🏼‍♀️", + ["woman_guard_tone3"] = "💂🏽‍♀️", + ["woman_guard_medium_skin_tone"] = "💂🏽‍♀️", + ["woman_guard_tone4"] = "💂🏾‍♀️", + ["woman_guard_medium_dark_skin_tone"] = "💂🏾‍♀️", + ["woman_guard_tone5"] = "💂🏿‍♀️", + ["woman_guard_dark_skin_tone"] = "💂🏿‍♀️", + ["man_guard"] = "💂‍♂️", + ["man_guard_tone1"] = "💂🏻‍♂️", + ["man_guard_light_skin_tone"] = "💂🏻‍♂️", + ["man_guard_tone2"] = "💂🏼‍♂️", + ["man_guard_medium_light_skin_tone"] = "💂🏼‍♂️", + ["man_guard_tone3"] = "💂🏽‍♂️", + ["man_guard_medium_skin_tone"] = "💂🏽‍♂️", + ["man_guard_tone4"] = "💂🏾‍♂️", + ["man_guard_medium_dark_skin_tone"] = "💂🏾‍♂️", + ["man_guard_tone5"] = "💂🏿‍♂️", + ["man_guard_dark_skin_tone"] = "💂🏿‍♂️", + ["detective"] = "🕵️", + ["spy"] = "🕵️", + ["sleuth_or_spy"] = "🕵️", + ["detective_tone1"] = "🕵🏻", + ["spy_tone1"] = "🕵🏻", + ["sleuth_or_spy_tone1"] = "🕵🏻", + ["detective_tone2"] = "🕵🏼", + ["spy_tone2"] = "🕵🏼", + ["sleuth_or_spy_tone2"] = "🕵🏼", + ["detective_tone3"] = "🕵🏽", + ["spy_tone3"] = "🕵🏽", + ["sleuth_or_spy_tone3"] = "🕵🏽", + ["detective_tone4"] = "🕵🏾", + ["spy_tone4"] = "🕵🏾", + ["sleuth_or_spy_tone4"] = "🕵🏾", + ["detective_tone5"] = "🕵🏿", + ["spy_tone5"] = "🕵🏿", + ["sleuth_or_spy_tone5"] = "🕵🏿", + ["woman_detective"] = "🕵️‍♀️", + ["woman_detective_tone1"] = "🕵🏻‍♀️", + ["woman_detective_light_skin_tone"] = "🕵🏻‍♀️", + ["woman_detective_tone2"] = "🕵🏼‍♀️", + ["woman_detective_medium_light_skin_tone"] = "🕵🏼‍♀️", + ["woman_detective_tone3"] = "🕵🏽‍♀️", + ["woman_detective_medium_skin_tone"] = "🕵🏽‍♀️", + ["woman_detective_tone4"] = "🕵🏾‍♀️", + ["woman_detective_medium_dark_skin_tone"] = "🕵🏾‍♀️", + ["woman_detective_tone5"] = "🕵🏿‍♀️", + ["woman_detective_dark_skin_tone"] = "🕵🏿‍♀️", + ["man_detective"] = "🕵️‍♂️", + ["man_detective_tone1"] = "🕵🏻‍♂️", + ["man_detective_light_skin_tone"] = "🕵🏻‍♂️", + ["man_detective_tone2"] = "🕵🏼‍♂️", + ["man_detective_medium_light_skin_tone"] = "🕵🏼‍♂️", + ["man_detective_tone3"] = "🕵🏽‍♂️", + ["man_detective_medium_skin_tone"] = "🕵🏽‍♂️", + ["man_detective_tone4"] = "🕵🏾‍♂️", + ["man_detective_medium_dark_skin_tone"] = "🕵🏾‍♂️", + ["man_detective_tone5"] = "🕵🏿‍♂️", + ["man_detective_dark_skin_tone"] = "🕵🏿‍♂️", + ["health_worker"] = "🧑‍⚕️", + ["health_worker_tone1"] = "🧑🏻‍⚕️", + ["health_worker_light_skin_tone"] = "🧑🏻‍⚕️", + ["health_worker_tone2"] = "🧑🏼‍⚕️", + ["health_worker_medium_light_skin_tone"] = "🧑🏼‍⚕️", + ["health_worker_tone3"] = "🧑🏽‍⚕️", + ["health_worker_medium_skin_tone"] = "🧑🏽‍⚕️", + ["health_worker_tone4"] = "🧑🏾‍⚕️", + ["health_worker_medium_dark_skin_tone"] = "🧑🏾‍⚕️", + ["health_worker_tone5"] = "🧑🏿‍⚕️", + ["health_worker_dark_skin_tone"] = "🧑🏿‍⚕️", + ["woman_health_worker"] = "👩‍⚕️", + ["woman_health_worker_tone1"] = "👩🏻‍⚕️", + ["woman_health_worker_light_skin_tone"] = "👩🏻‍⚕️", + ["woman_health_worker_tone2"] = "👩🏼‍⚕️", + ["woman_health_worker_medium_light_skin_tone"] = "👩🏼‍⚕️", + ["woman_health_worker_tone3"] = "👩🏽‍⚕️", + ["woman_health_worker_medium_skin_tone"] = "👩🏽‍⚕️", + ["woman_health_worker_tone4"] = "👩🏾‍⚕️", + ["woman_health_worker_medium_dark_skin_tone"] = "👩🏾‍⚕️", + ["woman_health_worker_tone5"] = "👩🏿‍⚕️", + ["woman_health_worker_dark_skin_tone"] = "👩🏿‍⚕️", + ["man_health_worker"] = "👨‍⚕️", + ["man_health_worker_tone1"] = "👨🏻‍⚕️", + ["man_health_worker_light_skin_tone"] = "👨🏻‍⚕️", + ["man_health_worker_tone2"] = "👨🏼‍⚕️", + ["man_health_worker_medium_light_skin_tone"] = "👨🏼‍⚕️", + ["man_health_worker_tone3"] = "👨🏽‍⚕️", + ["man_health_worker_medium_skin_tone"] = "👨🏽‍⚕️", + ["man_health_worker_tone4"] = "👨🏾‍⚕️", + ["man_health_worker_medium_dark_skin_tone"] = "👨🏾‍⚕️", + ["man_health_worker_tone5"] = "👨🏿‍⚕️", + ["man_health_worker_dark_skin_tone"] = "👨🏿‍⚕️", + ["farmer"] = "🧑‍🌾", + ["farmer_tone1"] = "🧑🏻‍🌾", + ["farmer_light_skin_tone"] = "🧑🏻‍🌾", + ["farmer_tone2"] = "🧑🏼‍🌾", + ["farmer_medium_light_skin_tone"] = "🧑🏼‍🌾", + ["farmer_tone3"] = "🧑🏽‍🌾", + ["farmer_medium_skin_tone"] = "🧑🏽‍🌾", + ["farmer_tone4"] = "🧑🏾‍🌾", + ["farmer_medium_dark_skin_tone"] = "🧑🏾‍🌾", + ["farmer_tone5"] = "🧑🏿‍🌾", + ["farmer_dark_skin_tone"] = "🧑🏿‍🌾", + ["woman_farmer"] = "👩‍🌾", + ["woman_farmer_tone1"] = "👩🏻‍🌾", + ["woman_farmer_light_skin_tone"] = "👩🏻‍🌾", + ["woman_farmer_tone2"] = "👩🏼‍🌾", + ["woman_farmer_medium_light_skin_tone"] = "👩🏼‍🌾", + ["woman_farmer_tone3"] = "👩🏽‍🌾", + ["woman_farmer_medium_skin_tone"] = "👩🏽‍🌾", + ["woman_farmer_tone4"] = "👩🏾‍🌾", + ["woman_farmer_medium_dark_skin_tone"] = "👩🏾‍🌾", + ["woman_farmer_tone5"] = "👩🏿‍🌾", + ["woman_farmer_dark_skin_tone"] = "👩🏿‍🌾", + ["man_farmer"] = "👨‍🌾", + ["man_farmer_tone1"] = "👨🏻‍🌾", + ["man_farmer_light_skin_tone"] = "👨🏻‍🌾", + ["man_farmer_tone2"] = "👨🏼‍🌾", + ["man_farmer_medium_light_skin_tone"] = "👨🏼‍🌾", + ["man_farmer_tone3"] = "👨🏽‍🌾", + ["man_farmer_medium_skin_tone"] = "👨🏽‍🌾", + ["man_farmer_tone4"] = "👨🏾‍🌾", + ["man_farmer_medium_dark_skin_tone"] = "👨🏾‍🌾", + ["man_farmer_tone5"] = "👨🏿‍🌾", + ["man_farmer_dark_skin_tone"] = "👨🏿‍🌾", + ["cook"] = "🧑‍🍳", + ["cook_tone1"] = "🧑🏻‍🍳", + ["cook_light_skin_tone"] = "🧑🏻‍🍳", + ["cook_tone2"] = "🧑🏼‍🍳", + ["cook_medium_light_skin_tone"] = "🧑🏼‍🍳", + ["cook_tone3"] = "🧑🏽‍🍳", + ["cook_medium_skin_tone"] = "🧑🏽‍🍳", + ["cook_tone4"] = "🧑🏾‍🍳", + ["cook_medium_dark_skin_tone"] = "🧑🏾‍🍳", + ["cook_tone5"] = "🧑🏿‍🍳", + ["cook_dark_skin_tone"] = "🧑🏿‍🍳", + ["woman_cook"] = "👩‍🍳", + ["woman_cook_tone1"] = "👩🏻‍🍳", + ["woman_cook_light_skin_tone"] = "👩🏻‍🍳", + ["woman_cook_tone2"] = "👩🏼‍🍳", + ["woman_cook_medium_light_skin_tone"] = "👩🏼‍🍳", + ["woman_cook_tone3"] = "👩🏽‍🍳", + ["woman_cook_medium_skin_tone"] = "👩🏽‍🍳", + ["woman_cook_tone4"] = "👩🏾‍🍳", + ["woman_cook_medium_dark_skin_tone"] = "👩🏾‍🍳", + ["woman_cook_tone5"] = "👩🏿‍🍳", + ["woman_cook_dark_skin_tone"] = "👩🏿‍🍳", + ["man_cook"] = "👨‍🍳", + ["man_cook_tone1"] = "👨🏻‍🍳", + ["man_cook_light_skin_tone"] = "👨🏻‍🍳", + ["man_cook_tone2"] = "👨🏼‍🍳", + ["man_cook_medium_light_skin_tone"] = "👨🏼‍🍳", + ["man_cook_tone3"] = "👨🏽‍🍳", + ["man_cook_medium_skin_tone"] = "👨🏽‍🍳", + ["man_cook_tone4"] = "👨🏾‍🍳", + ["man_cook_medium_dark_skin_tone"] = "👨🏾‍🍳", + ["man_cook_tone5"] = "👨🏿‍🍳", + ["man_cook_dark_skin_tone"] = "👨🏿‍🍳", + ["student"] = "🧑‍🎓", + ["student_tone1"] = "🧑🏻‍🎓", + ["student_light_skin_tone"] = "🧑🏻‍🎓", + ["student_tone2"] = "🧑🏼‍🎓", + ["student_medium_light_skin_tone"] = "🧑🏼‍🎓", + ["student_tone3"] = "🧑🏽‍🎓", + ["student_medium_skin_tone"] = "🧑🏽‍🎓", + ["student_tone4"] = "🧑🏾‍🎓", + ["student_medium_dark_skin_tone"] = "🧑🏾‍🎓", + ["student_tone5"] = "🧑🏿‍🎓", + ["student_dark_skin_tone"] = "🧑🏿‍🎓", + ["woman_student"] = "👩‍🎓", + ["woman_student_tone1"] = "👩🏻‍🎓", + ["woman_student_light_skin_tone"] = "👩🏻‍🎓", + ["woman_student_tone2"] = "👩🏼‍🎓", + ["woman_student_medium_light_skin_tone"] = "👩🏼‍🎓", + ["woman_student_tone3"] = "👩🏽‍🎓", + ["woman_student_medium_skin_tone"] = "👩🏽‍🎓", + ["woman_student_tone4"] = "👩🏾‍🎓", + ["woman_student_medium_dark_skin_tone"] = "👩🏾‍🎓", + ["woman_student_tone5"] = "👩🏿‍🎓", + ["woman_student_dark_skin_tone"] = "👩🏿‍🎓", + ["man_student"] = "👨‍🎓", + ["man_student_tone1"] = "👨🏻‍🎓", + ["man_student_light_skin_tone"] = "👨🏻‍🎓", + ["man_student_tone2"] = "👨🏼‍🎓", + ["man_student_medium_light_skin_tone"] = "👨🏼‍🎓", + ["man_student_tone3"] = "👨🏽‍🎓", + ["man_student_medium_skin_tone"] = "👨🏽‍🎓", + ["man_student_tone4"] = "👨🏾‍🎓", + ["man_student_medium_dark_skin_tone"] = "👨🏾‍🎓", + ["man_student_tone5"] = "👨🏿‍🎓", + ["man_student_dark_skin_tone"] = "👨🏿‍🎓", + ["singer"] = "🧑‍🎤", + ["singer_tone1"] = "🧑🏻‍🎤", + ["singer_light_skin_tone"] = "🧑🏻‍🎤", + ["singer_tone2"] = "🧑🏼‍🎤", + ["singer_medium_light_skin_tone"] = "🧑🏼‍🎤", + ["singer_tone3"] = "🧑🏽‍🎤", + ["singer_medium_skin_tone"] = "🧑🏽‍🎤", + ["singer_tone4"] = "🧑🏾‍🎤", + ["singer_medium_dark_skin_tone"] = "🧑🏾‍🎤", + ["singer_tone5"] = "🧑🏿‍🎤", + ["singer_dark_skin_tone"] = "🧑🏿‍🎤", + ["woman_singer"] = "👩‍🎤", + ["woman_singer_tone1"] = "👩🏻‍🎤", + ["woman_singer_light_skin_tone"] = "👩🏻‍🎤", + ["woman_singer_tone2"] = "👩🏼‍🎤", + ["woman_singer_medium_light_skin_tone"] = "👩🏼‍🎤", + ["woman_singer_tone3"] = "👩🏽‍🎤", + ["woman_singer_medium_skin_tone"] = "👩🏽‍🎤", + ["woman_singer_tone4"] = "👩🏾‍🎤", + ["woman_singer_medium_dark_skin_tone"] = "👩🏾‍🎤", + ["woman_singer_tone5"] = "👩🏿‍🎤", + ["woman_singer_dark_skin_tone"] = "👩🏿‍🎤", + ["man_singer"] = "👨‍🎤", + ["man_singer_tone1"] = "👨🏻‍🎤", + ["man_singer_light_skin_tone"] = "👨🏻‍🎤", + ["man_singer_tone2"] = "👨🏼‍🎤", + ["man_singer_medium_light_skin_tone"] = "👨🏼‍🎤", + ["man_singer_tone3"] = "👨🏽‍🎤", + ["man_singer_medium_skin_tone"] = "👨🏽‍🎤", + ["man_singer_tone4"] = "👨🏾‍🎤", + ["man_singer_medium_dark_skin_tone"] = "👨🏾‍🎤", + ["man_singer_tone5"] = "👨🏿‍🎤", + ["man_singer_dark_skin_tone"] = "👨🏿‍🎤", + ["teacher"] = "🧑‍🏫", + ["teacher_tone1"] = "🧑🏻‍🏫", + ["teacher_light_skin_tone"] = "🧑🏻‍🏫", + ["teacher_tone2"] = "🧑🏼‍🏫", + ["teacher_medium_light_skin_tone"] = "🧑🏼‍🏫", + ["teacher_tone3"] = "🧑🏽‍🏫", + ["teacher_medium_skin_tone"] = "🧑🏽‍🏫", + ["teacher_tone4"] = "🧑🏾‍🏫", + ["teacher_medium_dark_skin_tone"] = "🧑🏾‍🏫", + ["teacher_tone5"] = "🧑🏿‍🏫", + ["teacher_dark_skin_tone"] = "🧑🏿‍🏫", + ["woman_teacher"] = "👩‍🏫", + ["woman_teacher_tone1"] = "👩🏻‍🏫", + ["woman_teacher_light_skin_tone"] = "👩🏻‍🏫", + ["woman_teacher_tone2"] = "👩🏼‍🏫", + ["woman_teacher_medium_light_skin_tone"] = "👩🏼‍🏫", + ["woman_teacher_tone3"] = "👩🏽‍🏫", + ["woman_teacher_medium_skin_tone"] = "👩🏽‍🏫", + ["woman_teacher_tone4"] = "👩🏾‍🏫", + ["woman_teacher_medium_dark_skin_tone"] = "👩🏾‍🏫", + ["woman_teacher_tone5"] = "👩🏿‍🏫", + ["woman_teacher_dark_skin_tone"] = "👩🏿‍🏫", + ["man_teacher"] = "👨‍🏫", + ["man_teacher_tone1"] = "👨🏻‍🏫", + ["man_teacher_light_skin_tone"] = "👨🏻‍🏫", + ["man_teacher_tone2"] = "👨🏼‍🏫", + ["man_teacher_medium_light_skin_tone"] = "👨🏼‍🏫", + ["man_teacher_tone3"] = "👨🏽‍🏫", + ["man_teacher_medium_skin_tone"] = "👨🏽‍🏫", + ["man_teacher_tone4"] = "👨🏾‍🏫", + ["man_teacher_medium_dark_skin_tone"] = "👨🏾‍🏫", + ["man_teacher_tone5"] = "👨🏿‍🏫", + ["man_teacher_dark_skin_tone"] = "👨🏿‍🏫", + ["factory_worker"] = "🧑‍🏭", + ["factory_worker_tone1"] = "🧑🏻‍🏭", + ["factory_worker_light_skin_tone"] = "🧑🏻‍🏭", + ["factory_worker_tone2"] = "🧑🏼‍🏭", + ["factory_worker_medium_light_skin_tone"] = "🧑🏼‍🏭", + ["factory_worker_tone3"] = "🧑🏽‍🏭", + ["factory_worker_medium_skin_tone"] = "🧑🏽‍🏭", + ["factory_worker_tone4"] = "🧑🏾‍🏭", + ["factory_worker_medium_dark_skin_tone"] = "🧑🏾‍🏭", + ["factory_worker_tone5"] = "🧑🏿‍🏭", + ["factory_worker_dark_skin_tone"] = "🧑🏿‍🏭", + ["woman_factory_worker"] = "👩‍🏭", + ["woman_factory_worker_tone1"] = "👩🏻‍🏭", + ["woman_factory_worker_light_skin_tone"] = "👩🏻‍🏭", + ["woman_factory_worker_tone2"] = "👩🏼‍🏭", + ["woman_factory_worker_medium_light_skin_tone"] = "👩🏼‍🏭", + ["woman_factory_worker_tone3"] = "👩🏽‍🏭", + ["woman_factory_worker_medium_skin_tone"] = "👩🏽‍🏭", + ["woman_factory_worker_tone4"] = "👩🏾‍🏭", + ["woman_factory_worker_medium_dark_skin_tone"] = "👩🏾‍🏭", + ["woman_factory_worker_tone5"] = "👩🏿‍🏭", + ["woman_factory_worker_dark_skin_tone"] = "👩🏿‍🏭", + ["man_factory_worker"] = "👨‍🏭", + ["man_factory_worker_tone1"] = "👨🏻‍🏭", + ["man_factory_worker_light_skin_tone"] = "👨🏻‍🏭", + ["man_factory_worker_tone2"] = "👨🏼‍🏭", + ["man_factory_worker_medium_light_skin_tone"] = "👨🏼‍🏭", + ["man_factory_worker_tone3"] = "👨🏽‍🏭", + ["man_factory_worker_medium_skin_tone"] = "👨🏽‍🏭", + ["man_factory_worker_tone4"] = "👨🏾‍🏭", + ["man_factory_worker_medium_dark_skin_tone"] = "👨🏾‍🏭", + ["man_factory_worker_tone5"] = "👨🏿‍🏭", + ["man_factory_worker_dark_skin_tone"] = "👨🏿‍🏭", + ["technologist"] = "🧑‍💻", + ["technologist_tone1"] = "🧑🏻‍💻", + ["technologist_light_skin_tone"] = "🧑🏻‍💻", + ["technologist_tone2"] = "🧑🏼‍💻", + ["technologist_medium_light_skin_tone"] = "🧑🏼‍💻", + ["technologist_tone3"] = "🧑🏽‍💻", + ["technologist_medium_skin_tone"] = "🧑🏽‍💻", + ["technologist_tone4"] = "🧑🏾‍💻", + ["technologist_medium_dark_skin_tone"] = "🧑🏾‍💻", + ["technologist_tone5"] = "🧑🏿‍💻", + ["technologist_dark_skin_tone"] = "🧑🏿‍💻", + ["woman_technologist"] = "👩‍💻", + ["woman_technologist_tone1"] = "👩🏻‍💻", + ["woman_technologist_light_skin_tone"] = "👩🏻‍💻", + ["woman_technologist_tone2"] = "👩🏼‍💻", + ["woman_technologist_medium_light_skin_tone"] = "👩🏼‍💻", + ["woman_technologist_tone3"] = "👩🏽‍💻", + ["woman_technologist_medium_skin_tone"] = "👩🏽‍💻", + ["woman_technologist_tone4"] = "👩🏾‍💻", + ["woman_technologist_medium_dark_skin_tone"] = "👩🏾‍💻", + ["woman_technologist_tone5"] = "👩🏿‍💻", + ["woman_technologist_dark_skin_tone"] = "👩🏿‍💻", + ["man_technologist"] = "👨‍💻", + ["man_technologist_tone1"] = "👨🏻‍💻", + ["man_technologist_light_skin_tone"] = "👨🏻‍💻", + ["man_technologist_tone2"] = "👨🏼‍💻", + ["man_technologist_medium_light_skin_tone"] = "👨🏼‍💻", + ["man_technologist_tone3"] = "👨🏽‍💻", + ["man_technologist_medium_skin_tone"] = "👨🏽‍💻", + ["man_technologist_tone4"] = "👨🏾‍💻", + ["man_technologist_medium_dark_skin_tone"] = "👨🏾‍💻", + ["man_technologist_tone5"] = "👨🏿‍💻", + ["man_technologist_dark_skin_tone"] = "👨🏿‍💻", + ["office_worker"] = "🧑‍💼", + ["office_worker_tone1"] = "🧑🏻‍💼", + ["office_worker_light_skin_tone"] = "🧑🏻‍💼", + ["office_worker_tone2"] = "🧑🏼‍💼", + ["office_worker_medium_light_skin_tone"] = "🧑🏼‍💼", + ["office_worker_tone3"] = "🧑🏽‍💼", + ["office_worker_medium_skin_tone"] = "🧑🏽‍💼", + ["office_worker_tone4"] = "🧑🏾‍💼", + ["office_worker_medium_dark_skin_tone"] = "🧑🏾‍💼", + ["office_worker_tone5"] = "🧑🏿‍💼", + ["office_worker_dark_skin_tone"] = "🧑🏿‍💼", + ["woman_office_worker"] = "👩‍💼", + ["woman_office_worker_tone1"] = "👩🏻‍💼", + ["woman_office_worker_light_skin_tone"] = "👩🏻‍💼", + ["woman_office_worker_tone2"] = "👩🏼‍💼", + ["woman_office_worker_medium_light_skin_tone"] = "👩🏼‍💼", + ["woman_office_worker_tone3"] = "👩🏽‍💼", + ["woman_office_worker_medium_skin_tone"] = "👩🏽‍💼", + ["woman_office_worker_tone4"] = "👩🏾‍💼", + ["woman_office_worker_medium_dark_skin_tone"] = "👩🏾‍💼", + ["woman_office_worker_tone5"] = "👩🏿‍💼", + ["woman_office_worker_dark_skin_tone"] = "👩🏿‍💼", + ["man_office_worker"] = "👨‍💼", + ["man_office_worker_tone1"] = "👨🏻‍💼", + ["man_office_worker_light_skin_tone"] = "👨🏻‍💼", + ["man_office_worker_tone2"] = "👨🏼‍💼", + ["man_office_worker_medium_light_skin_tone"] = "👨🏼‍💼", + ["man_office_worker_tone3"] = "👨🏽‍💼", + ["man_office_worker_medium_skin_tone"] = "👨🏽‍💼", + ["man_office_worker_tone4"] = "👨🏾‍💼", + ["man_office_worker_medium_dark_skin_tone"] = "👨🏾‍💼", + ["man_office_worker_tone5"] = "👨🏿‍💼", + ["man_office_worker_dark_skin_tone"] = "👨🏿‍💼", + ["mechanic"] = "🧑‍🔧", + ["mechanic_tone1"] = "🧑🏻‍🔧", + ["mechanic_light_skin_tone"] = "🧑🏻‍🔧", + ["mechanic_tone2"] = "🧑🏼‍🔧", + ["mechanic_medium_light_skin_tone"] = "🧑🏼‍🔧", + ["mechanic_tone3"] = "🧑🏽‍🔧", + ["mechanic_medium_skin_tone"] = "🧑🏽‍🔧", + ["mechanic_tone4"] = "🧑🏾‍🔧", + ["mechanic_medium_dark_skin_tone"] = "🧑🏾‍🔧", + ["mechanic_tone5"] = "🧑🏿‍🔧", + ["mechanic_dark_skin_tone"] = "🧑🏿‍🔧", + ["woman_mechanic"] = "👩‍🔧", + ["woman_mechanic_tone1"] = "👩🏻‍🔧", + ["woman_mechanic_light_skin_tone"] = "👩🏻‍🔧", + ["woman_mechanic_tone2"] = "👩🏼‍🔧", + ["woman_mechanic_medium_light_skin_tone"] = "👩🏼‍🔧", + ["woman_mechanic_tone3"] = "👩🏽‍🔧", + ["woman_mechanic_medium_skin_tone"] = "👩🏽‍🔧", + ["woman_mechanic_tone4"] = "👩🏾‍🔧", + ["woman_mechanic_medium_dark_skin_tone"] = "👩🏾‍🔧", + ["woman_mechanic_tone5"] = "👩🏿‍🔧", + ["woman_mechanic_dark_skin_tone"] = "👩🏿‍🔧", + ["man_mechanic"] = "👨‍🔧", + ["man_mechanic_tone1"] = "👨🏻‍🔧", + ["man_mechanic_light_skin_tone"] = "👨🏻‍🔧", + ["man_mechanic_tone2"] = "👨🏼‍🔧", + ["man_mechanic_medium_light_skin_tone"] = "👨🏼‍🔧", + ["man_mechanic_tone3"] = "👨🏽‍🔧", + ["man_mechanic_medium_skin_tone"] = "👨🏽‍🔧", + ["man_mechanic_tone4"] = "👨🏾‍🔧", + ["man_mechanic_medium_dark_skin_tone"] = "👨🏾‍🔧", + ["man_mechanic_tone5"] = "👨🏿‍🔧", + ["man_mechanic_dark_skin_tone"] = "👨🏿‍🔧", + ["scientist"] = "🧑‍🔬", + ["scientist_tone1"] = "🧑🏻‍🔬", + ["scientist_light_skin_tone"] = "🧑🏻‍🔬", + ["scientist_tone2"] = "🧑🏼‍🔬", + ["scientist_medium_light_skin_tone"] = "🧑🏼‍🔬", + ["scientist_tone3"] = "🧑🏽‍🔬", + ["scientist_medium_skin_tone"] = "🧑🏽‍🔬", + ["scientist_tone4"] = "🧑🏾‍🔬", + ["scientist_medium_dark_skin_tone"] = "🧑🏾‍🔬", + ["scientist_tone5"] = "🧑🏿‍🔬", + ["scientist_dark_skin_tone"] = "🧑🏿‍🔬", + ["woman_scientist"] = "👩‍🔬", + ["woman_scientist_tone1"] = "👩🏻‍🔬", + ["woman_scientist_light_skin_tone"] = "👩🏻‍🔬", + ["woman_scientist_tone2"] = "👩🏼‍🔬", + ["woman_scientist_medium_light_skin_tone"] = "👩🏼‍🔬", + ["woman_scientist_tone3"] = "👩🏽‍🔬", + ["woman_scientist_medium_skin_tone"] = "👩🏽‍🔬", + ["woman_scientist_tone4"] = "👩🏾‍🔬", + ["woman_scientist_medium_dark_skin_tone"] = "👩🏾‍🔬", + ["woman_scientist_tone5"] = "👩🏿‍🔬", + ["woman_scientist_dark_skin_tone"] = "👩🏿‍🔬", + ["man_scientist"] = "👨‍🔬", + ["man_scientist_tone1"] = "👨🏻‍🔬", + ["man_scientist_light_skin_tone"] = "👨🏻‍🔬", + ["man_scientist_tone2"] = "👨🏼‍🔬", + ["man_scientist_medium_light_skin_tone"] = "👨🏼‍🔬", + ["man_scientist_tone3"] = "👨🏽‍🔬", + ["man_scientist_medium_skin_tone"] = "👨🏽‍🔬", + ["man_scientist_tone4"] = "👨🏾‍🔬", + ["man_scientist_medium_dark_skin_tone"] = "👨🏾‍🔬", + ["man_scientist_tone5"] = "👨🏿‍🔬", + ["man_scientist_dark_skin_tone"] = "👨🏿‍🔬", + ["artist"] = "🧑‍🎨", + ["artist_tone1"] = "🧑🏻‍🎨", + ["artist_light_skin_tone"] = "🧑🏻‍🎨", + ["artist_tone2"] = "🧑🏼‍🎨", + ["artist_medium_light_skin_tone"] = "🧑🏼‍🎨", + ["artist_tone3"] = "🧑🏽‍🎨", + ["artist_medium_skin_tone"] = "🧑🏽‍🎨", + ["artist_tone4"] = "🧑🏾‍🎨", + ["artist_medium_dark_skin_tone"] = "🧑🏾‍🎨", + ["artist_tone5"] = "🧑🏿‍🎨", + ["artist_dark_skin_tone"] = "🧑🏿‍🎨", + ["woman_artist"] = "👩‍🎨", + ["woman_artist_tone1"] = "👩🏻‍🎨", + ["woman_artist_light_skin_tone"] = "👩🏻‍🎨", + ["woman_artist_tone2"] = "👩🏼‍🎨", + ["woman_artist_medium_light_skin_tone"] = "👩🏼‍🎨", + ["woman_artist_tone3"] = "👩🏽‍🎨", + ["woman_artist_medium_skin_tone"] = "👩🏽‍🎨", + ["woman_artist_tone4"] = "👩🏾‍🎨", + ["woman_artist_medium_dark_skin_tone"] = "👩🏾‍🎨", + ["woman_artist_tone5"] = "👩🏿‍🎨", + ["woman_artist_dark_skin_tone"] = "👩🏿‍🎨", + ["man_artist"] = "👨‍🎨", + ["man_artist_tone1"] = "👨🏻‍🎨", + ["man_artist_light_skin_tone"] = "👨🏻‍🎨", + ["man_artist_tone2"] = "👨🏼‍🎨", + ["man_artist_medium_light_skin_tone"] = "👨🏼‍🎨", + ["man_artist_tone3"] = "👨🏽‍🎨", + ["man_artist_medium_skin_tone"] = "👨🏽‍🎨", + ["man_artist_tone4"] = "👨🏾‍🎨", + ["man_artist_medium_dark_skin_tone"] = "👨🏾‍🎨", + ["man_artist_tone5"] = "👨🏿‍🎨", + ["man_artist_dark_skin_tone"] = "👨🏿‍🎨", + ["firefighter"] = "🧑‍🚒", + ["firefighter_tone1"] = "🧑🏻‍🚒", + ["firefighter_light_skin_tone"] = "🧑🏻‍🚒", + ["firefighter_tone2"] = "🧑🏼‍🚒", + ["firefighter_medium_light_skin_tone"] = "🧑🏼‍🚒", + ["firefighter_tone3"] = "🧑🏽‍🚒", + ["firefighter_medium_skin_tone"] = "🧑🏽‍🚒", + ["firefighter_tone4"] = "🧑🏾‍🚒", + ["firefighter_medium_dark_skin_tone"] = "🧑🏾‍🚒", + ["firefighter_tone5"] = "🧑🏿‍🚒", + ["firefighter_dark_skin_tone"] = "🧑🏿‍🚒", + ["woman_firefighter"] = "👩‍🚒", + ["woman_firefighter_tone1"] = "👩🏻‍🚒", + ["woman_firefighter_light_skin_tone"] = "👩🏻‍🚒", + ["woman_firefighter_tone2"] = "👩🏼‍🚒", + ["woman_firefighter_medium_light_skin_tone"] = "👩🏼‍🚒", + ["woman_firefighter_tone3"] = "👩🏽‍🚒", + ["woman_firefighter_medium_skin_tone"] = "👩🏽‍🚒", + ["woman_firefighter_tone4"] = "👩🏾‍🚒", + ["woman_firefighter_medium_dark_skin_tone"] = "👩🏾‍🚒", + ["woman_firefighter_tone5"] = "👩🏿‍🚒", + ["woman_firefighter_dark_skin_tone"] = "👩🏿‍🚒", + ["man_firefighter"] = "👨‍🚒", + ["man_firefighter_tone1"] = "👨🏻‍🚒", + ["man_firefighter_light_skin_tone"] = "👨🏻‍🚒", + ["man_firefighter_tone2"] = "👨🏼‍🚒", + ["man_firefighter_medium_light_skin_tone"] = "👨🏼‍🚒", + ["man_firefighter_tone3"] = "👨🏽‍🚒", + ["man_firefighter_medium_skin_tone"] = "👨🏽‍🚒", + ["man_firefighter_tone4"] = "👨🏾‍🚒", + ["man_firefighter_medium_dark_skin_tone"] = "👨🏾‍🚒", + ["man_firefighter_tone5"] = "👨🏿‍🚒", + ["man_firefighter_dark_skin_tone"] = "👨🏿‍🚒", + ["pilot"] = "🧑‍✈️", + ["pilot_tone1"] = "🧑🏻‍✈️", + ["pilot_light_skin_tone"] = "🧑🏻‍✈️", + ["pilot_tone2"] = "🧑🏼‍✈️", + ["pilot_medium_light_skin_tone"] = "🧑🏼‍✈️", + ["pilot_tone3"] = "🧑🏽‍✈️", + ["pilot_medium_skin_tone"] = "🧑🏽‍✈️", + ["pilot_tone4"] = "🧑🏾‍✈️", + ["pilot_medium_dark_skin_tone"] = "🧑🏾‍✈️", + ["pilot_tone5"] = "🧑🏿‍✈️", + ["pilot_dark_skin_tone"] = "🧑🏿‍✈️", + ["woman_pilot"] = "👩‍✈️", + ["woman_pilot_tone1"] = "👩🏻‍✈️", + ["woman_pilot_light_skin_tone"] = "👩🏻‍✈️", + ["woman_pilot_tone2"] = "👩🏼‍✈️", + ["woman_pilot_medium_light_skin_tone"] = "👩🏼‍✈️", + ["woman_pilot_tone3"] = "👩🏽‍✈️", + ["woman_pilot_medium_skin_tone"] = "👩🏽‍✈️", + ["woman_pilot_tone4"] = "👩🏾‍✈️", + ["woman_pilot_medium_dark_skin_tone"] = "👩🏾‍✈️", + ["woman_pilot_tone5"] = "👩🏿‍✈️", + ["woman_pilot_dark_skin_tone"] = "👩🏿‍✈️", + ["man_pilot"] = "👨‍✈️", + ["man_pilot_tone1"] = "👨🏻‍✈️", + ["man_pilot_light_skin_tone"] = "👨🏻‍✈️", + ["man_pilot_tone2"] = "👨🏼‍✈️", + ["man_pilot_medium_light_skin_tone"] = "👨🏼‍✈️", + ["man_pilot_tone3"] = "👨🏽‍✈️", + ["man_pilot_medium_skin_tone"] = "👨🏽‍✈️", + ["man_pilot_tone4"] = "👨🏾‍✈️", + ["man_pilot_medium_dark_skin_tone"] = "👨🏾‍✈️", + ["man_pilot_tone5"] = "👨🏿‍✈️", + ["man_pilot_dark_skin_tone"] = "👨🏿‍✈️", + ["astronaut"] = "🧑‍🚀", + ["astronaut_tone1"] = "🧑🏻‍🚀", + ["astronaut_light_skin_tone"] = "🧑🏻‍🚀", + ["astronaut_tone2"] = "🧑🏼‍🚀", + ["astronaut_medium_light_skin_tone"] = "🧑🏼‍🚀", + ["astronaut_tone3"] = "🧑🏽‍🚀", + ["astronaut_medium_skin_tone"] = "🧑🏽‍🚀", + ["astronaut_tone4"] = "🧑🏾‍🚀", + ["astronaut_medium_dark_skin_tone"] = "🧑🏾‍🚀", + ["astronaut_tone5"] = "🧑🏿‍🚀", + ["astronaut_dark_skin_tone"] = "🧑🏿‍🚀", + ["woman_astronaut"] = "👩‍🚀", + ["woman_astronaut_tone1"] = "👩🏻‍🚀", + ["woman_astronaut_light_skin_tone"] = "👩🏻‍🚀", + ["woman_astronaut_tone2"] = "👩🏼‍🚀", + ["woman_astronaut_medium_light_skin_tone"] = "👩🏼‍🚀", + ["woman_astronaut_tone3"] = "👩🏽‍🚀", + ["woman_astronaut_medium_skin_tone"] = "👩🏽‍🚀", + ["woman_astronaut_tone4"] = "👩🏾‍🚀", + ["woman_astronaut_medium_dark_skin_tone"] = "👩🏾‍🚀", + ["woman_astronaut_tone5"] = "👩🏿‍🚀", + ["woman_astronaut_dark_skin_tone"] = "👩🏿‍🚀", + ["man_astronaut"] = "👨‍🚀", + ["man_astronaut_tone1"] = "👨🏻‍🚀", + ["man_astronaut_light_skin_tone"] = "👨🏻‍🚀", + ["man_astronaut_tone2"] = "👨🏼‍🚀", + ["man_astronaut_medium_light_skin_tone"] = "👨🏼‍🚀", + ["man_astronaut_tone3"] = "👨🏽‍🚀", + ["man_astronaut_medium_skin_tone"] = "👨🏽‍🚀", + ["man_astronaut_tone4"] = "👨🏾‍🚀", + ["man_astronaut_medium_dark_skin_tone"] = "👨🏾‍🚀", + ["man_astronaut_tone5"] = "👨🏿‍🚀", + ["man_astronaut_dark_skin_tone"] = "👨🏿‍🚀", + ["judge"] = "🧑‍⚖️", + ["judge_tone1"] = "🧑🏻‍⚖️", + ["judge_light_skin_tone"] = "🧑🏻‍⚖️", + ["judge_tone2"] = "🧑🏼‍⚖️", + ["judge_medium_light_skin_tone"] = "🧑🏼‍⚖️", + ["judge_tone3"] = "🧑🏽‍⚖️", + ["judge_medium_skin_tone"] = "🧑🏽‍⚖️", + ["judge_tone4"] = "🧑🏾‍⚖️", + ["judge_medium_dark_skin_tone"] = "🧑🏾‍⚖️", + ["judge_tone5"] = "🧑🏿‍⚖️", + ["judge_dark_skin_tone"] = "🧑🏿‍⚖️", + ["woman_judge"] = "👩‍⚖️", + ["woman_judge_tone1"] = "👩🏻‍⚖️", + ["woman_judge_light_skin_tone"] = "👩🏻‍⚖️", + ["woman_judge_tone2"] = "👩🏼‍⚖️", + ["woman_judge_medium_light_skin_tone"] = "👩🏼‍⚖️", + ["woman_judge_tone3"] = "👩🏽‍⚖️", + ["woman_judge_medium_skin_tone"] = "👩🏽‍⚖️", + ["woman_judge_tone4"] = "👩🏾‍⚖️", + ["woman_judge_medium_dark_skin_tone"] = "👩🏾‍⚖️", + ["woman_judge_tone5"] = "👩🏿‍⚖️", + ["woman_judge_dark_skin_tone"] = "👩🏿‍⚖️", + ["man_judge"] = "👨‍⚖️", + ["man_judge_tone1"] = "👨🏻‍⚖️", + ["man_judge_light_skin_tone"] = "👨🏻‍⚖️", + ["man_judge_tone2"] = "👨🏼‍⚖️", + ["man_judge_medium_light_skin_tone"] = "👨🏼‍⚖️", + ["man_judge_tone3"] = "👨🏽‍⚖️", + ["man_judge_medium_skin_tone"] = "👨🏽‍⚖️", + ["man_judge_tone4"] = "👨🏾‍⚖️", + ["man_judge_medium_dark_skin_tone"] = "👨🏾‍⚖️", + ["man_judge_tone5"] = "👨🏿‍⚖️", + ["man_judge_dark_skin_tone"] = "👨🏿‍⚖️", + ["person_with_veil"] = "👰", + ["person_with_veil_tone1"] = "👰🏻", + ["person_with_veil_tone2"] = "👰🏼", + ["person_with_veil_tone3"] = "👰🏽", + ["person_with_veil_tone4"] = "👰🏾", + ["person_with_veil_tone5"] = "👰🏿", + ["woman_with_veil"] = "👰‍♀️", + ["bride_with_veil"] = "👰‍♀️", + ["woman_with_veil_tone1"] = "👰🏻‍♀️", + ["woman_with_veil_light_skin_tone"] = "👰🏻‍♀️", + ["woman_with_veil_tone2"] = "👰🏼‍♀️", + ["woman_with_veil_medium_light_skin_tone"] = "👰🏼‍♀️", + ["woman_with_veil_tone3"] = "👰🏽‍♀️", + ["woman_with_veil_medium_skin_tone"] = "👰🏽‍♀️", + ["woman_with_veil_tone4"] = "👰🏾‍♀️", + ["woman_with_veil_medium_dark_skin_tone"] = "👰🏾‍♀️", + ["woman_with_veil_tone5"] = "👰🏿‍♀️", + ["woman_with_veil_dark_skin_tone"] = "👰🏿‍♀️", + ["man_with_veil"] = "👰‍♂️", + ["man_with_veil_tone1"] = "👰🏻‍♂️", + ["man_with_veil_light_skin_tone"] = "👰🏻‍♂️", + ["man_with_veil_tone2"] = "👰🏼‍♂️", + ["man_with_veil_medium_light_skin_tone"] = "👰🏼‍♂️", + ["man_with_veil_tone3"] = "👰🏽‍♂️", + ["man_with_veil_medium_skin_tone"] = "👰🏽‍♂️", + ["man_with_veil_tone4"] = "👰🏾‍♂️", + ["man_with_veil_medium_dark_skin_tone"] = "👰🏾‍♂️", + ["man_with_veil_tone5"] = "👰🏿‍♂️", + ["man_with_veil_dark_skin_tone"] = "👰🏿‍♂️", + ["person_in_tuxedo"] = "🤵", + ["person_in_tuxedo_tone1"] = "🤵🏻", + ["tuxedo_tone1"] = "🤵🏻", + ["person_in_tuxedo_tone2"] = "🤵🏼", + ["tuxedo_tone2"] = "🤵🏼", + ["person_in_tuxedo_tone3"] = "🤵🏽", + ["tuxedo_tone3"] = "🤵🏽", + ["person_in_tuxedo_tone4"] = "🤵🏾", + ["tuxedo_tone4"] = "🤵🏾", + ["person_in_tuxedo_tone5"] = "🤵🏿", + ["tuxedo_tone5"] = "🤵🏿", + ["woman_in_tuxedo"] = "🤵‍♀️", + ["woman_in_tuxedo_tone1"] = "🤵🏻‍♀️", + ["woman_in_tuxedo_light_skin_tone"] = "🤵🏻‍♀️", + ["woman_in_tuxedo_tone2"] = "🤵🏼‍♀️", + ["woman_in_tuxedo_medium_light_skin_tone"] = "🤵🏼‍♀️", + ["woman_in_tuxedo_tone3"] = "🤵🏽‍♀️", + ["woman_in_tuxedo_medium_skin_tone"] = "🤵🏽‍♀️", + ["woman_in_tuxedo_tone4"] = "🤵🏾‍♀️", + ["woman_in_tuxedo_medium_dark_skin_tone"] = "🤵🏾‍♀️", + ["woman_in_tuxedo_tone5"] = "🤵🏿‍♀️", + ["woman_in_tuxedo_dark_skin_tone"] = "🤵🏿‍♀️", + ["man_in_tuxedo"] = "🤵‍♂️", + ["man_in_tuxedo_tone1"] = "🤵🏻‍♂️", + ["man_in_tuxedo_light_skin_tone"] = "🤵🏻‍♂️", + ["man_in_tuxedo_tone2"] = "🤵🏼‍♂️", + ["man_in_tuxedo_medium_light_skin_tone"] = "🤵🏼‍♂️", + ["man_in_tuxedo_tone3"] = "🤵🏽‍♂️", + ["man_in_tuxedo_medium_skin_tone"] = "🤵🏽‍♂️", + ["man_in_tuxedo_tone4"] = "🤵🏾‍♂️", + ["man_in_tuxedo_medium_dark_skin_tone"] = "🤵🏾‍♂️", + ["man_in_tuxedo_tone5"] = "🤵🏿‍♂️", + ["man_in_tuxedo_dark_skin_tone"] = "🤵🏿‍♂️", + ["princess"] = "👸", + ["princess_tone1"] = "👸🏻", + ["princess_tone2"] = "👸🏼", + ["princess_tone3"] = "👸🏽", + ["princess_tone4"] = "👸🏾", + ["princess_tone5"] = "👸🏿", + ["prince"] = "🤴", + ["prince_tone1"] = "🤴🏻", + ["prince_tone2"] = "🤴🏼", + ["prince_tone3"] = "🤴🏽", + ["prince_tone4"] = "🤴🏾", + ["prince_tone5"] = "🤴🏿", + ["superhero"] = "🦸", + ["superhero_tone1"] = "🦸🏻", + ["superhero_light_skin_tone"] = "🦸🏻", + ["superhero_tone2"] = "🦸🏼", + ["superhero_medium_light_skin_tone"] = "🦸🏼", + ["superhero_tone3"] = "🦸🏽", + ["superhero_medium_skin_tone"] = "🦸🏽", + ["superhero_tone4"] = "🦸🏾", + ["superhero_medium_dark_skin_tone"] = "🦸🏾", + ["superhero_tone5"] = "🦸🏿", + ["superhero_dark_skin_tone"] = "🦸🏿", + ["woman_superhero"] = "🦸‍♀️", + ["woman_superhero_tone1"] = "🦸🏻‍♀️", + ["woman_superhero_light_skin_tone"] = "🦸🏻‍♀️", + ["woman_superhero_tone2"] = "🦸🏼‍♀️", + ["woman_superhero_medium_light_skin_tone"] = "🦸🏼‍♀️", + ["woman_superhero_tone3"] = "🦸🏽‍♀️", + ["woman_superhero_medium_skin_tone"] = "🦸🏽‍♀️", + ["woman_superhero_tone4"] = "🦸🏾‍♀️", + ["woman_superhero_medium_dark_skin_tone"] = "🦸🏾‍♀️", + ["woman_superhero_tone5"] = "🦸🏿‍♀️", + ["woman_superhero_dark_skin_tone"] = "🦸🏿‍♀️", + ["man_superhero"] = "🦸‍♂️", + ["man_superhero_tone1"] = "🦸🏻‍♂️", + ["man_superhero_light_skin_tone"] = "🦸🏻‍♂️", + ["man_superhero_tone2"] = "🦸🏼‍♂️", + ["man_superhero_medium_light_skin_tone"] = "🦸🏼‍♂️", + ["man_superhero_tone3"] = "🦸🏽‍♂️", + ["man_superhero_medium_skin_tone"] = "🦸🏽‍♂️", + ["man_superhero_tone4"] = "🦸🏾‍♂️", + ["man_superhero_medium_dark_skin_tone"] = "🦸🏾‍♂️", + ["man_superhero_tone5"] = "🦸🏿‍♂️", + ["man_superhero_dark_skin_tone"] = "🦸🏿‍♂️", + ["supervillain"] = "🦹", + ["supervillain_tone1"] = "🦹🏻", + ["supervillain_light_skin_tone"] = "🦹🏻", + ["supervillain_tone2"] = "🦹🏼", + ["supervillain_medium_light_skin_tone"] = "🦹🏼", + ["supervillain_tone3"] = "🦹🏽", + ["supervillain_medium_skin_tone"] = "🦹🏽", + ["supervillain_tone4"] = "🦹🏾", + ["supervillain_medium_dark_skin_tone"] = "🦹🏾", + ["supervillain_tone5"] = "🦹🏿", + ["supervillain_dark_skin_tone"] = "🦹🏿", + ["woman_supervillain"] = "🦹‍♀️", + ["woman_supervillain_tone1"] = "🦹🏻‍♀️", + ["woman_supervillain_light_skin_tone"] = "🦹🏻‍♀️", + ["woman_supervillain_tone2"] = "🦹🏼‍♀️", + ["woman_supervillain_medium_light_skin_tone"] = "🦹🏼‍♀️", + ["woman_supervillain_tone3"] = "🦹🏽‍♀️", + ["woman_supervillain_medium_skin_tone"] = "🦹🏽‍♀️", + ["woman_supervillain_tone4"] = "🦹🏾‍♀️", + ["woman_supervillain_medium_dark_skin_tone"] = "🦹🏾‍♀️", + ["woman_supervillain_tone5"] = "🦹🏿‍♀️", + ["woman_supervillain_dark_skin_tone"] = "🦹🏿‍♀️", + ["man_supervillain"] = "🦹‍♂️", + ["man_supervillain_tone1"] = "🦹🏻‍♂️", + ["man_supervillain_light_skin_tone"] = "🦹🏻‍♂️", + ["man_supervillain_tone2"] = "🦹🏼‍♂️", + ["man_supervillain_medium_light_skin_tone"] = "🦹🏼‍♂️", + ["man_supervillain_tone3"] = "🦹🏽‍♂️", + ["man_supervillain_medium_skin_tone"] = "🦹🏽‍♂️", + ["man_supervillain_tone4"] = "🦹🏾‍♂️", + ["man_supervillain_medium_dark_skin_tone"] = "🦹🏾‍♂️", + ["man_supervillain_tone5"] = "🦹🏿‍♂️", + ["man_supervillain_dark_skin_tone"] = "🦹🏿‍♂️", + ["ninja"] = "🥷", + ["ninja_tone1"] = "🥷🏻", + ["ninja_light_skin_tone"] = "🥷🏻", + ["ninja_tone2"] = "🥷🏼", + ["ninja_medium_light_skin_tone"] = "🥷🏼", + ["ninja_tone3"] = "🥷🏽", + ["ninja_medium_skin_tone"] = "🥷🏽", + ["ninja_tone4"] = "🥷🏾", + ["ninja_medium_dark_skin_tone"] = "🥷🏾", + ["ninja_tone5"] = "🥷🏿", + ["ninja_dark_skin_tone"] = "🥷🏿", + ["mx_claus"] = "🧑‍🎄", + ["mx_claus_tone1"] = "🧑🏻‍🎄", + ["mx_claus_light_skin_tone"] = "🧑🏻‍🎄", + ["mx_claus_tone2"] = "🧑🏼‍🎄", + ["mx_claus_medium_light_skin_tone"] = "🧑🏼‍🎄", + ["mx_claus_tone3"] = "🧑🏽‍🎄", + ["mx_claus_medium_skin_tone"] = "🧑🏽‍🎄", + ["mx_claus_tone4"] = "🧑🏾‍🎄", + ["mx_claus_medium_dark_skin_tone"] = "🧑🏾‍🎄", + ["mx_claus_tone5"] = "🧑🏿‍🎄", + ["mx_claus_dark_skin_tone"] = "🧑🏿‍🎄", + ["mrs_claus"] = "🤶", + ["mother_christmas"] = "🤶", + ["mrs_claus_tone1"] = "🤶🏻", + ["mother_christmas_tone1"] = "🤶🏻", + ["mrs_claus_tone2"] = "🤶🏼", + ["mother_christmas_tone2"] = "🤶🏼", + ["mrs_claus_tone3"] = "🤶🏽", + ["mother_christmas_tone3"] = "🤶🏽", + ["mrs_claus_tone4"] = "🤶🏾", + ["mother_christmas_tone4"] = "🤶🏾", + ["mrs_claus_tone5"] = "🤶🏿", + ["mother_christmas_tone5"] = "🤶🏿", + ["santa"] = "🎅", + ["santa_tone1"] = "🎅🏻", + ["santa_tone2"] = "🎅🏼", + ["santa_tone3"] = "🎅🏽", + ["santa_tone4"] = "🎅🏾", + ["santa_tone5"] = "🎅🏿", + ["mage"] = "🧙", + ["mage_tone1"] = "🧙🏻", + ["mage_light_skin_tone"] = "🧙🏻", + ["mage_tone2"] = "🧙🏼", + ["mage_medium_light_skin_tone"] = "🧙🏼", + ["mage_tone3"] = "🧙🏽", + ["mage_medium_skin_tone"] = "🧙🏽", + ["mage_tone4"] = "🧙🏾", + ["mage_medium_dark_skin_tone"] = "🧙🏾", + ["mage_tone5"] = "🧙🏿", + ["mage_dark_skin_tone"] = "🧙🏿", + ["woman_mage"] = "🧙‍♀️", + ["woman_mage_tone1"] = "🧙🏻‍♀️", + ["woman_mage_light_skin_tone"] = "🧙🏻‍♀️", + ["woman_mage_tone2"] = "🧙🏼‍♀️", + ["woman_mage_medium_light_skin_tone"] = "🧙🏼‍♀️", + ["woman_mage_tone3"] = "🧙🏽‍♀️", + ["woman_mage_medium_skin_tone"] = "🧙🏽‍♀️", + ["woman_mage_tone4"] = "🧙🏾‍♀️", + ["woman_mage_medium_dark_skin_tone"] = "🧙🏾‍♀️", + ["woman_mage_tone5"] = "🧙🏿‍♀️", + ["woman_mage_dark_skin_tone"] = "🧙🏿‍♀️", + ["man_mage"] = "🧙‍♂️", + ["man_mage_tone1"] = "🧙🏻‍♂️", + ["man_mage_light_skin_tone"] = "🧙🏻‍♂️", + ["man_mage_tone2"] = "🧙🏼‍♂️", + ["man_mage_medium_light_skin_tone"] = "🧙🏼‍♂️", + ["man_mage_tone3"] = "🧙🏽‍♂️", + ["man_mage_medium_skin_tone"] = "🧙🏽‍♂️", + ["man_mage_tone4"] = "🧙🏾‍♂️", + ["man_mage_medium_dark_skin_tone"] = "🧙🏾‍♂️", + ["man_mage_tone5"] = "🧙🏿‍♂️", + ["man_mage_dark_skin_tone"] = "🧙🏿‍♂️", + ["elf"] = "🧝", + ["elf_tone1"] = "🧝🏻", + ["elf_light_skin_tone"] = "🧝🏻", + ["elf_tone2"] = "🧝🏼", + ["elf_medium_light_skin_tone"] = "🧝🏼", + ["elf_tone3"] = "🧝🏽", + ["elf_medium_skin_tone"] = "🧝🏽", + ["elf_tone4"] = "🧝🏾", + ["elf_medium_dark_skin_tone"] = "🧝🏾", + ["elf_tone5"] = "🧝🏿", + ["elf_dark_skin_tone"] = "🧝🏿", + ["woman_elf"] = "🧝‍♀️", + ["woman_elf_tone1"] = "🧝🏻‍♀️", + ["woman_elf_light_skin_tone"] = "🧝🏻‍♀️", + ["woman_elf_tone2"] = "🧝🏼‍♀️", + ["woman_elf_medium_light_skin_tone"] = "🧝🏼‍♀️", + ["woman_elf_tone3"] = "🧝🏽‍♀️", + ["woman_elf_medium_skin_tone"] = "🧝🏽‍♀️", + ["woman_elf_tone4"] = "🧝🏾‍♀️", + ["woman_elf_medium_dark_skin_tone"] = "🧝🏾‍♀️", + ["woman_elf_tone5"] = "🧝🏿‍♀️", + ["woman_elf_dark_skin_tone"] = "🧝🏿‍♀️", + ["man_elf"] = "🧝‍♂️", + ["man_elf_tone1"] = "🧝🏻‍♂️", + ["man_elf_light_skin_tone"] = "🧝🏻‍♂️", + ["man_elf_tone2"] = "🧝🏼‍♂️", + ["man_elf_medium_light_skin_tone"] = "🧝🏼‍♂️", + ["man_elf_tone3"] = "🧝🏽‍♂️", + ["man_elf_medium_skin_tone"] = "🧝🏽‍♂️", + ["man_elf_tone4"] = "🧝🏾‍♂️", + ["man_elf_medium_dark_skin_tone"] = "🧝🏾‍♂️", + ["man_elf_tone5"] = "🧝🏿‍♂️", + ["man_elf_dark_skin_tone"] = "🧝🏿‍♂️", + ["vampire"] = "🧛", + ["vampire_tone1"] = "🧛🏻", + ["vampire_light_skin_tone"] = "🧛🏻", + ["vampire_tone2"] = "🧛🏼", + ["vampire_medium_light_skin_tone"] = "🧛🏼", + ["vampire_tone3"] = "🧛🏽", + ["vampire_medium_skin_tone"] = "🧛🏽", + ["vampire_tone4"] = "🧛🏾", + ["vampire_medium_dark_skin_tone"] = "🧛🏾", + ["vampire_tone5"] = "🧛🏿", + ["vampire_dark_skin_tone"] = "🧛🏿", + ["woman_vampire"] = "🧛‍♀️", + ["woman_vampire_tone1"] = "🧛🏻‍♀️", + ["woman_vampire_light_skin_tone"] = "🧛🏻‍♀️", + ["woman_vampire_tone2"] = "🧛🏼‍♀️", + ["woman_vampire_medium_light_skin_tone"] = "🧛🏼‍♀️", + ["woman_vampire_tone3"] = "🧛🏽‍♀️", + ["woman_vampire_medium_skin_tone"] = "🧛🏽‍♀️", + ["woman_vampire_tone4"] = "🧛🏾‍♀️", + ["woman_vampire_medium_dark_skin_tone"] = "🧛🏾‍♀️", + ["woman_vampire_tone5"] = "🧛🏿‍♀️", + ["woman_vampire_dark_skin_tone"] = "🧛🏿‍♀️", + ["man_vampire"] = "🧛‍♂️", + ["man_vampire_tone1"] = "🧛🏻‍♂️", + ["man_vampire_light_skin_tone"] = "🧛🏻‍♂️", + ["man_vampire_tone2"] = "🧛🏼‍♂️", + ["man_vampire_medium_light_skin_tone"] = "🧛🏼‍♂️", + ["man_vampire_tone3"] = "🧛🏽‍♂️", + ["man_vampire_medium_skin_tone"] = "🧛🏽‍♂️", + ["man_vampire_tone4"] = "🧛🏾‍♂️", + ["man_vampire_medium_dark_skin_tone"] = "🧛🏾‍♂️", + ["man_vampire_tone5"] = "🧛🏿‍♂️", + ["man_vampire_dark_skin_tone"] = "🧛🏿‍♂️", + ["zombie"] = "🧟", + ["woman_zombie"] = "🧟‍♀️", + ["man_zombie"] = "🧟‍♂️", + ["genie"] = "🧞", + ["woman_genie"] = "🧞‍♀️", + ["man_genie"] = "🧞‍♂️", + ["merperson"] = "🧜", + ["merperson_tone1"] = "🧜🏻", + ["merperson_light_skin_tone"] = "🧜🏻", + ["merperson_tone2"] = "🧜🏼", + ["merperson_medium_light_skin_tone"] = "🧜🏼", + ["merperson_tone3"] = "🧜🏽", + ["merperson_medium_skin_tone"] = "🧜🏽", + ["merperson_tone4"] = "🧜🏾", + ["merperson_medium_dark_skin_tone"] = "🧜🏾", + ["merperson_tone5"] = "🧜🏿", + ["merperson_dark_skin_tone"] = "🧜🏿", + ["mermaid"] = "🧜‍♀️", + ["mermaid_tone1"] = "🧜🏻‍♀️", + ["mermaid_light_skin_tone"] = "🧜🏻‍♀️", + ["mermaid_tone2"] = "🧜🏼‍♀️", + ["mermaid_medium_light_skin_tone"] = "🧜🏼‍♀️", + ["mermaid_tone3"] = "🧜🏽‍♀️", + ["mermaid_medium_skin_tone"] = "🧜🏽‍♀️", + ["mermaid_tone4"] = "🧜🏾‍♀️", + ["mermaid_medium_dark_skin_tone"] = "🧜🏾‍♀️", + ["mermaid_tone5"] = "🧜🏿‍♀️", + ["mermaid_dark_skin_tone"] = "🧜🏿‍♀️", + ["merman"] = "🧜‍♂️", + ["merman_tone1"] = "🧜🏻‍♂️", + ["merman_light_skin_tone"] = "🧜🏻‍♂️", + ["merman_tone2"] = "🧜🏼‍♂️", + ["merman_medium_light_skin_tone"] = "🧜🏼‍♂️", + ["merman_tone3"] = "🧜🏽‍♂️", + ["merman_medium_skin_tone"] = "🧜🏽‍♂️", + ["merman_tone4"] = "🧜🏾‍♂️", + ["merman_medium_dark_skin_tone"] = "🧜🏾‍♂️", + ["merman_tone5"] = "🧜🏿‍♂️", + ["merman_dark_skin_tone"] = "🧜🏿‍♂️", + ["fairy"] = "🧚", + ["fairy_tone1"] = "🧚🏻", + ["fairy_light_skin_tone"] = "🧚🏻", + ["fairy_tone2"] = "🧚🏼", + ["fairy_medium_light_skin_tone"] = "🧚🏼", + ["fairy_tone3"] = "🧚🏽", + ["fairy_medium_skin_tone"] = "🧚🏽", + ["fairy_tone4"] = "🧚🏾", + ["fairy_medium_dark_skin_tone"] = "🧚🏾", + ["fairy_tone5"] = "🧚🏿", + ["fairy_dark_skin_tone"] = "🧚🏿", + ["woman_fairy"] = "🧚‍♀️", + ["woman_fairy_tone1"] = "🧚🏻‍♀️", + ["woman_fairy_light_skin_tone"] = "🧚🏻‍♀️", + ["woman_fairy_tone2"] = "🧚🏼‍♀️", + ["woman_fairy_medium_light_skin_tone"] = "🧚🏼‍♀️", + ["woman_fairy_tone3"] = "🧚🏽‍♀️", + ["woman_fairy_medium_skin_tone"] = "🧚🏽‍♀️", + ["woman_fairy_tone4"] = "🧚🏾‍♀️", + ["woman_fairy_medium_dark_skin_tone"] = "🧚🏾‍♀️", + ["woman_fairy_tone5"] = "🧚🏿‍♀️", + ["woman_fairy_dark_skin_tone"] = "🧚🏿‍♀️", + ["man_fairy"] = "🧚‍♂️", + ["man_fairy_tone1"] = "🧚🏻‍♂️", + ["man_fairy_light_skin_tone"] = "🧚🏻‍♂️", + ["man_fairy_tone2"] = "🧚🏼‍♂️", + ["man_fairy_medium_light_skin_tone"] = "🧚🏼‍♂️", + ["man_fairy_tone3"] = "🧚🏽‍♂️", + ["man_fairy_medium_skin_tone"] = "🧚🏽‍♂️", + ["man_fairy_tone4"] = "🧚🏾‍♂️", + ["man_fairy_medium_dark_skin_tone"] = "🧚🏾‍♂️", + ["man_fairy_tone5"] = "🧚🏿‍♂️", + ["man_fairy_dark_skin_tone"] = "🧚🏿‍♂️", + ["angel"] = "👼", + ["angel_tone1"] = "👼🏻", + ["angel_tone2"] = "👼🏼", + ["angel_tone3"] = "👼🏽", + ["angel_tone4"] = "👼🏾", + ["angel_tone5"] = "👼🏿", + ["pregnant_woman"] = "🤰", + ["expecting_woman"] = "🤰", + ["pregnant_woman_tone1"] = "🤰🏻", + ["expecting_woman_tone1"] = "🤰🏻", + ["pregnant_woman_tone2"] = "🤰🏼", + ["expecting_woman_tone2"] = "🤰🏼", + ["pregnant_woman_tone3"] = "🤰🏽", + ["expecting_woman_tone3"] = "🤰🏽", + ["pregnant_woman_tone4"] = "🤰🏾", + ["expecting_woman_tone4"] = "🤰🏾", + ["pregnant_woman_tone5"] = "🤰🏿", + ["expecting_woman_tone5"] = "🤰🏿", + ["breast_feeding"] = "🤱", + ["breast_feeding_tone1"] = "🤱🏻", + ["breast_feeding_light_skin_tone"] = "🤱🏻", + ["breast_feeding_tone2"] = "🤱🏼", + ["breast_feeding_medium_light_skin_tone"] = "🤱🏼", + ["breast_feeding_tone3"] = "🤱🏽", + ["breast_feeding_medium_skin_tone"] = "🤱🏽", + ["breast_feeding_tone4"] = "🤱🏾", + ["breast_feeding_medium_dark_skin_tone"] = "🤱🏾", + ["breast_feeding_tone5"] = "🤱🏿", + ["breast_feeding_dark_skin_tone"] = "🤱🏿", + ["person_feeding_baby"] = "🧑‍🍼", + ["person_feeding_baby_tone1"] = "🧑🏻‍🍼", + ["person_feeding_baby_light_skin_tone"] = "🧑🏻‍🍼", + ["person_feeding_baby_tone2"] = "🧑🏼‍🍼", + ["person_feeding_baby_medium_light_skin_tone"] = "🧑🏼‍🍼", + ["person_feeding_baby_tone3"] = "🧑🏽‍🍼", + ["person_feeding_baby_medium_skin_tone"] = "🧑🏽‍🍼", + ["person_feeding_baby_tone4"] = "🧑🏾‍🍼", + ["person_feeding_baby_medium_dark_skin_tone"] = "🧑🏾‍🍼", + ["person_feeding_baby_tone5"] = "🧑🏿‍🍼", + ["person_feeding_baby_dark_skin_tone"] = "🧑🏿‍🍼", + ["woman_feeding_baby"] = "👩‍🍼", + ["woman_feeding_baby_tone1"] = "👩🏻‍🍼", + ["woman_feeding_baby_light_skin_tone"] = "👩🏻‍🍼", + ["woman_feeding_baby_tone2"] = "👩🏼‍🍼", + ["woman_feeding_baby_medium_light_skin_tone"] = "👩🏼‍🍼", + ["woman_feeding_baby_tone3"] = "👩🏽‍🍼", + ["woman_feeding_baby_medium_skin_tone"] = "👩🏽‍🍼", + ["woman_feeding_baby_tone4"] = "👩🏾‍🍼", + ["woman_feeding_baby_medium_dark_skin_tone"] = "👩🏾‍🍼", + ["woman_feeding_baby_tone5"] = "👩🏿‍🍼", + ["woman_feeding_baby_dark_skin_tone"] = "👩🏿‍🍼", + ["man_feeding_baby"] = "👨‍🍼", + ["man_feeding_baby_tone1"] = "👨🏻‍🍼", + ["man_feeding_baby_light_skin_tone"] = "👨🏻‍🍼", + ["man_feeding_baby_tone2"] = "👨🏼‍🍼", + ["man_feeding_baby_medium_light_skin_tone"] = "👨🏼‍🍼", + ["man_feeding_baby_tone3"] = "👨🏽‍🍼", + ["man_feeding_baby_medium_skin_tone"] = "👨🏽‍🍼", + ["man_feeding_baby_tone4"] = "👨🏾‍🍼", + ["man_feeding_baby_medium_dark_skin_tone"] = "👨🏾‍🍼", + ["man_feeding_baby_tone5"] = "👨🏿‍🍼", + ["man_feeding_baby_dark_skin_tone"] = "👨🏿‍🍼", + ["person_bowing"] = "🙇", + ["bow"] = "🙇", + ["person_bowing_tone1"] = "🙇🏻", + ["bow_tone1"] = "🙇🏻", + ["person_bowing_tone2"] = "🙇🏼", + ["bow_tone2"] = "🙇🏼", + ["person_bowing_tone3"] = "🙇🏽", + ["bow_tone3"] = "🙇🏽", + ["person_bowing_tone4"] = "🙇🏾", + ["bow_tone4"] = "🙇🏾", + ["person_bowing_tone5"] = "🙇🏿", + ["bow_tone5"] = "🙇🏿", + ["woman_bowing"] = "🙇‍♀️", + ["woman_bowing_tone1"] = "🙇🏻‍♀️", + ["woman_bowing_light_skin_tone"] = "🙇🏻‍♀️", + ["woman_bowing_tone2"] = "🙇🏼‍♀️", + ["woman_bowing_medium_light_skin_tone"] = "🙇🏼‍♀️", + ["woman_bowing_tone3"] = "🙇🏽‍♀️", + ["woman_bowing_medium_skin_tone"] = "🙇🏽‍♀️", + ["woman_bowing_tone4"] = "🙇🏾‍♀️", + ["woman_bowing_medium_dark_skin_tone"] = "🙇🏾‍♀️", + ["woman_bowing_tone5"] = "🙇🏿‍♀️", + ["woman_bowing_dark_skin_tone"] = "🙇🏿‍♀️", + ["man_bowing"] = "🙇‍♂️", + ["man_bowing_tone1"] = "🙇🏻‍♂️", + ["man_bowing_light_skin_tone"] = "🙇🏻‍♂️", + ["man_bowing_tone2"] = "🙇🏼‍♂️", + ["man_bowing_medium_light_skin_tone"] = "🙇🏼‍♂️", + ["man_bowing_tone3"] = "🙇🏽‍♂️", + ["man_bowing_medium_skin_tone"] = "🙇🏽‍♂️", + ["man_bowing_tone4"] = "🙇🏾‍♂️", + ["man_bowing_medium_dark_skin_tone"] = "🙇🏾‍♂️", + ["man_bowing_tone5"] = "🙇🏿‍♂️", + ["man_bowing_dark_skin_tone"] = "🙇🏿‍♂️", + ["person_tipping_hand"] = "💁", + ["information_desk_person"] = "💁", + ["person_tipping_hand_tone1"] = "💁🏻", + ["information_desk_person_tone1"] = "💁🏻", + ["person_tipping_hand_tone2"] = "💁🏼", + ["information_desk_person_tone2"] = "💁🏼", + ["person_tipping_hand_tone3"] = "💁🏽", + ["information_desk_person_tone3"] = "💁🏽", + ["person_tipping_hand_tone4"] = "💁🏾", + ["information_desk_person_tone4"] = "💁🏾", + ["person_tipping_hand_tone5"] = "💁🏿", + ["information_desk_person_tone5"] = "💁🏿", + ["woman_tipping_hand"] = "💁‍♀️", + ["woman_tipping_hand_tone1"] = "💁🏻‍♀️", + ["woman_tipping_hand_light_skin_tone"] = "💁🏻‍♀️", + ["woman_tipping_hand_tone2"] = "💁🏼‍♀️", + ["woman_tipping_hand_medium_light_skin_tone"] = "💁🏼‍♀️", + ["woman_tipping_hand_tone3"] = "💁🏽‍♀️", + ["woman_tipping_hand_medium_skin_tone"] = "💁🏽‍♀️", + ["woman_tipping_hand_tone4"] = "💁🏾‍♀️", + ["woman_tipping_hand_medium_dark_skin_tone"] = "💁🏾‍♀️", + ["woman_tipping_hand_tone5"] = "💁🏿‍♀️", + ["woman_tipping_hand_dark_skin_tone"] = "💁🏿‍♀️", + ["man_tipping_hand"] = "💁‍♂️", + ["man_tipping_hand_tone1"] = "💁🏻‍♂️", + ["man_tipping_hand_light_skin_tone"] = "💁🏻‍♂️", + ["man_tipping_hand_tone2"] = "💁🏼‍♂️", + ["man_tipping_hand_medium_light_skin_tone"] = "💁🏼‍♂️", + ["man_tipping_hand_tone3"] = "💁🏽‍♂️", + ["man_tipping_hand_medium_skin_tone"] = "💁🏽‍♂️", + ["man_tipping_hand_tone4"] = "💁🏾‍♂️", + ["man_tipping_hand_medium_dark_skin_tone"] = "💁🏾‍♂️", + ["man_tipping_hand_tone5"] = "💁🏿‍♂️", + ["man_tipping_hand_dark_skin_tone"] = "💁🏿‍♂️", + ["person_gesturing_no"] = "🙅", + ["no_good"] = "🙅", + ["person_gesturing_no_tone1"] = "🙅🏻", + ["no_good_tone1"] = "🙅🏻", + ["person_gesturing_no_tone2"] = "🙅🏼", + ["no_good_tone2"] = "🙅🏼", + ["person_gesturing_no_tone3"] = "🙅🏽", + ["no_good_tone3"] = "🙅🏽", + ["person_gesturing_no_tone4"] = "🙅🏾", + ["no_good_tone4"] = "🙅🏾", + ["person_gesturing_no_tone5"] = "🙅🏿", + ["no_good_tone5"] = "🙅🏿", + ["woman_gesturing_no"] = "🙅‍♀️", + ["woman_gesturing_no_tone1"] = "🙅🏻‍♀️", + ["woman_gesturing_no_light_skin_tone"] = "🙅🏻‍♀️", + ["woman_gesturing_no_tone2"] = "🙅🏼‍♀️", + ["woman_gesturing_no_medium_light_skin_tone"] = "🙅🏼‍♀️", + ["woman_gesturing_no_tone3"] = "🙅🏽‍♀️", + ["woman_gesturing_no_medium_skin_tone"] = "🙅🏽‍♀️", + ["woman_gesturing_no_tone4"] = "🙅🏾‍♀️", + ["woman_gesturing_no_medium_dark_skin_tone"] = "🙅🏾‍♀️", + ["woman_gesturing_no_tone5"] = "🙅🏿‍♀️", + ["woman_gesturing_no_dark_skin_tone"] = "🙅🏿‍♀️", + ["man_gesturing_no"] = "🙅‍♂️", + ["man_gesturing_no_tone1"] = "🙅🏻‍♂️", + ["man_gesturing_no_light_skin_tone"] = "🙅🏻‍♂️", + ["man_gesturing_no_tone2"] = "🙅🏼‍♂️", + ["man_gesturing_no_medium_light_skin_tone"] = "🙅🏼‍♂️", + ["man_gesturing_no_tone3"] = "🙅🏽‍♂️", + ["man_gesturing_no_medium_skin_tone"] = "🙅🏽‍♂️", + ["man_gesturing_no_tone4"] = "🙅🏾‍♂️", + ["man_gesturing_no_medium_dark_skin_tone"] = "🙅🏾‍♂️", + ["man_gesturing_no_tone5"] = "🙅🏿‍♂️", + ["man_gesturing_no_dark_skin_tone"] = "🙅🏿‍♂️", + ["person_gesturing_ok"] = "🙆", + ["ok_woman"] = "🙆", + ["person_gesturing_ok_tone1"] = "🙆🏻", + ["ok_woman_tone1"] = "🙆🏻", + ["person_gesturing_ok_tone2"] = "🙆🏼", + ["ok_woman_tone2"] = "🙆🏼", + ["person_gesturing_ok_tone3"] = "🙆🏽", + ["ok_woman_tone3"] = "🙆🏽", + ["person_gesturing_ok_tone4"] = "🙆🏾", + ["ok_woman_tone4"] = "🙆🏾", + ["person_gesturing_ok_tone5"] = "🙆🏿", + ["ok_woman_tone5"] = "🙆🏿", + ["woman_gesturing_ok"] = "🙆‍♀️", + ["woman_gesturing_ok_tone1"] = "🙆🏻‍♀️", + ["woman_gesturing_ok_light_skin_tone"] = "🙆🏻‍♀️", + ["woman_gesturing_ok_tone2"] = "🙆🏼‍♀️", + ["woman_gesturing_ok_medium_light_skin_tone"] = "🙆🏼‍♀️", + ["woman_gesturing_ok_tone3"] = "🙆🏽‍♀️", + ["woman_gesturing_ok_medium_skin_tone"] = "🙆🏽‍♀️", + ["woman_gesturing_ok_tone4"] = "🙆🏾‍♀️", + ["woman_gesturing_ok_medium_dark_skin_tone"] = "🙆🏾‍♀️", + ["woman_gesturing_ok_tone5"] = "🙆🏿‍♀️", + ["woman_gesturing_ok_dark_skin_tone"] = "🙆🏿‍♀️", + ["man_gesturing_ok"] = "🙆‍♂️", + ["man_gesturing_ok_tone1"] = "🙆🏻‍♂️", + ["man_gesturing_ok_light_skin_tone"] = "🙆🏻‍♂️", + ["man_gesturing_ok_tone2"] = "🙆🏼‍♂️", + ["man_gesturing_ok_medium_light_skin_tone"] = "🙆🏼‍♂️", + ["man_gesturing_ok_tone3"] = "🙆🏽‍♂️", + ["man_gesturing_ok_medium_skin_tone"] = "🙆🏽‍♂️", + ["man_gesturing_ok_tone4"] = "🙆🏾‍♂️", + ["man_gesturing_ok_medium_dark_skin_tone"] = "🙆🏾‍♂️", + ["man_gesturing_ok_tone5"] = "🙆🏿‍♂️", + ["man_gesturing_ok_dark_skin_tone"] = "🙆🏿‍♂️", + ["person_raising_hand"] = "🙋", + ["raising_hand"] = "🙋", + ["person_raising_hand_tone1"] = "🙋🏻", + ["raising_hand_tone1"] = "🙋🏻", + ["person_raising_hand_tone2"] = "🙋🏼", + ["raising_hand_tone2"] = "🙋🏼", + ["person_raising_hand_tone3"] = "🙋🏽", + ["raising_hand_tone3"] = "🙋🏽", + ["person_raising_hand_tone4"] = "🙋🏾", + ["raising_hand_tone4"] = "🙋🏾", + ["person_raising_hand_tone5"] = "🙋🏿", + ["raising_hand_tone5"] = "🙋🏿", + ["woman_raising_hand"] = "🙋‍♀️", + ["woman_raising_hand_tone1"] = "🙋🏻‍♀️", + ["woman_raising_hand_light_skin_tone"] = "🙋🏻‍♀️", + ["woman_raising_hand_tone2"] = "🙋🏼‍♀️", + ["woman_raising_hand_medium_light_skin_tone"] = "🙋🏼‍♀️", + ["woman_raising_hand_tone3"] = "🙋🏽‍♀️", + ["woman_raising_hand_medium_skin_tone"] = "🙋🏽‍♀️", + ["woman_raising_hand_tone4"] = "🙋🏾‍♀️", + ["woman_raising_hand_medium_dark_skin_tone"] = "🙋🏾‍♀️", + ["woman_raising_hand_tone5"] = "🙋🏿‍♀️", + ["woman_raising_hand_dark_skin_tone"] = "🙋🏿‍♀️", + ["man_raising_hand"] = "🙋‍♂️", + ["man_raising_hand_tone1"] = "🙋🏻‍♂️", + ["man_raising_hand_light_skin_tone"] = "🙋🏻‍♂️", + ["man_raising_hand_tone2"] = "🙋🏼‍♂️", + ["man_raising_hand_medium_light_skin_tone"] = "🙋🏼‍♂️", + ["man_raising_hand_tone3"] = "🙋🏽‍♂️", + ["man_raising_hand_medium_skin_tone"] = "🙋🏽‍♂️", + ["man_raising_hand_tone4"] = "🙋🏾‍♂️", + ["man_raising_hand_medium_dark_skin_tone"] = "🙋🏾‍♂️", + ["man_raising_hand_tone5"] = "🙋🏿‍♂️", + ["man_raising_hand_dark_skin_tone"] = "🙋🏿‍♂️", + ["deaf_person"] = "🧏", + ["deaf_person_tone1"] = "🧏🏻", + ["deaf_person_light_skin_tone"] = "🧏🏻", + ["deaf_person_tone2"] = "🧏🏼", + ["deaf_person_medium_light_skin_tone"] = "🧏🏼", + ["deaf_person_tone3"] = "🧏🏽", + ["deaf_person_medium_skin_tone"] = "🧏🏽", + ["deaf_person_tone4"] = "🧏🏾", + ["deaf_person_medium_dark_skin_tone"] = "🧏🏾", + ["deaf_person_tone5"] = "🧏🏿", + ["deaf_person_dark_skin_tone"] = "🧏🏿", + ["deaf_woman"] = "🧏‍♀️", + ["deaf_woman_tone1"] = "🧏🏻‍♀️", + ["deaf_woman_light_skin_tone"] = "🧏🏻‍♀️", + ["deaf_woman_tone2"] = "🧏🏼‍♀️", + ["deaf_woman_medium_light_skin_tone"] = "🧏🏼‍♀️", + ["deaf_woman_tone3"] = "🧏🏽‍♀️", + ["deaf_woman_medium_skin_tone"] = "🧏🏽‍♀️", + ["deaf_woman_tone4"] = "🧏🏾‍♀️", + ["deaf_woman_medium_dark_skin_tone"] = "🧏🏾‍♀️", + ["deaf_woman_tone5"] = "🧏🏿‍♀️", + ["deaf_woman_dark_skin_tone"] = "🧏🏿‍♀️", + ["deaf_man"] = "🧏‍♂️", + ["deaf_man_tone1"] = "🧏🏻‍♂️", + ["deaf_man_light_skin_tone"] = "🧏🏻‍♂️", + ["deaf_man_tone2"] = "🧏🏼‍♂️", + ["deaf_man_medium_light_skin_tone"] = "🧏🏼‍♂️", + ["deaf_man_tone3"] = "🧏🏽‍♂️", + ["deaf_man_medium_skin_tone"] = "🧏🏽‍♂️", + ["deaf_man_tone4"] = "🧏🏾‍♂️", + ["deaf_man_medium_dark_skin_tone"] = "🧏🏾‍♂️", + ["deaf_man_tone5"] = "🧏🏿‍♂️", + ["deaf_man_dark_skin_tone"] = "🧏🏿‍♂️", + ["person_facepalming"] = "🤦", + ["face_palm"] = "🤦", + ["facepalm"] = "🤦", + ["person_facepalming_tone1"] = "🤦🏻", + ["face_palm_tone1"] = "🤦🏻", + ["facepalm_tone1"] = "🤦🏻", + ["person_facepalming_tone2"] = "🤦🏼", + ["face_palm_tone2"] = "🤦🏼", + ["facepalm_tone2"] = "🤦🏼", + ["person_facepalming_tone3"] = "🤦🏽", + ["face_palm_tone3"] = "🤦🏽", + ["facepalm_tone3"] = "🤦🏽", + ["person_facepalming_tone4"] = "🤦🏾", + ["face_palm_tone4"] = "🤦🏾", + ["facepalm_tone4"] = "🤦🏾", + ["person_facepalming_tone5"] = "🤦🏿", + ["face_palm_tone5"] = "🤦🏿", + ["facepalm_tone5"] = "🤦🏿", + ["woman_facepalming"] = "🤦‍♀️", + ["woman_facepalming_tone1"] = "🤦🏻‍♀️", + ["woman_facepalming_light_skin_tone"] = "🤦🏻‍♀️", + ["woman_facepalming_tone2"] = "🤦🏼‍♀️", + ["woman_facepalming_medium_light_skin_tone"] = "🤦🏼‍♀️", + ["woman_facepalming_tone3"] = "🤦🏽‍♀️", + ["woman_facepalming_medium_skin_tone"] = "🤦🏽‍♀️", + ["woman_facepalming_tone4"] = "🤦🏾‍♀️", + ["woman_facepalming_medium_dark_skin_tone"] = "🤦🏾‍♀️", + ["woman_facepalming_tone5"] = "🤦🏿‍♀️", + ["woman_facepalming_dark_skin_tone"] = "🤦🏿‍♀️", + ["man_facepalming"] = "🤦‍♂️", + ["man_facepalming_tone1"] = "🤦🏻‍♂️", + ["man_facepalming_light_skin_tone"] = "🤦🏻‍♂️", + ["man_facepalming_tone2"] = "🤦🏼‍♂️", + ["man_facepalming_medium_light_skin_tone"] = "🤦🏼‍♂️", + ["man_facepalming_tone3"] = "🤦🏽‍♂️", + ["man_facepalming_medium_skin_tone"] = "🤦🏽‍♂️", + ["man_facepalming_tone4"] = "🤦🏾‍♂️", + ["man_facepalming_medium_dark_skin_tone"] = "🤦🏾‍♂️", + ["man_facepalming_tone5"] = "🤦🏿‍♂️", + ["man_facepalming_dark_skin_tone"] = "🤦🏿‍♂️", + ["person_shrugging"] = "🤷", + ["shrug"] = "🤷", + ["person_shrugging_tone1"] = "🤷🏻", + ["shrug_tone1"] = "🤷🏻", + ["person_shrugging_tone2"] = "🤷🏼", + ["shrug_tone2"] = "🤷🏼", + ["person_shrugging_tone3"] = "🤷🏽", + ["shrug_tone3"] = "🤷🏽", + ["person_shrugging_tone4"] = "🤷🏾", + ["shrug_tone4"] = "🤷🏾", + ["person_shrugging_tone5"] = "🤷🏿", + ["shrug_tone5"] = "🤷🏿", + ["woman_shrugging"] = "🤷‍♀️", + ["woman_shrugging_tone1"] = "🤷🏻‍♀️", + ["woman_shrugging_light_skin_tone"] = "🤷🏻‍♀️", + ["woman_shrugging_tone2"] = "🤷🏼‍♀️", + ["woman_shrugging_medium_light_skin_tone"] = "🤷🏼‍♀️", + ["woman_shrugging_tone3"] = "🤷🏽‍♀️", + ["woman_shrugging_medium_skin_tone"] = "🤷🏽‍♀️", + ["woman_shrugging_tone4"] = "🤷🏾‍♀️", + ["woman_shrugging_medium_dark_skin_tone"] = "🤷🏾‍♀️", + ["woman_shrugging_tone5"] = "🤷🏿‍♀️", + ["woman_shrugging_dark_skin_tone"] = "🤷🏿‍♀️", + ["man_shrugging"] = "🤷‍♂️", + ["man_shrugging_tone1"] = "🤷🏻‍♂️", + ["man_shrugging_light_skin_tone"] = "🤷🏻‍♂️", + ["man_shrugging_tone2"] = "🤷🏼‍♂️", + ["man_shrugging_medium_light_skin_tone"] = "🤷🏼‍♂️", + ["man_shrugging_tone3"] = "🤷🏽‍♂️", + ["man_shrugging_medium_skin_tone"] = "🤷🏽‍♂️", + ["man_shrugging_tone4"] = "🤷🏾‍♂️", + ["man_shrugging_medium_dark_skin_tone"] = "🤷🏾‍♂️", + ["man_shrugging_tone5"] = "🤷🏿‍♂️", + ["man_shrugging_dark_skin_tone"] = "🤷🏿‍♂️", + ["person_pouting"] = "🙎", + ["person_with_pouting_face"] = "🙎", + ["person_pouting_tone1"] = "🙎🏻", + ["person_with_pouting_face_tone1"] = "🙎🏻", + ["person_pouting_tone2"] = "🙎🏼", + ["person_with_pouting_face_tone2"] = "🙎🏼", + ["person_pouting_tone3"] = "🙎🏽", + ["person_with_pouting_face_tone3"] = "🙎🏽", + ["person_pouting_tone4"] = "🙎🏾", + ["person_with_pouting_face_tone4"] = "🙎🏾", + ["person_pouting_tone5"] = "🙎🏿", + ["person_with_pouting_face_tone5"] = "🙎🏿", + ["woman_pouting"] = "🙎‍♀️", + ["woman_pouting_tone1"] = "🙎🏻‍♀️", + ["woman_pouting_light_skin_tone"] = "🙎🏻‍♀️", + ["woman_pouting_tone2"] = "🙎🏼‍♀️", + ["woman_pouting_medium_light_skin_tone"] = "🙎🏼‍♀️", + ["woman_pouting_tone3"] = "🙎🏽‍♀️", + ["woman_pouting_medium_skin_tone"] = "🙎🏽‍♀️", + ["woman_pouting_tone4"] = "🙎🏾‍♀️", + ["woman_pouting_medium_dark_skin_tone"] = "🙎🏾‍♀️", + ["woman_pouting_tone5"] = "🙎🏿‍♀️", + ["woman_pouting_dark_skin_tone"] = "🙎🏿‍♀️", + ["man_pouting"] = "🙎‍♂️", + ["man_pouting_tone1"] = "🙎🏻‍♂️", + ["man_pouting_light_skin_tone"] = "🙎🏻‍♂️", + ["man_pouting_tone2"] = "🙎🏼‍♂️", + ["man_pouting_medium_light_skin_tone"] = "🙎🏼‍♂️", + ["man_pouting_tone3"] = "🙎🏽‍♂️", + ["man_pouting_medium_skin_tone"] = "🙎🏽‍♂️", + ["man_pouting_tone4"] = "🙎🏾‍♂️", + ["man_pouting_medium_dark_skin_tone"] = "🙎🏾‍♂️", + ["man_pouting_tone5"] = "🙎🏿‍♂️", + ["man_pouting_dark_skin_tone"] = "🙎🏿‍♂️", + ["person_frowning"] = "🙍", + ["person_frowning_tone1"] = "🙍🏻", + ["person_frowning_tone2"] = "🙍🏼", + ["person_frowning_tone3"] = "🙍🏽", + ["person_frowning_tone4"] = "🙍🏾", + ["person_frowning_tone5"] = "🙍🏿", + ["woman_frowning"] = "🙍‍♀️", + ["woman_frowning_tone1"] = "🙍🏻‍♀️", + ["woman_frowning_light_skin_tone"] = "🙍🏻‍♀️", + ["woman_frowning_tone2"] = "🙍🏼‍♀️", + ["woman_frowning_medium_light_skin_tone"] = "🙍🏼‍♀️", + ["woman_frowning_tone3"] = "🙍🏽‍♀️", + ["woman_frowning_medium_skin_tone"] = "🙍🏽‍♀️", + ["woman_frowning_tone4"] = "🙍🏾‍♀️", + ["woman_frowning_medium_dark_skin_tone"] = "🙍🏾‍♀️", + ["woman_frowning_tone5"] = "🙍🏿‍♀️", + ["woman_frowning_dark_skin_tone"] = "🙍🏿‍♀️", + ["man_frowning"] = "🙍‍♂️", + ["man_frowning_tone1"] = "🙍🏻‍♂️", + ["man_frowning_light_skin_tone"] = "🙍🏻‍♂️", + ["man_frowning_tone2"] = "🙍🏼‍♂️", + ["man_frowning_medium_light_skin_tone"] = "🙍🏼‍♂️", + ["man_frowning_tone3"] = "🙍🏽‍♂️", + ["man_frowning_medium_skin_tone"] = "🙍🏽‍♂️", + ["man_frowning_tone4"] = "🙍🏾‍♂️", + ["man_frowning_medium_dark_skin_tone"] = "🙍🏾‍♂️", + ["man_frowning_tone5"] = "🙍🏿‍♂️", + ["man_frowning_dark_skin_tone"] = "🙍🏿‍♂️", + ["person_getting_haircut"] = "💇", + ["haircut"] = "💇", + ["person_getting_haircut_tone1"] = "💇🏻", + ["haircut_tone1"] = "💇🏻", + ["person_getting_haircut_tone2"] = "💇🏼", + ["haircut_tone2"] = "💇🏼", + ["person_getting_haircut_tone3"] = "💇🏽", + ["haircut_tone3"] = "💇🏽", + ["person_getting_haircut_tone4"] = "💇🏾", + ["haircut_tone4"] = "💇🏾", + ["person_getting_haircut_tone5"] = "💇🏿", + ["haircut_tone5"] = "💇🏿", + ["woman_getting_haircut"] = "💇‍♀️", + ["woman_getting_haircut_tone1"] = "💇🏻‍♀️", + ["woman_getting_haircut_light_skin_tone"] = "💇🏻‍♀️", + ["woman_getting_haircut_tone2"] = "💇🏼‍♀️", + ["woman_getting_haircut_medium_light_skin_tone"] = "💇🏼‍♀️", + ["woman_getting_haircut_tone3"] = "💇🏽‍♀️", + ["woman_getting_haircut_medium_skin_tone"] = "💇🏽‍♀️", + ["woman_getting_haircut_tone4"] = "💇🏾‍♀️", + ["woman_getting_haircut_medium_dark_skin_tone"] = "💇🏾‍♀️", + ["woman_getting_haircut_tone5"] = "💇🏿‍♀️", + ["woman_getting_haircut_dark_skin_tone"] = "💇🏿‍♀️", + ["man_getting_haircut"] = "💇‍♂️", + ["man_getting_haircut_tone1"] = "💇🏻‍♂️", + ["man_getting_haircut_light_skin_tone"] = "💇🏻‍♂️", + ["man_getting_haircut_tone2"] = "💇🏼‍♂️", + ["man_getting_haircut_medium_light_skin_tone"] = "💇🏼‍♂️", + ["man_getting_haircut_tone3"] = "💇🏽‍♂️", + ["man_getting_haircut_medium_skin_tone"] = "💇🏽‍♂️", + ["man_getting_haircut_tone4"] = "💇🏾‍♂️", + ["man_getting_haircut_medium_dark_skin_tone"] = "💇🏾‍♂️", + ["man_getting_haircut_tone5"] = "💇🏿‍♂️", + ["man_getting_haircut_dark_skin_tone"] = "💇🏿‍♂️", + ["person_getting_massage"] = "💆", + ["massage"] = "💆", + ["person_getting_massage_tone1"] = "💆🏻", + ["massage_tone1"] = "💆🏻", + ["person_getting_massage_tone2"] = "💆🏼", + ["massage_tone2"] = "💆🏼", + ["person_getting_massage_tone3"] = "💆🏽", + ["massage_tone3"] = "💆🏽", + ["person_getting_massage_tone4"] = "💆🏾", + ["massage_tone4"] = "💆🏾", + ["person_getting_massage_tone5"] = "💆🏿", + ["massage_tone5"] = "💆🏿", + ["woman_getting_face_massage"] = "💆‍♀️", + ["woman_getting_face_massage_tone1"] = "💆🏻‍♀️", + ["woman_getting_face_massage_light_skin_tone"] = "💆🏻‍♀️", + ["woman_getting_face_massage_tone2"] = "💆🏼‍♀️", + ["woman_getting_face_massage_medium_light_skin_tone"] = "💆🏼‍♀️", + ["woman_getting_face_massage_tone3"] = "💆🏽‍♀️", + ["woman_getting_face_massage_medium_skin_tone"] = "💆🏽‍♀️", + ["woman_getting_face_massage_tone4"] = "💆🏾‍♀️", + ["woman_getting_face_massage_medium_dark_skin_tone"] = "💆🏾‍♀️", + ["woman_getting_face_massage_tone5"] = "💆🏿‍♀️", + ["woman_getting_face_massage_dark_skin_tone"] = "💆🏿‍♀️", + ["man_getting_face_massage"] = "💆‍♂️", + ["man_getting_face_massage_tone1"] = "💆🏻‍♂️", + ["man_getting_face_massage_light_skin_tone"] = "💆🏻‍♂️", + ["man_getting_face_massage_tone2"] = "💆🏼‍♂️", + ["man_getting_face_massage_medium_light_skin_tone"] = "💆🏼‍♂️", + ["man_getting_face_massage_tone3"] = "💆🏽‍♂️", + ["man_getting_face_massage_medium_skin_tone"] = "💆🏽‍♂️", + ["man_getting_face_massage_tone4"] = "💆🏾‍♂️", + ["man_getting_face_massage_medium_dark_skin_tone"] = "💆🏾‍♂️", + ["man_getting_face_massage_tone5"] = "💆🏿‍♂️", + ["man_getting_face_massage_dark_skin_tone"] = "💆🏿‍♂️", + ["person_in_steamy_room"] = "🧖", + ["person_in_steamy_room_tone1"] = "🧖🏻", + ["person_in_steamy_room_light_skin_tone"] = "🧖🏻", + ["person_in_steamy_room_tone2"] = "🧖🏼", + ["person_in_steamy_room_medium_light_skin_tone"] = "🧖🏼", + ["person_in_steamy_room_tone3"] = "🧖🏽", + ["person_in_steamy_room_medium_skin_tone"] = "🧖🏽", + ["person_in_steamy_room_tone4"] = "🧖🏾", + ["person_in_steamy_room_medium_dark_skin_tone"] = "🧖🏾", + ["person_in_steamy_room_tone5"] = "🧖🏿", + ["person_in_steamy_room_dark_skin_tone"] = "🧖🏿", + ["woman_in_steamy_room"] = "🧖‍♀️", + ["woman_in_steamy_room_tone1"] = "🧖🏻‍♀️", + ["woman_in_steamy_room_light_skin_tone"] = "🧖🏻‍♀️", + ["woman_in_steamy_room_tone2"] = "🧖🏼‍♀️", + ["woman_in_steamy_room_medium_light_skin_tone"] = "🧖🏼‍♀️", + ["woman_in_steamy_room_tone3"] = "🧖🏽‍♀️", + ["woman_in_steamy_room_medium_skin_tone"] = "🧖🏽‍♀️", + ["woman_in_steamy_room_tone4"] = "🧖🏾‍♀️", + ["woman_in_steamy_room_medium_dark_skin_tone"] = "🧖🏾‍♀️", + ["woman_in_steamy_room_tone5"] = "🧖🏿‍♀️", + ["woman_in_steamy_room_dark_skin_tone"] = "🧖🏿‍♀️", + ["man_in_steamy_room"] = "🧖‍♂️", + ["man_in_steamy_room_tone1"] = "🧖🏻‍♂️", + ["man_in_steamy_room_light_skin_tone"] = "🧖🏻‍♂️", + ["man_in_steamy_room_tone2"] = "🧖🏼‍♂️", + ["man_in_steamy_room_medium_light_skin_tone"] = "🧖🏼‍♂️", + ["man_in_steamy_room_tone3"] = "🧖🏽‍♂️", + ["man_in_steamy_room_medium_skin_tone"] = "🧖🏽‍♂️", + ["man_in_steamy_room_tone4"] = "🧖🏾‍♂️", + ["man_in_steamy_room_medium_dark_skin_tone"] = "🧖🏾‍♂️", + ["man_in_steamy_room_tone5"] = "🧖🏿‍♂️", + ["man_in_steamy_room_dark_skin_tone"] = "🧖🏿‍♂️", + ["nail_care"] = "💅", + ["nail_care_tone1"] = "💅🏻", + ["nail_care_tone2"] = "💅🏼", + ["nail_care_tone3"] = "💅🏽", + ["nail_care_tone4"] = "💅🏾", + ["nail_care_tone5"] = "💅🏿", + ["selfie"] = "🤳", + ["selfie_tone1"] = "🤳🏻", + ["selfie_tone2"] = "🤳🏼", + ["selfie_tone3"] = "🤳🏽", + ["selfie_tone4"] = "🤳🏾", + ["selfie_tone5"] = "🤳🏿", + ["dancer"] = "💃", + ["dancer_tone1"] = "💃🏻", + ["dancer_tone2"] = "💃🏼", + ["dancer_tone3"] = "💃🏽", + ["dancer_tone4"] = "💃🏾", + ["dancer_tone5"] = "💃🏿", + ["man_dancing"] = "🕺", + ["male_dancer"] = "🕺", + ["man_dancing_tone1"] = "🕺🏻", + ["male_dancer_tone1"] = "🕺🏻", + ["man_dancing_tone2"] = "🕺🏼", + ["male_dancer_tone2"] = "🕺🏼", + ["man_dancing_tone3"] = "🕺🏽", + ["male_dancer_tone3"] = "🕺🏽", + ["man_dancing_tone5"] = "🕺🏿", + ["male_dancer_tone5"] = "🕺🏿", + ["man_dancing_tone4"] = "🕺🏾", + ["male_dancer_tone4"] = "🕺🏾", + ["people_with_bunny_ears_partying"] = "👯", + ["dancers"] = "👯", + ["women_with_bunny_ears_partying"] = "👯‍♀️", + ["men_with_bunny_ears_partying"] = "👯‍♂️", + ["levitate"] = "🕴️", + ["man_in_business_suit_levitating"] = "🕴️", + ["levitate_tone1"] = "🕴🏻", + ["man_in_business_suit_levitating_tone1"] = "🕴🏻", + ["man_in_business_suit_levitating_light_skin_tone"] = "🕴🏻", + ["levitate_tone2"] = "🕴🏼", + ["man_in_business_suit_levitating_tone2"] = "🕴🏼", + ["man_in_business_suit_levitating_medium_light_skin_tone"] = "🕴🏼", + ["levitate_tone3"] = "🕴🏽", + ["man_in_business_suit_levitating_tone3"] = "🕴🏽", + ["man_in_business_suit_levitating_medium_skin_tone"] = "🕴🏽", + ["levitate_tone4"] = "🕴🏾", + ["man_in_business_suit_levitating_tone4"] = "🕴🏾", + ["man_in_business_suit_levitating_medium_dark_skin_tone"] = "🕴🏾", + ["levitate_tone5"] = "🕴🏿", + ["man_in_business_suit_levitating_tone5"] = "🕴🏿", + ["man_in_business_suit_levitating_dark_skin_tone"] = "🕴🏿", + ["person_in_manual_wheelchair"] = "🧑‍🦽", + ["person_in_manual_wheelchair_tone1"] = "🧑🏻‍🦽", + ["person_in_manual_wheelchair_light_skin_tone"] = "🧑🏻‍🦽", + ["person_in_manual_wheelchair_tone2"] = "🧑🏼‍🦽", + ["person_in_manual_wheelchair_medium_light_skin_tone"] = "🧑🏼‍🦽", + ["person_in_manual_wheelchair_tone3"] = "🧑🏽‍🦽", + ["person_in_manual_wheelchair_medium_skin_tone"] = "🧑🏽‍🦽", + ["person_in_manual_wheelchair_tone4"] = "🧑🏾‍🦽", + ["person_in_manual_wheelchair_medium_dark_skin_tone"] = "🧑🏾‍🦽", + ["person_in_manual_wheelchair_tone5"] = "🧑🏿‍🦽", + ["person_in_manual_wheelchair_dark_skin_tone"] = "🧑🏿‍🦽", + ["woman_in_manual_wheelchair"] = "👩‍🦽", + ["woman_in_manual_wheelchair_tone1"] = "👩🏻‍🦽", + ["woman_in_manual_wheelchair_light_skin_tone"] = "👩🏻‍🦽", + ["woman_in_manual_wheelchair_tone2"] = "👩🏼‍🦽", + ["woman_in_manual_wheelchair_medium_light_skin_tone"] = "👩🏼‍🦽", + ["woman_in_manual_wheelchair_tone3"] = "👩🏽‍🦽", + ["woman_in_manual_wheelchair_medium_skin_tone"] = "👩🏽‍🦽", + ["woman_in_manual_wheelchair_tone4"] = "👩🏾‍🦽", + ["woman_in_manual_wheelchair_medium_dark_skin_tone"] = "👩🏾‍🦽", + ["woman_in_manual_wheelchair_tone5"] = "👩🏿‍🦽", + ["woman_in_manual_wheelchair_dark_skin_tone"] = "👩🏿‍🦽", + ["man_in_manual_wheelchair"] = "👨‍🦽", + ["man_in_manual_wheelchair_tone1"] = "👨🏻‍🦽", + ["man_in_manual_wheelchair_light_skin_tone"] = "👨🏻‍🦽", + ["man_in_manual_wheelchair_tone2"] = "👨🏼‍🦽", + ["man_in_manual_wheelchair_medium_light_skin_tone"] = "👨🏼‍🦽", + ["man_in_manual_wheelchair_tone3"] = "👨🏽‍🦽", + ["man_in_manual_wheelchair_medium_skin_tone"] = "👨🏽‍🦽", + ["man_in_manual_wheelchair_tone4"] = "👨🏾‍🦽", + ["man_in_manual_wheelchair_medium_dark_skin_tone"] = "👨🏾‍🦽", + ["man_in_manual_wheelchair_tone5"] = "👨🏿‍🦽", + ["man_in_manual_wheelchair_dark_skin_tone"] = "👨🏿‍🦽", + ["person_in_motorized_wheelchair"] = "🧑‍🦼", + ["person_in_motorized_wheelchair_tone1"] = "🧑🏻‍🦼", + ["person_in_motorized_wheelchair_light_skin_tone"] = "🧑🏻‍🦼", + ["person_in_motorized_wheelchair_tone2"] = "🧑🏼‍🦼", + ["person_in_motorized_wheelchair_medium_light_skin_tone"] = "🧑🏼‍🦼", + ["person_in_motorized_wheelchair_tone3"] = "🧑🏽‍🦼", + ["person_in_motorized_wheelchair_medium_skin_tone"] = "🧑🏽‍🦼", + ["person_in_motorized_wheelchair_tone4"] = "🧑🏾‍🦼", + ["person_in_motorized_wheelchair_medium_dark_skin_tone"] = "🧑🏾‍🦼", + ["person_in_motorized_wheelchair_tone5"] = "🧑🏿‍🦼", + ["person_in_motorized_wheelchair_dark_skin_tone"] = "🧑🏿‍🦼", + ["woman_in_motorized_wheelchair"] = "👩‍🦼", + ["woman_in_motorized_wheelchair_tone1"] = "👩🏻‍🦼", + ["woman_in_motorized_wheelchair_light_skin_tone"] = "👩🏻‍🦼", + ["woman_in_motorized_wheelchair_tone2"] = "👩🏼‍🦼", + ["woman_in_motorized_wheelchair_medium_light_skin_tone"] = "👩🏼‍🦼", + ["woman_in_motorized_wheelchair_tone3"] = "👩🏽‍🦼", + ["woman_in_motorized_wheelchair_medium_skin_tone"] = "👩🏽‍🦼", + ["woman_in_motorized_wheelchair_tone4"] = "👩🏾‍🦼", + ["woman_in_motorized_wheelchair_medium_dark_skin_tone"] = "👩🏾‍🦼", + ["woman_in_motorized_wheelchair_tone5"] = "👩🏿‍🦼", + ["woman_in_motorized_wheelchair_dark_skin_tone"] = "👩🏿‍🦼", + ["man_in_motorized_wheelchair"] = "👨‍🦼", + ["man_in_motorized_wheelchair_tone1"] = "👨🏻‍🦼", + ["man_in_motorized_wheelchair_light_skin_tone"] = "👨🏻‍🦼", + ["man_in_motorized_wheelchair_tone2"] = "👨🏼‍🦼", + ["man_in_motorized_wheelchair_medium_light_skin_tone"] = "👨🏼‍🦼", + ["man_in_motorized_wheelchair_tone3"] = "👨🏽‍🦼", + ["man_in_motorized_wheelchair_medium_skin_tone"] = "👨🏽‍🦼", + ["man_in_motorized_wheelchair_tone4"] = "👨🏾‍🦼", + ["man_in_motorized_wheelchair_medium_dark_skin_tone"] = "👨🏾‍🦼", + ["man_in_motorized_wheelchair_tone5"] = "👨🏿‍🦼", + ["man_in_motorized_wheelchair_dark_skin_tone"] = "👨🏿‍🦼", + ["person_walking"] = "🚶", + ["walking"] = "🚶", + ["person_walking_tone1"] = "🚶🏻", + ["walking_tone1"] = "🚶🏻", + ["person_walking_tone2"] = "🚶🏼", + ["walking_tone2"] = "🚶🏼", + ["person_walking_tone3"] = "🚶🏽", + ["walking_tone3"] = "🚶🏽", + ["person_walking_tone4"] = "🚶🏾", + ["walking_tone4"] = "🚶🏾", + ["person_walking_tone5"] = "🚶🏿", + ["walking_tone5"] = "🚶🏿", + ["woman_walking"] = "🚶‍♀️", + ["woman_walking_tone1"] = "🚶🏻‍♀️", + ["woman_walking_light_skin_tone"] = "🚶🏻‍♀️", + ["woman_walking_tone2"] = "🚶🏼‍♀️", + ["woman_walking_medium_light_skin_tone"] = "🚶🏼‍♀️", + ["woman_walking_tone3"] = "🚶🏽‍♀️", + ["woman_walking_medium_skin_tone"] = "🚶🏽‍♀️", + ["woman_walking_tone4"] = "🚶🏾‍♀️", + ["woman_walking_medium_dark_skin_tone"] = "🚶🏾‍♀️", + ["woman_walking_tone5"] = "🚶🏿‍♀️", + ["woman_walking_dark_skin_tone"] = "🚶🏿‍♀️", + ["man_walking"] = "🚶‍♂️", + ["man_walking_tone1"] = "🚶🏻‍♂️", + ["man_walking_light_skin_tone"] = "🚶🏻‍♂️", + ["man_walking_tone2"] = "🚶🏼‍♂️", + ["man_walking_medium_light_skin_tone"] = "🚶🏼‍♂️", + ["man_walking_tone3"] = "🚶🏽‍♂️", + ["man_walking_medium_skin_tone"] = "🚶🏽‍♂️", + ["man_walking_tone4"] = "🚶🏾‍♂️", + ["man_walking_medium_dark_skin_tone"] = "🚶🏾‍♂️", + ["man_walking_tone5"] = "🚶🏿‍♂️", + ["man_walking_dark_skin_tone"] = "🚶🏿‍♂️", + ["person_with_probing_cane"] = "🧑‍🦯", + ["person_with_probing_cane_tone1"] = "🧑🏻‍🦯", + ["person_with_probing_cane_light_skin_tone"] = "🧑🏻‍🦯", + ["person_with_probing_cane_tone2"] = "🧑🏼‍🦯", + ["person_with_probing_cane_medium_light_skin_tone"] = "🧑🏼‍🦯", + ["person_with_probing_cane_tone3"] = "🧑🏽‍🦯", + ["person_with_probing_cane_medium_skin_tone"] = "🧑🏽‍🦯", + ["person_with_probing_cane_tone4"] = "🧑🏾‍🦯", + ["person_with_probing_cane_medium_dark_skin_tone"] = "🧑🏾‍🦯", + ["person_with_probing_cane_tone5"] = "🧑🏿‍🦯", + ["person_with_probing_cane_dark_skin_tone"] = "🧑🏿‍🦯", + ["woman_with_probing_cane"] = "👩‍🦯", + ["woman_with_probing_cane_tone1"] = "👩🏻‍🦯", + ["woman_with_probing_cane_light_skin_tone"] = "👩🏻‍🦯", + ["woman_with_probing_cane_tone2"] = "👩🏼‍🦯", + ["woman_with_probing_cane_medium_light_skin_tone"] = "👩🏼‍🦯", + ["woman_with_probing_cane_tone3"] = "👩🏽‍🦯", + ["woman_with_probing_cane_medium_skin_tone"] = "👩🏽‍🦯", + ["woman_with_probing_cane_tone4"] = "👩🏾‍🦯", + ["woman_with_probing_cane_medium_dark_skin_tone"] = "👩🏾‍🦯", + ["woman_with_probing_cane_tone5"] = "👩🏿‍🦯", + ["woman_with_probing_cane_dark_skin_tone"] = "👩🏿‍🦯", + ["man_with_probing_cane"] = "👨‍🦯", + ["man_with_probing_cane_tone1"] = "👨🏻‍🦯", + ["man_with_probing_cane_light_skin_tone"] = "👨🏻‍🦯", + ["man_with_probing_cane_tone3"] = "👨🏽‍🦯", + ["man_with_probing_cane_medium_skin_tone"] = "👨🏽‍🦯", + ["man_with_probing_cane_tone2"] = "👨🏼‍🦯", + ["man_with_probing_cane_medium_light_skin_tone"] = "👨🏼‍🦯", + ["man_with_probing_cane_tone4"] = "👨🏾‍🦯", + ["man_with_probing_cane_medium_dark_skin_tone"] = "👨🏾‍🦯", + ["man_with_probing_cane_tone5"] = "👨🏿‍🦯", + ["man_with_probing_cane_dark_skin_tone"] = "👨🏿‍🦯", + ["person_kneeling"] = "🧎", + ["person_kneeling_tone1"] = "🧎🏻", + ["person_kneeling_light_skin_tone"] = "🧎🏻", + ["person_kneeling_tone2"] = "🧎🏼", + ["person_kneeling_medium_light_skin_tone"] = "🧎🏼", + ["person_kneeling_tone3"] = "🧎🏽", + ["person_kneeling_medium_skin_tone"] = "🧎🏽", + ["person_kneeling_tone4"] = "🧎🏾", + ["person_kneeling_medium_dark_skin_tone"] = "🧎🏾", + ["person_kneeling_tone5"] = "🧎🏿", + ["person_kneeling_dark_skin_tone"] = "🧎🏿", + ["woman_kneeling"] = "🧎‍♀️", + ["woman_kneeling_tone1"] = "🧎🏻‍♀️", + ["woman_kneeling_light_skin_tone"] = "🧎🏻‍♀️", + ["woman_kneeling_tone2"] = "🧎🏼‍♀️", + ["woman_kneeling_medium_light_skin_tone"] = "🧎🏼‍♀️", + ["woman_kneeling_tone3"] = "🧎🏽‍♀️", + ["woman_kneeling_medium_skin_tone"] = "🧎🏽‍♀️", + ["woman_kneeling_tone4"] = "🧎🏾‍♀️", + ["woman_kneeling_medium_dark_skin_tone"] = "🧎🏾‍♀️", + ["woman_kneeling_tone5"] = "🧎🏿‍♀️", + ["woman_kneeling_dark_skin_tone"] = "🧎🏿‍♀️", + ["man_kneeling"] = "🧎‍♂️", + ["man_kneeling_tone1"] = "🧎🏻‍♂️", + ["man_kneeling_light_skin_tone"] = "🧎🏻‍♂️", + ["man_kneeling_tone2"] = "🧎🏼‍♂️", + ["man_kneeling_medium_light_skin_tone"] = "🧎🏼‍♂️", + ["man_kneeling_tone3"] = "🧎🏽‍♂️", + ["man_kneeling_medium_skin_tone"] = "🧎🏽‍♂️", + ["man_kneeling_tone4"] = "🧎🏾‍♂️", + ["man_kneeling_medium_dark_skin_tone"] = "🧎🏾‍♂️", + ["man_kneeling_tone5"] = "🧎🏿‍♂️", + ["man_kneeling_dark_skin_tone"] = "🧎🏿‍♂️", + ["person_running"] = "🏃", + ["runner"] = "🏃", + ["person_running_tone1"] = "🏃🏻", + ["runner_tone1"] = "🏃🏻", + ["person_running_tone2"] = "🏃🏼", + ["runner_tone2"] = "🏃🏼", + ["person_running_tone3"] = "🏃🏽", + ["runner_tone3"] = "🏃🏽", + ["person_running_tone4"] = "🏃🏾", + ["runner_tone4"] = "🏃🏾", + ["person_running_tone5"] = "🏃🏿", + ["runner_tone5"] = "🏃🏿", + ["woman_running"] = "🏃‍♀️", + ["woman_running_tone1"] = "🏃🏻‍♀️", + ["woman_running_light_skin_tone"] = "🏃🏻‍♀️", + ["woman_running_tone2"] = "🏃🏼‍♀️", + ["woman_running_medium_light_skin_tone"] = "🏃🏼‍♀️", + ["woman_running_tone3"] = "🏃🏽‍♀️", + ["woman_running_medium_skin_tone"] = "🏃🏽‍♀️", + ["woman_running_tone4"] = "🏃🏾‍♀️", + ["woman_running_medium_dark_skin_tone"] = "🏃🏾‍♀️", + ["woman_running_tone5"] = "🏃🏿‍♀️", + ["woman_running_dark_skin_tone"] = "🏃🏿‍♀️", + ["man_running"] = "🏃‍♂️", + ["man_running_tone1"] = "🏃🏻‍♂️", + ["man_running_light_skin_tone"] = "🏃🏻‍♂️", + ["man_running_tone2"] = "🏃🏼‍♂️", + ["man_running_medium_light_skin_tone"] = "🏃🏼‍♂️", + ["man_running_tone3"] = "🏃🏽‍♂️", + ["man_running_medium_skin_tone"] = "🏃🏽‍♂️", + ["man_running_tone4"] = "🏃🏾‍♂️", + ["man_running_medium_dark_skin_tone"] = "🏃🏾‍♂️", + ["man_running_tone5"] = "🏃🏿‍♂️", + ["man_running_dark_skin_tone"] = "🏃🏿‍♂️", + ["person_standing"] = "🧍", + ["person_standing_tone1"] = "🧍🏻", + ["person_standing_light_skin_tone"] = "🧍🏻", + ["person_standing_tone2"] = "🧍🏼", + ["person_standing_medium_light_skin_tone"] = "🧍🏼", + ["person_standing_tone3"] = "🧍🏽", + ["person_standing_medium_skin_tone"] = "🧍🏽", + ["person_standing_tone4"] = "🧍🏾", + ["person_standing_medium_dark_skin_tone"] = "🧍🏾", + ["person_standing_tone5"] = "🧍🏿", + ["person_standing_dark_skin_tone"] = "🧍🏿", + ["woman_standing"] = "🧍‍♀️", + ["woman_standing_tone1"] = "🧍🏻‍♀️", + ["woman_standing_light_skin_tone"] = "🧍🏻‍♀️", + ["woman_standing_tone2"] = "🧍🏼‍♀️", + ["woman_standing_medium_light_skin_tone"] = "🧍🏼‍♀️", + ["woman_standing_tone3"] = "🧍🏽‍♀️", + ["woman_standing_medium_skin_tone"] = "🧍🏽‍♀️", + ["woman_standing_tone4"] = "🧍🏾‍♀️", + ["woman_standing_medium_dark_skin_tone"] = "🧍🏾‍♀️", + ["woman_standing_tone5"] = "🧍🏿‍♀️", + ["woman_standing_dark_skin_tone"] = "🧍🏿‍♀️", + ["man_standing"] = "🧍‍♂️", + ["man_standing_tone1"] = "🧍🏻‍♂️", + ["man_standing_light_skin_tone"] = "🧍🏻‍♂️", + ["man_standing_tone2"] = "🧍🏼‍♂️", + ["man_standing_medium_light_skin_tone"] = "🧍🏼‍♂️", + ["man_standing_tone3"] = "🧍🏽‍♂️", + ["man_standing_medium_skin_tone"] = "🧍🏽‍♂️", + ["man_standing_tone4"] = "🧍🏾‍♂️", + ["man_standing_medium_dark_skin_tone"] = "🧍🏾‍♂️", + ["man_standing_tone5"] = "🧍🏿‍♂️", + ["man_standing_dark_skin_tone"] = "🧍🏿‍♂️", + ["people_holding_hands"] = "🧑‍🤝‍🧑", + ["people_holding_hands_tone1"] = "🧑🏻‍🤝‍🧑🏻", + ["people_holding_hands_light_skin_tone"] = "🧑🏻‍🤝‍🧑🏻", + ["people_holding_hands_tone1_tone2"] = "🧑🏻‍🤝‍🧑🏼", + ["people_holding_hands_light_skin_tone_medium_light_skin_tone"] = "🧑🏻‍🤝‍🧑🏼", + ["people_holding_hands_tone1_tone3"] = "🧑🏻‍🤝‍🧑🏽", + ["people_holding_hands_light_skin_tone_medium_skin_tone"] = "🧑🏻‍🤝‍🧑🏽", + ["people_holding_hands_tone1_tone4"] = "🧑🏻‍🤝‍🧑🏾", + ["people_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "🧑🏻‍🤝‍🧑🏾", + ["people_holding_hands_tone1_tone5"] = "🧑🏻‍🤝‍🧑🏿", + ["people_holding_hands_light_skin_tone_dark_skin_tone"] = "🧑🏻‍🤝‍🧑🏿", + ["people_holding_hands_tone2_tone1"] = "🧑🏼‍🤝‍🧑🏻", + ["people_holding_hands_medium_light_skin_tone_light_skin_tone"] = "🧑🏼‍🤝‍🧑🏻", + ["people_holding_hands_tone2"] = "🧑🏼‍🤝‍🧑🏼", + ["people_holding_hands_medium_light_skin_tone"] = "🧑🏼‍🤝‍🧑🏼", + ["people_holding_hands_tone2_tone3"] = "🧑🏼‍🤝‍🧑🏽", + ["people_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "🧑🏼‍🤝‍🧑🏽", + ["people_holding_hands_tone2_tone4"] = "🧑🏼‍🤝‍🧑🏾", + ["people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "🧑🏼‍🤝‍🧑🏾", + ["people_holding_hands_tone2_tone5"] = "🧑🏼‍🤝‍🧑🏿", + ["people_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "🧑🏼‍🤝‍🧑🏿", + ["people_holding_hands_tone3_tone1"] = "🧑🏽‍🤝‍🧑🏻", + ["people_holding_hands_medium_skin_tone_light_skin_tone"] = "🧑🏽‍🤝‍🧑🏻", + ["people_holding_hands_tone3_tone2"] = "🧑🏽‍🤝‍🧑🏼", + ["people_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "🧑🏽‍🤝‍🧑🏼", + ["people_holding_hands_tone3"] = "🧑🏽‍🤝‍🧑🏽", + ["people_holding_hands_medium_skin_tone"] = "🧑🏽‍🤝‍🧑🏽", + ["people_holding_hands_tone3_tone4"] = "🧑🏽‍🤝‍🧑🏾", + ["people_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "🧑🏽‍🤝‍🧑🏾", + ["people_holding_hands_tone3_tone5"] = "🧑🏽‍🤝‍🧑🏿", + ["people_holding_hands_medium_skin_tone_dark_skin_tone"] = "🧑🏽‍🤝‍🧑🏿", + ["people_holding_hands_tone4_tone1"] = "🧑🏾‍🤝‍🧑🏻", + ["people_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "🧑🏾‍🤝‍🧑🏻", + ["people_holding_hands_tone4_tone2"] = "🧑🏾‍🤝‍🧑🏼", + ["people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "🧑🏾‍🤝‍🧑🏼", + ["people_holding_hands_tone4_tone3"] = "🧑🏾‍🤝‍🧑🏽", + ["people_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "🧑🏾‍🤝‍🧑🏽", + ["people_holding_hands_tone4"] = "🧑🏾‍🤝‍🧑🏾", + ["people_holding_hands_medium_dark_skin_tone"] = "🧑🏾‍🤝‍🧑🏾", + ["people_holding_hands_tone4_tone5"] = "🧑🏾‍🤝‍🧑🏿", + ["people_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "🧑🏾‍🤝‍🧑🏿", + ["people_holding_hands_tone5_tone1"] = "🧑🏿‍🤝‍🧑🏻", + ["people_holding_hands_dark_skin_tone_light_skin_tone"] = "🧑🏿‍🤝‍🧑🏻", + ["people_holding_hands_tone5_tone2"] = "🧑🏿‍🤝‍🧑🏼", + ["people_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "🧑🏿‍🤝‍🧑🏼", + ["people_holding_hands_tone5_tone3"] = "🧑🏿‍🤝‍🧑🏽", + ["people_holding_hands_dark_skin_tone_medium_skin_tone"] = "🧑🏿‍🤝‍🧑🏽", + ["people_holding_hands_tone5_tone4"] = "🧑🏿‍🤝‍🧑🏾", + ["people_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "🧑🏿‍🤝‍🧑🏾", + ["people_holding_hands_tone5"] = "🧑🏿‍🤝‍🧑🏿", + ["people_holding_hands_dark_skin_tone"] = "🧑🏿‍🤝‍🧑🏿", + ["couple"] = "👫", + ["woman_and_man_holding_hands_tone1"] = "👫🏻", + ["woman_and_man_holding_hands_light_skin_tone"] = "👫🏻", + ["woman_and_man_holding_hands_tone1_tone2"] = "👩🏻‍🤝‍👨🏼", + ["woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍🤝‍👨🏼", + ["woman_and_man_holding_hands_tone1_tone3"] = "👩🏻‍🤝‍👨🏽", + ["woman_and_man_holding_hands_light_skin_tone_medium_skin_tone"] = "👩🏻‍🤝‍👨🏽", + ["woman_and_man_holding_hands_tone1_tone4"] = "👩🏻‍🤝‍👨🏾", + ["woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍🤝‍👨🏾", + ["woman_and_man_holding_hands_tone1_tone5"] = "👩🏻‍🤝‍👨🏿", + ["woman_and_man_holding_hands_light_skin_tone_dark_skin_tone"] = "👩🏻‍🤝‍👨🏿", + ["woman_and_man_holding_hands_tone2_tone1"] = "👩🏼‍🤝‍👨🏻", + ["woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍🤝‍👨🏻", + ["woman_and_man_holding_hands_tone2"] = "👫🏼", + ["woman_and_man_holding_hands_medium_light_skin_tone"] = "👫🏼", + ["woman_and_man_holding_hands_tone2_tone3"] = "👩🏼‍🤝‍👨🏽", + ["woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍🤝‍👨🏽", + ["woman_and_man_holding_hands_tone2_tone4"] = "👩🏼‍🤝‍👨🏾", + ["woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍🤝‍👨🏾", + ["woman_and_man_holding_hands_tone2_tone5"] = "👩🏼‍🤝‍👨🏿", + ["woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍🤝‍👨🏿", + ["woman_and_man_holding_hands_tone3_tone1"] = "👩🏽‍🤝‍👨🏻", + ["woman_and_man_holding_hands_medium_skin_tone_light_skin_tone"] = "👩🏽‍🤝‍👨🏻", + ["woman_and_man_holding_hands_tone3_tone2"] = "👩🏽‍🤝‍👨🏼", + ["woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍🤝‍👨🏼", + ["woman_and_man_holding_hands_tone3"] = "👫🏽", + ["woman_and_man_holding_hands_medium_skin_tone"] = "👫🏽", + ["woman_and_man_holding_hands_tone3_tone4"] = "👩🏽‍🤝‍👨🏾", + ["woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍🤝‍👨🏾", + ["woman_and_man_holding_hands_tone3_tone5"] = "👩🏽‍🤝‍👨🏿", + ["woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone"] = "👩🏽‍🤝‍👨🏿", + ["woman_and_man_holding_hands_tone4_tone1"] = "👩🏾‍🤝‍👨🏻", + ["woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍🤝‍👨🏻", + ["woman_and_man_holding_hands_tone4_tone2"] = "👩🏾‍🤝‍👨🏼", + ["woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍🤝‍👨🏼", + ["woman_and_man_holding_hands_tone4_tone3"] = "👩🏾‍🤝‍👨🏽", + ["woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍🤝‍👨🏽", + ["woman_and_man_holding_hands_tone4"] = "👫🏾", + ["woman_and_man_holding_hands_medium_dark_skin_tone"] = "👫🏾", + ["woman_and_man_holding_hands_tone4_tone5"] = "👩🏾‍🤝‍👨🏿", + ["woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍🤝‍👨🏿", + ["woman_and_man_holding_hands_tone5_tone1"] = "👩🏿‍🤝‍👨🏻", + ["woman_and_man_holding_hands_dark_skin_tone_light_skin_tone"] = "👩🏿‍🤝‍👨🏻", + ["woman_and_man_holding_hands_tone5_tone2"] = "👩🏿‍🤝‍👨🏼", + ["woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍🤝‍👨🏼", + ["woman_and_man_holding_hands_tone5_tone3"] = "👩🏿‍🤝‍👨🏽", + ["woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone"] = "👩🏿‍🤝‍👨🏽", + ["woman_and_man_holding_hands_tone5_tone4"] = "👩🏿‍🤝‍👨🏾", + ["woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍🤝‍👨🏾", + ["woman_and_man_holding_hands_tone5"] = "👫🏿", + ["woman_and_man_holding_hands_dark_skin_tone"] = "👫🏿", + ["two_women_holding_hands"] = "👭", + ["women_holding_hands_tone1"] = "👭🏻", + ["women_holding_hands_light_skin_tone"] = "👭🏻", + ["women_holding_hands_tone1_tone2"] = "👩🏻‍🤝‍👩🏼", + ["women_holding_hands_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍🤝‍👩🏼", + ["women_holding_hands_tone1_tone3"] = "👩🏻‍🤝‍👩🏽", + ["women_holding_hands_light_skin_tone_medium_skin_tone"] = "👩🏻‍🤝‍👩🏽", + ["women_holding_hands_tone1_tone4"] = "👩🏻‍🤝‍👩🏾", + ["women_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍🤝‍👩🏾", + ["women_holding_hands_tone1_tone5"] = "👩🏻‍🤝‍👩🏿", + ["women_holding_hands_light_skin_tone_dark_skin_tone"] = "👩🏻‍🤝‍👩🏿", + ["women_holding_hands_tone2_tone1"] = "👩🏼‍🤝‍👩🏻", + ["women_holding_hands_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍🤝‍👩🏻", + ["women_holding_hands_tone2"] = "👭🏼", + ["women_holding_hands_medium_light_skin_tone"] = "👭🏼", + ["women_holding_hands_tone2_tone3"] = "👩🏼‍🤝‍👩🏽", + ["women_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍🤝‍👩🏽", + ["women_holding_hands_tone2_tone4"] = "👩🏼‍🤝‍👩🏾", + ["women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍🤝‍👩🏾", + ["women_holding_hands_tone2_tone5"] = "👩🏼‍🤝‍👩🏿", + ["women_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍🤝‍👩🏿", + ["women_holding_hands_tone3_tone1"] = "👩🏽‍🤝‍👩🏻", + ["women_holding_hands_medium_skin_tone_light_skin_tone"] = "👩🏽‍🤝‍👩🏻", + ["women_holding_hands_tone3_tone2"] = "👩🏽‍🤝‍👩🏼", + ["women_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍🤝‍👩🏼", + ["women_holding_hands_tone3"] = "👭🏽", + ["women_holding_hands_medium_skin_tone"] = "👭🏽", + ["women_holding_hands_tone3_tone4"] = "👩🏽‍🤝‍👩🏾", + ["women_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍🤝‍👩🏾", + ["women_holding_hands_tone3_tone5"] = "👩🏽‍🤝‍👩🏿", + ["women_holding_hands_medium_skin_tone_dark_skin_tone"] = "👩🏽‍🤝‍👩🏿", + ["women_holding_hands_tone4_tone1"] = "👩🏾‍🤝‍👩🏻", + ["women_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍🤝‍👩🏻", + ["women_holding_hands_tone4_tone2"] = "👩🏾‍🤝‍👩🏼", + ["women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍🤝‍👩🏼", + ["women_holding_hands_tone4_tone3"] = "👩🏾‍🤝‍👩🏽", + ["women_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍🤝‍👩🏽", + ["women_holding_hands_tone4"] = "👭🏾", + ["women_holding_hands_medium_dark_skin_tone"] = "👭🏾", + ["women_holding_hands_tone4_tone5"] = "👩🏾‍🤝‍👩🏿", + ["women_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍🤝‍👩🏿", + ["women_holding_hands_tone5_tone1"] = "👩🏿‍🤝‍👩🏻", + ["women_holding_hands_dark_skin_tone_light_skin_tone"] = "👩🏿‍🤝‍👩🏻", + ["women_holding_hands_tone5_tone2"] = "👩🏿‍🤝‍👩🏼", + ["women_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍🤝‍👩🏼", + ["women_holding_hands_tone5_tone3"] = "👩🏿‍🤝‍👩🏽", + ["women_holding_hands_dark_skin_tone_medium_skin_tone"] = "👩🏿‍🤝‍👩🏽", + ["women_holding_hands_tone5_tone4"] = "👩🏿‍🤝‍👩🏾", + ["women_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍🤝‍👩🏾", + ["women_holding_hands_tone5"] = "👭🏿", + ["women_holding_hands_dark_skin_tone"] = "👭🏿", + ["two_men_holding_hands"] = "👬", + ["men_holding_hands_tone1"] = "👬🏻", + ["men_holding_hands_light_skin_tone"] = "👬🏻", + ["men_holding_hands_tone1_tone2"] = "👨🏻‍🤝‍👨🏼", + ["men_holding_hands_light_skin_tone_medium_light_skin_tone"] = "👨🏻‍🤝‍👨🏼", + ["men_holding_hands_tone1_tone3"] = "👨🏻‍🤝‍👨🏽", + ["men_holding_hands_light_skin_tone_medium_skin_tone"] = "👨🏻‍🤝‍👨🏽", + ["men_holding_hands_tone1_tone4"] = "👨🏻‍🤝‍👨🏾", + ["men_holding_hands_light_skin_tone_medium_dark_skin_tone"] = "👨🏻‍🤝‍👨🏾", + ["men_holding_hands_tone1_tone5"] = "👨🏻‍🤝‍👨🏿", + ["men_holding_hands_light_skin_tone_dark_skin_tone"] = "👨🏻‍🤝‍👨🏿", + ["men_holding_hands_tone2_tone1"] = "👨🏼‍🤝‍👨🏻", + ["men_holding_hands_medium_light_skin_tone_light_skin_tone"] = "👨🏼‍🤝‍👨🏻", + ["men_holding_hands_tone2"] = "👬🏼", + ["men_holding_hands_medium_light_skin_tone"] = "👬🏼", + ["men_holding_hands_tone2_tone3"] = "👨🏼‍🤝‍👨🏽", + ["men_holding_hands_medium_light_skin_tone_medium_skin_tone"] = "👨🏼‍🤝‍👨🏽", + ["men_holding_hands_tone2_tone4"] = "👨🏼‍🤝‍👨🏾", + ["men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone"] = "👨🏼‍🤝‍👨🏾", + ["men_holding_hands_tone2_tone5"] = "👨🏼‍🤝‍👨🏿", + ["men_holding_hands_medium_light_skin_tone_dark_skin_tone"] = "👨🏼‍🤝‍👨🏿", + ["men_holding_hands_tone3_tone1"] = "👨🏽‍🤝‍👨🏻", + ["men_holding_hands_medium_skin_tone_light_skin_tone"] = "👨🏽‍🤝‍👨🏻", + ["men_holding_hands_tone3_tone2"] = "👨🏽‍🤝‍👨🏼", + ["men_holding_hands_medium_skin_tone_medium_light_skin_tone"] = "👨🏽‍🤝‍👨🏼", + ["men_holding_hands_tone3"] = "👬🏽", + ["men_holding_hands_medium_skin_tone"] = "👬🏽", + ["men_holding_hands_tone3_tone4"] = "👨🏽‍🤝‍👨🏾", + ["men_holding_hands_medium_skin_tone_medium_dark_skin_tone"] = "👨🏽‍🤝‍👨🏾", + ["men_holding_hands_tone3_tone5"] = "👨🏽‍🤝‍👨🏿", + ["men_holding_hands_medium_skin_tone_dark_skin_tone"] = "👨🏽‍🤝‍👨🏿", + ["men_holding_hands_tone4_tone1"] = "👨🏾‍🤝‍👨🏻", + ["men_holding_hands_medium_dark_skin_tone_light_skin_tone"] = "👨🏾‍🤝‍👨🏻", + ["men_holding_hands_tone4_tone2"] = "👨🏾‍🤝‍👨🏼", + ["men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone"] = "👨🏾‍🤝‍👨🏼", + ["men_holding_hands_tone4_tone3"] = "👨🏾‍🤝‍👨🏽", + ["men_holding_hands_medium_dark_skin_tone_medium_skin_tone"] = "👨🏾‍🤝‍👨🏽", + ["men_holding_hands_tone4"] = "👬🏾", + ["men_holding_hands_medium_dark_skin_tone"] = "👬🏾", + ["men_holding_hands_tone4_tone5"] = "👨🏾‍🤝‍👨🏿", + ["men_holding_hands_medium_dark_skin_tone_dark_skin_tone"] = "👨🏾‍🤝‍👨🏿", + ["men_holding_hands_tone5_tone1"] = "👨🏿‍🤝‍👨🏻", + ["men_holding_hands_dark_skin_tone_light_skin_tone"] = "👨🏿‍🤝‍👨🏻", + ["men_holding_hands_tone5_tone2"] = "👨🏿‍🤝‍👨🏼", + ["men_holding_hands_dark_skin_tone_medium_light_skin_tone"] = "👨🏿‍🤝‍👨🏼", + ["men_holding_hands_tone5_tone3"] = "👨🏿‍🤝‍👨🏽", + ["men_holding_hands_dark_skin_tone_medium_skin_tone"] = "👨🏿‍🤝‍👨🏽", + ["men_holding_hands_tone5_tone4"] = "👨🏿‍🤝‍👨🏾", + ["men_holding_hands_dark_skin_tone_medium_dark_skin_tone"] = "👨🏿‍🤝‍👨🏾", + ["men_holding_hands_tone5"] = "👬🏿", + ["men_holding_hands_dark_skin_tone"] = "👬🏿", + ["couple_with_heart"] = "💑", + ["couple_with_heart_tone1"] = "💑🏻", + ["couple_with_heart_light_skin_tone"] = "💑🏻", + ["couple_with_heart_person_person_tone1_tone2"] = "🧑🏻‍❤️‍🧑🏼", + ["couple_with_heart_person_person_light_skin_tone_medium_light_skin_tone"] = "🧑🏻‍❤️‍🧑🏼", + ["couple_with_heart_person_person_tone1_tone3"] = "🧑🏻‍❤️‍🧑🏽", + ["couple_with_heart_person_person_light_skin_tone_medium_skin_tone"] = "🧑🏻‍❤️‍🧑🏽", + ["couple_with_heart_person_person_tone1_tone4"] = "🧑🏻‍❤️‍🧑🏾", + ["couple_with_heart_person_person_light_skin_tone_medium_dark_skin_tone"] = "🧑🏻‍❤️‍🧑🏾", + ["couple_with_heart_person_person_tone1_tone5"] = "🧑🏻‍❤️‍🧑🏿", + ["couple_with_heart_person_person_light_skin_tone_dark_skin_tone"] = "🧑🏻‍❤️‍🧑🏿", + ["couple_with_heart_person_person_tone2_tone1"] = "🧑🏼‍❤️‍🧑🏻", + ["couple_with_heart_person_person_medium_light_skin_tone_light_skin_tone"] = "🧑🏼‍❤️‍🧑🏻", + ["couple_with_heart_tone2"] = "💑🏼", + ["couple_with_heart_medium_light_skin_tone"] = "💑🏼", + ["couple_with_heart_person_person_tone2_tone3"] = "🧑🏼‍❤️‍🧑🏽", + ["couple_with_heart_person_person_medium_light_skin_tone_medium_skin_tone"] = "🧑🏼‍❤️‍🧑🏽", + ["couple_with_heart_person_person_tone2_tone4"] = "🧑🏼‍❤️‍🧑🏾", + ["couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone"] = "🧑🏼‍❤️‍🧑🏾", + ["couple_with_heart_person_person_tone2_tone5"] = "🧑🏼‍❤️‍🧑🏿", + ["couple_with_heart_person_person_medium_light_skin_tone_dark_skin_tone"] = "🧑🏼‍❤️‍🧑🏿", + ["couple_with_heart_person_person_tone3_tone1"] = "🧑🏽‍❤️‍🧑🏻", + ["couple_with_heart_person_person_medium_skin_tone_light_skin_tone"] = "🧑🏽‍❤️‍🧑🏻", + ["couple_with_heart_person_person_tone3_tone2"] = "🧑🏽‍❤️‍🧑🏼", + ["couple_with_heart_person_person_medium_skin_tone_medium_light_skin_tone"] = "🧑🏽‍❤️‍🧑🏼", + ["couple_with_heart_tone3"] = "💑🏽", + ["couple_with_heart_medium_skin_tone"] = "💑🏽", + ["couple_with_heart_person_person_tone3_tone4"] = "🧑🏽‍❤️‍🧑🏾", + ["couple_with_heart_person_person_medium_skin_tone_medium_dark_skin_tone"] = "🧑🏽‍❤️‍🧑🏾", + ["couple_with_heart_person_person_tone3_tone5"] = "🧑🏽‍❤️‍🧑🏿", + ["couple_with_heart_person_person_medium_skin_tone_dark_skin_tone"] = "🧑🏽‍❤️‍🧑🏿", + ["couple_with_heart_person_person_tone4_tone1"] = "🧑🏾‍❤️‍🧑🏻", + ["couple_with_heart_person_person_medium_dark_skin_tone_light_skin_tone"] = "🧑🏾‍❤️‍🧑🏻", + ["couple_with_heart_person_person_tone4_tone2"] = "🧑🏾‍❤️‍🧑🏼", + ["couple_with_heart_person_person_medium_dark_skin_tone_medium_light_skin_tone"] = "🧑🏾‍❤️‍🧑🏼", + ["couple_with_heart_person_person_tone4_tone3"] = "🧑🏾‍❤️‍🧑🏽", + ["couple_with_heart_person_person_medium_dark_skin_tone_medium_skin_tone"] = "🧑🏾‍❤️‍🧑🏽", + ["couple_with_heart_tone4"] = "💑🏾", + ["couple_with_heart_medium_dark_skin_tone"] = "💑🏾", + ["couple_with_heart_person_person_tone4_tone5"] = "🧑🏾‍❤️‍🧑🏿", + ["couple_with_heart_person_person_medium_dark_skin_tone_dark_skin_tone"] = "🧑🏾‍❤️‍🧑🏿", + ["couple_with_heart_person_person_tone5_tone1"] = "🧑🏿‍❤️‍🧑🏻", + ["couple_with_heart_person_person_dark_skin_tone_light_skin_tone"] = "🧑🏿‍❤️‍🧑🏻", + ["couple_with_heart_person_person_tone5_tone2"] = "🧑🏿‍❤️‍🧑🏼", + ["couple_with_heart_person_person_dark_skin_tone_medium_light_skin_tone"] = "🧑🏿‍❤️‍🧑🏼", + ["couple_with_heart_person_person_tone5_tone3"] = "🧑🏿‍❤️‍🧑🏽", + ["couple_with_heart_person_person_dark_skin_tone_medium_skin_tone"] = "🧑🏿‍❤️‍🧑🏽", + ["couple_with_heart_person_person_tone5_tone4"] = "🧑🏿‍❤️‍🧑🏾", + ["couple_with_heart_person_person_dark_skin_tone_medium_dark_skin_tone"] = "🧑🏿‍❤️‍🧑🏾", + ["couple_with_heart_tone5"] = "💑🏿", + ["couple_with_heart_dark_skin_tone"] = "💑🏿", + ["couple_with_heart_woman_man"] = "👩‍❤️‍👨", + ["couple_with_heart_woman_man_tone1"] = "👩🏻‍❤️‍👨🏻", + ["couple_with_heart_woman_man_light_skin_tone"] = "👩🏻‍❤️‍👨🏻", + ["couple_with_heart_woman_man_tone1_tone2"] = "👩🏻‍❤️‍👨🏼", + ["couple_with_heart_woman_man_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍👨🏼", + ["couple_with_heart_woman_man_tone1_tone3"] = "👩🏻‍❤️‍👨🏽", + ["couple_with_heart_woman_man_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍👨🏽", + ["couple_with_heart_woman_man_tone1_tone4"] = "👩🏻‍❤️‍👨🏾", + ["couple_with_heart_woman_man_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍👨🏾", + ["couple_with_heart_woman_man_tone1_tone5"] = "👩🏻‍❤️‍👨🏿", + ["couple_with_heart_woman_man_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍👨🏿", + ["couple_with_heart_woman_man_tone2_tone1"] = "👩🏼‍❤️‍👨🏻", + ["couple_with_heart_woman_man_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍👨🏻", + ["couple_with_heart_woman_man_tone2"] = "👩🏼‍❤️‍👨🏼", + ["couple_with_heart_woman_man_medium_light_skin_tone"] = "👩🏼‍❤️‍👨🏼", + ["couple_with_heart_woman_man_tone2_tone3"] = "👩🏼‍❤️‍👨🏽", + ["couple_with_heart_woman_man_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍👨🏽", + ["couple_with_heart_woman_man_tone2_tone4"] = "👩🏼‍❤️‍👨🏾", + ["couple_with_heart_woman_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍👨🏾", + ["couple_with_heart_woman_man_tone2_tone5"] = "👩🏼‍❤️‍👨🏿", + ["couple_with_heart_woman_man_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍👨🏿", + ["couple_with_heart_woman_man_tone3_tone1"] = "👩🏽‍❤️‍👨🏻", + ["couple_with_heart_woman_man_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍👨🏻", + ["couple_with_heart_woman_man_tone3_tone2"] = "👩🏽‍❤️‍👨🏼", + ["couple_with_heart_woman_man_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍👨🏼", + ["couple_with_heart_woman_man_tone3"] = "👩🏽‍❤️‍👨🏽", + ["couple_with_heart_woman_man_medium_skin_tone"] = "👩🏽‍❤️‍👨🏽", + ["couple_with_heart_woman_man_tone3_tone4"] = "👩🏽‍❤️‍👨🏾", + ["couple_with_heart_woman_man_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍👨🏾", + ["couple_with_heart_woman_man_tone3_tone5"] = "👩🏽‍❤️‍👨🏿", + ["couple_with_heart_woman_man_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍👨🏿", + ["couple_with_heart_woman_man_tone4_tone1"] = "👩🏾‍❤️‍👨🏻", + ["couple_with_heart_woman_man_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍👨🏻", + ["couple_with_heart_woman_man_tone4_tone2"] = "👩🏾‍❤️‍👨🏼", + ["couple_with_heart_woman_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍👨🏼", + ["couple_with_heart_woman_man_tone4_tone3"] = "👩🏾‍❤️‍👨🏽", + ["couple_with_heart_woman_man_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍👨🏽", + ["couple_with_heart_woman_man_tone4"] = "👩🏾‍❤️‍👨🏾", + ["couple_with_heart_woman_man_medium_dark_skin_tone"] = "👩🏾‍❤️‍👨🏾", + ["couple_with_heart_woman_man_tone4_tone5"] = "👩🏾‍❤️‍👨🏿", + ["couple_with_heart_woman_man_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍👨🏿", + ["couple_with_heart_woman_man_tone5_tone1"] = "👩🏿‍❤️‍👨🏻", + ["couple_with_heart_woman_man_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍👨🏻", + ["couple_with_heart_woman_man_tone5_tone2"] = "👩🏿‍❤️‍👨🏼", + ["couple_with_heart_woman_man_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍👨🏼", + ["couple_with_heart_woman_man_tone5_tone3"] = "👩🏿‍❤️‍👨🏽", + ["couple_with_heart_woman_man_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍👨🏽", + ["couple_with_heart_woman_man_tone5_tone4"] = "👩🏿‍❤️‍👨🏾", + ["couple_with_heart_woman_man_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍👨🏾", + ["couple_with_heart_woman_man_tone5"] = "👩🏿‍❤️‍👨🏿", + ["couple_with_heart_woman_man_dark_skin_tone"] = "👩🏿‍❤️‍👨🏿", + ["couple_ww"] = "👩‍❤️‍👩", + ["couple_with_heart_ww"] = "👩‍❤️‍👩", + ["couple_with_heart_woman_woman_tone1"] = "👩🏻‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_light_skin_tone"] = "👩🏻‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_tone1_tone2"] = "👩🏻‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_tone1_tone3"] = "👩🏻‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_tone1_tone4"] = "👩🏻‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_tone1_tone5"] = "👩🏻‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_tone2_tone1"] = "👩🏼‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_tone2"] = "👩🏼‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_medium_light_skin_tone"] = "👩🏼‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_tone2_tone3"] = "👩🏼‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_tone2_tone4"] = "👩🏼‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_tone2_tone5"] = "👩🏼‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_tone3_tone1"] = "👩🏽‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_tone3_tone2"] = "👩🏽‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_tone3"] = "👩🏽‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_medium_skin_tone"] = "👩🏽‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_tone3_tone4"] = "👩🏽‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_tone3_tone5"] = "👩🏽‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_tone4_tone1"] = "👩🏾‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_tone4_tone2"] = "👩🏾‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_tone4_tone3"] = "👩🏾‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_tone4"] = "👩🏾‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_medium_dark_skin_tone"] = "👩🏾‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_tone4_tone5"] = "👩🏾‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_tone5_tone1"] = "👩🏿‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍👩🏻", + ["couple_with_heart_woman_woman_tone5_tone2"] = "👩🏿‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍👩🏼", + ["couple_with_heart_woman_woman_tone5_tone3"] = "👩🏿‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍👩🏽", + ["couple_with_heart_woman_woman_tone5_tone4"] = "👩🏿‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍👩🏾", + ["couple_with_heart_woman_woman_tone5"] = "👩🏿‍❤️‍👩🏿", + ["couple_with_heart_woman_woman_dark_skin_tone"] = "👩🏿‍❤️‍👩🏿", + ["couple_mm"] = "👨‍❤️‍👨", + ["couple_with_heart_mm"] = "👨‍❤️‍👨", + ["couple_with_heart_man_man_tone1"] = "👨🏻‍❤️‍👨🏻", + ["couple_with_heart_man_man_light_skin_tone"] = "👨🏻‍❤️‍👨🏻", + ["couple_with_heart_man_man_tone1_tone2"] = "👨🏻‍❤️‍👨🏼", + ["couple_with_heart_man_man_light_skin_tone_medium_light_skin_tone"] = "👨🏻‍❤️‍👨🏼", + ["couple_with_heart_man_man_tone1_tone3"] = "👨🏻‍❤️‍👨🏽", + ["couple_with_heart_man_man_light_skin_tone_medium_skin_tone"] = "👨🏻‍❤️‍👨🏽", + ["couple_with_heart_man_man_tone1_tone4"] = "👨🏻‍❤️‍👨🏾", + ["couple_with_heart_man_man_light_skin_tone_medium_dark_skin_tone"] = "👨🏻‍❤️‍👨🏾", + ["couple_with_heart_man_man_tone1_tone5"] = "👨🏻‍❤️‍👨🏿", + ["couple_with_heart_man_man_light_skin_tone_dark_skin_tone"] = "👨🏻‍❤️‍👨🏿", + ["couple_with_heart_man_man_tone2_tone1"] = "👨🏼‍❤️‍👨🏻", + ["couple_with_heart_man_man_medium_light_skin_tone_light_skin_tone"] = "👨🏼‍❤️‍👨🏻", + ["couple_with_heart_man_man_tone2"] = "👨🏼‍❤️‍👨🏼", + ["couple_with_heart_man_man_medium_light_skin_tone"] = "👨🏼‍❤️‍👨🏼", + ["couple_with_heart_man_man_tone2_tone3"] = "👨🏼‍❤️‍👨🏽", + ["couple_with_heart_man_man_medium_light_skin_tone_medium_skin_tone"] = "👨🏼‍❤️‍👨🏽", + ["couple_with_heart_man_man_tone2_tone4"] = "👨🏼‍❤️‍👨🏾", + ["couple_with_heart_man_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👨🏼‍❤️‍👨🏾", + ["couple_with_heart_man_man_tone2_tone5"] = "👨🏼‍❤️‍👨🏿", + ["couple_with_heart_man_man_medium_light_skin_tone_dark_skin_tone"] = "👨🏼‍❤️‍👨🏿", + ["couple_with_heart_man_man_tone3_tone1"] = "👨🏽‍❤️‍👨🏻", + ["couple_with_heart_man_man_medium_skin_tone_light_skin_tone"] = "👨🏽‍❤️‍👨🏻", + ["couple_with_heart_man_man_tone3_tone2"] = "👨🏽‍❤️‍👨🏼", + ["couple_with_heart_man_man_medium_skin_tone_medium_light_skin_tone"] = "👨🏽‍❤️‍👨🏼", + ["couple_with_heart_man_man_tone3"] = "👨🏽‍❤️‍👨🏽", + ["couple_with_heart_man_man_medium_skin_tone"] = "👨🏽‍❤️‍👨🏽", + ["couple_with_heart_man_man_tone3_tone4"] = "👨🏽‍❤️‍👨🏾", + ["couple_with_heart_man_man_medium_skin_tone_medium_dark_skin_tone"] = "👨🏽‍❤️‍👨🏾", + ["couple_with_heart_man_man_tone3_tone5"] = "👨🏽‍❤️‍👨🏿", + ["couple_with_heart_man_man_medium_skin_tone_dark_skin_tone"] = "👨🏽‍❤️‍👨🏿", + ["couple_with_heart_man_man_tone4_tone1"] = "👨🏾‍❤️‍👨🏻", + ["couple_with_heart_man_man_medium_dark_skin_tone_light_skin_tone"] = "👨🏾‍❤️‍👨🏻", + ["couple_with_heart_man_man_tone4_tone2"] = "👨🏾‍❤️‍👨🏼", + ["couple_with_heart_man_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👨🏾‍❤️‍👨🏼", + ["couple_with_heart_man_man_tone4_tone3"] = "👨🏾‍❤️‍👨🏽", + ["couple_with_heart_man_man_medium_dark_skin_tone_medium_skin_tone"] = "👨🏾‍❤️‍👨🏽", + ["couple_with_heart_man_man_tone4"] = "👨🏾‍❤️‍👨🏾", + ["couple_with_heart_man_man_medium_dark_skin_tone"] = "👨🏾‍❤️‍👨🏾", + ["couple_with_heart_man_man_tone4_tone5"] = "👨🏾‍❤️‍👨🏿", + ["couple_with_heart_man_man_medium_dark_skin_tone_dark_skin_tone"] = "👨🏾‍❤️‍👨🏿", + ["couple_with_heart_man_man_tone5_tone1"] = "👨🏿‍❤️‍👨🏻", + ["couple_with_heart_man_man_dark_skin_tone_light_skin_tone"] = "👨🏿‍❤️‍👨🏻", + ["couple_with_heart_man_man_tone5_tone2"] = "👨🏿‍❤️‍👨🏼", + ["couple_with_heart_man_man_dark_skin_tone_medium_light_skin_tone"] = "👨🏿‍❤️‍👨🏼", + ["couple_with_heart_man_man_tone5_tone3"] = "👨🏿‍❤️‍👨🏽", + ["couple_with_heart_man_man_dark_skin_tone_medium_skin_tone"] = "👨🏿‍❤️‍👨🏽", + ["couple_with_heart_man_man_tone5_tone4"] = "👨🏿‍❤️‍👨🏾", + ["couple_with_heart_man_man_dark_skin_tone_medium_dark_skin_tone"] = "👨🏿‍❤️‍👨🏾", + ["couple_with_heart_man_man_tone5"] = "👨🏿‍❤️‍👨🏿", + ["couple_with_heart_man_man_dark_skin_tone"] = "👨🏿‍❤️‍👨🏿", + ["couplekiss"] = "💏", + ["kiss_person_person_tone5_tone4"] = "🧑🏿‍❤️‍💋‍🧑🏾", + ["kiss_person_person_dark_skin_tone_medium_dark_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏾", + ["kiss_tone1"] = "💏🏻", + ["kiss_light_skin_tone"] = "💏🏻", + ["kiss_person_person_tone1_tone2"] = "🧑🏻‍❤️‍💋‍🧑🏼", + ["kiss_person_person_light_skin_tone_medium_light_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏼", + ["kiss_person_person_tone1_tone3"] = "🧑🏻‍❤️‍💋‍🧑🏽", + ["kiss_person_person_light_skin_tone_medium_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏽", + ["kiss_person_person_tone1_tone4"] = "🧑🏻‍❤️‍💋‍🧑🏾", + ["kiss_person_person_light_skin_tone_medium_dark_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏾", + ["kiss_person_person_tone1_tone5"] = "🧑🏻‍❤️‍💋‍🧑🏿", + ["kiss_person_person_light_skin_tone_dark_skin_tone"] = "🧑🏻‍❤️‍💋‍🧑🏿", + ["kiss_person_person_tone2_tone1"] = "🧑🏼‍❤️‍💋‍🧑🏻", + ["kiss_person_person_medium_light_skin_tone_light_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏻", + ["kiss_tone2"] = "💏🏼", + ["kiss_medium_light_skin_tone"] = "💏🏼", + ["kiss_person_person_tone2_tone3"] = "🧑🏼‍❤️‍💋‍🧑🏽", + ["kiss_person_person_medium_light_skin_tone_medium_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏽", + ["kiss_person_person_tone2_tone4"] = "🧑🏼‍❤️‍💋‍🧑🏾", + ["kiss_person_person_medium_light_skin_tone_medium_dark_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏾", + ["kiss_person_person_tone2_tone5"] = "🧑🏼‍❤️‍💋‍🧑🏿", + ["kiss_person_person_medium_light_skin_tone_dark_skin_tone"] = "🧑🏼‍❤️‍💋‍🧑🏿", + ["kiss_person_person_tone3_tone1"] = "🧑🏽‍❤️‍💋‍🧑🏻", + ["kiss_person_person_medium_skin_tone_light_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏻", + ["kiss_person_person_tone3_tone2"] = "🧑🏽‍❤️‍💋‍🧑🏼", + ["kiss_person_person_medium_skin_tone_medium_light_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏼", + ["kiss_tone3"] = "💏🏽", + ["kiss_medium_skin_tone"] = "💏🏽", + ["kiss_person_person_tone3_tone4"] = "🧑🏽‍❤️‍💋‍🧑🏾", + ["kiss_person_person_medium_skin_tone_medium_dark_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏾", + ["kiss_person_person_tone3_tone5"] = "🧑🏽‍❤️‍💋‍🧑🏿", + ["kiss_person_person_medium_skin_tone_dark_skin_tone"] = "🧑🏽‍❤️‍💋‍🧑🏿", + ["kiss_person_person_tone4_tone1"] = "🧑🏾‍❤️‍💋‍🧑🏻", + ["kiss_person_person_medium_dark_skin_tone_light_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏻", + ["kiss_person_person_tone4_tone2"] = "🧑🏾‍❤️‍💋‍🧑🏼", + ["kiss_person_person_medium_dark_skin_tone_medium_light_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏼", + ["kiss_person_person_tone4_tone3"] = "🧑🏾‍❤️‍💋‍🧑🏽", + ["kiss_person_person_medium_dark_skin_tone_medium_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏽", + ["kiss_tone4"] = "💏🏾", + ["kiss_medium_dark_skin_tone"] = "💏🏾", + ["kiss_person_person_tone4_tone5"] = "🧑🏾‍❤️‍💋‍🧑🏿", + ["kiss_person_person_medium_dark_skin_tone_dark_skin_tone"] = "🧑🏾‍❤️‍💋‍🧑🏿", + ["kiss_person_person_tone5_tone1"] = "🧑🏿‍❤️‍💋‍🧑🏻", + ["kiss_person_person_dark_skin_tone_light_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏻", + ["kiss_person_person_tone5_tone2"] = "🧑🏿‍❤️‍💋‍🧑🏼", + ["kiss_person_person_dark_skin_tone_medium_light_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏼", + ["kiss_person_person_tone5_tone3"] = "🧑🏿‍❤️‍💋‍🧑🏽", + ["kiss_person_person_dark_skin_tone_medium_skin_tone"] = "🧑🏿‍❤️‍💋‍🧑🏽", + ["kiss_tone5"] = "💏🏿", + ["kiss_dark_skin_tone"] = "💏🏿", + ["kiss_woman_man"] = "👩‍❤️‍💋‍👨", + ["kiss_woman_man_tone1"] = "👩🏻‍❤️‍💋‍👨🏻", + ["kiss_woman_man_light_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏻", + ["kiss_woman_man_tone1_tone2"] = "👩🏻‍❤️‍💋‍👨🏼", + ["kiss_woman_man_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏼", + ["kiss_woman_man_tone1_tone3"] = "👩🏻‍❤️‍💋‍👨🏽", + ["kiss_woman_man_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏽", + ["kiss_woman_man_tone1_tone4"] = "👩🏻‍❤️‍💋‍👨🏾", + ["kiss_woman_man_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏾", + ["kiss_woman_man_tone1_tone5"] = "👩🏻‍❤️‍💋‍👨🏿", + ["kiss_woman_man_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👨🏿", + ["kiss_woman_man_tone2_tone1"] = "👩🏼‍❤️‍💋‍👨🏻", + ["kiss_woman_man_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏻", + ["kiss_woman_man_tone2"] = "👩🏼‍❤️‍💋‍👨🏼", + ["kiss_woman_man_medium_light_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏼", + ["kiss_woman_man_tone2_tone3"] = "👩🏼‍❤️‍💋‍👨🏽", + ["kiss_woman_man_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏽", + ["kiss_woman_man_tone2_tone4"] = "👩🏼‍❤️‍💋‍👨🏾", + ["kiss_woman_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏾", + ["kiss_woman_man_tone2_tone5"] = "👩🏼‍❤️‍💋‍👨🏿", + ["kiss_woman_man_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👨🏿", + ["kiss_woman_man_tone3_tone1"] = "👩🏽‍❤️‍💋‍👨🏻", + ["kiss_woman_man_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏻", + ["kiss_woman_man_tone3_tone2"] = "👩🏽‍❤️‍💋‍👨🏼", + ["kiss_woman_man_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏼", + ["kiss_woman_man_tone3"] = "👩🏽‍❤️‍💋‍👨🏽", + ["kiss_woman_man_medium_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏽", + ["kiss_woman_man_tone3_tone4"] = "👩🏽‍❤️‍💋‍👨🏾", + ["kiss_woman_man_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏾", + ["kiss_woman_man_tone3_tone5"] = "👩🏽‍❤️‍💋‍👨🏿", + ["kiss_woman_man_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👨🏿", + ["kiss_woman_man_tone4_tone1"] = "👩🏾‍❤️‍💋‍👨🏻", + ["kiss_woman_man_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏻", + ["kiss_woman_man_tone4_tone2"] = "👩🏾‍❤️‍💋‍👨🏼", + ["kiss_woman_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏼", + ["kiss_woman_man_tone4_tone3"] = "👩🏾‍❤️‍💋‍👨🏽", + ["kiss_woman_man_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏽", + ["kiss_woman_man_tone4"] = "👩🏾‍❤️‍💋‍👨🏾", + ["kiss_woman_man_medium_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏾", + ["kiss_woman_man_tone4_tone5"] = "👩🏾‍❤️‍💋‍👨🏿", + ["kiss_woman_man_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👨🏿", + ["kiss_woman_man_tone5_tone1"] = "👩🏿‍❤️‍💋‍👨🏻", + ["kiss_woman_man_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏻", + ["kiss_woman_man_tone5_tone2"] = "👩🏿‍❤️‍💋‍👨🏼", + ["kiss_woman_man_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏼", + ["kiss_woman_man_tone5_tone3"] = "👩🏿‍❤️‍💋‍👨🏽", + ["kiss_woman_man_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏽", + ["kiss_woman_man_tone5_tone4"] = "👩🏿‍❤️‍💋‍👨🏾", + ["kiss_woman_man_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏾", + ["kiss_woman_man_tone5"] = "👩🏿‍❤️‍💋‍👨🏿", + ["kiss_woman_man_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👨🏿", + ["kiss_ww"] = "👩‍❤️‍💋‍👩", + ["couplekiss_ww"] = "👩‍❤️‍💋‍👩", + ["kiss_woman_woman_tone1"] = "👩🏻‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_light_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_tone1_tone2"] = "👩🏻‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_light_skin_tone_medium_light_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_tone1_tone3"] = "👩🏻‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_light_skin_tone_medium_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_tone1_tone4"] = "👩🏻‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_light_skin_tone_medium_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_tone1_tone5"] = "👩🏻‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_light_skin_tone_dark_skin_tone"] = "👩🏻‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_tone2_tone1"] = "👩🏼‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_medium_light_skin_tone_light_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_tone2"] = "👩🏼‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_medium_light_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_tone2_tone3"] = "👩🏼‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_medium_light_skin_tone_medium_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_tone2_tone4"] = "👩🏼‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_medium_light_skin_tone_medium_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_tone2_tone5"] = "👩🏼‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_medium_light_skin_tone_dark_skin_tone"] = "👩🏼‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_tone3_tone1"] = "👩🏽‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_medium_skin_tone_light_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_tone3_tone2"] = "👩🏽‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_medium_skin_tone_medium_light_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_tone3"] = "👩🏽‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_medium_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_tone3_tone4"] = "👩🏽‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_medium_skin_tone_medium_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_tone3_tone5"] = "👩🏽‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_medium_skin_tone_dark_skin_tone"] = "👩🏽‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_tone4_tone1"] = "👩🏾‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_medium_dark_skin_tone_light_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_tone4_tone2"] = "👩🏾‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_medium_dark_skin_tone_medium_light_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_tone4_tone3"] = "👩🏾‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_medium_dark_skin_tone_medium_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_tone4"] = "👩🏾‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_medium_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_tone4_tone5"] = "👩🏾‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_medium_dark_skin_tone_dark_skin_tone"] = "👩🏾‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_tone5_tone1"] = "👩🏿‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_dark_skin_tone_light_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏻", + ["kiss_woman_woman_tone5_tone2"] = "👩🏿‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_dark_skin_tone_medium_light_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏼", + ["kiss_woman_woman_tone5_tone3"] = "👩🏿‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_dark_skin_tone_medium_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏽", + ["kiss_woman_woman_tone5_tone4"] = "👩🏿‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_dark_skin_tone_medium_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏾", + ["kiss_woman_woman_tone5"] = "👩🏿‍❤️‍💋‍👩🏿", + ["kiss_woman_woman_dark_skin_tone"] = "👩🏿‍❤️‍💋‍👩🏿", + ["kiss_mm"] = "👨‍❤️‍💋‍👨", + ["couplekiss_mm"] = "👨‍❤️‍💋‍👨", + ["kiss_man_man_tone1"] = "👨🏻‍❤️‍💋‍👨🏻", + ["kiss_man_man_light_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏻", + ["kiss_man_man_tone1_tone2"] = "👨🏻‍❤️‍💋‍👨🏼", + ["kiss_man_man_light_skin_tone_medium_light_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏼", + ["kiss_man_man_tone1_tone3"] = "👨🏻‍❤️‍💋‍👨🏽", + ["kiss_man_man_light_skin_tone_medium_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏽", + ["kiss_man_man_tone1_tone4"] = "👨🏻‍❤️‍💋‍👨🏾", + ["kiss_man_man_light_skin_tone_medium_dark_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏾", + ["kiss_man_man_tone1_tone5"] = "👨🏻‍❤️‍💋‍👨🏿", + ["kiss_man_man_light_skin_tone_dark_skin_tone"] = "👨🏻‍❤️‍💋‍👨🏿", + ["kiss_man_man_tone2_tone1"] = "👨🏼‍❤️‍💋‍👨🏻", + ["kiss_man_man_medium_light_skin_tone_light_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏻", + ["kiss_man_man_tone2"] = "👨🏼‍❤️‍💋‍👨🏼", + ["kiss_man_man_medium_light_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏼", + ["kiss_man_man_tone2_tone3"] = "👨🏼‍❤️‍💋‍👨🏽", + ["kiss_man_man_medium_light_skin_tone_medium_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏽", + ["kiss_man_man_tone2_tone4"] = "👨🏼‍❤️‍💋‍👨🏾", + ["kiss_man_man_medium_light_skin_tone_medium_dark_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏾", + ["kiss_man_man_tone2_tone5"] = "👨🏼‍❤️‍💋‍👨🏿", + ["kiss_man_man_medium_light_skin_tone_dark_skin_tone"] = "👨🏼‍❤️‍💋‍👨🏿", + ["kiss_man_man_tone3_tone1"] = "👨🏽‍❤️‍💋‍👨🏻", + ["kiss_man_man_medium_skin_tone_light_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏻", + ["kiss_man_man_tone3_tone2"] = "👨🏽‍❤️‍💋‍👨🏼", + ["kiss_man_man_medium_skin_tone_medium_light_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏼", + ["kiss_man_man_tone3"] = "👨🏽‍❤️‍💋‍👨🏽", + ["kiss_man_man_medium_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏽", + ["kiss_man_man_tone3_tone4"] = "👨🏽‍❤️‍💋‍👨🏾", + ["kiss_man_man_medium_skin_tone_medium_dark_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏾", + ["kiss_man_man_tone3_tone5"] = "👨🏽‍❤️‍💋‍👨🏿", + ["kiss_man_man_medium_skin_tone_dark_skin_tone"] = "👨🏽‍❤️‍💋‍👨🏿", + ["kiss_man_man_tone4_tone1"] = "👨🏾‍❤️‍💋‍👨🏻", + ["kiss_man_man_medium_dark_skin_tone_light_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏻", + ["kiss_man_man_tone4_tone2"] = "👨🏾‍❤️‍💋‍👨🏼", + ["kiss_man_man_medium_dark_skin_tone_medium_light_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏼", + ["kiss_man_man_tone4_tone3"] = "👨🏾‍❤️‍💋‍👨🏽", + ["kiss_man_man_medium_dark_skin_tone_medium_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏽", + ["kiss_man_man_tone4"] = "👨🏾‍❤️‍💋‍👨🏾", + ["kiss_man_man_medium_dark_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏾", + ["kiss_man_man_tone4_tone5"] = "👨🏾‍❤️‍💋‍👨🏿", + ["kiss_man_man_medium_dark_skin_tone_dark_skin_tone"] = "👨🏾‍❤️‍💋‍👨🏿", + ["kiss_man_man_tone5_tone1"] = "👨🏿‍❤️‍💋‍👨🏻", + ["kiss_man_man_dark_skin_tone_light_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏻", + ["kiss_man_man_tone5_tone2"] = "👨🏿‍❤️‍💋‍👨🏼", + ["kiss_man_man_dark_skin_tone_medium_light_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏼", + ["kiss_man_man_tone5_tone3"] = "👨🏿‍❤️‍💋‍👨🏽", + ["kiss_man_man_dark_skin_tone_medium_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏽", + ["kiss_man_man_tone5_tone4"] = "👨🏿‍❤️‍💋‍👨🏾", + ["kiss_man_man_dark_skin_tone_medium_dark_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏾", + ["kiss_man_man_tone5"] = "👨🏿‍❤️‍💋‍👨🏿", + ["kiss_man_man_dark_skin_tone"] = "👨🏿‍❤️‍💋‍👨🏿", + ["family"] = "👪", + ["family_man_woman_boy"] = "👨‍👩‍👦", + ["family_mwg"] = "👨‍👩‍👧", + ["family_mwgb"] = "👨‍👩‍👧‍👦", + ["family_mwbb"] = "👨‍👩‍👦‍👦", + ["family_mwgg"] = "👨‍👩‍👧‍👧", + ["family_wwb"] = "👩‍👩‍👦", + ["family_wwg"] = "👩‍👩‍👧", + ["family_wwgb"] = "👩‍👩‍👧‍👦", + ["family_wwbb"] = "👩‍👩‍👦‍👦", + ["family_wwgg"] = "👩‍👩‍👧‍👧", + ["family_mmb"] = "👨‍👨‍👦", + ["family_mmg"] = "👨‍👨‍👧", + ["family_mmgb"] = "👨‍👨‍👧‍👦", + ["family_mmbb"] = "👨‍👨‍👦‍👦", + ["family_mmgg"] = "👨‍👨‍👧‍👧", + ["family_woman_boy"] = "👩‍👦", + ["family_woman_girl"] = "👩‍👧", + ["family_woman_girl_boy"] = "👩‍👧‍👦", + ["family_woman_boy_boy"] = "👩‍👦‍👦", + ["family_woman_girl_girl"] = "👩‍👧‍👧", + ["family_man_boy"] = "👨‍👦", + ["family_man_girl"] = "👨‍👧", + ["family_man_girl_boy"] = "👨‍👧‍👦", + ["family_man_boy_boy"] = "👨‍👦‍👦", + ["family_man_girl_girl"] = "👨‍👧‍👧", + ["yarn"] = "🧶", + ["thread"] = "🧵", + ["coat"] = "🧥", + ["lab_coat"] = "🥼", + ["safety_vest"] = "🦺", + ["womans_clothes"] = "👚", + ["shirt"] = "👕", + ["jeans"] = "👖", + ["briefs"] = "🩲", + ["shorts"] = "🩳", + ["necktie"] = "👔", + ["dress"] = "👗", + ["bikini"] = "👙", + ["one_piece_swimsuit"] = "🩱", + ["kimono"] = "👘", + ["sari"] = "🥻", + ["womans_flat_shoe"] = "🥿", + ["high_heel"] = "👠", + ["sandal"] = "👡", + ["boot"] = "👢", + ["mans_shoe"] = "👞", + ["athletic_shoe"] = "👟", + ["hiking_boot"] = "🥾", + ["thong_sandal"] = "🩴", + ["socks"] = "🧦", + ["gloves"] = "🧤", + ["scarf"] = "🧣", + ["tophat"] = "🎩", + ["billed_cap"] = "🧢", + ["womans_hat"] = "👒", + ["mortar_board"] = "🎓", + ["helmet_with_cross"] = "⛑️", + ["helmet_with_white_cross"] = "⛑️", + ["military_helmet"] = "🪖", + ["crown"] = "👑", + ["ring"] = "💍", + ["pouch"] = "👝", + ["purse"] = "👛", + ["handbag"] = "👜", + ["briefcase"] = "💼", + ["school_satchel"] = "🎒", + ["luggage"] = "🧳", + ["eyeglasses"] = "👓", + ["dark_sunglasses"] = "🕶️", + ["goggles"] = "🥽", + ["closed_umbrella"] = "🌂", + ["dog"] = "🐶", + ["cat"] = "🐱", + ["mouse"] = "🐭", + ["hamster"] = "🐹", + ["rabbit"] = "🐰", + ["fox"] = "🦊", + ["fox_face"] = "🦊", + ["bear"] = "🐻", + ["panda_face"] = "🐼", + ["polar_bear"] = "🐻‍❄️", + ["koala"] = "🐨", + ["tiger"] = "🐯", + ["lion_face"] = "🦁", + ["lion"] = "🦁", + ["cow"] = "🐮", + ["pig"] = "🐷", + ["pig_nose"] = "🐽", + ["frog"] = "🐸", + ["monkey_face"] = "🐵", + ["see_no_evil"] = "🙈", + ["hear_no_evil"] = "🙉", + ["speak_no_evil"] = "🙊", + ["monkey"] = "🐒", + ["chicken"] = "🐔", + ["penguin"] = "🐧", + ["bird"] = "🐦", + ["baby_chick"] = "🐤", + ["hatching_chick"] = "🐣", + ["hatched_chick"] = "🐥", + ["duck"] = "🦆", + ["dodo"] = "🦤", + ["eagle"] = "🦅", + ["owl"] = "🦉", + ["bat"] = "🦇", + ["wolf"] = "🐺", + ["boar"] = "🐗", + ["horse"] = "🐴", + ["unicorn"] = "🦄", + ["unicorn_face"] = "🦄", + ["bee"] = "🐝", + ["bug"] = "🐛", + ["butterfly"] = "🦋", + ["snail"] = "🐌", + ["worm"] = "🪱", + ["lady_beetle"] = "🐞", + ["ant"] = "🐜", + ["fly"] = "🪰", + ["mosquito"] = "🦟", + ["cockroach"] = "🪳", + ["beetle"] = "🪲", + ["cricket"] = "🦗", + ["spider"] = "🕷️", + ["spider_web"] = "🕸️", + ["scorpion"] = "🦂", + ["turtle"] = "🐢", + ["snake"] = "🐍", + ["lizard"] = "🦎", + ["t_rex"] = "🦖", + ["sauropod"] = "🦕", + ["octopus"] = "🐙", + ["squid"] = "🦑", + ["shrimp"] = "🦐", + ["lobster"] = "🦞", + ["crab"] = "🦀", + ["blowfish"] = "🐡", + ["tropical_fish"] = "🐠", + ["fish"] = "🐟", + ["seal"] = "🦭", + ["dolphin"] = "🐬", + ["whale"] = "🐳", + ["whale2"] = "🐋", + ["shark"] = "🦈", + ["crocodile"] = "🐊", + ["tiger2"] = "🐅", + ["leopard"] = "🐆", + ["zebra"] = "🦓", + ["gorilla"] = "🦍", + ["orangutan"] = "🦧", + ["elephant"] = "🐘", + ["mammoth"] = "🦣", + ["bison"] = "🦬", + ["hippopotamus"] = "🦛", + ["rhino"] = "🦏", + ["rhinoceros"] = "🦏", + ["dromedary_camel"] = "🐪", + ["camel"] = "🐫", + ["giraffe"] = "🦒", + ["kangaroo"] = "🦘", + ["water_buffalo"] = "🐃", + ["ox"] = "🐂", + ["cow2"] = "🐄", + ["racehorse"] = "🐎", + ["pig2"] = "🐖", + ["ram"] = "🐏", + ["sheep"] = "🐑", + ["llama"] = "🦙", + ["goat"] = "🐐", + ["deer"] = "🦌", + ["dog2"] = "🐕", + ["poodle"] = "🐩", + ["guide_dog"] = "🦮", + ["service_dog"] = "🐕‍🦺", + ["cat2"] = "🐈", + ["black_cat"] = "🐈‍⬛", + ["rooster"] = "🐓", + ["turkey"] = "🦃", + ["peacock"] = "🦚", + ["parrot"] = "🦜", + ["swan"] = "🦢", + ["flamingo"] = "🦩", + ["dove"] = "🕊️", + ["dove_of_peace"] = "🕊️", + ["rabbit2"] = "🐇", + ["raccoon"] = "🦝", + ["skunk"] = "🦨", + ["badger"] = "🦡", + ["beaver"] = "🦫", + ["otter"] = "🦦", + ["sloth"] = "🦥", + ["mouse2"] = "🐁", + ["rat"] = "🐀", + ["chipmunk"] = "🐿️", + ["hedgehog"] = "🦔", + ["feet"] = "🐾", + ["paw_prints"] = "🐾", + ["dragon"] = "🐉", + ["dragon_face"] = "🐲", + ["cactus"] = "🌵", + ["christmas_tree"] = "🎄", + ["evergreen_tree"] = "🌲", + ["deciduous_tree"] = "🌳", + ["palm_tree"] = "🌴", + ["seedling"] = "🌱", + ["herb"] = "🌿", + ["shamrock"] = "☘️", + ["four_leaf_clover"] = "🍀", + ["bamboo"] = "🎍", + ["tanabata_tree"] = "🎋", + ["leaves"] = "🍃", + ["fallen_leaf"] = "🍂", + ["maple_leaf"] = "🍁", + ["feather"] = "🪶", + ["mushroom"] = "🍄", + ["shell"] = "🐚", + ["rock"] = "🪨", + ["wood"] = "🪵", + ["ear_of_rice"] = "🌾", + ["potted_plant"] = "🪴", + ["bouquet"] = "💐", + ["tulip"] = "🌷", + ["rose"] = "🌹", + ["wilted_rose"] = "🥀", + ["wilted_flower"] = "🥀", + ["hibiscus"] = "🌺", + ["cherry_blossom"] = "🌸", + ["blossom"] = "🌼", + ["sunflower"] = "🌻", + ["sun_with_face"] = "🌞", + ["full_moon_with_face"] = "🌝", + ["first_quarter_moon_with_face"] = "🌛", + ["last_quarter_moon_with_face"] = "🌜", + ["new_moon_with_face"] = "🌚", + ["full_moon"] = "🌕", + ["waning_gibbous_moon"] = "🌖", + ["last_quarter_moon"] = "🌗", + ["waning_crescent_moon"] = "🌘", + ["new_moon"] = "🌑", + ["waxing_crescent_moon"] = "🌒", + ["first_quarter_moon"] = "🌓", + ["waxing_gibbous_moon"] = "🌔", + ["crescent_moon"] = "🌙", + ["earth_americas"] = "🌎", + ["earth_africa"] = "🌍", + ["earth_asia"] = "🌏", + ["ringed_planet"] = "🪐", + ["dizzy"] = "💫", + ["star"] = "⭐", + ["star2"] = "🌟", + ["sparkles"] = "✨", + ["zap"] = "⚡", + ["comet"] = "☄️", + ["boom"] = "💥", + ["fire"] = "🔥", + ["flame"] = "🔥", + ["cloud_tornado"] = "🌪️", + ["cloud_with_tornado"] = "🌪️", + ["rainbow"] = "🌈", + ["sunny"] = "☀️", + ["white_sun_small_cloud"] = "🌤️", + ["white_sun_with_small_cloud"] = "🌤️", + ["partly_sunny"] = "⛅", + ["white_sun_cloud"] = "🌥️", + ["white_sun_behind_cloud"] = "🌥️", + ["cloud"] = "☁️", + ["white_sun_rain_cloud"] = "🌦️", + ["white_sun_behind_cloud_with_rain"] = "🌦️", + ["cloud_rain"] = "🌧️", + ["cloud_with_rain"] = "🌧️", + ["thunder_cloud_rain"] = "⛈️", + ["thunder_cloud_and_rain"] = "⛈️", + ["cloud_lightning"] = "🌩️", + ["cloud_with_lightning"] = "🌩️", + ["cloud_snow"] = "🌨️", + ["cloud_with_snow"] = "🌨️", + ["snowflake"] = "❄️", + ["snowman2"] = "☃️", + ["snowman"] = "⛄", + ["wind_blowing_face"] = "🌬️", + ["dash"] = "💨", + ["droplet"] = "💧", + ["sweat_drops"] = "💦", + ["umbrella"] = "☔", + ["umbrella2"] = "☂️", + ["ocean"] = "🌊", + ["fog"] = "🌫️", + ["green_apple"] = "🍏", + ["apple"] = "🍎", + ["pear"] = "🍐", + ["tangerine"] = "🍊", + ["lemon"] = "🍋", + ["banana"] = "🍌", + ["watermelon"] = "🍉", + ["grapes"] = "🍇", + ["blueberries"] = "🫐", + ["strawberry"] = "🍓", + ["melon"] = "🍈", + ["cherries"] = "🍒", + ["peach"] = "🍑", + ["mango"] = "🥭", + ["pineapple"] = "🍍", + ["coconut"] = "🥥", + ["kiwi"] = "🥝", + ["kiwifruit"] = "🥝", + ["tomato"] = "🍅", + ["eggplant"] = "🍆", + ["avocado"] = "🥑", + ["olive"] = "🫒", + ["broccoli"] = "🥦", + ["leafy_green"] = "🥬", + ["bell_pepper"] = "🫑", + ["cucumber"] = "🥒", + ["hot_pepper"] = "🌶️", + ["corn"] = "🌽", + ["carrot"] = "🥕", + ["garlic"] = "🧄", + ["onion"] = "🧅", + ["potato"] = "🥔", + ["sweet_potato"] = "🍠", + ["croissant"] = "🥐", + ["bagel"] = "🥯", + ["bread"] = "🍞", + ["french_bread"] = "🥖", + ["baguette_bread"] = "🥖", + ["flatbread"] = "🫓", + ["pretzel"] = "🥨", + ["cheese"] = "🧀", + ["cheese_wedge"] = "🧀", + ["egg"] = "🥚", + ["cooking"] = "🍳", + ["butter"] = "🧈", + ["pancakes"] = "🥞", + ["waffle"] = "🧇", + ["bacon"] = "🥓", + ["cut_of_meat"] = "🥩", + ["poultry_leg"] = "🍗", + ["meat_on_bone"] = "🍖", + ["hotdog"] = "🌭", + ["hot_dog"] = "🌭", + ["hamburger"] = "🍔", + ["fries"] = "🍟", + ["pizza"] = "🍕", + ["sandwich"] = "🥪", + ["stuffed_flatbread"] = "🥙", + ["stuffed_pita"] = "🥙", + ["falafel"] = "🧆", + ["taco"] = "🌮", + ["burrito"] = "🌯", + ["tamale"] = "🫔", + ["salad"] = "🥗", + ["green_salad"] = "🥗", + ["shallow_pan_of_food"] = "🥘", + ["paella"] = "🥘", + ["fondue"] = "🫕", + ["canned_food"] = "🥫", + ["spaghetti"] = "🍝", + ["ramen"] = "🍜", + ["stew"] = "🍲", + ["curry"] = "🍛", + ["sushi"] = "🍣", + ["bento"] = "🍱", + ["dumpling"] = "🥟", + ["oyster"] = "🦪", + ["fried_shrimp"] = "🍤", + ["rice_ball"] = "🍙", + ["rice"] = "🍚", + ["rice_cracker"] = "🍘", + ["fish_cake"] = "🍥", + ["fortune_cookie"] = "🥠", + ["moon_cake"] = "🥮", + ["oden"] = "🍢", + ["dango"] = "🍡", + ["shaved_ice"] = "🍧", + ["ice_cream"] = "🍨", + ["icecream"] = "🍦", + ["pie"] = "🥧", + ["cupcake"] = "🧁", + ["cake"] = "🍰", + ["birthday"] = "🎂", + ["custard"] = "🍮", + ["pudding"] = "🍮", + ["flan"] = "🍮", + ["lollipop"] = "🍭", + ["candy"] = "🍬", + ["chocolate_bar"] = "🍫", + ["popcorn"] = "🍿", + ["doughnut"] = "🍩", + ["cookie"] = "🍪", + ["chestnut"] = "🌰", + ["peanuts"] = "🥜", + ["shelled_peanut"] = "🥜", + ["honey_pot"] = "🍯", + ["milk"] = "🥛", + ["glass_of_milk"] = "🥛", + ["baby_bottle"] = "🍼", + ["coffee"] = "☕", + ["tea"] = "🍵", + ["teapot"] = "🫖", + ["mate"] = "🧉", + ["bubble_tea"] = "🧋", + ["beverage_box"] = "🧃", + ["cup_with_straw"] = "🥤", + ["sake"] = "🍶", + ["beer"] = "🍺", + ["beers"] = "🍻", + ["champagne_glass"] = "🥂", + ["clinking_glass"] = "🥂", + ["wine_glass"] = "🍷", + ["tumbler_glass"] = "🥃", + ["whisky"] = "🥃", + ["cocktail"] = "🍸", + ["tropical_drink"] = "🍹", + ["champagne"] = "🍾", + ["bottle_with_popping_cork"] = "🍾", + ["ice_cube"] = "🧊", + ["spoon"] = "🥄", + ["fork_and_knife"] = "🍴", + ["fork_knife_plate"] = "🍽️", + ["fork_and_knife_with_plate"] = "🍽️", + ["bowl_with_spoon"] = "🥣", + ["takeout_box"] = "🥡", + ["chopsticks"] = "🥢", + ["salt"] = "🧂", + ["soccer"] = "⚽", + ["basketball"] = "🏀", + ["football"] = "🏈", + ["baseball"] = "⚾", + ["softball"] = "🥎", + ["tennis"] = "🎾", + ["volleyball"] = "🏐", + ["rugby_football"] = "🏉", + ["flying_disc"] = "🥏", + ["boomerang"] = "🪃", + ["8ball"] = "🎱", + ["yo_yo"] = "🪀", + ["ping_pong"] = "🏓", + ["table_tennis"] = "🏓", + ["badminton"] = "🏸", + ["hockey"] = "🏒", + ["field_hockey"] = "🏑", + ["lacrosse"] = "🥍", + ["cricket_game"] = "🏏", + ["cricket_bat_ball"] = "🏏", + ["goal"] = "🥅", + ["goal_net"] = "🥅", + ["golf"] = "⛳", + ["kite"] = "🪁", + ["bow_and_arrow"] = "🏹", + ["archery"] = "🏹", + ["fishing_pole_and_fish"] = "🎣", + ["diving_mask"] = "🤿", + ["boxing_glove"] = "🥊", + ["boxing_gloves"] = "🥊", + ["martial_arts_uniform"] = "🥋", + ["karate_uniform"] = "🥋", + ["running_shirt_with_sash"] = "🎽", + ["skateboard"] = "🛹", + ["roller_skate"] = "🛼", + ["sled"] = "🛷", + ["ice_skate"] = "⛸️", + ["curling_stone"] = "🥌", + ["ski"] = "🎿", + ["skier"] = "⛷️", + ["snowboarder"] = "🏂", + ["snowboarder_tone1"] = "🏂🏻", + ["snowboarder_light_skin_tone"] = "🏂🏻", + ["snowboarder_tone2"] = "🏂🏼", + ["snowboarder_medium_light_skin_tone"] = "🏂🏼", + ["snowboarder_tone3"] = "🏂🏽", + ["snowboarder_medium_skin_tone"] = "🏂🏽", + ["snowboarder_tone4"] = "🏂🏾", + ["snowboarder_medium_dark_skin_tone"] = "🏂🏾", + ["snowboarder_tone5"] = "🏂🏿", + ["snowboarder_dark_skin_tone"] = "🏂🏿", + ["parachute"] = "🪂", + ["person_lifting_weights"] = "🏋️", + ["lifter"] = "🏋️", + ["weight_lifter"] = "🏋️", + ["person_lifting_weights_tone1"] = "🏋🏻", + ["lifter_tone1"] = "🏋🏻", + ["weight_lifter_tone1"] = "🏋🏻", + ["person_lifting_weights_tone2"] = "🏋🏼", + ["lifter_tone2"] = "🏋🏼", + ["weight_lifter_tone2"] = "🏋🏼", + ["person_lifting_weights_tone3"] = "🏋🏽", + ["lifter_tone3"] = "🏋🏽", + ["weight_lifter_tone3"] = "🏋🏽", + ["person_lifting_weights_tone4"] = "🏋🏾", + ["lifter_tone4"] = "🏋🏾", + ["weight_lifter_tone4"] = "🏋🏾", + ["person_lifting_weights_tone5"] = "🏋🏿", + ["lifter_tone5"] = "🏋🏿", + ["weight_lifter_tone5"] = "🏋🏿", + ["woman_lifting_weights"] = "🏋️‍♀️", + ["woman_lifting_weights_tone1"] = "🏋🏻‍♀️", + ["woman_lifting_weights_light_skin_tone"] = "🏋🏻‍♀️", + ["woman_lifting_weights_tone2"] = "🏋🏼‍♀️", + ["woman_lifting_weights_medium_light_skin_tone"] = "🏋🏼‍♀️", + ["woman_lifting_weights_tone3"] = "🏋🏽‍♀️", + ["woman_lifting_weights_medium_skin_tone"] = "🏋🏽‍♀️", + ["woman_lifting_weights_tone4"] = "🏋🏾‍♀️", + ["woman_lifting_weights_medium_dark_skin_tone"] = "🏋🏾‍♀️", + ["woman_lifting_weights_tone5"] = "🏋🏿‍♀️", + ["woman_lifting_weights_dark_skin_tone"] = "🏋🏿‍♀️", + ["man_lifting_weights"] = "🏋️‍♂️", + ["man_lifting_weights_tone1"] = "🏋🏻‍♂️", + ["man_lifting_weights_light_skin_tone"] = "🏋🏻‍♂️", + ["man_lifting_weights_tone2"] = "🏋🏼‍♂️", + ["man_lifting_weights_medium_light_skin_tone"] = "🏋🏼‍♂️", + ["man_lifting_weights_tone3"] = "🏋🏽‍♂️", + ["man_lifting_weights_medium_skin_tone"] = "🏋🏽‍♂️", + ["man_lifting_weights_tone4"] = "🏋🏾‍♂️", + ["man_lifting_weights_medium_dark_skin_tone"] = "🏋🏾‍♂️", + ["man_lifting_weights_tone5"] = "🏋🏿‍♂️", + ["man_lifting_weights_dark_skin_tone"] = "🏋🏿‍♂️", + ["people_wrestling"] = "🤼", + ["wrestlers"] = "🤼", + ["wrestling"] = "🤼", + ["women_wrestling"] = "🤼‍♀️", + ["men_wrestling"] = "🤼‍♂️", + ["person_doing_cartwheel"] = "🤸", + ["cartwheel"] = "🤸", + ["person_doing_cartwheel_tone1"] = "🤸🏻", + ["cartwheel_tone1"] = "🤸🏻", + ["person_doing_cartwheel_tone2"] = "🤸🏼", + ["cartwheel_tone2"] = "🤸🏼", + ["person_doing_cartwheel_tone3"] = "🤸🏽", + ["cartwheel_tone3"] = "🤸🏽", + ["person_doing_cartwheel_tone4"] = "🤸🏾", + ["cartwheel_tone4"] = "🤸🏾", + ["person_doing_cartwheel_tone5"] = "🤸🏿", + ["cartwheel_tone5"] = "🤸🏿", + ["woman_cartwheeling"] = "🤸‍♀️", + ["woman_cartwheeling_tone1"] = "🤸🏻‍♀️", + ["woman_cartwheeling_light_skin_tone"] = "🤸🏻‍♀️", + ["woman_cartwheeling_tone2"] = "🤸🏼‍♀️", + ["woman_cartwheeling_medium_light_skin_tone"] = "🤸🏼‍♀️", + ["woman_cartwheeling_tone3"] = "🤸🏽‍♀️", + ["woman_cartwheeling_medium_skin_tone"] = "🤸🏽‍♀️", + ["woman_cartwheeling_tone4"] = "🤸🏾‍♀️", + ["woman_cartwheeling_medium_dark_skin_tone"] = "🤸🏾‍♀️", + ["woman_cartwheeling_tone5"] = "🤸🏿‍♀️", + ["woman_cartwheeling_dark_skin_tone"] = "🤸🏿‍♀️", + ["man_cartwheeling"] = "🤸‍♂️", + ["man_cartwheeling_tone1"] = "🤸🏻‍♂️", + ["man_cartwheeling_light_skin_tone"] = "🤸🏻‍♂️", + ["man_cartwheeling_tone2"] = "🤸🏼‍♂️", + ["man_cartwheeling_medium_light_skin_tone"] = "🤸🏼‍♂️", + ["man_cartwheeling_tone3"] = "🤸🏽‍♂️", + ["man_cartwheeling_medium_skin_tone"] = "🤸🏽‍♂️", + ["man_cartwheeling_tone4"] = "🤸🏾‍♂️", + ["man_cartwheeling_medium_dark_skin_tone"] = "🤸🏾‍♂️", + ["man_cartwheeling_tone5"] = "🤸🏿‍♂️", + ["man_cartwheeling_dark_skin_tone"] = "🤸🏿‍♂️", + ["person_bouncing_ball"] = "⛹️", + ["basketball_player"] = "⛹️", + ["person_with_ball"] = "⛹️", + ["person_bouncing_ball_tone1"] = "⛹🏻", + ["basketball_player_tone1"] = "⛹🏻", + ["person_with_ball_tone1"] = "⛹🏻", + ["person_bouncing_ball_tone2"] = "⛹🏼", + ["basketball_player_tone2"] = "⛹🏼", + ["person_with_ball_tone2"] = "⛹🏼", + ["person_bouncing_ball_tone3"] = "⛹🏽", + ["basketball_player_tone3"] = "⛹🏽", + ["person_with_ball_tone3"] = "⛹🏽", + ["person_bouncing_ball_tone4"] = "⛹🏾", + ["basketball_player_tone4"] = "⛹🏾", + ["person_with_ball_tone4"] = "⛹🏾", + ["person_bouncing_ball_tone5"] = "⛹🏿", + ["basketball_player_tone5"] = "⛹🏿", + ["person_with_ball_tone5"] = "⛹🏿", + ["woman_bouncing_ball"] = "⛹️‍♀️", + ["woman_bouncing_ball_tone1"] = "⛹🏻‍♀️", + ["woman_bouncing_ball_light_skin_tone"] = "⛹🏻‍♀️", + ["woman_bouncing_ball_tone2"] = "⛹🏼‍♀️", + ["woman_bouncing_ball_medium_light_skin_tone"] = "⛹🏼‍♀️", + ["woman_bouncing_ball_tone3"] = "⛹🏽‍♀️", + ["woman_bouncing_ball_medium_skin_tone"] = "⛹🏽‍♀️", + ["woman_bouncing_ball_tone4"] = "⛹🏾‍♀️", + ["woman_bouncing_ball_medium_dark_skin_tone"] = "⛹🏾‍♀️", + ["woman_bouncing_ball_tone5"] = "⛹🏿‍♀️", + ["woman_bouncing_ball_dark_skin_tone"] = "⛹🏿‍♀️", + ["man_bouncing_ball"] = "⛹️‍♂️", + ["man_bouncing_ball_tone1"] = "⛹🏻‍♂️", + ["man_bouncing_ball_light_skin_tone"] = "⛹🏻‍♂️", + ["man_bouncing_ball_tone2"] = "⛹🏼‍♂️", + ["man_bouncing_ball_medium_light_skin_tone"] = "⛹🏼‍♂️", + ["man_bouncing_ball_tone3"] = "⛹🏽‍♂️", + ["man_bouncing_ball_medium_skin_tone"] = "⛹🏽‍♂️", + ["man_bouncing_ball_tone4"] = "⛹🏾‍♂️", + ["man_bouncing_ball_medium_dark_skin_tone"] = "⛹🏾‍♂️", + ["man_bouncing_ball_tone5"] = "⛹🏿‍♂️", + ["man_bouncing_ball_dark_skin_tone"] = "⛹🏿‍♂️", + ["person_fencing"] = "🤺", + ["fencer"] = "🤺", + ["fencing"] = "🤺", + ["person_playing_handball"] = "🤾", + ["handball"] = "🤾", + ["person_playing_handball_tone1"] = "🤾🏻", + ["handball_tone1"] = "🤾🏻", + ["person_playing_handball_tone2"] = "🤾🏼", + ["handball_tone2"] = "🤾🏼", + ["person_playing_handball_tone3"] = "🤾🏽", + ["handball_tone3"] = "🤾🏽", + ["person_playing_handball_tone4"] = "🤾🏾", + ["handball_tone4"] = "🤾🏾", + ["person_playing_handball_tone5"] = "🤾🏿", + ["handball_tone5"] = "🤾🏿", + ["woman_playing_handball"] = "🤾‍♀️", + ["woman_playing_handball_tone1"] = "🤾🏻‍♀️", + ["woman_playing_handball_light_skin_tone"] = "🤾🏻‍♀️", + ["woman_playing_handball_tone2"] = "🤾🏼‍♀️", + ["woman_playing_handball_medium_light_skin_tone"] = "🤾🏼‍♀️", + ["woman_playing_handball_tone3"] = "🤾🏽‍♀️", + ["woman_playing_handball_medium_skin_tone"] = "🤾🏽‍♀️", + ["woman_playing_handball_tone4"] = "🤾🏾‍♀️", + ["woman_playing_handball_medium_dark_skin_tone"] = "🤾🏾‍♀️", + ["woman_playing_handball_tone5"] = "🤾🏿‍♀️", + ["woman_playing_handball_dark_skin_tone"] = "🤾🏿‍♀️", + ["man_playing_handball"] = "🤾‍♂️", + ["man_playing_handball_tone1"] = "🤾🏻‍♂️", + ["man_playing_handball_light_skin_tone"] = "🤾🏻‍♂️", + ["man_playing_handball_tone2"] = "🤾🏼‍♂️", + ["man_playing_handball_medium_light_skin_tone"] = "🤾🏼‍♂️", + ["man_playing_handball_tone3"] = "🤾🏽‍♂️", + ["man_playing_handball_medium_skin_tone"] = "🤾🏽‍♂️", + ["man_playing_handball_tone4"] = "🤾🏾‍♂️", + ["man_playing_handball_medium_dark_skin_tone"] = "🤾🏾‍♂️", + ["man_playing_handball_tone5"] = "🤾🏿‍♂️", + ["man_playing_handball_dark_skin_tone"] = "🤾🏿‍♂️", + ["person_golfing"] = "🏌️", + ["golfer"] = "🏌️", + ["person_golfing_tone1"] = "🏌🏻", + ["person_golfing_light_skin_tone"] = "🏌🏻", + ["person_golfing_tone2"] = "🏌🏼", + ["person_golfing_medium_light_skin_tone"] = "🏌🏼", + ["person_golfing_tone3"] = "🏌🏽", + ["person_golfing_medium_skin_tone"] = "🏌🏽", + ["person_golfing_tone4"] = "🏌🏾", + ["person_golfing_medium_dark_skin_tone"] = "🏌🏾", + ["person_golfing_tone5"] = "🏌🏿", + ["person_golfing_dark_skin_tone"] = "🏌🏿", + ["woman_golfing"] = "🏌️‍♀️", + ["woman_golfing_tone1"] = "🏌🏻‍♀️", + ["woman_golfing_light_skin_tone"] = "🏌🏻‍♀️", + ["woman_golfing_tone2"] = "🏌🏼‍♀️", + ["woman_golfing_medium_light_skin_tone"] = "🏌🏼‍♀️", + ["woman_golfing_tone3"] = "🏌🏽‍♀️", + ["woman_golfing_medium_skin_tone"] = "🏌🏽‍♀️", + ["woman_golfing_tone4"] = "🏌🏾‍♀️", + ["woman_golfing_medium_dark_skin_tone"] = "🏌🏾‍♀️", + ["woman_golfing_tone5"] = "🏌🏿‍♀️", + ["woman_golfing_dark_skin_tone"] = "🏌🏿‍♀️", + ["man_golfing"] = "🏌️‍♂️", + ["man_golfing_tone1"] = "🏌🏻‍♂️", + ["man_golfing_light_skin_tone"] = "🏌🏻‍♂️", + ["man_golfing_tone2"] = "🏌🏼‍♂️", + ["man_golfing_medium_light_skin_tone"] = "🏌🏼‍♂️", + ["man_golfing_tone3"] = "🏌🏽‍♂️", + ["man_golfing_medium_skin_tone"] = "🏌🏽‍♂️", + ["man_golfing_tone4"] = "🏌🏾‍♂️", + ["man_golfing_medium_dark_skin_tone"] = "🏌🏾‍♂️", + ["man_golfing_tone5"] = "🏌🏿‍♂️", + ["man_golfing_dark_skin_tone"] = "🏌🏿‍♂️", + ["horse_racing"] = "🏇", + ["horse_racing_tone1"] = "🏇🏻", + ["horse_racing_tone2"] = "🏇🏼", + ["horse_racing_tone3"] = "🏇🏽", + ["horse_racing_tone4"] = "🏇🏾", + ["horse_racing_tone5"] = "🏇🏿", + ["person_in_lotus_position"] = "🧘", + ["person_in_lotus_position_tone1"] = "🧘🏻", + ["person_in_lotus_position_light_skin_tone"] = "🧘🏻", + ["person_in_lotus_position_tone2"] = "🧘🏼", + ["person_in_lotus_position_medium_light_skin_tone"] = "🧘🏼", + ["person_in_lotus_position_tone3"] = "🧘🏽", + ["person_in_lotus_position_medium_skin_tone"] = "🧘🏽", + ["person_in_lotus_position_tone4"] = "🧘🏾", + ["person_in_lotus_position_medium_dark_skin_tone"] = "🧘🏾", + ["person_in_lotus_position_tone5"] = "🧘🏿", + ["person_in_lotus_position_dark_skin_tone"] = "🧘🏿", + ["woman_in_lotus_position"] = "🧘‍♀️", + ["woman_in_lotus_position_tone1"] = "🧘🏻‍♀️", + ["woman_in_lotus_position_light_skin_tone"] = "🧘🏻‍♀️", + ["woman_in_lotus_position_tone2"] = "🧘🏼‍♀️", + ["woman_in_lotus_position_medium_light_skin_tone"] = "🧘🏼‍♀️", + ["woman_in_lotus_position_tone3"] = "🧘🏽‍♀️", + ["woman_in_lotus_position_medium_skin_tone"] = "🧘🏽‍♀️", + ["woman_in_lotus_position_tone4"] = "🧘🏾‍♀️", + ["woman_in_lotus_position_medium_dark_skin_tone"] = "🧘🏾‍♀️", + ["woman_in_lotus_position_tone5"] = "🧘🏿‍♀️", + ["woman_in_lotus_position_dark_skin_tone"] = "🧘🏿‍♀️", + ["man_in_lotus_position"] = "🧘‍♂️", + ["man_in_lotus_position_tone1"] = "🧘🏻‍♂️", + ["man_in_lotus_position_light_skin_tone"] = "🧘🏻‍♂️", + ["man_in_lotus_position_tone2"] = "🧘🏼‍♂️", + ["man_in_lotus_position_medium_light_skin_tone"] = "🧘🏼‍♂️", + ["man_in_lotus_position_tone3"] = "🧘🏽‍♂️", + ["man_in_lotus_position_medium_skin_tone"] = "🧘🏽‍♂️", + ["man_in_lotus_position_tone4"] = "🧘🏾‍♂️", + ["man_in_lotus_position_medium_dark_skin_tone"] = "🧘🏾‍♂️", + ["man_in_lotus_position_tone5"] = "🧘🏿‍♂️", + ["man_in_lotus_position_dark_skin_tone"] = "🧘🏿‍♂️", + ["person_surfing"] = "🏄", + ["surfer"] = "🏄", + ["person_surfing_tone1"] = "🏄🏻", + ["surfer_tone1"] = "🏄🏻", + ["person_surfing_tone2"] = "🏄🏼", + ["surfer_tone2"] = "🏄🏼", + ["person_surfing_tone3"] = "🏄🏽", + ["surfer_tone3"] = "🏄🏽", + ["person_surfing_tone4"] = "🏄🏾", + ["surfer_tone4"] = "🏄🏾", + ["person_surfing_tone5"] = "🏄🏿", + ["surfer_tone5"] = "🏄🏿", + ["woman_surfing"] = "🏄‍♀️", + ["woman_surfing_tone1"] = "🏄🏻‍♀️", + ["woman_surfing_light_skin_tone"] = "🏄🏻‍♀️", + ["woman_surfing_tone2"] = "🏄🏼‍♀️", + ["woman_surfing_medium_light_skin_tone"] = "🏄🏼‍♀️", + ["woman_surfing_tone3"] = "🏄🏽‍♀️", + ["woman_surfing_medium_skin_tone"] = "🏄🏽‍♀️", + ["woman_surfing_tone4"] = "🏄🏾‍♀️", + ["woman_surfing_medium_dark_skin_tone"] = "🏄🏾‍♀️", + ["woman_surfing_tone5"] = "🏄🏿‍♀️", + ["woman_surfing_dark_skin_tone"] = "🏄🏿‍♀️", + ["man_surfing"] = "🏄‍♂️", + ["man_surfing_tone1"] = "🏄🏻‍♂️", + ["man_surfing_light_skin_tone"] = "🏄🏻‍♂️", + ["man_surfing_tone2"] = "🏄🏼‍♂️", + ["man_surfing_medium_light_skin_tone"] = "🏄🏼‍♂️", + ["man_surfing_tone3"] = "🏄🏽‍♂️", + ["man_surfing_medium_skin_tone"] = "🏄🏽‍♂️", + ["man_surfing_tone4"] = "🏄🏾‍♂️", + ["man_surfing_medium_dark_skin_tone"] = "🏄🏾‍♂️", + ["man_surfing_tone5"] = "🏄🏿‍♂️", + ["man_surfing_dark_skin_tone"] = "🏄🏿‍♂️", + ["person_swimming"] = "🏊", + ["swimmer"] = "🏊", + ["person_swimming_tone1"] = "🏊🏻", + ["swimmer_tone1"] = "🏊🏻", + ["person_swimming_tone2"] = "🏊🏼", + ["swimmer_tone2"] = "🏊🏼", + ["person_swimming_tone3"] = "🏊🏽", + ["swimmer_tone3"] = "🏊🏽", + ["person_swimming_tone4"] = "🏊🏾", + ["swimmer_tone4"] = "🏊🏾", + ["person_swimming_tone5"] = "🏊🏿", + ["swimmer_tone5"] = "🏊🏿", + ["woman_swimming"] = "🏊‍♀️", + ["woman_swimming_tone1"] = "🏊🏻‍♀️", + ["woman_swimming_light_skin_tone"] = "🏊🏻‍♀️", + ["woman_swimming_tone2"] = "🏊🏼‍♀️", + ["woman_swimming_medium_light_skin_tone"] = "🏊🏼‍♀️", + ["woman_swimming_tone3"] = "🏊🏽‍♀️", + ["woman_swimming_medium_skin_tone"] = "🏊🏽‍♀️", + ["woman_swimming_tone4"] = "🏊🏾‍♀️", + ["woman_swimming_medium_dark_skin_tone"] = "🏊🏾‍♀️", + ["woman_swimming_tone5"] = "🏊🏿‍♀️", + ["woman_swimming_dark_skin_tone"] = "🏊🏿‍♀️", + ["man_swimming"] = "🏊‍♂️", + ["man_swimming_tone1"] = "🏊🏻‍♂️", + ["man_swimming_light_skin_tone"] = "🏊🏻‍♂️", + ["man_swimming_tone2"] = "🏊🏼‍♂️", + ["man_swimming_medium_light_skin_tone"] = "🏊🏼‍♂️", + ["man_swimming_tone3"] = "🏊🏽‍♂️", + ["man_swimming_medium_skin_tone"] = "🏊🏽‍♂️", + ["man_swimming_tone4"] = "🏊🏾‍♂️", + ["man_swimming_medium_dark_skin_tone"] = "🏊🏾‍♂️", + ["man_swimming_tone5"] = "🏊🏿‍♂️", + ["man_swimming_dark_skin_tone"] = "🏊🏿‍♂️", + ["person_playing_water_polo"] = "🤽", + ["water_polo"] = "🤽", + ["person_playing_water_polo_tone1"] = "🤽🏻", + ["water_polo_tone1"] = "🤽🏻", + ["person_playing_water_polo_tone2"] = "🤽🏼", + ["water_polo_tone2"] = "🤽🏼", + ["person_playing_water_polo_tone3"] = "🤽🏽", + ["water_polo_tone3"] = "🤽🏽", + ["person_playing_water_polo_tone4"] = "🤽🏾", + ["water_polo_tone4"] = "🤽🏾", + ["person_playing_water_polo_tone5"] = "🤽🏿", + ["water_polo_tone5"] = "🤽🏿", + ["woman_playing_water_polo"] = "🤽‍♀️", + ["woman_playing_water_polo_tone1"] = "🤽🏻‍♀️", + ["woman_playing_water_polo_light_skin_tone"] = "🤽🏻‍♀️", + ["woman_playing_water_polo_tone2"] = "🤽🏼‍♀️", + ["woman_playing_water_polo_medium_light_skin_tone"] = "🤽🏼‍♀️", + ["woman_playing_water_polo_tone3"] = "🤽🏽‍♀️", + ["woman_playing_water_polo_medium_skin_tone"] = "🤽🏽‍♀️", + ["woman_playing_water_polo_tone4"] = "🤽🏾‍♀️", + ["woman_playing_water_polo_medium_dark_skin_tone"] = "🤽🏾‍♀️", + ["woman_playing_water_polo_tone5"] = "🤽🏿‍♀️", + ["woman_playing_water_polo_dark_skin_tone"] = "🤽🏿‍♀️", + ["man_playing_water_polo"] = "🤽‍♂️", + ["man_playing_water_polo_tone1"] = "🤽🏻‍♂️", + ["man_playing_water_polo_light_skin_tone"] = "🤽🏻‍♂️", + ["man_playing_water_polo_tone2"] = "🤽🏼‍♂️", + ["man_playing_water_polo_medium_light_skin_tone"] = "🤽🏼‍♂️", + ["man_playing_water_polo_tone3"] = "🤽🏽‍♂️", + ["man_playing_water_polo_medium_skin_tone"] = "🤽🏽‍♂️", + ["man_playing_water_polo_tone4"] = "🤽🏾‍♂️", + ["man_playing_water_polo_medium_dark_skin_tone"] = "🤽🏾‍♂️", + ["man_playing_water_polo_tone5"] = "🤽🏿‍♂️", + ["man_playing_water_polo_dark_skin_tone"] = "🤽🏿‍♂️", + ["person_rowing_boat"] = "🚣", + ["rowboat"] = "🚣", + ["person_rowing_boat_tone1"] = "🚣🏻", + ["rowboat_tone1"] = "🚣🏻", + ["person_rowing_boat_tone2"] = "🚣🏼", + ["rowboat_tone2"] = "🚣🏼", + ["person_rowing_boat_tone3"] = "🚣🏽", + ["rowboat_tone3"] = "🚣🏽", + ["person_rowing_boat_tone4"] = "🚣🏾", + ["rowboat_tone4"] = "🚣🏾", + ["person_rowing_boat_tone5"] = "🚣🏿", + ["rowboat_tone5"] = "🚣🏿", + ["woman_rowing_boat"] = "🚣‍♀️", + ["woman_rowing_boat_tone1"] = "🚣🏻‍♀️", + ["woman_rowing_boat_light_skin_tone"] = "🚣🏻‍♀️", + ["woman_rowing_boat_tone2"] = "🚣🏼‍♀️", + ["woman_rowing_boat_medium_light_skin_tone"] = "🚣🏼‍♀️", + ["woman_rowing_boat_tone3"] = "🚣🏽‍♀️", + ["woman_rowing_boat_medium_skin_tone"] = "🚣🏽‍♀️", + ["woman_rowing_boat_tone4"] = "🚣🏾‍♀️", + ["woman_rowing_boat_medium_dark_skin_tone"] = "🚣🏾‍♀️", + ["woman_rowing_boat_tone5"] = "🚣🏿‍♀️", + ["woman_rowing_boat_dark_skin_tone"] = "🚣🏿‍♀️", + ["man_rowing_boat"] = "🚣‍♂️", + ["man_rowing_boat_tone1"] = "🚣🏻‍♂️", + ["man_rowing_boat_light_skin_tone"] = "🚣🏻‍♂️", + ["man_rowing_boat_tone2"] = "🚣🏼‍♂️", + ["man_rowing_boat_medium_light_skin_tone"] = "🚣🏼‍♂️", + ["man_rowing_boat_tone3"] = "🚣🏽‍♂️", + ["man_rowing_boat_medium_skin_tone"] = "🚣🏽‍♂️", + ["man_rowing_boat_tone4"] = "🚣🏾‍♂️", + ["man_rowing_boat_medium_dark_skin_tone"] = "🚣🏾‍♂️", + ["man_rowing_boat_tone5"] = "🚣🏿‍♂️", + ["man_rowing_boat_dark_skin_tone"] = "🚣🏿‍♂️", + ["person_climbing"] = "🧗", + ["person_climbing_tone1"] = "🧗🏻", + ["person_climbing_light_skin_tone"] = "🧗🏻", + ["person_climbing_tone2"] = "🧗🏼", + ["person_climbing_medium_light_skin_tone"] = "🧗🏼", + ["person_climbing_tone3"] = "🧗🏽", + ["person_climbing_medium_skin_tone"] = "🧗🏽", + ["person_climbing_tone4"] = "🧗🏾", + ["person_climbing_medium_dark_skin_tone"] = "🧗🏾", + ["person_climbing_tone5"] = "🧗🏿", + ["person_climbing_dark_skin_tone"] = "🧗🏿", + ["woman_climbing"] = "🧗‍♀️", + ["woman_climbing_tone1"] = "🧗🏻‍♀️", + ["woman_climbing_light_skin_tone"] = "🧗🏻‍♀️", + ["woman_climbing_tone2"] = "🧗🏼‍♀️", + ["woman_climbing_medium_light_skin_tone"] = "🧗🏼‍♀️", + ["woman_climbing_tone3"] = "🧗🏽‍♀️", + ["woman_climbing_medium_skin_tone"] = "🧗🏽‍♀️", + ["woman_climbing_tone4"] = "🧗🏾‍♀️", + ["woman_climbing_medium_dark_skin_tone"] = "🧗🏾‍♀️", + ["woman_climbing_tone5"] = "🧗🏿‍♀️", + ["woman_climbing_dark_skin_tone"] = "🧗🏿‍♀️", + ["man_climbing"] = "🧗‍♂️", + ["man_climbing_tone1"] = "🧗🏻‍♂️", + ["man_climbing_light_skin_tone"] = "🧗🏻‍♂️", + ["man_climbing_tone2"] = "🧗🏼‍♂️", + ["man_climbing_medium_light_skin_tone"] = "🧗🏼‍♂️", + ["man_climbing_tone3"] = "🧗🏽‍♂️", + ["man_climbing_medium_skin_tone"] = "🧗🏽‍♂️", + ["man_climbing_tone4"] = "🧗🏾‍♂️", + ["man_climbing_medium_dark_skin_tone"] = "🧗🏾‍♂️", + ["man_climbing_tone5"] = "🧗🏿‍♂️", + ["man_climbing_dark_skin_tone"] = "🧗🏿‍♂️", + ["person_mountain_biking"] = "🚵", + ["mountain_bicyclist"] = "🚵", + ["person_mountain_biking_tone1"] = "🚵🏻", + ["mountain_bicyclist_tone1"] = "🚵🏻", + ["person_mountain_biking_tone2"] = "🚵🏼", + ["mountain_bicyclist_tone2"] = "🚵🏼", + ["person_mountain_biking_tone3"] = "🚵🏽", + ["mountain_bicyclist_tone3"] = "🚵🏽", + ["person_mountain_biking_tone4"] = "🚵🏾", + ["mountain_bicyclist_tone4"] = "🚵🏾", + ["person_mountain_biking_tone5"] = "🚵🏿", + ["mountain_bicyclist_tone5"] = "🚵🏿", + ["woman_mountain_biking"] = "🚵‍♀️", + ["woman_mountain_biking_tone1"] = "🚵🏻‍♀️", + ["woman_mountain_biking_light_skin_tone"] = "🚵🏻‍♀️", + ["woman_mountain_biking_tone2"] = "🚵🏼‍♀️", + ["woman_mountain_biking_medium_light_skin_tone"] = "🚵🏼‍♀️", + ["woman_mountain_biking_tone3"] = "🚵🏽‍♀️", + ["woman_mountain_biking_medium_skin_tone"] = "🚵🏽‍♀️", + ["woman_mountain_biking_tone4"] = "🚵🏾‍♀️", + ["woman_mountain_biking_medium_dark_skin_tone"] = "🚵🏾‍♀️", + ["woman_mountain_biking_tone5"] = "🚵🏿‍♀️", + ["woman_mountain_biking_dark_skin_tone"] = "🚵🏿‍♀️", + ["man_mountain_biking"] = "🚵‍♂️", + ["man_mountain_biking_tone1"] = "🚵🏻‍♂️", + ["man_mountain_biking_light_skin_tone"] = "🚵🏻‍♂️", + ["man_mountain_biking_tone2"] = "🚵🏼‍♂️", + ["man_mountain_biking_medium_light_skin_tone"] = "🚵🏼‍♂️", + ["man_mountain_biking_tone3"] = "🚵🏽‍♂️", + ["man_mountain_biking_medium_skin_tone"] = "🚵🏽‍♂️", + ["man_mountain_biking_tone4"] = "🚵🏾‍♂️", + ["man_mountain_biking_medium_dark_skin_tone"] = "🚵🏾‍♂️", + ["man_mountain_biking_tone5"] = "🚵🏿‍♂️", + ["man_mountain_biking_dark_skin_tone"] = "🚵🏿‍♂️", + ["person_biking"] = "🚴", + ["bicyclist"] = "🚴", + ["person_biking_tone1"] = "🚴🏻", + ["bicyclist_tone1"] = "🚴🏻", + ["person_biking_tone2"] = "🚴🏼", + ["bicyclist_tone2"] = "🚴🏼", + ["person_biking_tone3"] = "🚴🏽", + ["bicyclist_tone3"] = "🚴🏽", + ["person_biking_tone4"] = "🚴🏾", + ["bicyclist_tone4"] = "🚴🏾", + ["person_biking_tone5"] = "🚴🏿", + ["bicyclist_tone5"] = "🚴🏿", + ["woman_biking"] = "🚴‍♀️", + ["woman_biking_tone1"] = "🚴🏻‍♀️", + ["woman_biking_light_skin_tone"] = "🚴🏻‍♀️", + ["woman_biking_tone2"] = "🚴🏼‍♀️", + ["woman_biking_medium_light_skin_tone"] = "🚴🏼‍♀️", + ["woman_biking_tone3"] = "🚴🏽‍♀️", + ["woman_biking_medium_skin_tone"] = "🚴🏽‍♀️", + ["woman_biking_tone4"] = "🚴🏾‍♀️", + ["woman_biking_medium_dark_skin_tone"] = "🚴🏾‍♀️", + ["woman_biking_tone5"] = "🚴🏿‍♀️", + ["woman_biking_dark_skin_tone"] = "🚴🏿‍♀️", + ["man_biking"] = "🚴‍♂️", + ["man_biking_tone1"] = "🚴🏻‍♂️", + ["man_biking_light_skin_tone"] = "🚴🏻‍♂️", + ["man_biking_tone2"] = "🚴🏼‍♂️", + ["man_biking_medium_light_skin_tone"] = "🚴🏼‍♂️", + ["man_biking_tone3"] = "🚴🏽‍♂️", + ["man_biking_medium_skin_tone"] = "🚴🏽‍♂️", + ["man_biking_tone4"] = "🚴🏾‍♂️", + ["man_biking_medium_dark_skin_tone"] = "🚴🏾‍♂️", + ["man_biking_tone5"] = "🚴🏿‍♂️", + ["man_biking_dark_skin_tone"] = "🚴🏿‍♂️", + ["trophy"] = "🏆", + ["first_place"] = "🥇", + ["first_place_medal"] = "🥇", + ["second_place"] = "🥈", + ["second_place_medal"] = "🥈", + ["third_place"] = "🥉", + ["third_place_medal"] = "🥉", + ["medal"] = "🏅", + ["sports_medal"] = "🏅", + ["military_medal"] = "🎖️", + ["rosette"] = "🏵️", + ["reminder_ribbon"] = "🎗️", + ["ticket"] = "🎫", + ["tickets"] = "🎟️", + ["admission_tickets"] = "🎟️", + ["circus_tent"] = "🎪", + ["person_juggling"] = "🤹", + ["juggling"] = "🤹", + ["juggler"] = "🤹", + ["person_juggling_tone1"] = "🤹🏻", + ["juggling_tone1"] = "🤹🏻", + ["juggler_tone1"] = "🤹🏻", + ["person_juggling_tone2"] = "🤹🏼", + ["juggling_tone2"] = "🤹🏼", + ["juggler_tone2"] = "🤹🏼", + ["person_juggling_tone3"] = "🤹🏽", + ["juggling_tone3"] = "🤹🏽", + ["juggler_tone3"] = "🤹🏽", + ["person_juggling_tone4"] = "🤹🏾", + ["juggling_tone4"] = "🤹🏾", + ["juggler_tone4"] = "🤹🏾", + ["person_juggling_tone5"] = "🤹🏿", + ["juggling_tone5"] = "🤹🏿", + ["juggler_tone5"] = "🤹🏿", + ["woman_juggling"] = "🤹‍♀️", + ["woman_juggling_tone1"] = "🤹🏻‍♀️", + ["woman_juggling_light_skin_tone"] = "🤹🏻‍♀️", + ["woman_juggling_tone2"] = "🤹🏼‍♀️", + ["woman_juggling_medium_light_skin_tone"] = "🤹🏼‍♀️", + ["woman_juggling_tone3"] = "🤹🏽‍♀️", + ["woman_juggling_medium_skin_tone"] = "🤹🏽‍♀️", + ["woman_juggling_tone4"] = "🤹🏾‍♀️", + ["woman_juggling_medium_dark_skin_tone"] = "🤹🏾‍♀️", + ["woman_juggling_tone5"] = "🤹🏿‍♀️", + ["woman_juggling_dark_skin_tone"] = "🤹🏿‍♀️", + ["man_juggling"] = "🤹‍♂️", + ["man_juggling_tone1"] = "🤹🏻‍♂️", + ["man_juggling_light_skin_tone"] = "🤹🏻‍♂️", + ["man_juggling_tone2"] = "🤹🏼‍♂️", + ["man_juggling_medium_light_skin_tone"] = "🤹🏼‍♂️", + ["man_juggling_tone3"] = "🤹🏽‍♂️", + ["man_juggling_medium_skin_tone"] = "🤹🏽‍♂️", + ["man_juggling_tone4"] = "🤹🏾‍♂️", + ["man_juggling_medium_dark_skin_tone"] = "🤹🏾‍♂️", + ["man_juggling_tone5"] = "🤹🏿‍♂️", + ["man_juggling_dark_skin_tone"] = "🤹🏿‍♂️", + ["performing_arts"] = "🎭", + ["ballet_shoes"] = "🩰", + ["art"] = "🎨", + ["clapper"] = "🎬", + ["microphone"] = "🎤", + ["headphones"] = "🎧", + ["musical_score"] = "🎼", + ["musical_keyboard"] = "🎹", + ["drum"] = "🥁", + ["drum_with_drumsticks"] = "🥁", + ["long_drum"] = "🪘", + ["saxophone"] = "🎷", + ["trumpet"] = "🎺", + ["guitar"] = "🎸", + ["banjo"] = "🪕", + ["violin"] = "🎻", + ["accordion"] = "🪗", + ["game_die"] = "🎲", + ["chess_pawn"] = "♟️", + ["dart"] = "🎯", + ["bowling"] = "🎳", + ["video_game"] = "🎮", + ["slot_machine"] = "🎰", + ["jigsaw"] = "🧩", + ["red_car"] = "🚗", + ["taxi"] = "🚕", + ["blue_car"] = "🚙", + ["pickup_truck"] = "🛻", + ["bus"] = "🚌", + ["trolleybus"] = "🚎", + ["race_car"] = "🏎️", + ["racing_car"] = "🏎️", + ["police_car"] = "🚓", + ["ambulance"] = "🚑", + ["fire_engine"] = "🚒", + ["minibus"] = "🚐", + ["truck"] = "🚚", + ["articulated_lorry"] = "🚛", + ["tractor"] = "🚜", + ["probing_cane"] = "🦯", + ["manual_wheelchair"] = "🦽", + ["motorized_wheelchair"] = "🦼", + ["scooter"] = "🛴", + ["bike"] = "🚲", + ["motor_scooter"] = "🛵", + ["motorbike"] = "🛵", + ["motorcycle"] = "🏍️", + ["racing_motorcycle"] = "🏍️", + ["auto_rickshaw"] = "🛺", + ["rotating_light"] = "🚨", + ["oncoming_police_car"] = "🚔", + ["oncoming_bus"] = "🚍", + ["oncoming_automobile"] = "🚘", + ["oncoming_taxi"] = "🚖", + ["aerial_tramway"] = "🚡", + ["mountain_cableway"] = "🚠", + ["suspension_railway"] = "🚟", + ["railway_car"] = "🚃", + ["train"] = "🚋", + ["mountain_railway"] = "🚞", + ["monorail"] = "🚝", + ["bullettrain_side"] = "🚄", + ["bullettrain_front"] = "🚅", + ["light_rail"] = "🚈", + ["steam_locomotive"] = "🚂", + ["train2"] = "🚆", + ["metro"] = "🚇", + ["tram"] = "🚊", + ["station"] = "🚉", + ["airplane"] = "✈️", + ["airplane_departure"] = "🛫", + ["airplane_arriving"] = "🛬", + ["airplane_small"] = "🛩️", + ["small_airplane"] = "🛩️", + ["seat"] = "💺", + ["satellite_orbital"] = "🛰️", + ["rocket"] = "🚀", + ["flying_saucer"] = "🛸", + ["helicopter"] = "🚁", + ["canoe"] = "🛶", + ["kayak"] = "🛶", + ["sailboat"] = "⛵", + ["speedboat"] = "🚤", + ["motorboat"] = "🛥️", + ["cruise_ship"] = "🛳️", + ["passenger_ship"] = "🛳️", + ["ferry"] = "⛴️", + ["ship"] = "🚢", + ["anchor"] = "⚓", + ["fuelpump"] = "⛽", + ["construction"] = "🚧", + ["vertical_traffic_light"] = "🚦", + ["traffic_light"] = "🚥", + ["busstop"] = "🚏", + ["map"] = "🗺️", + ["world_map"] = "🗺️", + ["moyai"] = "🗿", + ["statue_of_liberty"] = "🗽", + ["tokyo_tower"] = "🗼", + ["european_castle"] = "🏰", + ["japanese_castle"] = "🏯", + ["stadium"] = "🏟️", + ["ferris_wheel"] = "🎡", + ["roller_coaster"] = "🎢", + ["carousel_horse"] = "🎠", + ["fountain"] = "⛲", + ["beach_umbrella"] = "⛱️", + ["umbrella_on_ground"] = "⛱️", + ["beach"] = "🏖️", + ["beach_with_umbrella"] = "🏖️", + ["island"] = "🏝️", + ["desert_island"] = "🏝️", + ["desert"] = "🏜️", + ["volcano"] = "🌋", + ["mountain"] = "⛰️", + ["mountain_snow"] = "🏔️", + ["snow_capped_mountain"] = "🏔️", + ["mount_fuji"] = "🗻", + ["camping"] = "🏕️", + ["tent"] = "⛺", + ["house"] = "🏠", + ["house_with_garden"] = "🏡", + ["homes"] = "🏘️", + ["house_buildings"] = "🏘️", + ["house_abandoned"] = "🏚️", + ["derelict_house_building"] = "🏚️", + ["hut"] = "🛖", + ["construction_site"] = "🏗️", + ["building_construction"] = "🏗️", + ["factory"] = "🏭", + ["office"] = "🏢", + ["department_store"] = "🏬", + ["post_office"] = "🏣", + ["european_post_office"] = "🏤", + ["hospital"] = "🏥", + ["bank"] = "🏦", + ["hotel"] = "🏨", + ["convenience_store"] = "🏪", + ["school"] = "🏫", + ["love_hotel"] = "🏩", + ["wedding"] = "💒", + ["classical_building"] = "🏛️", + ["church"] = "⛪", + ["mosque"] = "🕌", + ["synagogue"] = "🕍", + ["hindu_temple"] = "🛕", + ["kaaba"] = "🕋", + ["shinto_shrine"] = "⛩️", + ["railway_track"] = "🛤️", + ["railroad_track"] = "🛤️", + ["motorway"] = "🛣️", + ["japan"] = "🗾", + ["rice_scene"] = "🎑", + ["park"] = "🏞️", + ["national_park"] = "🏞️", + ["sunrise"] = "🌅", + ["sunrise_over_mountains"] = "🌄", + ["stars"] = "🌠", + ["sparkler"] = "🎇", + ["fireworks"] = "🎆", + ["city_sunset"] = "🌇", + ["city_sunrise"] = "🌇", + ["city_dusk"] = "🌆", + ["cityscape"] = "🏙️", + ["night_with_stars"] = "🌃", + ["milky_way"] = "🌌", + ["bridge_at_night"] = "🌉", + ["foggy"] = "🌁", + ["watch"] = "⌚", + ["mobile_phone"] = "📱", + ["iphone"] = "📱", + ["calling"] = "📲", + ["computer"] = "💻", + ["keyboard"] = "⌨️", + ["desktop"] = "🖥️", + ["desktop_computer"] = "🖥️", + ["printer"] = "🖨️", + ["mouse_three_button"] = "🖱️", + ["three_button_mouse"] = "🖱️", + ["trackball"] = "🖲️", + ["joystick"] = "🕹️", + ["compression"] = "🗜️", + ["minidisc"] = "💽", + ["floppy_disk"] = "💾", + ["cd"] = "💿", + ["dvd"] = "📀", + ["vhs"] = "📼", + ["camera"] = "📷", + ["camera_with_flash"] = "📸", + ["video_camera"] = "📹", + ["movie_camera"] = "🎥", + ["projector"] = "📽️", + ["film_projector"] = "📽️", + ["film_frames"] = "🎞️", + ["telephone_receiver"] = "📞", + ["telephone"] = "☎️", + ["pager"] = "📟", + ["fax"] = "📠", + ["tv"] = "📺", + ["radio"] = "📻", + ["microphone2"] = "🎙️", + ["studio_microphone"] = "🎙️", + ["level_slider"] = "🎚️", + ["control_knobs"] = "🎛️", + ["compass"] = "🧭", + ["stopwatch"] = "⏱️", + ["timer"] = "⏲️", + ["timer_clock"] = "⏲️", + ["alarm_clock"] = "⏰", + ["clock"] = "🕰️", + ["mantlepiece_clock"] = "🕰️", + ["hourglass"] = "⌛", + ["hourglass_flowing_sand"] = "⏳", + ["satellite"] = "📡", + ["battery"] = "🔋", + ["electric_plug"] = "🔌", + ["bulb"] = "💡", + ["flashlight"] = "🔦", + ["candle"] = "🕯️", + ["diya_lamp"] = "🪔", + ["fire_extinguisher"] = "🧯", + ["oil"] = "🛢️", + ["oil_drum"] = "🛢️", + ["money_with_wings"] = "💸", + ["dollar"] = "💵", + ["yen"] = "💴", + ["euro"] = "💶", + ["pound"] = "💷", + ["coin"] = "🪙", + ["moneybag"] = "💰", + ["credit_card"] = "💳", + ["gem"] = "💎", + ["scales"] = "⚖️", + ["ladder"] = "🪜", + ["toolbox"] = "🧰", + ["screwdriver"] = "🪛", + ["wrench"] = "🔧", + ["hammer"] = "🔨", + ["hammer_pick"] = "⚒️", + ["hammer_and_pick"] = "⚒️", + ["tools"] = "🛠️", + ["hammer_and_wrench"] = "🛠️", + ["pick"] = "⛏️", + ["nut_and_bolt"] = "🔩", + ["gear"] = "⚙️", + ["bricks"] = "🧱", + ["chains"] = "⛓️", + ["hook"] = "🪝", + ["knot"] = "🪢", + ["magnet"] = "🧲", + ["gun"] = "🔫", + ["bomb"] = "💣", + ["firecracker"] = "🧨", + ["axe"] = "🪓", + ["carpentry_saw"] = "🪚", + ["knife"] = "🔪", + ["dagger"] = "🗡️", + ["dagger_knife"] = "🗡️", + ["crossed_swords"] = "⚔️", + ["shield"] = "🛡️", + ["smoking"] = "🚬", + ["coffin"] = "⚰️", + ["headstone"] = "🪦", + ["urn"] = "⚱️", + ["funeral_urn"] = "⚱️", + ["amphora"] = "🏺", + ["magic_wand"] = "🪄", + ["crystal_ball"] = "🔮", + ["prayer_beads"] = "📿", + ["nazar_amulet"] = "🧿", + ["barber"] = "💈", + ["alembic"] = "⚗️", + ["telescope"] = "🔭", + ["microscope"] = "🔬", + ["hole"] = "🕳️", + ["window"] = "🪟", + ["adhesive_bandage"] = "🩹", + ["stethoscope"] = "🩺", + ["pill"] = "💊", + ["syringe"] = "💉", + ["drop_of_blood"] = "🩸", + ["dna"] = "🧬", + ["microbe"] = "🦠", + ["petri_dish"] = "🧫", + ["test_tube"] = "🧪", + ["thermometer"] = "🌡️", + ["mouse_trap"] = "🪤", + ["broom"] = "🧹", + ["basket"] = "🧺", + ["sewing_needle"] = "🪡", + ["roll_of_paper"] = "🧻", + ["toilet"] = "🚽", + ["plunger"] = "🪠", + ["bucket"] = "🪣", + ["potable_water"] = "🚰", + ["shower"] = "🚿", + ["bathtub"] = "🛁", + ["bath"] = "🛀", + ["bath_tone1"] = "🛀🏻", + ["bath_tone2"] = "🛀🏼", + ["bath_tone3"] = "🛀🏽", + ["bath_tone4"] = "🛀🏾", + ["bath_tone5"] = "🛀🏿", + ["toothbrush"] = "🪥", + ["soap"] = "🧼", + ["razor"] = "🪒", + ["sponge"] = "🧽", + ["squeeze_bottle"] = "🧴", + ["bellhop"] = "🛎️", + ["bellhop_bell"] = "🛎️", + ["key"] = "🔑", + ["key2"] = "🗝️", + ["old_key"] = "🗝️", + ["door"] = "🚪", + ["chair"] = "🪑", + ["mirror"] = "🪞", + ["couch"] = "🛋️", + ["couch_and_lamp"] = "🛋️", + ["bed"] = "🛏️", + ["sleeping_accommodation"] = "🛌", + ["person_in_bed_tone1"] = "🛌🏻", + ["person_in_bed_light_skin_tone"] = "🛌🏻", + ["person_in_bed_tone2"] = "🛌🏼", + ["person_in_bed_medium_light_skin_tone"] = "🛌🏼", + ["person_in_bed_tone3"] = "🛌🏽", + ["person_in_bed_medium_skin_tone"] = "🛌🏽", + ["person_in_bed_tone4"] = "🛌🏾", + ["person_in_bed_medium_dark_skin_tone"] = "🛌🏾", + ["person_in_bed_tone5"] = "🛌🏿", + ["person_in_bed_dark_skin_tone"] = "🛌🏿", + ["teddy_bear"] = "🧸", + ["frame_photo"] = "🖼️", + ["frame_with_picture"] = "🖼️", + ["shopping_bags"] = "🛍️", + ["shopping_cart"] = "🛒", + ["shopping_trolley"] = "🛒", + ["gift"] = "🎁", + ["balloon"] = "🎈", + ["flags"] = "🎏", + ["ribbon"] = "🎀", + ["confetti_ball"] = "🎊", + ["tada"] = "🎉", + ["piñata"] = "🪅", + ["nesting_dolls"] = "🪆", + ["dolls"] = "🎎", + ["izakaya_lantern"] = "🏮", + ["wind_chime"] = "🎐", + ["red_envelope"] = "🧧", + ["envelope"] = "✉️", + ["envelope_with_arrow"] = "📩", + ["incoming_envelope"] = "📨", + ["e_mail"] = "📧", + ["email"] = "📧", + ["love_letter"] = "💌", + ["inbox_tray"] = "📥", + ["outbox_tray"] = "📤", + ["package"] = "📦", + ["label"] = "🏷️", + ["mailbox_closed"] = "📪", + ["mailbox"] = "📫", + ["mailbox_with_mail"] = "📬", + ["mailbox_with_no_mail"] = "📭", + ["postbox"] = "📮", + ["postal_horn"] = "📯", + ["placard"] = "🪧", + ["scroll"] = "📜", + ["page_with_curl"] = "📃", + ["page_facing_up"] = "📄", + ["bookmark_tabs"] = "📑", + ["receipt"] = "🧾", + ["bar_chart"] = "📊", + ["chart_with_upwards_trend"] = "📈", + ["chart_with_downwards_trend"] = "📉", + ["notepad_spiral"] = "🗒️", + ["spiral_note_pad"] = "🗒️", + ["calendar_spiral"] = "🗓️", + ["spiral_calendar_pad"] = "🗓️", + ["calendar"] = "📆", + ["date"] = "📅", + ["wastebasket"] = "🗑️", + ["card_index"] = "📇", + ["card_box"] = "🗃️", + ["card_file_box"] = "🗃️", + ["ballot_box"] = "🗳️", + ["ballot_box_with_ballot"] = "🗳️", + ["file_cabinet"] = "🗄️", + ["clipboard"] = "📋", + ["file_folder"] = "📁", + ["open_file_folder"] = "📂", + ["dividers"] = "🗂️", + ["card_index_dividers"] = "🗂️", + ["newspaper2"] = "🗞️", + ["rolled_up_newspaper"] = "🗞️", + ["newspaper"] = "📰", + ["notebook"] = "📓", + ["notebook_with_decorative_cover"] = "📔", + ["ledger"] = "📒", + ["closed_book"] = "📕", + ["green_book"] = "📗", + ["blue_book"] = "📘", + ["orange_book"] = "📙", + ["books"] = "📚", + ["book"] = "📖", + ["bookmark"] = "🔖", + ["safety_pin"] = "🧷", + ["link"] = "🔗", + ["paperclip"] = "📎", + ["paperclips"] = "🖇️", + ["linked_paperclips"] = "🖇️", + ["triangular_ruler"] = "📐", + ["straight_ruler"] = "📏", + ["abacus"] = "🧮", + ["pushpin"] = "📌", + ["round_pushpin"] = "📍", + ["scissors"] = "✂️", + ["pen_ballpoint"] = "🖊️", + ["lower_left_ballpoint_pen"] = "🖊️", + ["pen_fountain"] = "🖋️", + ["lower_left_fountain_pen"] = "🖋️", + ["black_nib"] = "✒️", + ["paintbrush"] = "🖌️", + ["lower_left_paintbrush"] = "🖌️", + ["crayon"] = "🖍️", + ["lower_left_crayon"] = "🖍️", + ["pencil"] = "📝", + ["memo"] = "📝", + ["pencil2"] = "✏️", + ["mag"] = "🔍", + ["mag_right"] = "🔎", + ["lock_with_ink_pen"] = "🔏", + ["closed_lock_with_key"] = "🔐", + ["lock"] = "🔒", + ["unlock"] = "🔓", + ["heart"] = "❤️", + ["orange_heart"] = "🧡", + ["yellow_heart"] = "💛", + ["green_heart"] = "💚", + ["blue_heart"] = "💙", + ["purple_heart"] = "💜", + ["black_heart"] = "🖤", + ["brown_heart"] = "🤎", + ["white_heart"] = "🤍", + ["broken_heart"] = "💔", + ["heart_exclamation"] = "❣️", + ["heavy_heart_exclamation_mark_ornament"] = "❣️", + ["two_hearts"] = "💕", + ["revolving_hearts"] = "💞", + ["heartbeat"] = "💓", + ["heartpulse"] = "💗", + ["sparkling_heart"] = "💖", + ["cupid"] = "💘", + ["gift_heart"] = "💝", + ["mending_heart"] = "❤️‍🩹", + ["heart_on_fire"] = "❤️‍🔥", + ["heart_decoration"] = "💟", + ["peace"] = "☮️", + ["peace_symbol"] = "☮️", + ["cross"] = "✝️", + ["latin_cross"] = "✝️", + ["star_and_crescent"] = "☪️", + ["om_symbol"] = "🕉️", + ["wheel_of_dharma"] = "☸️", + ["star_of_david"] = "✡️", + ["six_pointed_star"] = "🔯", + ["menorah"] = "🕎", + ["yin_yang"] = "☯️", + ["orthodox_cross"] = "☦️", + ["place_of_worship"] = "🛐", + ["worship_symbol"] = "🛐", + ["ophiuchus"] = "⛎", + ["aries"] = "♈", + ["taurus"] = "♉", + ["gemini"] = "♊", + ["cancer"] = "♋", + ["leo"] = "♌", + ["virgo"] = "♍", + ["libra"] = "♎", + ["scorpius"] = "♏", + ["sagittarius"] = "♐", + ["capricorn"] = "♑", + ["aquarius"] = "♒", + ["pisces"] = "♓", + ["id"] = "🆔", + ["atom"] = "⚛️", + ["atom_symbol"] = "⚛️", + ["accept"] = "🉑", + ["radioactive"] = "☢️", + ["radioactive_sign"] = "☢️", + ["biohazard"] = "☣️", + ["biohazard_sign"] = "☣️", + ["mobile_phone_off"] = "📴", + ["vibration_mode"] = "📳", + ["u6709"] = "🈶", + ["u7121"] = "🈚", + ["u7533"] = "🈸", + ["u55b6"] = "🈺", + ["u6708"] = "🈷️", + ["eight_pointed_black_star"] = "✴️", + ["vs"] = "🆚", + ["white_flower"] = "💮", + ["ideograph_advantage"] = "🉐", + ["secret"] = "㊙️", + ["congratulations"] = "㊗️", + ["u5408"] = "🈴", + ["u6e80"] = "🈵", + ["u5272"] = "🈹", + ["u7981"] = "🈲", + ["a"] = "🅰️", + ["b"] = "🅱️", + ["ab"] = "🆎", + ["cl"] = "🆑", + ["o2"] = "🅾️", + ["sos"] = "🆘", + ["x"] = "❌", + ["o"] = "⭕", + ["octagonal_sign"] = "🛑", + ["stop_sign"] = "🛑", + ["no_entry"] = "⛔", + ["name_badge"] = "📛", + ["no_entry_sign"] = "🚫", + ["100"] = "💯", + ["anger"] = "💢", + ["hotsprings"] = "♨️", + ["no_pedestrians"] = "🚷", + ["do_not_litter"] = "🚯", + ["no_bicycles"] = "🚳", + ["non_potable_water"] = "🚱", + ["underage"] = "🔞", + ["no_mobile_phones"] = "📵", + ["no_smoking"] = "🚭", + ["exclamation"] = "❗", + ["grey_exclamation"] = "❕", + ["question"] = "❓", + ["grey_question"] = "❔", + ["bangbang"] = "‼️", + ["interrobang"] = "⁉️", + ["low_brightness"] = "🔅", + ["high_brightness"] = "🔆", + ["part_alternation_mark"] = "〽️", + ["warning"] = "⚠️", + ["children_crossing"] = "🚸", + ["trident"] = "🔱", + ["fleur_de_lis"] = "⚜️", + ["beginner"] = "🔰", + ["recycle"] = "♻️", + ["white_check_mark"] = "✅", + ["u6307"] = "🈯", + ["chart"] = "💹", + ["sparkle"] = "❇️", + ["eight_spoked_asterisk"] = "✳️", + ["negative_squared_cross_mark"] = "❎", + ["globe_with_meridians"] = "🌐", + ["diamond_shape_with_a_dot_inside"] = "💠", + ["m"] = "Ⓜ️", + ["cyclone"] = "🌀", + ["zzz"] = "💤", + ["atm"] = "🏧", + ["wc"] = "🚾", + ["wheelchair"] = "♿", + ["parking"] = "🅿️", + ["u7a7a"] = "🈳", + ["sa"] = "🈂️", + ["passport_control"] = "🛂", + ["customs"] = "🛃", + ["baggage_claim"] = "🛄", + ["left_luggage"] = "🛅", + ["elevator"] = "🛗", + ["mens"] = "🚹", + ["womens"] = "🚺", + ["baby_symbol"] = "🚼", + ["restroom"] = "🚻", + ["put_litter_in_its_place"] = "🚮", + ["cinema"] = "🎦", + ["signal_strength"] = "📶", + ["koko"] = "🈁", + ["symbols"] = "🔣", + ["information_source"] = "ℹ️", + ["abc"] = "🔤", + ["abcd"] = "🔡", + ["capital_abcd"] = "🔠", + ["ng"] = "🆖", + ["ok"] = "🆗", + ["up"] = "🆙", + ["cool"] = "🆒", + ["new"] = "🆕", + ["free"] = "🆓", + ["zero"] = "0️⃣", + ["one"] = "1️⃣", + ["two"] = "2️⃣", + ["three"] = "3️⃣", + ["four"] = "4️⃣", + ["five"] = "5️⃣", + ["six"] = "6️⃣", + ["seven"] = "7️⃣", + ["eight"] = "8️⃣", + ["nine"] = "9️⃣", + ["keycap_ten"] = "🔟", + ["1234"] = "🔢", + ["hash"] = "#️⃣", + ["asterisk"] = "*️⃣", + ["keycap_asterisk"] = "*️⃣", + ["eject"] = "⏏️", + ["eject_symbol"] = "⏏️", + ["arrow_forward"] = "▶️", + ["pause_button"] = "⏸️", + ["double_vertical_bar"] = "⏸️", + ["play_pause"] = "⏯️", + ["stop_button"] = "⏹️", + ["record_button"] = "⏺️", + ["track_next"] = "⏭️", + ["next_track"] = "⏭️", + ["track_previous"] = "⏮️", + ["previous_track"] = "⏮️", + ["fast_forward"] = "⏩", + ["rewind"] = "⏪", + ["arrow_double_up"] = "⏫", + ["arrow_double_down"] = "⏬", + ["arrow_backward"] = "◀️", + ["arrow_up_small"] = "🔼", + ["arrow_down_small"] = "🔽", + ["arrow_right"] = "➡️", + ["arrow_left"] = "⬅️", + ["arrow_up"] = "⬆️", + ["arrow_down"] = "⬇️", + ["arrow_upper_right"] = "↗️", + ["arrow_lower_right"] = "↘️", + ["arrow_lower_left"] = "↙️", + ["arrow_upper_left"] = "↖️", + ["arrow_up_down"] = "↕️", + ["left_right_arrow"] = "↔️", + ["arrow_right_hook"] = "↪️", + ["leftwards_arrow_with_hook"] = "↩️", + ["arrow_heading_up"] = "⤴️", + ["arrow_heading_down"] = "⤵️", + ["twisted_rightwards_arrows"] = "🔀", + ["repeat"] = "🔁", + ["repeat_one"] = "🔂", + ["arrows_counterclockwise"] = "🔄", + ["arrows_clockwise"] = "🔃", + ["musical_note"] = "🎵", + ["notes"] = "🎶", + ["heavy_plus_sign"] = "➕", + ["heavy_minus_sign"] = "➖", + ["heavy_division_sign"] = "➗", + ["heavy_multiplication_x"] = "✖️", + ["infinity"] = "♾️", + ["heavy_dollar_sign"] = "💲", + ["currency_exchange"] = "💱", + ["tm"] = "™️", + ["copyright"] = "©️", + ["registered"] = "®️", + ["wavy_dash"] = "〰️", + ["curly_loop"] = "➰", + ["loop"] = "➿", + ["end"] = "🔚", + ["back"] = "🔙", + ["on"] = "🔛", + ["top"] = "🔝", + ["soon"] = "🔜", + ["heavy_check_mark"] = "✔️", + ["ballot_box_with_check"] = "☑️", + ["radio_button"] = "🔘", + ["white_circle"] = "⚪", + ["black_circle"] = "⚫", + ["red_circle"] = "🔴", + ["blue_circle"] = "🔵", + ["brown_circle"] = "🟤", + ["purple_circle"] = "🟣", + ["green_circle"] = "🟢", + ["yellow_circle"] = "🟡", + ["orange_circle"] = "🟠", + ["small_red_triangle"] = "🔺", + ["small_red_triangle_down"] = "🔻", + ["small_orange_diamond"] = "🔸", + ["small_blue_diamond"] = "🔹", + ["large_orange_diamond"] = "🔶", + ["large_blue_diamond"] = "🔷", + ["white_square_button"] = "🔳", + ["black_square_button"] = "🔲", + ["black_small_square"] = "▪️", + ["white_small_square"] = "▫️", + ["black_medium_small_square"] = "◾", + ["white_medium_small_square"] = "◽", + ["black_medium_square"] = "◼️", + ["white_medium_square"] = "◻️", + ["black_large_square"] = "⬛", + ["white_large_square"] = "⬜", + ["orange_square"] = "🟧", + ["blue_square"] = "🟦", + ["red_square"] = "🟥", + ["brown_square"] = "🟫", + ["purple_square"] = "🟪", + ["green_square"] = "🟩", + ["yellow_square"] = "🟨", + ["speaker"] = "🔈", + ["mute"] = "🔇", + ["sound"] = "🔉", + ["loud_sound"] = "🔊", + ["bell"] = "🔔", + ["no_bell"] = "🔕", + ["mega"] = "📣", + ["loudspeaker"] = "📢", + ["speech_left"] = "🗨️", + ["left_speech_bubble"] = "🗨️", + ["eye_in_speech_bubble"] = "👁‍🗨", + ["speech_balloon"] = "💬", + ["thought_balloon"] = "💭", + ["anger_right"] = "🗯️", + ["right_anger_bubble"] = "🗯️", + ["spades"] = "♠️", + ["clubs"] = "♣️", + ["hearts"] = "♥️", + ["diamonds"] = "♦️", + ["black_joker"] = "🃏", + ["flower_playing_cards"] = "🎴", + ["mahjong"] = "🀄", + ["clock1"] = "🕐", + ["clock2"] = "🕑", + ["clock3"] = "🕒", + ["clock4"] = "🕓", + ["clock5"] = "🕔", + ["clock6"] = "🕕", + ["clock7"] = "🕖", + ["clock8"] = "🕗", + ["clock9"] = "🕘", + ["clock10"] = "🕙", + ["clock11"] = "🕚", + ["clock12"] = "🕛", + ["clock130"] = "🕜", + ["clock230"] = "🕝", + ["clock330"] = "🕞", + ["clock430"] = "🕟", + ["clock530"] = "🕠", + ["clock630"] = "🕡", + ["clock730"] = "🕢", + ["clock830"] = "🕣", + ["clock930"] = "🕤", + ["clock1030"] = "🕥", + ["clock1130"] = "🕦", + ["clock1230"] = "🕧", + ["female_sign"] = "♀️", + ["male_sign"] = "♂️", + ["transgender_symbol"] = "⚧", + ["medical_symbol"] = "⚕️", + ["regional_indicator_z"] = "🇿", + ["regional_indicator_y"] = "🇾", + ["regional_indicator_x"] = "🇽", + ["regional_indicator_w"] = "🇼", + ["regional_indicator_v"] = "🇻", + ["regional_indicator_u"] = "🇺", + ["regional_indicator_t"] = "🇹", + ["regional_indicator_s"] = "🇸", + ["regional_indicator_r"] = "🇷", + ["regional_indicator_q"] = "🇶", + ["regional_indicator_p"] = "🇵", + ["regional_indicator_o"] = "🇴", + ["regional_indicator_n"] = "🇳", + ["regional_indicator_m"] = "🇲", + ["regional_indicator_l"] = "🇱", + ["regional_indicator_k"] = "🇰", + ["regional_indicator_j"] = "🇯", + ["regional_indicator_i"] = "🇮", + ["regional_indicator_h"] = "🇭", + ["regional_indicator_g"] = "🇬", + ["regional_indicator_f"] = "🇫", + ["regional_indicator_e"] = "🇪", + ["regional_indicator_d"] = "🇩", + ["regional_indicator_c"] = "🇨", + ["regional_indicator_b"] = "🇧", + ["regional_indicator_a"] = "🇦", + ["flag_white"] = "🏳️", + ["flag_black"] = "🏴", + ["checkered_flag"] = "🏁", + ["triangular_flag_on_post"] = "🚩", + ["rainbow_flag"] = "🏳️‍🌈", + ["gay_pride_flag"] = "🏳️‍🌈", + ["transgender_flag"] = "🏳️‍⚧️", + ["pirate_flag"] = "🏴‍☠️", + ["flag_af"] = "🇦🇫", + ["flag_ax"] = "🇦🇽", + ["flag_al"] = "🇦🇱", + ["flag_dz"] = "🇩🇿", + ["flag_as"] = "🇦🇸", + ["flag_ad"] = "🇦🇩", + ["flag_ao"] = "🇦🇴", + ["flag_ai"] = "🇦🇮", + ["flag_aq"] = "🇦🇶", + ["flag_ag"] = "🇦🇬", + ["flag_ar"] = "🇦🇷", + ["flag_am"] = "🇦🇲", + ["flag_aw"] = "🇦🇼", + ["flag_au"] = "🇦🇺", + ["flag_at"] = "🇦🇹", + ["flag_az"] = "🇦🇿", + ["flag_bs"] = "🇧🇸", + ["flag_bh"] = "🇧🇭", + ["flag_bd"] = "🇧🇩", + ["flag_bb"] = "🇧🇧", + ["flag_by"] = "🇧🇾", + ["flag_be"] = "🇧🇪", + ["flag_bz"] = "🇧🇿", + ["flag_bj"] = "🇧🇯", + ["flag_bm"] = "🇧🇲", + ["flag_bt"] = "🇧🇹", + ["flag_bo"] = "🇧🇴", + ["flag_ba"] = "🇧🇦", + ["flag_bw"] = "🇧🇼", + ["flag_br"] = "🇧🇷", + ["flag_io"] = "🇮🇴", + ["flag_vg"] = "🇻🇬", + ["flag_bn"] = "🇧🇳", + ["flag_bg"] = "🇧🇬", + ["flag_bf"] = "🇧🇫", + ["flag_bi"] = "🇧🇮", + ["flag_kh"] = "🇰🇭", + ["flag_cm"] = "🇨🇲", + ["flag_ca"] = "🇨🇦", + ["flag_ic"] = "🇮🇨", + ["flag_cv"] = "🇨🇻", + ["flag_bq"] = "🇧🇶", + ["flag_ky"] = "🇰🇾", + ["flag_cf"] = "🇨🇫", + ["flag_td"] = "🇹🇩", + ["flag_cl"] = "🇨🇱", + ["flag_cn"] = "🇨🇳", + ["flag_cx"] = "🇨🇽", + ["flag_cc"] = "🇨🇨", + ["flag_co"] = "🇨🇴", + ["flag_km"] = "🇰🇲", + ["flag_cg"] = "🇨🇬", + ["flag_cd"] = "🇨🇩", + ["flag_ck"] = "🇨🇰", + ["flag_cr"] = "🇨🇷", + ["flag_ci"] = "🇨🇮", + ["flag_hr"] = "🇭🇷", + ["flag_cu"] = "🇨🇺", + ["flag_cw"] = "🇨🇼", + ["flag_cy"] = "🇨🇾", + ["flag_cz"] = "🇨🇿", + ["flag_dk"] = "🇩🇰", + ["flag_dj"] = "🇩🇯", + ["flag_dm"] = "🇩🇲", + ["flag_do"] = "🇩🇴", + ["flag_ec"] = "🇪🇨", + ["flag_eg"] = "🇪🇬", + ["flag_sv"] = "🇸🇻", + ["flag_gq"] = "🇬🇶", + ["flag_er"] = "🇪🇷", + ["flag_ee"] = "🇪🇪", + ["flag_et"] = "🇪🇹", + ["flag_eu"] = "🇪🇺", + ["flag_fk"] = "🇫🇰", + ["flag_fo"] = "🇫🇴", + ["flag_fj"] = "🇫🇯", + ["flag_fi"] = "🇫🇮", + ["flag_fr"] = "🇫🇷", + ["flag_gf"] = "🇬🇫", + ["flag_pf"] = "🇵🇫", + ["flag_tf"] = "🇹🇫", + ["flag_ga"] = "🇬🇦", + ["flag_gm"] = "🇬🇲", + ["flag_ge"] = "🇬🇪", + ["flag_de"] = "🇩🇪", + ["flag_gh"] = "🇬🇭", + ["flag_gi"] = "🇬🇮", + ["flag_gr"] = "🇬🇷", + ["flag_gl"] = "🇬🇱", + ["flag_gd"] = "🇬🇩", + ["flag_gp"] = "🇬🇵", + ["flag_gu"] = "🇬🇺", + ["flag_gt"] = "🇬🇹", + ["flag_gg"] = "🇬🇬", + ["flag_gn"] = "🇬🇳", + ["flag_gw"] = "🇬🇼", + ["flag_gy"] = "🇬🇾", + ["flag_ht"] = "🇭🇹", + ["flag_hn"] = "🇭🇳", + ["flag_hk"] = "🇭🇰", + ["flag_hu"] = "🇭🇺", + ["flag_is"] = "🇮🇸", + ["flag_in"] = "🇮🇳", + ["flag_id"] = "🇮🇩", + ["flag_ir"] = "🇮🇷", + ["flag_iq"] = "🇮🇶", + ["flag_ie"] = "🇮🇪", + ["flag_im"] = "🇮🇲", + ["flag_il"] = "🇮🇱", + ["flag_it"] = "🇮🇹", + ["flag_jm"] = "🇯🇲", + ["flag_jp"] = "🇯🇵", + ["crossed_flags"] = "🎌", + ["flag_je"] = "🇯🇪", + ["flag_jo"] = "🇯🇴", + ["flag_kz"] = "🇰🇿", + ["flag_ke"] = "🇰🇪", + ["flag_ki"] = "🇰🇮", + ["flag_xk"] = "🇽🇰", + ["flag_kw"] = "🇰🇼", + ["flag_kg"] = "🇰🇬", + ["flag_la"] = "🇱🇦", + ["flag_lv"] = "🇱🇻", + ["flag_lb"] = "🇱🇧", + ["flag_ls"] = "🇱🇸", + ["flag_lr"] = "🇱🇷", + ["flag_ly"] = "🇱🇾", + ["flag_li"] = "🇱🇮", + ["flag_lt"] = "🇱🇹", + ["flag_lu"] = "🇱🇺", + ["flag_mo"] = "🇲🇴", + ["flag_mk"] = "🇲🇰", + ["flag_mg"] = "🇲🇬", + ["flag_mw"] = "🇲🇼", + ["flag_my"] = "🇲🇾", + ["flag_mv"] = "🇲🇻", + ["flag_ml"] = "🇲🇱", + ["flag_mt"] = "🇲🇹", + ["flag_mh"] = "🇲🇭", + ["flag_mq"] = "🇲🇶", + ["flag_mr"] = "🇲🇷", + ["flag_mu"] = "🇲🇺", + ["flag_yt"] = "🇾🇹", + ["flag_mx"] = "🇲🇽", + ["flag_fm"] = "🇫🇲", + ["flag_md"] = "🇲🇩", + ["flag_mc"] = "🇲🇨", + ["flag_mn"] = "🇲🇳", + ["flag_me"] = "🇲🇪", + ["flag_ms"] = "🇲🇸", + ["flag_ma"] = "🇲🇦", + ["flag_mz"] = "🇲🇿", + ["flag_mm"] = "🇲🇲", + ["flag_na"] = "🇳🇦", + ["flag_nr"] = "🇳🇷", + ["flag_np"] = "🇳🇵", + ["flag_nl"] = "🇳🇱", + ["flag_nc"] = "🇳🇨", + ["flag_nz"] = "🇳🇿", + ["flag_ni"] = "🇳🇮", + ["flag_ne"] = "🇳🇪", + ["flag_ng"] = "🇳🇬", + ["flag_nu"] = "🇳🇺", + ["flag_nf"] = "🇳🇫", + ["flag_kp"] = "🇰🇵", + ["flag_mp"] = "🇲🇵", + ["flag_no"] = "🇳🇴", + ["flag_om"] = "🇴🇲", + ["flag_pk"] = "🇵🇰", + ["flag_pw"] = "🇵🇼", + ["flag_ps"] = "🇵🇸", + ["flag_pa"] = "🇵🇦", + ["flag_pg"] = "🇵🇬", + ["flag_py"] = "🇵🇾", + ["flag_pe"] = "🇵🇪", + ["flag_ph"] = "🇵🇭", + ["flag_pn"] = "🇵🇳", + ["flag_pl"] = "🇵🇱", + ["flag_pt"] = "🇵🇹", + ["flag_pr"] = "🇵🇷", + ["flag_qa"] = "🇶🇦", + ["flag_re"] = "🇷🇪", + ["flag_ro"] = "🇷🇴", + ["flag_ru"] = "🇷🇺", + ["flag_rw"] = "🇷🇼", + ["flag_ws"] = "🇼🇸", + ["flag_sm"] = "🇸🇲", + ["flag_st"] = "🇸🇹", + ["flag_sa"] = "🇸🇦", + ["flag_sn"] = "🇸🇳", + ["flag_rs"] = "🇷🇸", + ["flag_sc"] = "🇸🇨", + ["flag_sl"] = "🇸🇱", + ["flag_sg"] = "🇸🇬", + ["flag_sx"] = "🇸🇽", + ["flag_sk"] = "🇸🇰", + ["flag_si"] = "🇸🇮", + ["flag_gs"] = "🇬🇸", + ["flag_sb"] = "🇸🇧", + ["flag_so"] = "🇸🇴", + ["flag_za"] = "🇿🇦", + ["flag_kr"] = "🇰🇷", + ["flag_ss"] = "🇸🇸", + ["flag_es"] = "🇪🇸", + ["flag_lk"] = "🇱🇰", + ["flag_bl"] = "🇧🇱", + ["flag_sh"] = "🇸🇭", + ["flag_kn"] = "🇰🇳", + ["flag_lc"] = "🇱🇨", + ["flag_pm"] = "🇵🇲", + ["flag_vc"] = "🇻🇨", + ["flag_sd"] = "🇸🇩", + ["flag_sr"] = "🇸🇷", + ["flag_sz"] = "🇸🇿", + ["flag_se"] = "🇸🇪", + ["flag_ch"] = "🇨🇭", + ["flag_sy"] = "🇸🇾", + ["flag_tw"] = "🇹🇼", + ["flag_tj"] = "🇹🇯", + ["flag_tz"] = "🇹🇿", + ["flag_th"] = "🇹🇭", + ["flag_tl"] = "🇹🇱", + ["flag_tg"] = "🇹🇬", + ["flag_tk"] = "🇹🇰", + ["flag_to"] = "🇹🇴", + ["flag_tt"] = "🇹🇹", + ["flag_tn"] = "🇹🇳", + ["flag_tr"] = "🇹🇷", + ["flag_tm"] = "🇹🇲", + ["flag_tc"] = "🇹🇨", + ["flag_vi"] = "🇻🇮", + ["flag_tv"] = "🇹🇻", + ["flag_ug"] = "🇺🇬", + ["flag_ua"] = "🇺🇦", + ["flag_ae"] = "🇦🇪", + ["flag_gb"] = "🇬🇧", + ["england"] = "🏴󠁧󠁢󠁥󠁮󠁧󠁿", + ["scotland"] = "🏴󠁧󠁢󠁳󠁣󠁴󠁿", + ["wales"] = "🏴󠁧󠁢󠁷󠁬󠁳󠁿", + ["flag_us"] = "🇺🇸", + ["flag_uy"] = "🇺🇾", + ["flag_uz"] = "🇺🇿", + ["flag_vu"] = "🇻🇺", + ["flag_va"] = "🇻🇦", + ["flag_ve"] = "🇻🇪", + ["flag_vn"] = "🇻🇳", + ["flag_wf"] = "🇼🇫", + ["flag_eh"] = "🇪🇭", + ["flag_ye"] = "🇾🇪", + ["flag_zm"] = "🇿🇲", + ["flag_zw"] = "🇿🇼", + ["flag_ac"] = "🇦🇨", + ["flag_bv"] = "🇧🇻", + ["flag_cp"] = "🇨🇵", + ["flag_ea"] = "🇪🇦", + ["flag_dg"] = "🇩🇬", + ["flag_hm"] = "🇭🇲", + ["flag_mf"] = "🇲🇫", + ["flag_sj"] = "🇸🇯", + ["flag_ta"] = "🇹🇦", + ["flag_um"] = "🇺🇲", + ["united_nations"] = "🇺🇳" + }; - public static string? TryGetCode(string name) => _toCodes.GetValueOrDefault(name); + public static string? TryGetCode(string name) => _toCodes.GetValueOrDefault(name); - public static string? TryGetName(string code) => _fromCodes.GetValueOrDefault(code); - } + public static string? TryGetName(string code) => _fromCodes.GetValueOrDefault(code); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/AsyncExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/AsyncExtensions.cs index 6cf6c97..b5d2707 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/AsyncExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/AsyncExtensions.cs @@ -5,48 +5,47 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class AsyncExtensions { - public static class AsyncExtensions + private static async ValueTask> AggregateAsync( + this IAsyncEnumerable asyncEnumerable) { - private static async ValueTask> AggregateAsync( - this IAsyncEnumerable asyncEnumerable) - { - var list = new List(); + var list = new List(); + + await foreach (var i in asyncEnumerable) + list.Add(i); - await foreach (var i in asyncEnumerable) - list.Add(i); + return list; + } - return list; - } + public static ValueTaskAwaiter> GetAwaiter( + this IAsyncEnumerable asyncEnumerable) => + asyncEnumerable.AggregateAsync().GetAwaiter(); - public static ValueTaskAwaiter> GetAwaiter( - this IAsyncEnumerable asyncEnumerable) => - asyncEnumerable.AggregateAsync().GetAwaiter(); + public static async ValueTask ParallelForEachAsync( + this IEnumerable source, + Func handleAsync, + int degreeOfParallelism, + CancellationToken cancellationToken = default) + { + using var semaphore = new SemaphoreSlim(degreeOfParallelism); - public static async ValueTask ParallelForEachAsync( - this IEnumerable source, - Func handleAsync, - int degreeOfParallelism, - CancellationToken cancellationToken = default) + await Task.WhenAll(source.Select(async item => { - using var semaphore = new SemaphoreSlim(degreeOfParallelism); + // ReSharper disable once AccessToDisposedClosure + await semaphore.WaitAsync(cancellationToken); - await Task.WhenAll(source.Select(async item => + try + { + await handleAsync(item); + } + finally { // ReSharper disable once AccessToDisposedClosure - await semaphore.WaitAsync(cancellationToken); - - try - { - await handleAsync(item); - } - finally - { - // ReSharper disable once AccessToDisposedClosure - semaphore.Release(); - } - })); - } + semaphore.Release(); + } + })); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/BinaryExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/BinaryExtensions.cs index 5894377..121aa3f 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/BinaryExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/BinaryExtensions.cs @@ -1,19 +1,18 @@ using System.Text; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class BinaryExtensions { - public static class BinaryExtensions + public static string ToHex(this byte[] data) { - public static string ToHex(this byte[] data) - { - var buffer = new StringBuilder(); - - foreach (var t in data) - { - buffer.Append(t.ToString("X2")); - } + var buffer = new StringBuilder(); - return buffer.ToString(); + foreach (var t in data) + { + buffer.Append(t.ToString("X2")); } + + return buffer.ToString(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/ColorExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/ColorExtensions.cs index 10d5fbb..124debc 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/ColorExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/ColorExtensions.cs @@ -1,15 +1,14 @@ using System.Drawing; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class ColorExtensions { - public static class ColorExtensions - { - public static Color WithAlpha(this Color color, int alpha) => Color.FromArgb(alpha, color); + public static Color WithAlpha(this Color color, int alpha) => Color.FromArgb(alpha, color); - public static Color ResetAlpha(this Color color) => color.WithAlpha(255); + public static Color ResetAlpha(this Color color) => color.WithAlpha(255); - public static int ToRgb(this Color color) => color.ToArgb() & 0xffffff; + public static int ToRgb(this Color color) => color.ToArgb() & 0xffffff; - public static string ToHex(this Color color) => $"#{color.R:X2}{color.G:X2}{color.B:X2}"; - } + public static string ToHex(this Color color) => $"#{color.R:X2}{color.G:X2}{color.B:X2}"; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/DateExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/DateExtensions.cs index 9a4c1ca..4f1c47a 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/DateExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/DateExtensions.cs @@ -1,11 +1,10 @@ using System; using System.Globalization; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class DateExtensions { - public static class DateExtensions - { - public static string ToLocalString(this DateTimeOffset dateTime, string format) => - dateTime.ToLocalTime().ToString(format, CultureInfo.InvariantCulture); - } + public static string ToLocalString(this DateTimeOffset dateTime, string format) => + dateTime.ToLocalTime().ToString(format, CultureInfo.InvariantCulture); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/GenericExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/GenericExtensions.cs index 48744f8..3997987 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/GenericExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/GenericExtensions.cs @@ -1,14 +1,13 @@ using System; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class GenericExtensions { - public static class GenericExtensions - { - public static TOut Pipe(this TIn input, Func transform) => transform(input); + public static TOut Pipe(this TIn input, Func transform) => transform(input); - public static T? NullIf(this T value, Func predicate) where T : struct => - !predicate(value) - ? value - : null; - } + public static T? NullIf(this T value, Func predicate) where T : struct => + !predicate(value) + ? value + : null; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/HttpExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/HttpExtensions.cs index 2b8d9ec..0f74ad1 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/HttpExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/HttpExtensions.cs @@ -1,12 +1,11 @@ using System.Net.Http.Headers; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class HttpExtensions { - public static class HttpExtensions - { - public static string? TryGetValue(this HttpContentHeaders headers, string name) => - headers.TryGetValues(name, out var values) - ? string.Concat(values) - : null; - } + public static string? TryGetValue(this HttpContentHeaders headers, string name) => + headers.TryGetValues(name, out var values) + ? string.Concat(values) + : null; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs index 7f9858a..336b7db 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/StringExtensions.cs @@ -1,33 +1,32 @@ using System.Collections.Generic; using System.Text; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class StringExtensions { - public static class StringExtensions - { - public static string? NullIfWhiteSpace(this string str) => - !string.IsNullOrWhiteSpace(str) - ? str - : null; + public static string? NullIfWhiteSpace(this string str) => + !string.IsNullOrWhiteSpace(str) + ? str + : null; - public static string Truncate(this string str, int charCount) => - str.Length > charCount - ? str[..charCount] - : str; + public static string Truncate(this string str, int charCount) => + str.Length > charCount + ? str[..charCount] + : str; - public static IEnumerable GetRunes(this string str) + public static IEnumerable GetRunes(this string str) + { + var lastIndex = 0; + while (lastIndex < str.Length && Rune.TryGetRuneAt(str, lastIndex, out var rune)) { - var lastIndex = 0; - while (lastIndex < str.Length && Rune.TryGetRuneAt(str, lastIndex, out var rune)) - { - yield return rune; - lastIndex += rune.Utf16SequenceLength; - } + yield return rune; + lastIndex += rune.Utf16SequenceLength; } - - public static StringBuilder AppendIfNotEmpty(this StringBuilder builder, char value) => - builder.Length > 0 - ? builder.Append(value) - : builder; } + + public static StringBuilder AppendIfNotEmpty(this StringBuilder builder, char value) => + builder.Length > 0 + ? builder.Append(value) + : builder; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Extensions/SuperpowerExtensions.cs b/DiscordChatExporter.Core/Utils/Extensions/SuperpowerExtensions.cs index 09d4bdf..d3bc469 100644 --- a/DiscordChatExporter.Core/Utils/Extensions/SuperpowerExtensions.cs +++ b/DiscordChatExporter.Core/Utils/Extensions/SuperpowerExtensions.cs @@ -3,25 +3,24 @@ using System.Diagnostics.CodeAnalysis; using Superpower; using Superpower.Parsers; -namespace DiscordChatExporter.Core.Utils.Extensions +namespace DiscordChatExporter.Core.Utils.Extensions; + +public static class SuperpowerExtensions { - public static class SuperpowerExtensions - { - public static TextParser Text(this TextParser parser) => - parser.Select(chars => new string(chars)); + public static TextParser Text(this TextParser parser) => + parser.Select(chars => new string(chars)); - public static TextParser Token(this TextParser parser) => - parser.Between(Character.WhiteSpace.IgnoreMany(), Character.WhiteSpace.IgnoreMany()); + public static TextParser Token(this TextParser parser) => + parser.Between(Character.WhiteSpace.IgnoreMany(), Character.WhiteSpace.IgnoreMany()); - // Only used for debugging while writing Superpower parsers. - // From https://twitter.com/nblumhardt/status/1389349059786264578 - [ExcludeFromCodeCoverage] - public static TextParser Log(this TextParser parser, string description) => i => - { - Console.WriteLine($"Trying {description} ->"); - var r = parser(i); - Console.WriteLine($"Result was {r}"); - return r; - }; - } + // Only used for debugging while writing Superpower parsers. + // From https://twitter.com/nblumhardt/status/1389349059786264578 + [ExcludeFromCodeCoverage] + public static TextParser Log(this TextParser parser, string description) => i => + { + Console.WriteLine($"Trying {description} ->"); + var r = parser(i); + Console.WriteLine($"Result was {r}"); + return r; + }; } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/FileFormat.cs b/DiscordChatExporter.Core/Utils/FileFormat.cs index 80b78e1..3306902 100644 --- a/DiscordChatExporter.Core/Utils/FileFormat.cs +++ b/DiscordChatExporter.Core/Utils/FileFormat.cs @@ -1,41 +1,40 @@ using System; using System.Collections.Generic; -namespace DiscordChatExporter.Core.Utils +namespace DiscordChatExporter.Core.Utils; + +public static class FileFormat { - public static class FileFormat + private static readonly HashSet ImageFormats = new(StringComparer.OrdinalIgnoreCase) { - private static readonly HashSet ImageFormats = new(StringComparer.OrdinalIgnoreCase) - { - ".jpg", - ".jpeg", - ".png", - ".gif", - ".gifv", - ".bmp", - ".webp" - }; + ".jpg", + ".jpeg", + ".png", + ".gif", + ".gifv", + ".bmp", + ".webp" + }; - public static bool IsImage(string format) => ImageFormats.Contains(format); + public static bool IsImage(string format) => ImageFormats.Contains(format); - private static readonly HashSet VideoFormats = new(StringComparer.OrdinalIgnoreCase) - { - ".mp4", - ".webm", - ".mov" - }; + private static readonly HashSet VideoFormats = new(StringComparer.OrdinalIgnoreCase) + { + ".mp4", + ".webm", + ".mov" + }; - public static bool IsVideo(string format) => VideoFormats.Contains(format); + public static bool IsVideo(string format) => VideoFormats.Contains(format); - private static readonly HashSet AudioFormats = new(StringComparer.OrdinalIgnoreCase) - { - ".mp3", - ".wav", - ".ogg", - ".flac", - ".m4a" - }; + private static readonly HashSet AudioFormats = new(StringComparer.OrdinalIgnoreCase) + { + ".mp3", + ".wav", + ".ogg", + ".flac", + ".m4a" + }; - public static bool IsAudio(string format) => AudioFormats.Contains(format); - } + public static bool IsAudio(string format) => AudioFormats.Contains(format); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/Http.cs b/DiscordChatExporter.Core/Utils/Http.cs index f505fe1..9de8107 100644 --- a/DiscordChatExporter.Core/Utils/Http.cs +++ b/DiscordChatExporter.Core/Utils/Http.cs @@ -8,60 +8,59 @@ using System.Threading.Tasks; using DiscordChatExporter.Core.Utils.Extensions; using Polly; -namespace DiscordChatExporter.Core.Utils +namespace DiscordChatExporter.Core.Utils; + +public static class Http { - public static class Http - { - public static HttpClient Client { get; } = new(); + public static HttpClient Client { get; } = new(); - public static IAsyncPolicy ResponsePolicy { get; } = - Policy - .Handle() - .Or() - .OrResult(m => m.StatusCode == HttpStatusCode.TooManyRequests) - .OrResult(m => m.StatusCode == HttpStatusCode.RequestTimeout) - .OrResult(m => m.StatusCode >= HttpStatusCode.InternalServerError) - .WaitAndRetryAsync( - 8, - (i, result, _) => + public static IAsyncPolicy ResponsePolicy { get; } = + Policy + .Handle() + .Or() + .OrResult(m => m.StatusCode == HttpStatusCode.TooManyRequests) + .OrResult(m => m.StatusCode == HttpStatusCode.RequestTimeout) + .OrResult(m => m.StatusCode >= HttpStatusCode.InternalServerError) + .WaitAndRetryAsync( + 8, + (i, result, _) => + { + // If rate-limited, use retry-after as a guide + if (result.Result?.StatusCode == HttpStatusCode.TooManyRequests) { - // If rate-limited, use retry-after as a guide - if (result.Result?.StatusCode == HttpStatusCode.TooManyRequests) + // Only start respecting retry-after after a few attempts, because + // Discord often sends unreasonable (20+ minutes) retry-after + // on the very first request. + if (i > 3) { - // Only start respecting retry-after after a few attempts, because - // Discord often sends unreasonable (20+ minutes) retry-after - // on the very first request. - if (i > 3) - { - var retryAfterDelay = result.Result.Headers.RetryAfter?.Delta; - if (retryAfterDelay is not null) - return retryAfterDelay.Value + TimeSpan.FromSeconds(1); // margin just in case - } + var retryAfterDelay = result.Result.Headers.RetryAfter?.Delta; + if (retryAfterDelay is not null) + return retryAfterDelay.Value + TimeSpan.FromSeconds(1); // margin just in case } + } - return TimeSpan.FromSeconds(Math.Pow(2, i) + 1); - }, - (_, _, _, _) => Task.CompletedTask - ); + return TimeSpan.FromSeconds(Math.Pow(2, i) + 1); + }, + (_, _, _, _) => Task.CompletedTask + ); - private static HttpStatusCode? TryGetStatusCodeFromException(HttpRequestException ex) => - // This is extremely frail, but there's no other way - Regex - .Match(ex.Message, @": (\d+) \(") - .Groups[1] - .Value - .NullIfWhiteSpace()? - .Pipe(s => (HttpStatusCode) int.Parse(s, CultureInfo.InvariantCulture)); + private static HttpStatusCode? TryGetStatusCodeFromException(HttpRequestException ex) => + // This is extremely frail, but there's no other way + Regex + .Match(ex.Message, @": (\d+) \(") + .Groups[1] + .Value + .NullIfWhiteSpace()? + .Pipe(s => (HttpStatusCode) int.Parse(s, CultureInfo.InvariantCulture)); - public static IAsyncPolicy ExceptionPolicy { get; } = - Policy - .Handle() // dangerous - .Or(ex => - TryGetStatusCodeFromException(ex) is - HttpStatusCode.TooManyRequests or - HttpStatusCode.RequestTimeout or - HttpStatusCode.InternalServerError - ) - .WaitAndRetryAsync(4, i => TimeSpan.FromSeconds(Math.Pow(2, i) + 1)); - } + public static IAsyncPolicy ExceptionPolicy { get; } = + Policy + .Handle() // dangerous + .Or(ex => + TryGetStatusCodeFromException(ex) is + HttpStatusCode.TooManyRequests or + HttpStatusCode.RequestTimeout or + HttpStatusCode.InternalServerError + ) + .WaitAndRetryAsync(4, i => TimeSpan.FromSeconds(Math.Pow(2, i) + 1)); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/PathEx.cs b/DiscordChatExporter.Core/Utils/PathEx.cs index 1ef74a1..06b5709 100644 --- a/DiscordChatExporter.Core/Utils/PathEx.cs +++ b/DiscordChatExporter.Core/Utils/PathEx.cs @@ -1,18 +1,17 @@ using System.IO; using System.Text; -namespace DiscordChatExporter.Core.Utils +namespace DiscordChatExporter.Core.Utils; + +public static class PathEx { - public static class PathEx + public static StringBuilder EscapePath(StringBuilder pathBuffer) { - public static StringBuilder EscapePath(StringBuilder pathBuffer) - { - foreach (var invalidChar in Path.GetInvalidFileNameChars()) - pathBuffer.Replace(invalidChar, '_'); - - return pathBuffer; - } + foreach (var invalidChar in Path.GetInvalidFileNameChars()) + pathBuffer.Replace(invalidChar, '_'); - public static string EscapePath(string path) => EscapePath(new StringBuilder(path)).ToString(); + return pathBuffer; } + + public static string EscapePath(string path) => EscapePath(new StringBuilder(path)).ToString(); } \ No newline at end of file diff --git a/DiscordChatExporter.Core/Utils/UrlBuilder.cs b/DiscordChatExporter.Core/Utils/UrlBuilder.cs index a7897c2..c20e4a4 100644 --- a/DiscordChatExporter.Core/Utils/UrlBuilder.cs +++ b/DiscordChatExporter.Core/Utils/UrlBuilder.cs @@ -4,42 +4,41 @@ using System.Linq; using System.Net; using System.Text; -namespace DiscordChatExporter.Core.Utils +namespace DiscordChatExporter.Core.Utils; + +public class UrlBuilder { - public class UrlBuilder - { - private string _path = ""; + private string _path = ""; - private readonly Dictionary _queryParameters = new(StringComparer.OrdinalIgnoreCase); + private readonly Dictionary _queryParameters = new(StringComparer.OrdinalIgnoreCase); - public UrlBuilder SetPath(string path) - { - _path = path; - return this; - } + public UrlBuilder SetPath(string path) + { + _path = path; + return this; + } - public UrlBuilder SetQueryParameter(string key, string? value, bool ignoreUnsetValue = true) - { - if (ignoreUnsetValue && string.IsNullOrWhiteSpace(value)) - return this; + public UrlBuilder SetQueryParameter(string key, string? value, bool ignoreUnsetValue = true) + { + if (ignoreUnsetValue && string.IsNullOrWhiteSpace(value)) + return this; - var keyEncoded = WebUtility.UrlEncode(key); - var valueEncoded = WebUtility.UrlEncode(value); - _queryParameters[keyEncoded] = valueEncoded; + var keyEncoded = WebUtility.UrlEncode(key); + var valueEncoded = WebUtility.UrlEncode(value); + _queryParameters[keyEncoded] = valueEncoded; - return this; - } + return this; + } - public string Build() - { - var buffer = new StringBuilder(); + public string Build() + { + var buffer = new StringBuilder(); - buffer.Append(_path); + buffer.Append(_path); - if (_queryParameters.Any()) - buffer.Append('?').AppendJoin('&', _queryParameters.Select(kvp => $"{kvp.Key}={kvp.Value}")); + if (_queryParameters.Any()) + buffer.Append('?').AppendJoin('&', _queryParameters.Select(kvp => $"{kvp.Key}={kvp.Value}")); - return buffer.ToString(); - } + return buffer.ToString(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/App.xaml.cs b/DiscordChatExporter.Gui/App.xaml.cs index 5d7fcfe..f883b92 100644 --- a/DiscordChatExporter.Gui/App.xaml.cs +++ b/DiscordChatExporter.Gui/App.xaml.cs @@ -3,47 +3,46 @@ using System.Reflection; using DiscordChatExporter.Gui.Utils; using MaterialDesignThemes.Wpf; -namespace DiscordChatExporter.Gui +namespace DiscordChatExporter.Gui; + +public partial class App { - public partial class App - { - private static Assembly Assembly { get; } = typeof(App).Assembly; + private static Assembly Assembly { get; } = typeof(App).Assembly; + + public static string Name { get; } = Assembly.GetName().Name!; - public static string Name { get; } = Assembly.GetName().Name!; + public static Version Version { get; } = Assembly.GetName().Version!; - public static Version Version { get; } = Assembly.GetName().Version!; + public static string VersionString { get; } = Version.ToString(3); - public static string VersionString { get; } = Version.ToString(3); + public static string GitHubProjectUrl { get; } = "https://github.com/Tyrrrz/DiscordChatExporter"; - public static string GitHubProjectUrl { get; } = "https://github.com/Tyrrrz/DiscordChatExporter"; + public static string GitHubProjectWikiUrl { get; } = GitHubProjectUrl + "/wiki"; +} - public static string GitHubProjectWikiUrl { get; } = GitHubProjectUrl + "/wiki"; +public partial class App +{ + private static Theme LightTheme { get; } = Theme.Create( + new MaterialDesignLightTheme(), + MediaColor.FromHex("#343838"), + MediaColor.FromHex("#F9A825") + ); + + private static Theme DarkTheme { get; } = Theme.Create( + new MaterialDesignDarkTheme(), + MediaColor.FromHex("#E8E8E8"), + MediaColor.FromHex("#F9A825") + ); + + public static void SetLightTheme() + { + var paletteHelper = new PaletteHelper(); + paletteHelper.SetTheme(LightTheme); } - public partial class App + public static void SetDarkTheme() { - private static Theme LightTheme { get; } = Theme.Create( - new MaterialDesignLightTheme(), - MediaColor.FromHex("#343838"), - MediaColor.FromHex("#F9A825") - ); - - private static Theme DarkTheme { get; } = Theme.Create( - new MaterialDesignDarkTheme(), - MediaColor.FromHex("#E8E8E8"), - MediaColor.FromHex("#F9A825") - ); - - public static void SetLightTheme() - { - var paletteHelper = new PaletteHelper(); - paletteHelper.SetTheme(LightTheme); - } - - public static void SetDarkTheme() - { - var paletteHelper = new PaletteHelper(); - paletteHelper.SetTheme(DarkTheme); - } + var paletteHelper = new PaletteHelper(); + paletteHelper.SetTheme(DarkTheme); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Behaviors/ChannelMultiSelectionListBoxBehavior.cs b/DiscordChatExporter.Gui/Behaviors/ChannelMultiSelectionListBoxBehavior.cs index 08b9cd3..4b01dcc 100644 --- a/DiscordChatExporter.Gui/Behaviors/ChannelMultiSelectionListBoxBehavior.cs +++ b/DiscordChatExporter.Gui/Behaviors/ChannelMultiSelectionListBoxBehavior.cs @@ -1,8 +1,7 @@ using DiscordChatExporter.Core.Discord.Data; -namespace DiscordChatExporter.Gui.Behaviors +namespace DiscordChatExporter.Gui.Behaviors; + +public class ChannelMultiSelectionListBoxBehavior : MultiSelectionListBoxBehavior { - public class ChannelMultiSelectionListBoxBehavior : MultiSelectionListBoxBehavior - { - } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Behaviors/MultiSelectionListBoxBehavior.cs b/DiscordChatExporter.Gui/Behaviors/MultiSelectionListBoxBehavior.cs index bd4e9bd..f8bf5fc 100644 --- a/DiscordChatExporter.Gui/Behaviors/MultiSelectionListBoxBehavior.cs +++ b/DiscordChatExporter.Gui/Behaviors/MultiSelectionListBoxBehavior.cs @@ -5,88 +5,87 @@ using System.Windows; using System.Windows.Controls; using Microsoft.Xaml.Behaviors; -namespace DiscordChatExporter.Gui.Behaviors +namespace DiscordChatExporter.Gui.Behaviors; + +public class MultiSelectionListBoxBehavior : Behavior { - public class MultiSelectionListBoxBehavior : Behavior + public static readonly DependencyProperty SelectedItemsProperty = + DependencyProperty.Register(nameof(SelectedItems), typeof(IList), + typeof(MultiSelectionListBoxBehavior), + new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, + OnSelectedItemsChanged)); + + private static void OnSelectedItemsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) { - public static readonly DependencyProperty SelectedItemsProperty = - DependencyProperty.Register(nameof(SelectedItems), typeof(IList), - typeof(MultiSelectionListBoxBehavior), - new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, - OnSelectedItemsChanged)); + var behavior = (MultiSelectionListBoxBehavior) sender; + if (behavior._modelHandled) return; - private static void OnSelectedItemsChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args) - { - var behavior = (MultiSelectionListBoxBehavior) sender; - if (behavior._modelHandled) return; + if (behavior.AssociatedObject is null) + return; - if (behavior.AssociatedObject is null) - return; + behavior._modelHandled = true; + behavior.SelectItems(); + behavior._modelHandled = false; + } - behavior._modelHandled = true; - behavior.SelectItems(); - behavior._modelHandled = false; - } + private bool _viewHandled; + private bool _modelHandled; + + public IList? SelectedItems + { + get => (IList?) GetValue(SelectedItemsProperty); + set => SetValue(SelectedItemsProperty, value); + } - private bool _viewHandled; - private bool _modelHandled; + // Propagate selected items from model to view + private void SelectItems() + { + _viewHandled = true; - public IList? SelectedItems + AssociatedObject.SelectedItems.Clear(); + if (SelectedItems is not null) { - get => (IList?) GetValue(SelectedItemsProperty); - set => SetValue(SelectedItemsProperty, value); + foreach (var item in SelectedItems) + AssociatedObject.SelectedItems.Add(item); } - // Propagate selected items from model to view - private void SelectItems() - { - _viewHandled = true; - - AssociatedObject.SelectedItems.Clear(); - if (SelectedItems is not null) - { - foreach (var item in SelectedItems) - AssociatedObject.SelectedItems.Add(item); - } + _viewHandled = false; + } - _viewHandled = false; - } + // Propagate selected items from view to model + private void OnListBoxSelectionChanged(object? sender, SelectionChangedEventArgs args) + { + if (_viewHandled) return; + if (AssociatedObject.Items.SourceCollection is null) return; - // Propagate selected items from view to model - private void OnListBoxSelectionChanged(object? sender, SelectionChangedEventArgs args) - { - if (_viewHandled) return; - if (AssociatedObject.Items.SourceCollection is null) return; + SelectedItems = AssociatedObject.SelectedItems.Cast().ToArray(); + } - SelectedItems = AssociatedObject.SelectedItems.Cast().ToArray(); - } + // Re-select items when the set of items changes + private void OnListBoxItemsChanged(object? sender, NotifyCollectionChangedEventArgs args) + { + if (_viewHandled) return; + if (AssociatedObject.Items.SourceCollection is null) return; + SelectItems(); + } - // Re-select items when the set of items changes - private void OnListBoxItemsChanged(object? sender, NotifyCollectionChangedEventArgs args) - { - if (_viewHandled) return; - if (AssociatedObject.Items.SourceCollection is null) return; - SelectItems(); - } + protected override void OnAttached() + { + base.OnAttached(); - protected override void OnAttached() - { - base.OnAttached(); + AssociatedObject.SelectionChanged += OnListBoxSelectionChanged; + ((INotifyCollectionChanged) AssociatedObject.Items).CollectionChanged += OnListBoxItemsChanged; + } - AssociatedObject.SelectionChanged += OnListBoxSelectionChanged; - ((INotifyCollectionChanged) AssociatedObject.Items).CollectionChanged += OnListBoxItemsChanged; - } + /// + protected override void OnDetaching() + { + base.OnDetaching(); - /// - protected override void OnDetaching() + if (AssociatedObject is not null) { - base.OnDetaching(); - - if (AssociatedObject is not null) - { - AssociatedObject.SelectionChanged -= OnListBoxSelectionChanged; - ((INotifyCollectionChanged) AssociatedObject.Items).CollectionChanged -= OnListBoxItemsChanged; - } + AssociatedObject.SelectionChanged -= OnListBoxSelectionChanged; + ((INotifyCollectionChanged) AssociatedObject.Items).CollectionChanged -= OnListBoxItemsChanged; } } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Converters/DateTimeOffsetToDateTimeConverter.cs b/DiscordChatExporter.Gui/Converters/DateTimeOffsetToDateTimeConverter.cs index 850415b..0bce69d 100644 --- a/DiscordChatExporter.Gui/Converters/DateTimeOffsetToDateTimeConverter.cs +++ b/DiscordChatExporter.Gui/Converters/DateTimeOffsetToDateTimeConverter.cs @@ -2,27 +2,26 @@ using System.Globalization; using System.Windows.Data; -namespace DiscordChatExporter.Gui.Converters +namespace DiscordChatExporter.Gui.Converters; + +[ValueConversion(typeof(DateTimeOffset?), typeof(DateTime?))] +public class DateTimeOffsetToDateTimeConverter : IValueConverter { - [ValueConversion(typeof(DateTimeOffset?), typeof(DateTime?))] - public class DateTimeOffsetToDateTimeConverter : IValueConverter - { - public static DateTimeOffsetToDateTimeConverter Instance { get; } = new(); + public static DateTimeOffsetToDateTimeConverter Instance { get; } = new(); - public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is DateTimeOffset dateTimeOffsetValue) - return dateTimeOffsetValue.DateTime; + public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is DateTimeOffset dateTimeOffsetValue) + return dateTimeOffsetValue.DateTime; - return default(DateTime?); - } + return default(DateTime?); + } - public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is DateTime dateTimeValue) - return new DateTimeOffset(dateTimeValue); + public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is DateTime dateTimeValue) + return new DateTimeOffset(dateTimeValue); - return default(DateTimeOffset?); - } + return default(DateTimeOffset?); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Converters/ExportFormatToStringConverter.cs b/DiscordChatExporter.Gui/Converters/ExportFormatToStringConverter.cs index 99563b4..1e16dd8 100644 --- a/DiscordChatExporter.Gui/Converters/ExportFormatToStringConverter.cs +++ b/DiscordChatExporter.Gui/Converters/ExportFormatToStringConverter.cs @@ -3,22 +3,21 @@ using System.Globalization; using System.Windows.Data; using DiscordChatExporter.Core.Exporting; -namespace DiscordChatExporter.Gui.Converters -{ - [ValueConversion(typeof(ExportFormat), typeof(string))] - public class ExportFormatToStringConverter : IValueConverter - { - public static ExportFormatToStringConverter Instance { get; } = new(); +namespace DiscordChatExporter.Gui.Converters; - public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is ExportFormat exportFormatValue) - return exportFormatValue.GetDisplayName(); +[ValueConversion(typeof(ExportFormat), typeof(string))] +public class ExportFormatToStringConverter : IValueConverter +{ + public static ExportFormatToStringConverter Instance { get; } = new(); - return default(string?); - } + public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is ExportFormat exportFormatValue) + return exportFormatValue.GetDisplayName(); - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => - throw new NotSupportedException(); + return default(string?); } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => + throw new NotSupportedException(); } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Converters/InverseBoolConverter.cs b/DiscordChatExporter.Gui/Converters/InverseBoolConverter.cs index a32781a..fafcc7e 100644 --- a/DiscordChatExporter.Gui/Converters/InverseBoolConverter.cs +++ b/DiscordChatExporter.Gui/Converters/InverseBoolConverter.cs @@ -2,27 +2,26 @@ using System.Globalization; using System.Windows.Data; -namespace DiscordChatExporter.Gui.Converters +namespace DiscordChatExporter.Gui.Converters; + +[ValueConversion(typeof(bool), typeof(bool))] +public class InverseBoolConverter : IValueConverter { - [ValueConversion(typeof(bool), typeof(bool))] - public class InverseBoolConverter : IValueConverter - { - public static InverseBoolConverter Instance { get; } = new(); + public static InverseBoolConverter Instance { get; } = new(); - public object Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is bool boolValue) - return !boolValue; + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is bool boolValue) + return !boolValue; - return default(bool); - } + return default(bool); + } - public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is bool boolValue) - return !boolValue; + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is bool boolValue) + return !boolValue; - return default(bool); - } + return default(bool); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Converters/TimeSpanToDateTimeConverter.cs b/DiscordChatExporter.Gui/Converters/TimeSpanToDateTimeConverter.cs index 22075ab..0a45bf4 100644 --- a/DiscordChatExporter.Gui/Converters/TimeSpanToDateTimeConverter.cs +++ b/DiscordChatExporter.Gui/Converters/TimeSpanToDateTimeConverter.cs @@ -2,27 +2,26 @@ using System.Globalization; using System.Windows.Data; -namespace DiscordChatExporter.Gui.Converters +namespace DiscordChatExporter.Gui.Converters; + +[ValueConversion(typeof(TimeSpan?), typeof(DateTime?))] +public class TimeSpanToDateTimeConverter : IValueConverter { - [ValueConversion(typeof(TimeSpan?), typeof(DateTime?))] - public class TimeSpanToDateTimeConverter : IValueConverter - { - public static TimeSpanToDateTimeConverter Instance { get; } = new(); + public static TimeSpanToDateTimeConverter Instance { get; } = new(); - public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is TimeSpan timeSpanValue) - return DateTime.Today.Add(timeSpanValue); + public object? Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is TimeSpan timeSpanValue) + return DateTime.Today.Add(timeSpanValue); - return default(DateTime?); - } + return default(DateTime?); + } - public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) - { - if (value is DateTime dateTimeValue) - return dateTimeValue.TimeOfDay; + public object? ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value is DateTime dateTimeValue) + return dateTimeValue.TimeOfDay; - return default(TimeSpan?); - } + return default(TimeSpan?); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Services/SettingsService.cs b/DiscordChatExporter.Gui/Services/SettingsService.cs index cec9267..dda9c09 100644 --- a/DiscordChatExporter.Gui/Services/SettingsService.cs +++ b/DiscordChatExporter.Gui/Services/SettingsService.cs @@ -2,39 +2,38 @@ using DiscordChatExporter.Core.Exporting; using Tyrrrz.Settings; -namespace DiscordChatExporter.Gui.Services -{ - public class SettingsService : SettingsManager - { - public bool IsAutoUpdateEnabled { get; set; } = true; +namespace DiscordChatExporter.Gui.Services; - public bool IsDarkModeEnabled { get; set; } +public class SettingsService : SettingsManager +{ + public bool IsAutoUpdateEnabled { get; set; } = true; - public bool IsTokenPersisted { get; set; } = true; + public bool IsDarkModeEnabled { get; set; } - public string DateFormat { get; set; } = "dd-MMM-yy hh:mm tt"; + public bool IsTokenPersisted { get; set; } = true; - public int ParallelLimit { get; set; } = 1; + public string DateFormat { get; set; } = "dd-MMM-yy hh:mm tt"; - public bool ShouldReuseMedia { get; set; } + public int ParallelLimit { get; set; } = 1; - public AuthToken? LastToken { get; set; } + public bool ShouldReuseMedia { get; set; } - public ExportFormat LastExportFormat { get; set; } = ExportFormat.HtmlDark; + public AuthToken? LastToken { get; set; } - public string? LastPartitionLimitValue { get; set; } + public ExportFormat LastExportFormat { get; set; } = ExportFormat.HtmlDark; - public string? LastMessageFilterValue { get; set; } + public string? LastPartitionLimitValue { get; set; } - public bool LastShouldDownloadMedia { get; set; } + public string? LastMessageFilterValue { get; set; } - public SettingsService() - { - Configuration.StorageSpace = StorageSpace.Instance; - Configuration.SubDirectoryPath = ""; - Configuration.FileName = "Settings.dat"; - } + public bool LastShouldDownloadMedia { get; set; } - public bool ShouldSerializeLastToken() => IsTokenPersisted; + public SettingsService() + { + Configuration.StorageSpace = StorageSpace.Instance; + Configuration.SubDirectoryPath = ""; + Configuration.FileName = "Settings.dat"; } + + public bool ShouldSerializeLastToken() => IsTokenPersisted; } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Services/UpdateService.cs b/DiscordChatExporter.Gui/Services/UpdateService.cs index 6584dd2..615227a 100644 --- a/DiscordChatExporter.Gui/Services/UpdateService.cs +++ b/DiscordChatExporter.Gui/Services/UpdateService.cs @@ -4,78 +4,77 @@ using Onova; using Onova.Exceptions; using Onova.Services; -namespace DiscordChatExporter.Gui.Services +namespace DiscordChatExporter.Gui.Services; + +public class UpdateService : IDisposable { - public class UpdateService : IDisposable + private readonly IUpdateManager _updateManager = new UpdateManager( + new GithubPackageResolver("Tyrrrz", "DiscordChatExporter", "DiscordChatExporter.zip"), + new ZipPackageExtractor() + ); + + private readonly SettingsService _settingsService; + + private Version? _updateVersion; + private bool _updatePrepared; + private bool _updaterLaunched; + + public UpdateService(SettingsService settingsService) + { + _settingsService = settingsService; + } + + public async ValueTask CheckForUpdatesAsync() { - private readonly IUpdateManager _updateManager = new UpdateManager( - new GithubPackageResolver("Tyrrrz", "DiscordChatExporter", "DiscordChatExporter.zip"), - new ZipPackageExtractor() - ); + if (!_settingsService.IsAutoUpdateEnabled) + return null; - private readonly SettingsService _settingsService; + var check = await _updateManager.CheckForUpdatesAsync(); + return check.CanUpdate ? check.LastVersion : null; + } - private Version? _updateVersion; - private bool _updatePrepared; - private bool _updaterLaunched; + public async ValueTask PrepareUpdateAsync(Version version) + { + if (!_settingsService.IsAutoUpdateEnabled) + return; - public UpdateService(SettingsService settingsService) + try { - _settingsService = settingsService; + await _updateManager.PrepareUpdateAsync(_updateVersion = version); + _updatePrepared = true; } - - public async ValueTask CheckForUpdatesAsync() + catch (UpdaterAlreadyLaunchedException) { - if (!_settingsService.IsAutoUpdateEnabled) - return null; - - var check = await _updateManager.CheckForUpdatesAsync(); - return check.CanUpdate ? check.LastVersion : null; + // Ignore race conditions } - - public async ValueTask PrepareUpdateAsync(Version version) + catch (LockFileNotAcquiredException) { - if (!_settingsService.IsAutoUpdateEnabled) - return; - - try - { - await _updateManager.PrepareUpdateAsync(_updateVersion = version); - _updatePrepared = true; - } - catch (UpdaterAlreadyLaunchedException) - { - // Ignore race conditions - } - catch (LockFileNotAcquiredException) - { - // Ignore race conditions - } + // Ignore race conditions } + } - public void FinalizeUpdate(bool needRestart) - { - if (!_settingsService.IsAutoUpdateEnabled) - return; + public void FinalizeUpdate(bool needRestart) + { + if (!_settingsService.IsAutoUpdateEnabled) + return; - if (_updateVersion is null || !_updatePrepared || _updaterLaunched) - return; + if (_updateVersion is null || !_updatePrepared || _updaterLaunched) + return; - try - { - _updateManager.LaunchUpdater(_updateVersion, needRestart); - _updaterLaunched = true; - } - catch (UpdaterAlreadyLaunchedException) - { - // Ignore race conditions - } - catch (LockFileNotAcquiredException) - { - // Ignore race conditions - } + try + { + _updateManager.LaunchUpdater(_updateVersion, needRestart); + _updaterLaunched = true; + } + catch (UpdaterAlreadyLaunchedException) + { + // Ignore race conditions + } + catch (LockFileNotAcquiredException) + { + // Ignore race conditions } - - public void Dispose() => _updateManager.Dispose(); } + + public void Dispose() => _updateManager.Dispose(); } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Utils/MediaColor.cs b/DiscordChatExporter.Gui/Utils/MediaColor.cs index 40467fb..f6bb041 100644 --- a/DiscordChatExporter.Gui/Utils/MediaColor.cs +++ b/DiscordChatExporter.Gui/Utils/MediaColor.cs @@ -1,9 +1,8 @@ using System.Windows.Media; -namespace DiscordChatExporter.Gui.Utils +namespace DiscordChatExporter.Gui.Utils; + +internal static class MediaColor { - internal static class MediaColor - { - public static Color FromHex(string hex) => (Color) ColorConverter.ConvertFromString(hex); - } + public static Color FromHex(string hex) => (Color) ColorConverter.ConvertFromString(hex); } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Utils/ProcessEx.cs b/DiscordChatExporter.Gui/Utils/ProcessEx.cs index 2dde873..f52c748 100644 --- a/DiscordChatExporter.Gui/Utils/ProcessEx.cs +++ b/DiscordChatExporter.Gui/Utils/ProcessEx.cs @@ -1,17 +1,16 @@ using System.Diagnostics; -namespace DiscordChatExporter.Gui.Utils +namespace DiscordChatExporter.Gui.Utils; + +internal static class ProcessEx { - internal static class ProcessEx + public static void StartShellExecute(string path) { - public static void StartShellExecute(string path) + var startInfo = new ProcessStartInfo(path) { - var startInfo = new ProcessStartInfo(path) - { - UseShellExecute = true - }; + UseShellExecute = true + }; - using (Process.Start(startInfo)) {} - } + using (Process.Start(startInfo)) {} } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs index 9c6a2df..d45f12e 100644 --- a/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Dialogs/ExportSetupViewModel.cs @@ -10,129 +10,128 @@ using DiscordChatExporter.Core.Utils.Extensions; using DiscordChatExporter.Gui.Services; using DiscordChatExporter.Gui.ViewModels.Framework; -namespace DiscordChatExporter.Gui.ViewModels.Dialogs +namespace DiscordChatExporter.Gui.ViewModels.Dialogs; + +public class ExportSetupViewModel : DialogScreen { - public class ExportSetupViewModel : DialogScreen - { - private readonly DialogManager _dialogManager; - private readonly SettingsService _settingsService; + private readonly DialogManager _dialogManager; + private readonly SettingsService _settingsService; + + public Guild? Guild { get; set; } - public Guild? Guild { get; set; } + public IReadOnlyList? Channels { get; set; } - public IReadOnlyList? Channels { get; set; } + public bool IsSingleChannel => Channels is null || Channels.Count == 1; - public bool IsSingleChannel => Channels is null || Channels.Count == 1; + public string? OutputPath { get; set; } - public string? OutputPath { get; set; } + public IReadOnlyList AvailableFormats => + Enum.GetValues(typeof(ExportFormat)).Cast().ToArray(); - public IReadOnlyList AvailableFormats => - Enum.GetValues(typeof(ExportFormat)).Cast().ToArray(); + public ExportFormat SelectedFormat { get; set; } - public ExportFormat SelectedFormat { get; set; } + // This date/time abomination is required because we use separate controls to set these - // This date/time abomination is required because we use separate controls to set these + public DateTimeOffset? AfterDate { get; set; } - public DateTimeOffset? AfterDate { get; set; } + public bool IsAfterDateSet => AfterDate is not null; - public bool IsAfterDateSet => AfterDate is not null; + public TimeSpan? AfterTime { get; set; } - public TimeSpan? AfterTime { get; set; } + public DateTimeOffset? After => AfterDate?.Add(AfterTime ?? TimeSpan.Zero); - public DateTimeOffset? After => AfterDate?.Add(AfterTime ?? TimeSpan.Zero); + public DateTimeOffset? BeforeDate { get; set; } - public DateTimeOffset? BeforeDate { get; set; } + public bool IsBeforeDateSet => BeforeDate is not null; - public bool IsBeforeDateSet => BeforeDate is not null; + public TimeSpan? BeforeTime { get; set; } - public TimeSpan? BeforeTime { get; set; } + public DateTimeOffset? Before => BeforeDate?.Add(BeforeTime ?? TimeSpan.Zero); - public DateTimeOffset? Before => BeforeDate?.Add(BeforeTime ?? TimeSpan.Zero); + public string? PartitionLimitValue { get; set; } - public string? PartitionLimitValue { get; set; } + public PartitionLimit PartitionLimit => !string.IsNullOrWhiteSpace(PartitionLimitValue) + ? PartitionLimit.Parse(PartitionLimitValue) + : PartitionLimit.Null; - public PartitionLimit PartitionLimit => !string.IsNullOrWhiteSpace(PartitionLimitValue) - ? PartitionLimit.Parse(PartitionLimitValue) - : PartitionLimit.Null; + public string? MessageFilterValue { get; set; } - public string? MessageFilterValue { get; set; } + public MessageFilter MessageFilter => !string.IsNullOrWhiteSpace(MessageFilterValue) + ? MessageFilter.Parse(MessageFilterValue) + : MessageFilter.Null; - public MessageFilter MessageFilter => !string.IsNullOrWhiteSpace(MessageFilterValue) - ? MessageFilter.Parse(MessageFilterValue) - : MessageFilter.Null; + public bool ShouldDownloadMedia { get; set; } - public bool ShouldDownloadMedia { get; set; } + // Whether to show the "advanced options" by default when the dialog opens. + // This is active if any of the advanced options are set to non-default values. + public bool IsAdvancedSectionDisplayedByDefault => + After != default || + Before != default || + !string.IsNullOrWhiteSpace(PartitionLimitValue) || + !string.IsNullOrWhiteSpace(MessageFilterValue) || + ShouldDownloadMedia != default; - // Whether to show the "advanced options" by default when the dialog opens. - // This is active if any of the advanced options are set to non-default values. - public bool IsAdvancedSectionDisplayedByDefault => - After != default || - Before != default || - !string.IsNullOrWhiteSpace(PartitionLimitValue) || - !string.IsNullOrWhiteSpace(MessageFilterValue) || - ShouldDownloadMedia != default; + public ExportSetupViewModel(DialogManager dialogManager, SettingsService settingsService) + { + _dialogManager = dialogManager; + _settingsService = settingsService; + + // Persist preferences + SelectedFormat = _settingsService.LastExportFormat; + PartitionLimitValue = _settingsService.LastPartitionLimitValue; + MessageFilterValue = _settingsService.LastMessageFilterValue; + ShouldDownloadMedia = _settingsService.LastShouldDownloadMedia; + } - public ExportSetupViewModel(DialogManager dialogManager, SettingsService settingsService) + public void Confirm() + { + // Persist preferences + _settingsService.LastExportFormat = SelectedFormat; + _settingsService.LastPartitionLimitValue = PartitionLimitValue; + _settingsService.LastMessageFilterValue = MessageFilterValue; + _settingsService.LastShouldDownloadMedia = ShouldDownloadMedia; + + // If single channel - prompt file path + if (Channels is not null && IsSingleChannel) { - _dialogManager = dialogManager; - _settingsService = settingsService; - - // Persist preferences - SelectedFormat = _settingsService.LastExportFormat; - PartitionLimitValue = _settingsService.LastPartitionLimitValue; - MessageFilterValue = _settingsService.LastMessageFilterValue; - ShouldDownloadMedia = _settingsService.LastShouldDownloadMedia; + var channel = Channels.Single(); + var defaultFileName = ExportRequest.GetDefaultOutputFileName( + Guild!, + channel, + SelectedFormat, + After?.Pipe(Snowflake.FromDate), + Before?.Pipe(Snowflake.FromDate) + ); + + // Filter + var ext = SelectedFormat.GetFileExtension(); + var filter = $"{ext.ToUpperInvariant()} files|*.{ext}"; + + OutputPath = _dialogManager.PromptSaveFilePath(filter, defaultFileName); } - - public void Confirm() + // If multiple channels - prompt dir path + else { - // Persist preferences - _settingsService.LastExportFormat = SelectedFormat; - _settingsService.LastPartitionLimitValue = PartitionLimitValue; - _settingsService.LastMessageFilterValue = MessageFilterValue; - _settingsService.LastShouldDownloadMedia = ShouldDownloadMedia; - - // If single channel - prompt file path - if (Channels is not null && IsSingleChannel) - { - var channel = Channels.Single(); - var defaultFileName = ExportRequest.GetDefaultOutputFileName( - Guild!, - channel, - SelectedFormat, - After?.Pipe(Snowflake.FromDate), - Before?.Pipe(Snowflake.FromDate) - ); - - // Filter - var ext = SelectedFormat.GetFileExtension(); - var filter = $"{ext.ToUpperInvariant()} files|*.{ext}"; - - OutputPath = _dialogManager.PromptSaveFilePath(filter, defaultFileName); - } - // If multiple channels - prompt dir path - else - { - OutputPath = _dialogManager.PromptDirectoryPath(); - } - - if (string.IsNullOrWhiteSpace(OutputPath)) - return; - - Close(true); + OutputPath = _dialogManager.PromptDirectoryPath(); } + + if (string.IsNullOrWhiteSpace(OutputPath)) + return; + + Close(true); } +} - public static class ExportSetupViewModelExtensions +public static class ExportSetupViewModelExtensions +{ + public static ExportSetupViewModel CreateExportSetupViewModel(this IViewModelFactory factory, + Guild guild, IReadOnlyList channels) { - public static ExportSetupViewModel CreateExportSetupViewModel(this IViewModelFactory factory, - Guild guild, IReadOnlyList channels) - { - var viewModel = factory.CreateExportSetupViewModel(); + var viewModel = factory.CreateExportSetupViewModel(); - viewModel.Guild = guild; - viewModel.Channels = channels; + viewModel.Guild = guild; + viewModel.Channels = channels; - return viewModel; - } + return viewModel; } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/Dialogs/MessageBoxViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Dialogs/MessageBoxViewModel.cs index 426fd63..0847395 100644 --- a/DiscordChatExporter.Gui/ViewModels/Dialogs/MessageBoxViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Dialogs/MessageBoxViewModel.cs @@ -1,27 +1,26 @@ using DiscordChatExporter.Gui.ViewModels.Framework; -namespace DiscordChatExporter.Gui.ViewModels.Dialogs +namespace DiscordChatExporter.Gui.ViewModels.Dialogs; + +public class MessageBoxViewModel : DialogScreen { - public class MessageBoxViewModel : DialogScreen - { - public string? Title { get; set; } + public string? Title { get; set; } - public string? Message { get; set; } - } + public string? Message { get; set; } +} - public static class MessageBoxViewModelExtensions +public static class MessageBoxViewModelExtensions +{ + public static MessageBoxViewModel CreateMessageBoxViewModel( + this IViewModelFactory factory, + string title, + string message) { - public static MessageBoxViewModel CreateMessageBoxViewModel( - this IViewModelFactory factory, - string title, - string message) - { - var viewModel = factory.CreateMessageBoxViewModel(); + var viewModel = factory.CreateMessageBoxViewModel(); - viewModel.Title = title; - viewModel.Message = message; + viewModel.Title = title; + viewModel.Message = message; - return viewModel; - } + return viewModel; } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs b/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs index d372b87..cf858b3 100644 --- a/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/Dialogs/SettingsViewModel.cs @@ -2,49 +2,48 @@ using DiscordChatExporter.Gui.Services; using DiscordChatExporter.Gui.ViewModels.Framework; -namespace DiscordChatExporter.Gui.ViewModels.Dialogs +namespace DiscordChatExporter.Gui.ViewModels.Dialogs; + +public class SettingsViewModel : DialogScreen { - public class SettingsViewModel : DialogScreen + private readonly SettingsService _settingsService; + + public bool IsAutoUpdateEnabled + { + get => _settingsService.IsAutoUpdateEnabled; + set => _settingsService.IsAutoUpdateEnabled = value; + } + + public bool IsDarkModeEnabled + { + get => _settingsService.IsDarkModeEnabled; + set => _settingsService.IsDarkModeEnabled = value; + } + + public bool IsTokenPersisted + { + get => _settingsService.IsTokenPersisted; + set => _settingsService.IsTokenPersisted = value; + } + + public string DateFormat + { + get => _settingsService.DateFormat; + set => _settingsService.DateFormat = value; + } + + public int ParallelLimit { - private readonly SettingsService _settingsService; - - public bool IsAutoUpdateEnabled - { - get => _settingsService.IsAutoUpdateEnabled; - set => _settingsService.IsAutoUpdateEnabled = value; - } - - public bool IsDarkModeEnabled - { - get => _settingsService.IsDarkModeEnabled; - set => _settingsService.IsDarkModeEnabled = value; - } - - public bool IsTokenPersisted - { - get => _settingsService.IsTokenPersisted; - set => _settingsService.IsTokenPersisted = value; - } - - public string DateFormat - { - get => _settingsService.DateFormat; - set => _settingsService.DateFormat = value; - } - - public int ParallelLimit - { - get => _settingsService.ParallelLimit; - set => _settingsService.ParallelLimit = Math.Clamp(value, 1, 10); - } - - public bool ShouldReuseMedia - { - get => _settingsService.ShouldReuseMedia; - set => _settingsService.ShouldReuseMedia = value; - } - - public SettingsViewModel(SettingsService settingsService) => - _settingsService = settingsService; + get => _settingsService.ParallelLimit; + set => _settingsService.ParallelLimit = Math.Clamp(value, 1, 10); } + + public bool ShouldReuseMedia + { + get => _settingsService.ShouldReuseMedia; + set => _settingsService.ShouldReuseMedia = value; + } + + public SettingsViewModel(SettingsService settingsService) => + _settingsService = settingsService; } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/Framework/DialogManager.cs b/DiscordChatExporter.Gui/ViewModels/Framework/DialogManager.cs index 3af7be6..4ad1ed9 100644 --- a/DiscordChatExporter.Gui/ViewModels/Framework/DialogManager.cs +++ b/DiscordChatExporter.Gui/ViewModels/Framework/DialogManager.cs @@ -6,58 +6,57 @@ using Microsoft.Win32; using Ookii.Dialogs.Wpf; using Stylet; -namespace DiscordChatExporter.Gui.ViewModels.Framework +namespace DiscordChatExporter.Gui.ViewModels.Framework; + +public class DialogManager { - public class DialogManager + private readonly IViewManager _viewManager; + + public DialogManager(IViewManager viewManager) { - private readonly IViewManager _viewManager; + _viewManager = viewManager; + } - public DialogManager(IViewManager viewManager) - { - _viewManager = viewManager; - } + public async ValueTask ShowDialogAsync(DialogScreen dialogScreen) + { + var view = _viewManager.CreateAndBindViewForModelIfNecessary(dialogScreen); - public async ValueTask ShowDialogAsync(DialogScreen dialogScreen) + void OnDialogOpened(object? sender, DialogOpenedEventArgs openArgs) { - var view = _viewManager.CreateAndBindViewForModelIfNecessary(dialogScreen); - - void OnDialogOpened(object? sender, DialogOpenedEventArgs openArgs) + void OnScreenClosed(object? o, EventArgs closeArgs) { - void OnScreenClosed(object? o, EventArgs closeArgs) - { - openArgs.Session.Close(); - dialogScreen.Closed -= OnScreenClosed; - } - - dialogScreen.Closed += OnScreenClosed; + openArgs.Session.Close(); + dialogScreen.Closed -= OnScreenClosed; } - await DialogHost.Show(view, OnDialogOpened); - - return dialogScreen.DialogResult; + dialogScreen.Closed += OnScreenClosed; } - public string? PromptSaveFilePath(string filter = "All files|*.*", string defaultFilePath = "") + await DialogHost.Show(view, OnDialogOpened); + + return dialogScreen.DialogResult; + } + + public string? PromptSaveFilePath(string filter = "All files|*.*", string defaultFilePath = "") + { + var dialog = new SaveFileDialog { - var dialog = new SaveFileDialog - { - Filter = filter, - AddExtension = true, - FileName = defaultFilePath, - DefaultExt = Path.GetExtension(defaultFilePath) - }; + Filter = filter, + AddExtension = true, + FileName = defaultFilePath, + DefaultExt = Path.GetExtension(defaultFilePath) + }; - return dialog.ShowDialog() == true ? dialog.FileName : null; - } + return dialog.ShowDialog() == true ? dialog.FileName : null; + } - public string? PromptDirectoryPath(string defaultDirPath = "") + public string? PromptDirectoryPath(string defaultDirPath = "") + { + var dialog = new VistaFolderBrowserDialog { - var dialog = new VistaFolderBrowserDialog - { - SelectedPath = defaultDirPath - }; + SelectedPath = defaultDirPath + }; - return dialog.ShowDialog() == true ? dialog.SelectedPath : null; - } + return dialog.ShowDialog() == true ? dialog.SelectedPath : null; } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/Framework/DialogScreen.cs b/DiscordChatExporter.Gui/ViewModels/Framework/DialogScreen.cs index 05e74b4..94dab0f 100644 --- a/DiscordChatExporter.Gui/ViewModels/Framework/DialogScreen.cs +++ b/DiscordChatExporter.Gui/ViewModels/Framework/DialogScreen.cs @@ -1,22 +1,21 @@ using System; using Stylet; -namespace DiscordChatExporter.Gui.ViewModels.Framework -{ - public abstract class DialogScreen : PropertyChangedBase - { - public T? DialogResult { get; private set; } +namespace DiscordChatExporter.Gui.ViewModels.Framework; - public event EventHandler? Closed; +public abstract class DialogScreen : PropertyChangedBase +{ + public T? DialogResult { get; private set; } - public void Close(T dialogResult) - { - DialogResult = dialogResult; - Closed?.Invoke(this, EventArgs.Empty); - } - } + public event EventHandler? Closed; - public abstract class DialogScreen : DialogScreen + public void Close(T dialogResult) { + DialogResult = dialogResult; + Closed?.Invoke(this, EventArgs.Empty); } +} + +public abstract class DialogScreen : DialogScreen +{ } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/Framework/IViewModelFactory.cs b/DiscordChatExporter.Gui/ViewModels/Framework/IViewModelFactory.cs index b543038..d5e086d 100644 --- a/DiscordChatExporter.Gui/ViewModels/Framework/IViewModelFactory.cs +++ b/DiscordChatExporter.Gui/ViewModels/Framework/IViewModelFactory.cs @@ -1,14 +1,13 @@ using DiscordChatExporter.Gui.ViewModels.Dialogs; -namespace DiscordChatExporter.Gui.ViewModels.Framework +namespace DiscordChatExporter.Gui.ViewModels.Framework; + +// Used to instantiate new view models while making use of dependency injection +public interface IViewModelFactory { - // Used to instantiate new view models while making use of dependency injection - public interface IViewModelFactory - { - ExportSetupViewModel CreateExportSetupViewModel(); + ExportSetupViewModel CreateExportSetupViewModel(); - MessageBoxViewModel CreateMessageBoxViewModel(); + MessageBoxViewModel CreateMessageBoxViewModel(); - SettingsViewModel CreateSettingsViewModel(); - } + SettingsViewModel CreateSettingsViewModel(); } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs b/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs index 1fa35db..7252984 100644 --- a/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs +++ b/DiscordChatExporter.Gui/ViewModels/RootViewModel.cs @@ -16,247 +16,246 @@ using Gress; using MaterialDesignThemes.Wpf; using Stylet; -namespace DiscordChatExporter.Gui.ViewModels +namespace DiscordChatExporter.Gui.ViewModels; + +public class RootViewModel : Screen { - public class RootViewModel : Screen - { - private readonly IViewModelFactory _viewModelFactory; - private readonly DialogManager _dialogManager; - private readonly SettingsService _settingsService; - private readonly UpdateService _updateService; + private readonly IViewModelFactory _viewModelFactory; + private readonly DialogManager _dialogManager; + private readonly SettingsService _settingsService; + private readonly UpdateService _updateService; - public ISnackbarMessageQueue Notifications { get; } = new SnackbarMessageQueue(TimeSpan.FromSeconds(5)); + public ISnackbarMessageQueue Notifications { get; } = new SnackbarMessageQueue(TimeSpan.FromSeconds(5)); - public IProgressManager ProgressManager { get; } = new ProgressManager(); + public IProgressManager ProgressManager { get; } = new ProgressManager(); - public bool IsBusy { get; private set; } + public bool IsBusy { get; private set; } - public bool IsProgressIndeterminate { get; private set; } + public bool IsProgressIndeterminate { get; private set; } - public bool IsBotToken { get; set; } + public bool IsBotToken { get; set; } - public string? TokenValue { get; set; } + public string? TokenValue { get; set; } - private IReadOnlyDictionary>? GuildChannelMap { get; set; } + private IReadOnlyDictionary>? GuildChannelMap { get; set; } - public IReadOnlyList? AvailableGuilds => GuildChannelMap?.Keys.ToArray(); + public IReadOnlyList? AvailableGuilds => GuildChannelMap?.Keys.ToArray(); - public Guild? SelectedGuild { get; set; } + public Guild? SelectedGuild { get; set; } - public IReadOnlyList? AvailableChannels => SelectedGuild is not null - ? GuildChannelMap?[SelectedGuild] - : null; + public IReadOnlyList? AvailableChannels => SelectedGuild is not null + ? GuildChannelMap?[SelectedGuild] + : null; - public IReadOnlyList? SelectedChannels { get; set; } + public IReadOnlyList? SelectedChannels { get; set; } - public RootViewModel( - IViewModelFactory viewModelFactory, - DialogManager dialogManager, - SettingsService settingsService, - UpdateService updateService) - { - _viewModelFactory = viewModelFactory; - _dialogManager = dialogManager; - _settingsService = settingsService; - _updateService = updateService; + public RootViewModel( + IViewModelFactory viewModelFactory, + DialogManager dialogManager, + SettingsService settingsService, + UpdateService updateService) + { + _viewModelFactory = viewModelFactory; + _dialogManager = dialogManager; + _settingsService = settingsService; + _updateService = updateService; - DisplayName = $"{App.Name} v{App.VersionString}"; + DisplayName = $"{App.Name} v{App.VersionString}"; - // Update busy state when progress manager changes - ProgressManager.Bind(o => o.IsActive, (_, _) => - IsBusy = ProgressManager.IsActive - ); + // Update busy state when progress manager changes + ProgressManager.Bind(o => o.IsActive, (_, _) => + IsBusy = ProgressManager.IsActive + ); - ProgressManager.Bind(o => o.IsActive, (_, _) => - IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress is <= 0 or >= 1 - ); + ProgressManager.Bind(o => o.IsActive, (_, _) => + IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress is <= 0 or >= 1 + ); - ProgressManager.Bind(o => o.Progress, (_, _) => - IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress is <= 0 or >= 1 - ); - } + ProgressManager.Bind(o => o.Progress, (_, _) => + IsProgressIndeterminate = ProgressManager.IsActive && ProgressManager.Progress is <= 0 or >= 1 + ); + } - private async ValueTask CheckForUpdatesAsync() + private async ValueTask CheckForUpdatesAsync() + { + try { - try - { - var updateVersion = await _updateService.CheckForUpdatesAsync(); - if (updateVersion is null) - return; - - Notifications.Enqueue($"Downloading update to {App.Name} v{updateVersion}..."); - await _updateService.PrepareUpdateAsync(updateVersion); - - Notifications.Enqueue( - "Update has been downloaded and will be installed when you exit", - "INSTALL NOW", () => - { - _updateService.FinalizeUpdate(true); - RequestClose(); - } - ); - } - catch - { - // Failure to update shouldn't crash the application - Notifications.Enqueue("Failed to perform application update"); - } - } + var updateVersion = await _updateService.CheckForUpdatesAsync(); + if (updateVersion is null) + return; - protected override async void OnViewLoaded() - { - base.OnViewLoaded(); + Notifications.Enqueue($"Downloading update to {App.Name} v{updateVersion}..."); + await _updateService.PrepareUpdateAsync(updateVersion); - _settingsService.Load(); + Notifications.Enqueue( + "Update has been downloaded and will be installed when you exit", + "INSTALL NOW", () => + { + _updateService.FinalizeUpdate(true); + RequestClose(); + } + ); + } + catch + { + // Failure to update shouldn't crash the application + Notifications.Enqueue("Failed to perform application update"); + } + } - if (_settingsService.LastToken is not null) - { - IsBotToken = _settingsService.LastToken.Kind == AuthTokenKind.Bot; - TokenValue = _settingsService.LastToken.Value; - } + protected override async void OnViewLoaded() + { + base.OnViewLoaded(); - if (_settingsService.IsDarkModeEnabled) - { - App.SetDarkTheme(); - } - else - { - App.SetLightTheme(); - } + _settingsService.Load(); - await CheckForUpdatesAsync(); + if (_settingsService.LastToken is not null) + { + IsBotToken = _settingsService.LastToken.Kind == AuthTokenKind.Bot; + TokenValue = _settingsService.LastToken.Value; } - protected override void OnClose() + if (_settingsService.IsDarkModeEnabled) { - base.OnClose(); - - _settingsService.Save(); - _updateService.FinalizeUpdate(false); + App.SetDarkTheme(); } - - public async void ShowSettings() + else { - var dialog = _viewModelFactory.CreateSettingsViewModel(); - await _dialogManager.ShowDialogAsync(dialog); + App.SetLightTheme(); } - public void ShowHelp() => ProcessEx.StartShellExecute(App.GitHubProjectWikiUrl); + await CheckForUpdatesAsync(); + } - public bool CanPopulateGuildsAndChannels => - !IsBusy && !string.IsNullOrWhiteSpace(TokenValue); + protected override void OnClose() + { + base.OnClose(); - public async void PopulateGuildsAndChannels() - { - using var operation = ProgressManager.CreateOperation(); + _settingsService.Save(); + _updateService.FinalizeUpdate(false); + } - try - { - var tokenValue = TokenValue?.Trim('"', ' '); - if (string.IsNullOrWhiteSpace(tokenValue)) - return; + public async void ShowSettings() + { + var dialog = _viewModelFactory.CreateSettingsViewModel(); + await _dialogManager.ShowDialogAsync(dialog); + } - var token = new AuthToken( - IsBotToken ? AuthTokenKind.Bot : AuthTokenKind.User, - tokenValue - ); + public void ShowHelp() => ProcessEx.StartShellExecute(App.GitHubProjectWikiUrl); - _settingsService.LastToken = token; + public bool CanPopulateGuildsAndChannels => + !IsBusy && !string.IsNullOrWhiteSpace(TokenValue); - var discord = new DiscordClient(token); + public async void PopulateGuildsAndChannels() + { + using var operation = ProgressManager.CreateOperation(); - var guildChannelMap = new Dictionary>(); - await foreach (var guild in discord.GetUserGuildsAsync()) - { - var channels = await discord.GetGuildChannelsAsync(guild.Id); - guildChannelMap[guild] = channels.Where(c => c.IsTextChannel).ToArray(); - } + try + { + var tokenValue = TokenValue?.Trim('"', ' '); + if (string.IsNullOrWhiteSpace(tokenValue)) + return; - GuildChannelMap = guildChannelMap; - SelectedGuild = guildChannelMap.Keys.FirstOrDefault(); - } - catch (DiscordChatExporterException ex) when (!ex.IsFatal) + var token = new AuthToken( + IsBotToken ? AuthTokenKind.Bot : AuthTokenKind.User, + tokenValue + ); + + _settingsService.LastToken = token; + + var discord = new DiscordClient(token); + + var guildChannelMap = new Dictionary>(); + await foreach (var guild in discord.GetUserGuildsAsync()) { - Notifications.Enqueue(ex.Message.TrimEnd('.')); + var channels = await discord.GetGuildChannelsAsync(guild.Id); + guildChannelMap[guild] = channels.Where(c => c.IsTextChannel).ToArray(); } - catch (Exception ex) - { - var dialog = _viewModelFactory.CreateMessageBoxViewModel( - "Error pulling guilds and channels", - ex.ToString() - ); - await _dialogManager.ShowDialogAsync(dialog); - } + GuildChannelMap = guildChannelMap; + SelectedGuild = guildChannelMap.Keys.FirstOrDefault(); + } + catch (DiscordChatExporterException ex) when (!ex.IsFatal) + { + Notifications.Enqueue(ex.Message.TrimEnd('.')); + } + catch (Exception ex) + { + var dialog = _viewModelFactory.CreateMessageBoxViewModel( + "Error pulling guilds and channels", + ex.ToString() + ); + + await _dialogManager.ShowDialogAsync(dialog); } + } - public bool CanExportChannels => - !IsBusy && SelectedGuild is not null && SelectedChannels is not null && SelectedChannels.Any(); + public bool CanExportChannels => + !IsBusy && SelectedGuild is not null && SelectedChannels is not null && SelectedChannels.Any(); - public async void ExportChannels() + public async void ExportChannels() + { + try { - try - { - var token = _settingsService.LastToken; - if (token is null || SelectedGuild is null || SelectedChannels is null || !SelectedChannels.Any()) - return; + var token = _settingsService.LastToken; + if (token is null || SelectedGuild is null || SelectedChannels is null || !SelectedChannels.Any()) + return; - var dialog = _viewModelFactory.CreateExportSetupViewModel(SelectedGuild, SelectedChannels); - if (await _dialogManager.ShowDialogAsync(dialog) != true) - return; + var dialog = _viewModelFactory.CreateExportSetupViewModel(SelectedGuild, SelectedChannels); + if (await _dialogManager.ShowDialogAsync(dialog) != true) + return; - var exporter = new ChannelExporter(token); + var exporter = new ChannelExporter(token); - var operations = ProgressManager.CreateOperations(dialog.Channels!.Count); - var successfulExportCount = 0; + var operations = ProgressManager.CreateOperations(dialog.Channels!.Count); + var successfulExportCount = 0; - await dialog.Channels.Zip(operations).ParallelForEachAsync(async tuple => - { - var (channel, operation) = tuple; - - try - { - var request = new ExportRequest( - dialog.Guild!, - channel!, - dialog.OutputPath!, - dialog.SelectedFormat, - dialog.After?.Pipe(Snowflake.FromDate), - dialog.Before?.Pipe(Snowflake.FromDate), - dialog.PartitionLimit, - dialog.MessageFilter, - dialog.ShouldDownloadMedia, - _settingsService.ShouldReuseMedia, - _settingsService.DateFormat - ); - - await exporter.ExportChannelAsync(request, operation); - - Interlocked.Increment(ref successfulExportCount); - } - catch (DiscordChatExporterException ex) when (!ex.IsFatal) - { - Notifications.Enqueue(ex.Message.TrimEnd('.')); - } - finally - { - operation.Dispose(); - } - }, Math.Max(1, _settingsService.ParallelLimit)); - - // Notify of overall completion - if (successfulExportCount > 0) - Notifications.Enqueue($"Successfully exported {successfulExportCount} channel(s)"); - } - catch (Exception ex) + await dialog.Channels.Zip(operations).ParallelForEachAsync(async tuple => { - var dialog = _viewModelFactory.CreateMessageBoxViewModel( - "Error exporting channel(s)", - ex.ToString() - ); + var (channel, operation) = tuple; - await _dialogManager.ShowDialogAsync(dialog); - } + try + { + var request = new ExportRequest( + dialog.Guild!, + channel!, + dialog.OutputPath!, + dialog.SelectedFormat, + dialog.After?.Pipe(Snowflake.FromDate), + dialog.Before?.Pipe(Snowflake.FromDate), + dialog.PartitionLimit, + dialog.MessageFilter, + dialog.ShouldDownloadMedia, + _settingsService.ShouldReuseMedia, + _settingsService.DateFormat + ); + + await exporter.ExportChannelAsync(request, operation); + + Interlocked.Increment(ref successfulExportCount); + } + catch (DiscordChatExporterException ex) when (!ex.IsFatal) + { + Notifications.Enqueue(ex.Message.TrimEnd('.')); + } + finally + { + operation.Dispose(); + } + }, Math.Max(1, _settingsService.ParallelLimit)); + + // Notify of overall completion + if (successfulExportCount > 0) + Notifications.Enqueue($"Successfully exported {successfulExportCount} channel(s)"); + } + catch (Exception ex) + { + var dialog = _viewModelFactory.CreateMessageBoxViewModel( + "Error exporting channel(s)", + ex.ToString() + ); + + await _dialogManager.ShowDialogAsync(dialog); } } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml.cs b/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml.cs index d6195cd..77b7a76 100644 --- a/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml.cs +++ b/DiscordChatExporter.Gui/Views/Dialogs/ExportSetupView.xaml.cs @@ -1,10 +1,9 @@ -namespace DiscordChatExporter.Gui.Views.Dialogs +namespace DiscordChatExporter.Gui.Views.Dialogs; + +public partial class ExportSetupView { - public partial class ExportSetupView + public ExportSetupView() { - public ExportSetupView() - { - InitializeComponent(); - } + InitializeComponent(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml.cs b/DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml.cs index d6c1801..1561027 100644 --- a/DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml.cs +++ b/DiscordChatExporter.Gui/Views/Dialogs/MessageBoxView.xaml.cs @@ -1,10 +1,9 @@ -namespace DiscordChatExporter.Gui.Views.Dialogs +namespace DiscordChatExporter.Gui.Views.Dialogs; + +public partial class MessageBoxView { - public partial class MessageBoxView + public MessageBoxView() { - public MessageBoxView() - { - InitializeComponent(); - } + InitializeComponent(); } } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml.cs b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml.cs index 647dbe7..16daa9d 100644 --- a/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml.cs +++ b/DiscordChatExporter.Gui/Views/Dialogs/SettingsView.xaml.cs @@ -1,18 +1,17 @@ using System.Windows; -namespace DiscordChatExporter.Gui.Views.Dialogs +namespace DiscordChatExporter.Gui.Views.Dialogs; + +public partial class SettingsView { - public partial class SettingsView + public SettingsView() { - public SettingsView() - { - InitializeComponent(); - } + InitializeComponent(); + } - private void DarkModeToggleButton_Checked(object sender, RoutedEventArgs e) => - App.SetDarkTheme(); + private void DarkModeToggleButton_Checked(object sender, RoutedEventArgs e) => + App.SetDarkTheme(); - private void DarkModeToggleButton_Unchecked(object sender, RoutedEventArgs e) => - App.SetLightTheme(); - } + private void DarkModeToggleButton_Unchecked(object sender, RoutedEventArgs e) => + App.SetLightTheme(); } \ No newline at end of file diff --git a/DiscordChatExporter.Gui/Views/RootView.xaml.cs b/DiscordChatExporter.Gui/Views/RootView.xaml.cs index f9a00a9..e960ebb 100644 --- a/DiscordChatExporter.Gui/Views/RootView.xaml.cs +++ b/DiscordChatExporter.Gui/Views/RootView.xaml.cs @@ -1,10 +1,9 @@ -namespace DiscordChatExporter.Gui.Views +namespace DiscordChatExporter.Gui.Views; + +public partial class RootView { - public partial class RootView + public RootView() { - public RootView() - { - InitializeComponent(); - } + InitializeComponent(); } } \ No newline at end of file