├── .git-blame-ignore-revs ├── .github └── workflows │ ├── ci.yml │ └── release.yml ├── .gitignore ├── .mailmap ├── .scalafmt.conf ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build.sbt ├── project ├── build.properties └── plugins.sbt └── src ├── main ├── scala-2.12 │ └── com │ │ └── lightbend │ │ └── emoji │ │ └── ScalaVersionSpecific.scala ├── scala-2.13 │ └── com │ │ └── lightbend │ │ └── emoji │ │ └── ScalaVersionSpecific.scala ├── scala-2 │ └── com │ │ └── lightbend │ │ └── emoji │ │ ├── Emoji.scala │ │ └── ShortCodes.scala └── scala-3 │ └── com │ └── lightbend │ └── emoji │ ├── Emoji.scala │ ├── ScalaVersionSpecific.scala │ └── ShortCodes.scala └── test ├── scala-2 └── com │ └── lightbend │ └── emoji │ ├── EmojiSpec.scala │ └── ShortCodesSpec.scala └── scala-3 └── com └── lightbend └── emoji ├── EmojiSuite.scala └── ShortCodesSuite.scala /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Scala Steward: Reformat with scalafmt 3.5.9 2 | b7a986a1dab16a376a77ace87dd2eec507a991aa 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | on: 3 | push: 4 | branches: 5 | - main 6 | pull_request: 7 | jobs: 8 | test: 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | java: [8, 11, 17, 21] 13 | scala: [2.13.x, 3.x] 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: coursier/cache-action@v6 18 | - uses: actions/setup-java@v4 19 | with: 20 | distribution: temurin 21 | java-version: ${{matrix.java}} 22 | - uses: sbt/setup-sbt@v1 23 | - name: Test 24 | run: sbt ++${{matrix.scala}} test mimaReportBinaryIssues package 25 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | tags: ["*"] 5 | jobs: 6 | publish: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@v4 10 | with: 11 | fetch-depth: 0 12 | - uses: actions/setup-java@v4 13 | with: 14 | distribution: temurin 15 | java-version: 8 16 | - uses: sbt/setup-sbt@v1 17 | - uses: olafurpg/setup-gpg@v3 18 | - run: sbt ci-release 19 | env: 20 | PGP_PASSPHRASE: ${{secrets.PGP_PASSPHRASE}} 21 | PGP_SECRET: ${{secrets.PGP_SECRET}} 22 | SONATYPE_PASSWORD: ${{secrets.SONATYPE_PASSWORD}} 23 | SONATYPE_USERNAME: ${{secrets.SONATYPE_USERNAME}} 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### SBT template 3 | # Simple Build Tool 4 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control 5 | 6 | target/ 7 | lib_managed/ 8 | src_managed/ 9 | project/boot/ 10 | .history 11 | .cache 12 | 13 | 14 | ### JetBrains template 15 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm 16 | 17 | *.iml 18 | 19 | ## Directory-based project format: 20 | .idea/ 21 | # if you remove the above rule, at least ignore the following: 22 | 23 | # User-specific stuff: 24 | # .idea/workspace.xml 25 | # .idea/tasks.xml 26 | # .idea/dictionaries 27 | 28 | # Sensitive or high-churn files: 29 | # .idea/dataSources.ids 30 | # .idea/dataSources.xml 31 | # .idea/sqlDataSources.xml 32 | # .idea/dynamic.xml 33 | # .idea/uiDesigner.xml 34 | 35 | # Gradle: 36 | # .idea/gradle.xml 37 | # .idea/libraries 38 | 39 | # Mongo Explorer plugin: 40 | # .idea/mongoSettings.xml 41 | 42 | ## File-based project format: 43 | *.ipr 44 | *.iws 45 | 46 | ## Plugin-specific files: 47 | 48 | # IntelliJ 49 | out/ 50 | 51 | # mpeltonen/sbt-idea plugin 52 | .idea_modules/ 53 | 54 | # JIRA plugin 55 | atlassian-ide-plugin.xml 56 | 57 | # Crashlytics plugin (for Android Studio and IntelliJ) 58 | com_crashlytics_export_strings.xml 59 | crashlytics.properties 60 | crashlytics-build.properties 61 | 62 | 63 | ### Scala template 64 | *.class 65 | *.log 66 | 67 | # sbt specific 68 | .lib/ 69 | dist/* 70 | project/plugins/project/ 71 | 72 | # Scala-IDE specific 73 | .scala_dependencies 74 | .worksheet 75 | 76 | 77 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Scala Steward 2 | Scala Steward 3 | Philippus Baalman 4 | -------------------------------------------------------------------------------- /.scalafmt.conf: -------------------------------------------------------------------------------- 1 | version = 3.9.7 2 | runner.dialect = scala213 3 | maxColumn = 100 4 | newlines.source = keep 5 | rewrite.trailingCommas.style = keep 6 | docstrings.style = Asterisk 7 | project.layout = StandardConvention 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | All repositories in these organizations: 2 | 3 | * [lightbend](https://github.com/lightbend) 4 | * [akka](https://github.com/akka) 5 | * [lagom](https://github.com/lagom) 6 | * [playframework](https://github.com/playframework) 7 | * [sbt](https://github.com/sbt) 8 | * [slick](https://github.com/slick) 9 | 10 | are covered by the Lightbend Community Code of Conduct: https://www.lightbend.com/conduct 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Releasing 2 | 3 | ### Preparation 4 | 5 | You will need credentials for publishing to the "typesafe" 6 | organization on Bintray. 7 | 8 | ### Release steps 9 | 10 | 1. Update the version number in `build.sbt` and `README.md`. Commit the changes. 11 | 2. Tag the commit with e.g. `git tag -a 9.8.7` and push the tag 12 | to GitHub. 13 | 3. Create the release at https://github.com/lightbend/lightbend-emoji/releases . 14 | 4. Locally, run `+publish` (the `+` is for cross-publishing for multiple 15 | Scala version) followed by `bintrayRelease`. 16 | 17 | If this last step succeeds, you will see e.g. `typesafe/emoji@9.8.7 18 | was released`. The artifacts will become available within a minute or two. 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015-2024 Lightbend Inc. [http://www.lightbend.com] 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 | use this file except in compliance with the License. You may obtain a copy of 5 | the License at 6 | 7 | [http://www.apache.org/licenses/LICENSE-2.0] 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 | License for the specific language governing permissions and limitations under 13 | the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Lightbend Emoji 2 | 3 | [![Build Status](https://github.com/lightbend-labs/lightbend-emoji/workflows/test/badge.svg)](https://github.com/lightbend-labs/lightbend-emoji/actions/workflows/ci.yml?query=workflow%3Atest+branch%3Amain) 4 | ![Current Version](https://img.shields.io/badge/version-1.2.1-brightgreen.svg?style=flat "1.2.1") 5 | 6 | Lightbend Emoji is a wrapper around Java's Unicode handling. 7 | 8 | ## Installation 9 | 10 | Supported Scala versions: 3, 2.13 11 | 12 | (The last version to support Scala 2.12 was [1.3.0](https://github.com/lightbend-labs/lightbend-emoji/releases/tag/1.3.0).) 13 | 14 | Add to `build.sbt`, inserting current version: 15 | 16 | ``` 17 | libraryDependencies += "com.lightbend" %% "emoji" % "" 18 | ``` 19 | 20 | ## Usage 21 | 22 | ``` 23 | $ sbt console 24 | scala> import com.lightbend.emoji._ 25 | scala> import com.lightbend.emoji.Emoji.Implicits._ 26 | ``` 27 | 28 | You can map Emoji directly from a Unicode character: 29 | 30 | ``` 31 | scala> Emoji(0x1f603) 32 | res0: com.lightbend.emoji.Emoji = 😃 33 | ``` 34 | 35 | Or you can map the implicit from `Int` or `String`: 36 | 37 | ``` 38 | scala> 0x1f603.emoji 39 | res1: com.lightbend.emoji.Emoji = 😃 40 | scala> "0x1f603".codePointEmoji 41 | res2: com.lightbend.emoji.Emoji = 😃 42 | ``` 43 | 44 | Once you have an emoji, you can ask it for `codePoint` (`Int`) or hexadecimal value: 45 | 46 | ``` 47 | scala> res2.hex 48 | res3: String = 0x1f603 49 | scala> res2.codePoint 50 | res4: Int = 128515 51 | ``` 52 | 53 | Unicode codepoints are not very convenient, so there's a `ShortCodes` class which is designed to be used as an implicit parameter for emoji mapping. 54 | 55 | There is a default mapping available, which allows you to map from a string directly to an emoji: 56 | 57 | ``` 58 | scala> import com.lightbend.emoji.ShortCodes.Implicits._ 59 | scala> import com.lightbend.emoji.ShortCodes.Defaults._ 60 | scala> "smiley".emoji 61 | res5: com.lightbend.emoji.Emoji = 😃 62 | ``` 63 | 64 | Short codes are not very convenient, so there's an emoji interpolator for constructing strings using familiar syntax: 65 | 66 | ``` 67 | scala> e"Have a nice day! :smiley:" 68 | res6: String = Have a nice day! 😃 69 | ``` 70 | 71 | It supports the same escapes as the standard interpolator, and is forgiving of colons that don't delimit a valid 72 | short name. The colon can be escaped with a backslash: 73 | 74 | ``` 75 | scala> e"Dear Customer: Have a nice day! :) :smiley:" 76 | res7: String = Dear Customer: Have a nice day! :) 😃 77 | 78 | scala> e"\:smiley\: is interpolated as :smiley:" 79 | res8: String = :smiley: is interpolated as 😃 80 | ``` 81 | 82 | You can query the current mapping for short codes: 83 | 84 | ``` 85 | scala> ShortCodes.current.shortCodes.filter(_.startsWith("heart")) 86 | res9: scala.collection.Set[String] = Set(heart_decoration, heart_eyes_cat, hearts, heart_eyes, heartpulse, heart, heartbeat) 87 | ``` 88 | 89 | Finally, you can also use your own short codes mapping: 90 | 91 | ``` 92 | scala> implicit val mycodes = new ShortCodes() 93 | mycodes: com.lightbend.emoji.ShortCodes = com.lightbend.emoji.ShortCodes@49fd69f5 94 | scala> mycodes.entry(Emoji(0x1f603), "yay") 95 | scala> "yay".emoji 96 | res1: com.lightbend.emoji.Emoji = 😃 97 | ``` 98 | 99 | ## Scala 3 100 | 101 | Imports for extension methods are slightly shorter in Scala 3. 102 | 103 | The default `ShortCodes` is `given` in `ShortCodes`. 104 | ``` 105 | scala> import com.lightbend.emoji.Emoji.* 106 | scala> import com.lightbend.emoji.ShortCodes.{given, *} 107 | ``` 108 | 109 | ## Similar Works 110 | 111 | These libraries have not been evaluated, and they may work or not: 112 | 113 | * https://github.com/vdurmont/emoji-java 114 | * https://github.com/kcthota/emoji4j 115 | 116 | ## Bugs 117 | 118 | Sadly, there is no direct mapping to [emoji-cheat-sheet](http://www.emoji-cheat-sheet.com/) or [emoji searcher](http://emoji.muan.co/), because some emoji are mapped directly to glyphs, without [Unicode involvement](http://apps.timwhitlock.info/emoji/tables/unicode), e.g. [:neckbeard:](https://signalvnoise.com/posts/3395-neckbeard). 119 | 120 | ## Typesafe Emojr 121 | 122 | For an example of Lightbend Emoji in an Enterprise Mission Critical Environment, please see [Typesafe Emojr](https://github.com/typesafehub/typesafe-emojr). 123 | 124 | Note that Typesafe Emojr has not been Lightbend-rebranded or ported 125 | to Scala 2.12+. To register your interest in an updated version, please 126 | contact Lightbend's enterprise sales team. 127 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | /// publishing 2 | 3 | name := "emoji" 4 | organization := "com.lightbend" 5 | homepage := Some(url("https://github.com/lightbend/lightbend-emoji")) 6 | licenses += ("Apache-2.0", url("https://www.apache.org/licenses/LICENSE-2.0.html")) 7 | scmInfo := Some(ScmInfo( 8 | url("https://github.com/lightbend/lightbend-emoji"), 9 | "scm:git:git@github.com:lightbend/lightbend-emoji.git" 10 | )) 11 | developers := List( 12 | Developer( 13 | id = "Lightbend", 14 | name = "Lightbend, Inc.", 15 | email = "", 16 | url = url("https://www.lightbend.com") 17 | ) 18 | ) 19 | 20 | ThisBuild / dynverVTagPrefix := false 21 | ThisBuild / versionScheme := Some("early-semver") 22 | 23 | /// build 24 | 25 | crossScalaVersions := Seq("2.13.16", "3.3.6") 26 | scalaVersion := crossScalaVersions.value.head 27 | 28 | libraryDependencies ++= Seq( 29 | "org.scalatest" %% "scalatest-wordspec" % "3.2.19" % Test, 30 | "org.scalatest" %% "scalatest-shouldmatchers" % "3.2.19" % Test, 31 | "org.scalameta" %% "munit" % "1.1.1" % Test, 32 | ) 33 | 34 | scalacOptions ++= Seq("-unchecked", "-deprecation", "-feature", "-Xfatal-warnings") ++ ( 35 | CrossVersion.partialVersion(scalaVersion.value) match { 36 | case Some((2, _)) => Seq("-Xlint") 37 | case _ => Seq.empty 38 | } 39 | ) 40 | 41 | Compile / console / scalacOptions ~= (_ filterNot Set( 42 | "-Xlint", 43 | "-Xfatal-warnings" 44 | )) 45 | 46 | Test / scalacOptions ~= (_ filterNot Set( 47 | "-Xfatal-warnings" 48 | )) 49 | 50 | console / initialCommands := { 51 | """import com.lightbend.emoji._ 52 | |import com.lightbend.emoji.Emoji.Implicits._ 53 | |import com.lightbend.emoji.ShortCodes.Implicits._ 54 | |""".stripMargin 55 | } 56 | 57 | /// MiMa 58 | 59 | mimaPreviousArtifacts := Set(organization.value %% name.value % "1.3.0") 60 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.11.1 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "1.1.4") 2 | addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.11.1") 3 | -------------------------------------------------------------------------------- /src/main/scala-2.12/com/lightbend/emoji/ScalaVersionSpecific.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | object ScalaVersionSpecific { 7 | def checkLengths(sc: StringContext, args: Seq[Any]): Unit = 8 | sc.checkLengths(args) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala-2.13/com/lightbend/emoji/ScalaVersionSpecific.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | object ScalaVersionSpecific { 7 | def checkLengths(sc: StringContext, args: Seq[Any]): Unit = 8 | StringContext.checkLengths(args, sc.parts) 9 | } 10 | -------------------------------------------------------------------------------- /src/main/scala-2/com/lightbend/emoji/Emoji.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import scala.util.Try 7 | 8 | /** 9 | * The value class representing a codepoint in the Emoji set. 10 | * 11 | * @param codePoint 12 | * the codepoint representing the Emoji character 13 | */ 14 | class Emoji private (val codePoint: Int) extends AnyVal { 15 | 16 | /** 17 | * Returns the sequence of characters (usually surrogate pairs). 18 | */ 19 | def chars: Array[Char] = Character.toChars(codePoint) 20 | 21 | /** 22 | * Returns the emoji's Unicode name. 23 | */ 24 | def name: String = Emoji.name(this.codePoint) 25 | 26 | /** 27 | * Returns the hexadecimal code. 28 | * 29 | * @return 30 | */ 31 | def toHexString: String = Emoji.toHexString(this.codePoint) 32 | 33 | /** 34 | * A convenience method that prepends "0x" before toHexString 35 | * 36 | * @return 37 | */ 38 | def hex: String = "0x" + toHexString 39 | 40 | /** 41 | * Returns the emoji as a String. Use this if you want smiley faces. 42 | */ 43 | override def toString = new String(chars) 44 | } 45 | 46 | class EmojiNotFound(msg: String) extends RuntimeException(msg) 47 | 48 | /** 49 | * This is the singleton object for Emoji. 50 | */ 51 | object Emoji { 52 | 53 | object Implicits { 54 | 55 | implicit class RichStringEmoji(string: String) { 56 | 57 | // Don't want this to conflict with shortCode.emoji 58 | def codePointEmoji: Emoji = { 59 | val codePoint = Try(Integer.parseInt(string, 16)).recover { 60 | case e: NumberFormatException => 61 | val stripped = string.replace("0x", "") 62 | Integer.parseInt(stripped, 16) 63 | }.getOrElse { 64 | throw new EmojiNotFound("Cannot parse emoji from hexadecimal string") 65 | } 66 | Emoji(codePoint) 67 | } 68 | } 69 | 70 | implicit class RichIntEmoji(codePoint: Int) { 71 | def emoji: Emoji = { 72 | Emoji(codePoint) 73 | } 74 | } 75 | 76 | } 77 | 78 | /** 79 | * Returns the emoji for the given array of characters, throws EmojiNotFound 80 | */ 81 | def apply(chars: Array[Char]): Emoji = { 82 | val codePoint = Character.codePointAt(chars, 0) 83 | apply(codePoint) 84 | } 85 | 86 | /** 87 | * Returns the emoji given a string containing the codepoint. 88 | */ 89 | def apply(string: String): Emoji = { 90 | val codePoint = string.codePointAt(0) 91 | apply(codePoint) 92 | } 93 | 94 | /** 95 | * Returns the emoji for this codepoint if found, throws EmojiNotFound otherwise. 96 | */ 97 | def apply(codePoint: Int): Emoji = { 98 | validate(codePoint) 99 | new Emoji(codePoint) 100 | } 101 | 102 | /** 103 | * Returns Some(emoji) if found, None otherwise. 104 | */ 105 | def get(codePoint: Int): Option[Emoji] = { 106 | if (Emoji.isEmoji(codePoint)) { 107 | Some(new Emoji(codePoint)) 108 | } else { 109 | None 110 | } 111 | } 112 | 113 | /** 114 | * Returns true if this is a valid Unicode codepoint, false otherwise. 115 | */ 116 | def isEmoji(codePoint: Int): Boolean = { 117 | // there is no codeblock for unicode. 118 | // val block = UnicodeBlock.of(codePoint) 119 | // block == Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS || 120 | // block == Character.UnicodeBlock.EMOTICONS || 121 | // block == Character.UnicodeBlock.TRANSPORT_AND_MAP_SYMBOLS || 122 | // block == Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS || 123 | // block == Character.UnicodeBlock.DINGBATS 124 | Character.isValidCodePoint(codePoint) 125 | } 126 | 127 | /** 128 | * Throws an exception if this is not a valid Unicode codepoint. 129 | */ 130 | def validate(codePoint: Int): Unit = { 131 | if (!Emoji.isEmoji(codePoint)) { 132 | throw new EmojiNotFound("Code point is not emoji!") 133 | } 134 | } 135 | 136 | /** 137 | * Returns the unicode name for this codePoint. Throws EmojiNotFound if this is not a valid 138 | * codepoint. 139 | * 140 | * @param codePoint 141 | * the codePoint. 142 | * @return 143 | * the unicode description of the emoji. 144 | */ 145 | def name(codePoint: Int): String = { 146 | Option(Character.getName(codePoint)).getOrElse { 147 | throw new EmojiNotFound("No name found for this codePoint") 148 | } 149 | } 150 | 151 | /** 152 | * Returns the hexadecimal string of the code point. 153 | */ 154 | def toHexString(codePoint: Int): String = { 155 | codePoint.toHexString 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /src/main/scala-2/com/lightbend/emoji/ShortCodes.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import ScalaVersionSpecific.checkLengths 7 | 8 | /** 9 | * An emoji to shortcode mapping. This is a class that should be declared and used as an implicit 10 | * value, so that shortcode mappings don't have to be global across an application. 11 | * 12 | * "import ShortCodes.Defaults._" to import the default shortcode mapping. "import 13 | * ShortCodes.Implicits._" to enrich Emoji and String with shortcode methods. 14 | */ 15 | class ShortCodes(template: Option[ShortCodes] = None) { 16 | 17 | private val emojiToShortCodes = collection.mutable.Map[Emoji, collection.Set[String]]() 18 | 19 | private val shortCodeToEmoji = collection.mutable.Map[String, Emoji]() 20 | 21 | template.foreach { t => 22 | for ((emoji, shortCodes) <- t.emojiToShortCodes) { 23 | shortCodes.foreach(code => entry(emoji, code)) 24 | } 25 | } 26 | 27 | /** 28 | * Defines a mapping between an emoji and a short code. Emojis may have multiple short code 29 | * mappings. 30 | */ 31 | def entry(emoji: Emoji, shortCode: String): Unit = { 32 | emojiToShortCodes.get(emoji) match { 33 | case Some(shortCodes) => 34 | emojiToShortCodes += (emoji -> (shortCodes ++ Set(shortCode))) 35 | case None => 36 | emojiToShortCodes += (emoji -> Set(shortCode)) 37 | } 38 | 39 | shortCodeToEmoji += (shortCode -> emoji) 40 | } 41 | 42 | /** 43 | * Returns the short codes for this emoji. 44 | */ 45 | def shortCodes(emoji: Emoji): Option[collection.Set[String]] = { 46 | emojiToShortCodes.get(emoji) 47 | } 48 | 49 | /** 50 | * Returns Some(emoji) if a short code is defined, None otherwise 51 | */ 52 | def emoji(shortCode: String): Option[Emoji] = { 53 | shortCodeToEmoji.get(shortCode) 54 | } 55 | 56 | /** 57 | * Returns the set of emojis that have short codes. 58 | */ 59 | def emojis: collection.Set[Emoji] = { 60 | emojiToShortCodes.keySet 61 | } 62 | 63 | /** 64 | * Returns the set of short codes mapped to emojis. 65 | */ 66 | def shortCodes: collection.Set[String] = { 67 | shortCodeToEmoji.keySet 68 | } 69 | 70 | /** 71 | * Removes emoji from the shortcodes mapping. This removes all the codes that map to the emoji as 72 | * well. 73 | */ 74 | def removeEmoji(emoji: Emoji): Unit = { 75 | emojiToShortCodes.remove(emoji).foreach { shortCodes => 76 | shortCodes.foreach { shortCode => 77 | shortCodeToEmoji.remove(shortCode) 78 | } 79 | } 80 | } 81 | 82 | /** 83 | * Removes a shortcode from the mapping. This does not remove the emoji. 84 | */ 85 | def removeCode(shortCode: String): Unit = { 86 | shortCodeToEmoji.remove(shortCode).foreach { emoji => 87 | emojiToShortCodes.get(emoji).map { codes => 88 | val set = codes diff Set(shortCode) 89 | if (set.isEmpty) { 90 | emojiToShortCodes.remove(emoji) 91 | } else { 92 | emojiToShortCodes.put(emoji, set) 93 | } 94 | } 95 | } 96 | } 97 | 98 | /** 99 | * Completely removes the emoji and shortcodes from the mapping. 100 | */ 101 | def clear(): Unit = { 102 | emojiToShortCodes.clear() 103 | shortCodeToEmoji.clear() 104 | } 105 | 106 | } 107 | 108 | /** 109 | * Companion object for shortcodes. 110 | */ 111 | object ShortCodes { 112 | 113 | /** 114 | * Returns the in-scope implicit shortcodes mapping. 115 | */ 116 | def current(implicit shortCodes: ShortCodes): ShortCodes = { 117 | shortCodes 118 | } 119 | 120 | /** 121 | * Maps short codes onto Emoji and String, so you can say "+1".emoji and thumbsUpEmoji.shortCodes. 122 | */ 123 | object Implicits { 124 | 125 | implicit class ShortCodeString(shortCode: String) { 126 | def emoji(implicit shortCodes: ShortCodes): Emoji = { 127 | shortCodes.emoji(shortCode).getOrElse { 128 | throw new EmojiNotFound("No emoji found for short code") 129 | } 130 | } 131 | } 132 | 133 | implicit class EmojiShortCodes(emoji: Emoji) { 134 | def shortCodes(implicit shortCodes: ShortCodes): Option[collection.Set[String]] = { 135 | shortCodes.shortCodes(emoji) 136 | } 137 | } 138 | 139 | private val colonSyntax = ":([a-zA-Z0-9_+-]+):".r 140 | 141 | implicit class Emojilator(sc: StringContext) { 142 | import StringContext.InvalidEscapeException 143 | 144 | def e(args: Any*)(implicit shortCodes: ShortCodes): String = { 145 | def emojify(s: String): String = colonSyntax.replaceAllIn( 146 | s, 147 | m => 148 | try m.group(1).emoji.toString 149 | catch { case _: EmojiNotFound => m.matched } 150 | ) 151 | checkLengths(sc, args) 152 | val sb = new java.lang.StringBuilder 153 | def process(part: String): String = emojify(StringContext.processEscapes(part)) 154 | def partly(part: String): Unit = { 155 | try sb append process(part) 156 | catch { 157 | case e: InvalidEscapeException 158 | if e.index < part.length - 1 && part.charAt(e.index + 1) == ':' => 159 | sb append process(part.substring(0, e.index)) 160 | sb append ":" 161 | partly(part.substring(e.index + 2)) 162 | } 163 | } 164 | val pi = sc.parts.iterator 165 | val ai = args.iterator 166 | partly(pi.next()) 167 | while (ai.hasNext) { 168 | sb append ai.next() 169 | partly(pi.next()) 170 | } 171 | sb.toString 172 | } 173 | } 174 | } 175 | 176 | /** 177 | * The default shortcodes mapping, as used by emoji-cheat-sheet. 178 | */ 179 | object Defaults { 180 | implicit lazy val defaultImplicit: ShortCodes = { 181 | val sc = new ShortCodes 182 | defaults(sc) 183 | sc 184 | } 185 | 186 | def defaults(sc: ShortCodes) = { 187 | import sc._ 188 | 189 | entry(Emoji(0x1f44d), ("+1")) 190 | entry(Emoji(0x1f44e), ("-1")) 191 | entry(Emoji(0x1f4af), ("100")) 192 | entry(Emoji(0x1f522), ("1234")) 193 | entry(Emoji(0x1f3b1), ("8ball")) 194 | entry(Emoji(0x1f170), ("a")) 195 | entry(Emoji(0x1f18e), ("ab")) 196 | entry(Emoji(0x1f524), ("abc")) 197 | entry(Emoji(0x1f521), ("abcd")) 198 | entry(Emoji(0x1f251), ("accept")) 199 | entry(Emoji(0x1f6a1), ("aerial_tramway")) 200 | entry(Emoji(0x02708), ("airplane")) 201 | entry(Emoji(0x023f0), ("alarm_clock")) 202 | entry(Emoji(0x1f47d), ("alien")) 203 | entry(Emoji(0x1f691), ("ambulance")) 204 | entry(Emoji(0x02693), ("anchor")) 205 | entry(Emoji(0x1f47c), ("angel")) 206 | entry(Emoji(0x1f4a2), ("anger")) 207 | entry(Emoji(0x1f620), ("angry")) 208 | entry(Emoji(0x1f627), ("anguished")) 209 | entry(Emoji(0x1f41c), ("ant")) 210 | entry(Emoji(0x1f34e), ("apple")) 211 | entry(Emoji(0x02652), ("aquarius")) 212 | entry(Emoji(0x02648), ("aries")) 213 | entry(Emoji(0x025c0), ("arrow_backward")) 214 | entry(Emoji(0x023ec), ("arrow_double_down")) 215 | entry(Emoji(0x023eb), ("arrow_double_up")) 216 | entry(Emoji(0x02b07), ("arrow_down")) 217 | entry(Emoji(0x1f53d), ("arrow_down_small")) 218 | entry(Emoji(0x025b6), ("arrow_forward")) 219 | entry(Emoji(0x02935), ("arrow_heading_down")) 220 | entry(Emoji(0x02934), ("arrow_heading_up")) 221 | entry(Emoji(0x02b05), ("arrow_left")) 222 | entry(Emoji(0x02199), ("arrow_lower_left")) 223 | entry(Emoji(0x02198), ("arrow_lower_right")) 224 | entry(Emoji(0x027a1), ("arrow_right")) 225 | entry(Emoji(0x021aa), ("arrow_right_hook")) 226 | entry(Emoji(0x02b06), ("arrow_up")) 227 | entry(Emoji(0x02195), ("arrow_up_down")) 228 | entry(Emoji(0x1f53c), ("arrow_up_small")) 229 | entry(Emoji(0x02196), ("arrow_upper_left")) 230 | entry(Emoji(0x02197), ("arrow_upper_right")) 231 | entry(Emoji(0x1f503), ("arrows_clockwise")) 232 | entry(Emoji(0x1f504), ("arrows_counterclockwise")) 233 | entry(Emoji(0x1f3a8), ("art")) 234 | entry(Emoji(0x1f69b), ("articulated_lorry")) 235 | entry(Emoji(0x1f632), ("astonished")) 236 | entry(Emoji(0x1f45f), ("athletic_shoe")) 237 | entry(Emoji(0x1f3e7), ("atm")) 238 | entry(Emoji(0x1f171), ("b")) 239 | entry(Emoji(0x1f476), ("baby")) 240 | entry(Emoji(0x1f37c), ("baby_bottle")) 241 | entry(Emoji(0x1f424), ("baby_chick")) 242 | entry(Emoji(0x1f6bc), ("baby_symbol")) 243 | entry(Emoji(0x1f519), ("back")) 244 | entry(Emoji(0x1f6c4), ("baggage_claim")) 245 | entry(Emoji(0x1f388), ("balloon")) 246 | entry(Emoji(0x02611), ("ballot_box_with_check")) 247 | entry(Emoji(0x1f38d), ("bamboo")) 248 | entry(Emoji(0x1f34c), ("banana")) 249 | entry(Emoji(0x0203c), ("bangbang")) 250 | entry(Emoji(0x1f3e6), ("bank")) 251 | entry(Emoji(0x1f4ca), ("bar_chart")) 252 | entry(Emoji(0x1f488), ("barber")) 253 | entry(Emoji(0x026be), ("baseball")) 254 | entry(Emoji(0x1f3c0), ("basketball")) 255 | entry(Emoji(0x1f6c0), ("bath")) 256 | entry(Emoji(0x1f6c1), ("bathtub")) 257 | entry(Emoji(0x1f50b), ("battery")) 258 | entry(Emoji(0x1f43b), ("bear")) 259 | entry(Emoji(0x1f41d), ("bee")) 260 | entry(Emoji(0x1f37a), ("beer")) 261 | entry(Emoji(0x1f37b), ("beers")) 262 | entry(Emoji(0x1f41e), ("beetle")) 263 | entry(Emoji(0x1f530), ("beginner")) 264 | entry(Emoji(0x1f514), ("bell")) 265 | entry(Emoji(0x1f371), ("bento")) 266 | entry(Emoji(0x1f6b4), ("bicyclist")) 267 | entry(Emoji(0x1f6b2), ("bike")) 268 | entry(Emoji(0x1f459), ("bikini")) 269 | entry(Emoji(0x1f426), ("bird")) 270 | entry(Emoji(0x1f382), ("birthday")) 271 | entry(Emoji(0x026ab), ("black_circle")) 272 | entry(Emoji(0x1f0cf), ("black_joker")) 273 | entry(Emoji(0x02b1b), ("black_large_square")) 274 | entry(Emoji(0x025fe), ("black_medium_small_square")) 275 | entry(Emoji(0x025fc), ("black_medium_square")) 276 | entry(Emoji(0x02712), ("black_nib")) 277 | entry(Emoji(0x025aa), ("black_small_square")) 278 | entry(Emoji(0x1f532), ("black_square_button")) 279 | entry(Emoji(0x1f33c), ("blossom")) 280 | entry(Emoji(0x1f421), ("blowfish")) 281 | entry(Emoji(0x1f4d8), ("blue_book")) 282 | entry(Emoji(0x1f699), ("blue_car")) 283 | entry(Emoji(0x1f499), ("blue_heart")) 284 | entry(Emoji(0x1f60a), ("blush")) 285 | entry(Emoji(0x1f417), ("boar")) 286 | entry(Emoji(0x026f5), ("boat")) 287 | entry(Emoji(0x1f4a3), ("bomb")) 288 | entry(Emoji(0x1f4d6), ("book")) 289 | entry(Emoji(0x1f516), ("bookmark")) 290 | entry(Emoji(0x1f4d1), ("bookmark_tabs")) 291 | entry(Emoji(0x1f4da), ("books")) 292 | entry(Emoji(0x1f4a5), ("boom")) 293 | entry(Emoji(0x1f462), ("boot")) 294 | entry(Emoji(0x1f490), ("bouquet")) 295 | entry(Emoji(0x1f647), ("bow")) 296 | entry(Emoji(0x1f3b3), ("bowling")) 297 | entry(Emoji(0x1f466), ("boy")) 298 | entry(Emoji(0x1f35e), ("bread")) 299 | entry(Emoji(0x1f470), ("bride_with_veil")) 300 | entry(Emoji(0x1f309), ("bridge_at_night")) 301 | entry(Emoji(0x1f4bc), ("briefcase")) 302 | entry(Emoji(0x1f494), ("broken_heart")) 303 | entry(Emoji(0x1f41b), ("bug")) 304 | entry(Emoji(0x1f4a1), ("bulb")) 305 | entry(Emoji(0x1f685), ("bullettrain_front")) 306 | entry(Emoji(0x1f684), ("bullettrain_side")) 307 | entry(Emoji(0x1f68c), ("bus")) 308 | entry(Emoji(0x1f68f), ("busstop")) 309 | entry(Emoji(0x1f464), ("bust_in_silhouette")) 310 | entry(Emoji(0x1f465), ("busts_in_silhouette")) 311 | entry(Emoji(0x1f335), ("cactus")) 312 | entry(Emoji(0x1f370), ("cake")) 313 | entry(Emoji(0x1f4c6), ("calendar")) 314 | entry(Emoji(0x1f4f2), ("calling")) 315 | entry(Emoji(0x1f42b), ("camel")) 316 | entry(Emoji(0x1f4f7), ("camera")) 317 | entry(Emoji(0x0264b), ("cancer")) 318 | entry(Emoji(0x1f36c), ("candy")) 319 | entry(Emoji(0x1f520), ("capital_abcd")) 320 | entry(Emoji(0x02651), ("capricorn")) 321 | entry(Emoji(0x1f697), ("car")) 322 | entry(Emoji(0x1f4c7), ("card_index")) 323 | entry(Emoji(0x1f3a0), ("carousel_horse")) 324 | entry(Emoji(0x1f431), ("cat")) 325 | entry(Emoji(0x1f408), ("cat2")) 326 | entry(Emoji(0x1f4bf), ("cd")) 327 | entry(Emoji(0x1f4b9), ("chart")) 328 | entry(Emoji(0x1f4c9), ("chart_with_downwards_trend")) 329 | entry(Emoji(0x1f4c8), ("chart_with_upwards_trend")) 330 | entry(Emoji(0x1f3c1), ("checkered_flag")) 331 | entry(Emoji(0x1f352), ("cherries")) 332 | entry(Emoji(0x1f338), ("cherry_blossom")) 333 | entry(Emoji(0x1f330), ("chestnut")) 334 | entry(Emoji(0x1f414), ("chicken")) 335 | entry(Emoji(0x1f6b8), ("children_crossing")) 336 | entry(Emoji(0x1f36b), ("chocolate_bar")) 337 | entry(Emoji(0x1f384), ("christmas_tree")) 338 | entry(Emoji(0x026ea), ("church")) 339 | entry(Emoji(0x1f3a6), ("cinema")) 340 | entry(Emoji(0x1f3aa), ("circus_tent")) 341 | entry(Emoji(0x1f307), ("city_sunrise")) 342 | entry(Emoji(0x1f306), ("city_sunset")) 343 | entry(Emoji(0x1f191), ("cl")) 344 | entry(Emoji(0x1f44f), ("clap")) 345 | entry(Emoji(0x1f3ac), ("clapper")) 346 | entry(Emoji(0x1f4cb), ("clipboard")) 347 | entry(Emoji(0x1f550), ("clock1")) 348 | entry(Emoji(0x1f559), ("clock10")) 349 | entry(Emoji(0x1f565), ("clock1030")) 350 | entry(Emoji(0x1f55a), ("clock11")) 351 | entry(Emoji(0x1f566), ("clock1130")) 352 | entry(Emoji(0x1f55b), ("clock12")) 353 | entry(Emoji(0x1f567), ("clock1230")) 354 | entry(Emoji(0x1f55c), ("clock130")) 355 | entry(Emoji(0x1f551), ("clock2")) 356 | entry(Emoji(0x1f55d), ("clock230")) 357 | entry(Emoji(0x1f552), ("clock3")) 358 | entry(Emoji(0x1f55e), ("clock330")) 359 | entry(Emoji(0x1f553), ("clock4")) 360 | entry(Emoji(0x1f55f), ("clock430")) 361 | entry(Emoji(0x1f554), ("clock5")) 362 | entry(Emoji(0x1f560), ("clock530")) 363 | entry(Emoji(0x1f555), ("clock6")) 364 | entry(Emoji(0x1f561), ("clock630")) 365 | entry(Emoji(0x1f556), ("clock7")) 366 | entry(Emoji(0x1f562), ("clock730")) 367 | entry(Emoji(0x1f557), ("clock8")) 368 | entry(Emoji(0x1f563), ("clock830")) 369 | entry(Emoji(0x1f558), ("clock9")) 370 | entry(Emoji(0x1f564), ("clock930")) 371 | entry(Emoji(0x1f4d5), ("closed_book")) 372 | entry(Emoji(0x1f510), ("closed_lock_with_key")) 373 | entry(Emoji(0x1f302), ("closed_umbrella")) 374 | entry(Emoji(0x02601), ("cloud")) 375 | entry(Emoji(0x02663), ("clubs")) 376 | entry(Emoji(0x1f378), ("cocktail")) 377 | entry(Emoji(0x02615), ("coffee")) 378 | entry(Emoji(0x1f630), ("cold_sweat")) 379 | entry(Emoji(0x1f4a5), ("collision")) 380 | entry(Emoji(0x1f4bb), ("computer")) 381 | entry(Emoji(0x1f38a), ("confetti_ball")) 382 | entry(Emoji(0x1f616), ("confounded")) 383 | entry(Emoji(0x1f615), ("confused")) 384 | entry(Emoji(0x03297), ("congratulations")) 385 | entry(Emoji(0x1f6a7), ("construction")) 386 | entry(Emoji(0x1f477), ("construction_worker")) 387 | entry(Emoji(0x1f3ea), ("convenience_store")) 388 | entry(Emoji(0x1f36a), ("cookie")) 389 | entry(Emoji(0x1f192), ("cool")) 390 | entry(Emoji(0x1f46e), ("cop")) 391 | entry(Emoji(0x000a9), ("copyright")) 392 | entry(Emoji(0x1f33d), ("corn")) 393 | entry(Emoji(0x1f46b), ("couple")) 394 | entry(Emoji(0x1f491), ("couple_with_heart")) 395 | entry(Emoji(0x1f48f), ("couplekiss")) 396 | entry(Emoji(0x1f42e), ("cow")) 397 | entry(Emoji(0x1f404), ("cow2")) 398 | entry(Emoji(0x1f4b3), ("credit_card")) 399 | entry(Emoji(0x1f319), ("crescent_moon")) 400 | entry(Emoji(0x1f40a), ("crocodile")) 401 | entry(Emoji(0x1f38c), ("crossed_flags")) 402 | entry(Emoji(0x1f451), ("crown")) 403 | entry(Emoji(0x1f622), ("cry")) 404 | entry(Emoji(0x1f63f), ("crying_cat_face")) 405 | entry(Emoji(0x1f52e), ("crystal_ball")) 406 | entry(Emoji(0x1f498), ("cupid")) 407 | entry(Emoji(0x027b0), ("curly_loop")) 408 | entry(Emoji(0x1f4b1), ("currency_exchange")) 409 | entry(Emoji(0x1f35b), ("curry")) 410 | entry(Emoji(0x1f36e), ("custard")) 411 | entry(Emoji(0x1f6c3), ("customs")) 412 | entry(Emoji(0x1f300), ("cyclone")) 413 | entry(Emoji(0x1f483), ("dancer")) 414 | entry(Emoji(0x1f46f), ("dancers")) 415 | entry(Emoji(0x1f361), ("dango")) 416 | entry(Emoji(0x1f3af), ("dart")) 417 | entry(Emoji(0x1f4a8), ("dash")) 418 | entry(Emoji(0x1f4c5), ("date")) 419 | entry(Emoji(0x1f333), ("deciduous_tree")) 420 | entry(Emoji(0x1f3ec), ("department_store")) 421 | entry(Emoji(0x1f4a0), ("diamond_shape_with_a_dot_inside")) 422 | entry(Emoji(0x02666), ("diamonds")) 423 | entry(Emoji(0x1f61e), ("disappointed")) 424 | entry(Emoji(0x1f625), ("disappointed_relieved")) 425 | entry(Emoji(0x1f4ab), ("dizzy")) 426 | entry(Emoji(0x1f635), ("dizzy_face")) 427 | entry(Emoji(0x1f6af), ("do_not_litter")) 428 | entry(Emoji(0x1f436), ("dog")) 429 | entry(Emoji(0x1f415), ("dog2")) 430 | entry(Emoji(0x1f4b5), ("dollar")) 431 | entry(Emoji(0x1f38e), ("dolls")) 432 | entry(Emoji(0x1f42c), ("dolphin")) 433 | entry(Emoji(0x1f6aa), ("door")) 434 | entry(Emoji(0x1f369), ("doughnut")) 435 | entry(Emoji(0x1f409), ("dragon")) 436 | entry(Emoji(0x1f432), ("dragon_face")) 437 | entry(Emoji(0x1f457), ("dress")) 438 | entry(Emoji(0x1f42a), ("dromedary_camel")) 439 | entry(Emoji(0x1f4a7), ("droplet")) 440 | entry(Emoji(0x1f4c0), ("dvd")) 441 | entry(Emoji(0x1f4e7), ("e-mail")) 442 | entry(Emoji(0x1f442), ("ear")) 443 | entry(Emoji(0x1f33e), ("ear_of_rice")) 444 | entry(Emoji(0x1f30d), ("earth_africa")) 445 | entry(Emoji(0x1f30e), ("earth_americas")) 446 | entry(Emoji(0x1f30f), ("earth_asia")) 447 | entry(Emoji(0x1f373), ("egg")) 448 | entry(Emoji(0x1f346), ("eggplant")) 449 | entry(Emoji(0x02734), ("eight_pointed_black_star")) 450 | entry(Emoji(0x02733), ("eight_spoked_asterisk")) 451 | entry(Emoji(0x1f50c), ("electric_plug")) 452 | entry(Emoji(0x1f418), ("elephant")) 453 | entry(Emoji(0x02709), ("email")) 454 | entry(Emoji(0x1f51a), ("end")) 455 | entry(Emoji(0x02709), ("envelope")) 456 | entry(Emoji(0x1f4e9), ("envelope_with_arrow")) 457 | entry(Emoji(0x1f4b6), ("euro")) 458 | entry(Emoji(0x1f3f0), ("european_castle")) 459 | entry(Emoji(0x1f3e4), ("european_post_office")) 460 | entry(Emoji(0x1f332), ("evergreen_tree")) 461 | entry(Emoji(0x02757), ("exclamation")) 462 | entry(Emoji(0x1f611), ("expressionless")) 463 | entry(Emoji(0x1f453), ("eyeglasses")) 464 | entry(Emoji(0x1f440), ("eyes")) 465 | entry(Emoji(0x1f44a), ("facepunch")) 466 | entry(Emoji(0x1f3ed), ("factory")) 467 | entry(Emoji(0x1f342), ("fallen_leaf")) 468 | entry(Emoji(0x1f46a), ("family")) 469 | entry(Emoji(0x023e9), ("fast_forward")) 470 | entry(Emoji(0x1f4e0), ("fax")) 471 | entry(Emoji(0x1f628), ("fearful")) 472 | entry(Emoji(0x1f43e), ("feet")) 473 | entry(Emoji(0x1f3a1), ("ferris_wheel")) 474 | entry(Emoji(0x1f4c1), ("file_folder")) 475 | entry(Emoji(0x1f525), ("fire")) 476 | entry(Emoji(0x1f692), ("fire_engine")) 477 | entry(Emoji(0x1f386), ("fireworks")) 478 | entry(Emoji(0x1f313), ("first_quarter_moon")) 479 | entry(Emoji(0x1f31b), ("first_quarter_moon_with_face")) 480 | entry(Emoji(0x1f41f), ("fish")) 481 | entry(Emoji(0x1f365), ("fish_cake")) 482 | entry(Emoji(0x1f3a3), ("fishing_pole_and_fish")) 483 | entry(Emoji(0x0270a), ("fist")) 484 | entry(Emoji(0x1f38f), ("flags")) 485 | entry(Emoji(0x1f526), ("flashlight")) 486 | entry(Emoji(0x1f42c), ("flipper")) 487 | entry(Emoji(0x1f4be), ("floppy_disk")) 488 | entry(Emoji(0x1f3b4), ("flower_playing_cards")) 489 | entry(Emoji(0x1f633), ("flushed")) 490 | entry(Emoji(0x1f301), ("foggy")) 491 | entry(Emoji(0x1f3c8), ("football")) 492 | entry(Emoji(0x1f463), ("footprints")) 493 | entry(Emoji(0x1f374), ("fork_and_knife")) 494 | entry(Emoji(0x026f2), ("fountain")) 495 | entry(Emoji(0x1f340), ("four_leaf_clover")) 496 | entry(Emoji(0x1f193), ("free")) 497 | entry(Emoji(0x1f364), ("fried_shrimp")) 498 | entry(Emoji(0x1f35f), ("fries")) 499 | entry(Emoji(0x1f438), ("frog")) 500 | entry(Emoji(0x1f626), ("frowning")) 501 | entry(Emoji(0x026fd), ("fuelpump")) 502 | entry(Emoji(0x1f315), ("full_moon")) 503 | entry(Emoji(0x1f31d), ("full_moon_with_face")) 504 | entry(Emoji(0x1f3b2), ("game_die")) 505 | entry(Emoji(0x1f48e), ("gem")) 506 | entry(Emoji(0x0264a), ("gemini")) 507 | entry(Emoji(0x1f47b), ("ghost")) 508 | entry(Emoji(0x1f381), ("gift")) 509 | entry(Emoji(0x1f49d), ("gift_heart")) 510 | entry(Emoji(0x1f467), ("girl")) 511 | entry(Emoji(0x1f310), ("globe_with_meridians")) 512 | entry(Emoji(0x1f410), ("goat")) 513 | entry(Emoji(0x026f3), ("golf")) 514 | entry(Emoji(0x1f347), ("grapes")) 515 | entry(Emoji(0x1f34f), ("green_apple")) 516 | entry(Emoji(0x1f4d7), ("green_book")) 517 | entry(Emoji(0x1f49a), ("green_heart")) 518 | entry(Emoji(0x02755), ("grey_exclamation")) 519 | entry(Emoji(0x02754), ("grey_question")) 520 | entry(Emoji(0x1f62c), ("grimacing")) 521 | entry(Emoji(0x1f601), ("grin")) 522 | entry(Emoji(0x1f600), ("grinning")) 523 | entry(Emoji(0x1f482), ("guardsman")) 524 | entry(Emoji(0x1f3b8), ("guitar")) 525 | entry(Emoji(0x1f52b), ("gun")) 526 | entry(Emoji(0x1f487), ("haircut")) 527 | entry(Emoji(0x1f354), ("hamburger")) 528 | entry(Emoji(0x1f528), ("hammer")) 529 | entry(Emoji(0x1f439), ("hamster")) 530 | entry(Emoji(0x0270b), ("hand")) 531 | entry(Emoji(0x1f45c), ("handbag")) 532 | entry(Emoji(0x1f4a9), ("hankey")) 533 | entry(Emoji(0x1f425), ("hatched_chick")) 534 | entry(Emoji(0x1f423), ("hatching_chick")) 535 | entry(Emoji(0x1f3a7), ("headphones")) 536 | entry(Emoji(0x1f649), ("hear_no_evil")) 537 | entry(Emoji(0x02764), ("heart")) 538 | entry(Emoji(0x1f49f), ("heart_decoration")) 539 | entry(Emoji(0x1f60d), ("heart_eyes")) 540 | entry(Emoji(0x1f63b), ("heart_eyes_cat")) 541 | entry(Emoji(0x1f493), ("heartbeat")) 542 | entry(Emoji(0x1f497), ("heartpulse")) 543 | entry(Emoji(0x02665), ("hearts")) 544 | entry(Emoji(0x02714), ("heavy_check_mark")) 545 | entry(Emoji(0x02797), ("heavy_division_sign")) 546 | entry(Emoji(0x1f4b2), ("heavy_dollar_sign")) 547 | entry(Emoji(0x02757), ("heavy_exclamation_mark")) 548 | entry(Emoji(0x02796), ("heavy_minus_sign")) 549 | entry(Emoji(0x02716), ("heavy_multiplication_x")) 550 | entry(Emoji(0x02795), ("heavy_plus_sign")) 551 | entry(Emoji(0x1f681), ("helicopter")) 552 | entry(Emoji(0x1f33f), ("herb")) 553 | entry(Emoji(0x1f33a), ("hibiscus")) 554 | entry(Emoji(0x1f506), ("high_brightness")) 555 | entry(Emoji(0x1f460), ("high_heel")) 556 | entry(Emoji(0x1f52a), ("hocho")) 557 | entry(Emoji(0x1f36f), ("honey_pot")) 558 | entry(Emoji(0x1f41d), ("honeybee")) 559 | entry(Emoji(0x1f434), ("horse")) 560 | entry(Emoji(0x1f3c7), ("horse_racing")) 561 | entry(Emoji(0x1f3e5), ("hospital")) 562 | entry(Emoji(0x1f3e8), ("hotel")) 563 | entry(Emoji(0x02668), ("hotsprings")) 564 | entry(Emoji(0x0231b), ("hourglass")) 565 | entry(Emoji(0x023f3), ("hourglass_flowing_sand")) 566 | entry(Emoji(0x1f3e0), ("house")) 567 | entry(Emoji(0x1f3e1), ("house_with_garden")) 568 | entry(Emoji(0x1f62f), ("hushed")) 569 | entry(Emoji(0x1f368), ("ice_cream")) 570 | entry(Emoji(0x1f366), ("icecream")) 571 | entry(Emoji(0x1f194), ("id")) 572 | entry(Emoji(0x1f250), ("ideograph_advantage")) 573 | entry(Emoji(0x1f47f), ("imp")) 574 | entry(Emoji(0x1f4e5), ("inbox_tray")) 575 | entry(Emoji(0x1f4e8), ("incoming_envelope")) 576 | entry(Emoji(0x1f481), ("information_desk_person")) 577 | entry(Emoji(0x02139), ("information_source")) 578 | entry(Emoji(0x1f607), ("innocent")) 579 | entry(Emoji(0x02049), ("interrobang")) 580 | entry(Emoji(0x1f4f1), ("iphone")) 581 | entry(Emoji(0x1f3ee), ("izakaya_lantern")) 582 | entry(Emoji(0x1f383), ("jack_o_lantern")) 583 | entry(Emoji(0x1f5fe), ("japan")) 584 | entry(Emoji(0x1f3ef), ("japanese_castle")) 585 | entry(Emoji(0x1f47a), ("japanese_goblin")) 586 | entry(Emoji(0x1f479), ("japanese_ogre")) 587 | entry(Emoji(0x1f456), ("jeans")) 588 | entry(Emoji(0x1f602), ("joy")) 589 | entry(Emoji(0x1f639), ("joy_cat")) 590 | entry(Emoji(0x1f511), ("key")) 591 | entry(Emoji(0x1f51f), ("keycap_ten")) 592 | entry(Emoji(0x1f458), ("kimono")) 593 | entry(Emoji(0x1f48b), ("kiss")) 594 | entry(Emoji(0x1f617), ("kissing")) 595 | entry(Emoji(0x1f63d), ("kissing_cat")) 596 | entry(Emoji(0x1f61a), ("kissing_closed_eyes")) 597 | entry(Emoji(0x1f618), ("kissing_heart")) 598 | entry(Emoji(0x1f619), ("kissing_smiling_eyes")) 599 | entry(Emoji(0x1f428), ("koala")) 600 | entry(Emoji(0x1f201), ("koko")) 601 | entry(Emoji(0x1f3ee), ("lantern")) 602 | entry(Emoji(0x1f535), ("large_blue_circle")) 603 | entry(Emoji(0x1f537), ("large_blue_diamond")) 604 | entry(Emoji(0x1f536), ("large_orange_diamond")) 605 | entry(Emoji(0x1f317), ("last_quarter_moon")) 606 | entry(Emoji(0x1f31c), ("last_quarter_moon_with_face")) 607 | entry(Emoji(0x1f606), ("laughing")) 608 | entry(Emoji(0x1f343), ("leaves")) 609 | entry(Emoji(0x1f4d2), ("ledger")) 610 | entry(Emoji(0x1f6c5), ("left_luggage")) 611 | entry(Emoji(0x02194), ("left_right_arrow")) 612 | entry(Emoji(0x021a9), ("leftwards_arrow_with_hook")) 613 | entry(Emoji(0x1f34b), ("lemon")) 614 | entry(Emoji(0x0264c), ("leo")) 615 | entry(Emoji(0x1f406), ("leopard")) 616 | entry(Emoji(0x0264e), ("libra")) 617 | entry(Emoji(0x1f688), ("light_rail")) 618 | entry(Emoji(0x1f517), ("link")) 619 | entry(Emoji(0x1f444), ("lips")) 620 | entry(Emoji(0x1f484), ("lipstick")) 621 | entry(Emoji(0x1f512), ("lock")) 622 | entry(Emoji(0x1f50f), ("lock_with_ink_pen")) 623 | entry(Emoji(0x1f36d), ("lollipop")) 624 | entry(Emoji(0x027bf), ("loop")) 625 | entry(Emoji(0x1f4e2), ("loudspeaker")) 626 | entry(Emoji(0x1f3e9), ("love_hotel")) 627 | entry(Emoji(0x1f48c), ("love_letter")) 628 | entry(Emoji(0x1f505), ("low_brightness")) 629 | entry(Emoji(0x024c2), ("m")) 630 | entry(Emoji(0x1f50d), ("mag")) 631 | entry(Emoji(0x1f50e), ("mag_right")) 632 | entry(Emoji(0x1f004), ("mahjong")) 633 | entry(Emoji(0x1f4eb), ("mailbox")) 634 | entry(Emoji(0x1f4ea), ("mailbox_closed")) 635 | entry(Emoji(0x1f4ec), ("mailbox_with_mail")) 636 | entry(Emoji(0x1f4ed), ("mailbox_with_no_mail")) 637 | entry(Emoji(0x1f468), ("man")) 638 | entry(Emoji(0x1f472), ("man_with_gua_pi_mao")) 639 | entry(Emoji(0x1f473), ("man_with_turban")) 640 | entry(Emoji(0x1f45e), ("mans_shoe")) 641 | entry(Emoji(0x1f341), ("maple_leaf")) 642 | entry(Emoji(0x1f637), ("mask")) 643 | entry(Emoji(0x1f486), ("massage")) 644 | entry(Emoji(0x1f356), ("meat_on_bone")) 645 | entry(Emoji(0x1f4e3), ("mega")) 646 | entry(Emoji(0x1f348), ("melon")) 647 | entry(Emoji(0x1f4dd), ("memo")) 648 | entry(Emoji(0x1f6b9), ("mens")) 649 | entry(Emoji(0x1f687), ("metro")) 650 | entry(Emoji(0x1f3a4), ("microphone")) 651 | entry(Emoji(0x1f52c), ("microscope")) 652 | entry(Emoji(0x1f30c), ("milky_way")) 653 | entry(Emoji(0x1f690), ("minibus")) 654 | entry(Emoji(0x1f4bd), ("minidisc")) 655 | entry(Emoji(0x1f4f4), ("mobile_phone_off")) 656 | entry(Emoji(0x1f4b8), ("money_with_wings")) 657 | entry(Emoji(0x1f4b0), ("moneybag")) 658 | entry(Emoji(0x1f412), ("monkey")) 659 | entry(Emoji(0x1f435), ("monkey_face")) 660 | entry(Emoji(0x1f69d), ("monorail")) 661 | entry(Emoji(0x1f314), ("moon")) 662 | entry(Emoji(0x1f393), ("mortar_board")) 663 | entry(Emoji(0x1f5fb), ("mount_fuji")) 664 | entry(Emoji(0x1f6b5), ("mountain_bicyclist")) 665 | entry(Emoji(0x1f6a0), ("mountain_cableway")) 666 | entry(Emoji(0x1f69e), ("mountain_railway")) 667 | entry(Emoji(0x1f42d), ("mouse")) 668 | entry(Emoji(0x1f401), ("mouse2")) 669 | entry(Emoji(0x1f3a5), ("movie_camera")) 670 | entry(Emoji(0x1f5ff), ("moyai")) 671 | entry(Emoji(0x1f4aa), ("muscle")) 672 | entry(Emoji(0x1f344), ("mushroom")) 673 | entry(Emoji(0x1f3b9), ("musical_keyboard")) 674 | entry(Emoji(0x1f3b5), ("musical_note")) 675 | entry(Emoji(0x1f3bc), ("musical_score")) 676 | entry(Emoji(0x1f507), ("mute")) 677 | entry(Emoji(0x1f485), ("nail_care")) 678 | entry(Emoji(0x1f4db), ("name_badge")) 679 | entry(Emoji(0x1f454), ("necktie")) 680 | entry(Emoji(0x0274e), ("negative_squared_cross_mark")) 681 | entry(Emoji(0x1f610), ("neutral_face")) 682 | entry(Emoji(0x1f195), ("new")) 683 | entry(Emoji(0x1f311), ("new_moon")) 684 | entry(Emoji(0x1f31a), ("new_moon_with_face")) 685 | entry(Emoji(0x1f4f0), ("newspaper")) 686 | entry(Emoji(0x1f196), ("ng")) 687 | entry(Emoji(0x1f515), ("no_bell")) 688 | entry(Emoji(0x1f6b3), ("no_bicycles")) 689 | entry(Emoji(0x026d4), ("no_entry")) 690 | entry(Emoji(0x1f6ab), ("no_entry_sign")) 691 | entry(Emoji(0x1f645), ("no_good")) 692 | entry(Emoji(0x1f4f5), ("no_mobile_phones")) 693 | entry(Emoji(0x1f636), ("no_mouth")) 694 | entry(Emoji(0x1f6b7), ("no_pedestrians")) 695 | entry(Emoji(0x1f6ad), ("no_smoking")) 696 | entry(Emoji(0x1f6b1), ("non-potable_water")) 697 | entry(Emoji(0x1f443), ("nose")) 698 | entry(Emoji(0x1f4d3), ("notebook")) 699 | entry(Emoji(0x1f4d4), ("notebook_with_decorative_cover")) 700 | entry(Emoji(0x1f3b6), ("notes")) 701 | entry(Emoji(0x1f529), ("nut_and_bolt")) 702 | entry(Emoji(0x02b55), ("o")) 703 | entry(Emoji(0x1f17e), ("o2")) 704 | entry(Emoji(0x1f30a), ("ocean")) 705 | entry(Emoji(0x1f419), ("octopus")) 706 | entry(Emoji(0x1f362), ("oden")) 707 | entry(Emoji(0x1f3e2), ("office")) 708 | entry(Emoji(0x1f197), ("ok")) 709 | entry(Emoji(0x1f44c), ("ok_hand")) 710 | entry(Emoji(0x1f646), ("ok_woman")) 711 | entry(Emoji(0x1f474), ("older_man")) 712 | entry(Emoji(0x1f475), ("older_woman")) 713 | entry(Emoji(0x1f51b), ("on")) 714 | entry(Emoji(0x1f698), ("oncoming_automobile")) 715 | entry(Emoji(0x1f68d), ("oncoming_bus")) 716 | entry(Emoji(0x1f694), ("oncoming_police_car")) 717 | entry(Emoji(0x1f696), ("oncoming_taxi")) 718 | entry(Emoji(0x1f4d6), ("open_book")) 719 | entry(Emoji(0x1f4c2), ("open_file_folder")) 720 | entry(Emoji(0x1f450), ("open_hands")) 721 | entry(Emoji(0x1f62e), ("open_mouth")) 722 | entry(Emoji(0x026ce), ("ophiuchus")) 723 | entry(Emoji(0x1f4d9), ("orange_book")) 724 | entry(Emoji(0x1f4e4), ("outbox_tray")) 725 | entry(Emoji(0x1f402), ("ox")) 726 | entry(Emoji(0x1f4e6), ("package")) 727 | entry(Emoji(0x1f4c4), ("page_facing_up")) 728 | entry(Emoji(0x1f4c3), ("page_with_curl")) 729 | entry(Emoji(0x1f4df), ("pager")) 730 | entry(Emoji(0x1f334), ("palm_tree")) 731 | entry(Emoji(0x1f43c), ("panda_face")) 732 | entry(Emoji(0x1f4ce), ("paperclip")) 733 | entry(Emoji(0x1f17f), ("parking")) 734 | entry(Emoji(0x0303d), ("part_alternation_mark")) 735 | entry(Emoji(0x026c5), ("partly_sunny")) 736 | entry(Emoji(0x1f6c2), ("passport_control")) 737 | entry(Emoji(0x1f43e), ("paw_prints")) 738 | entry(Emoji(0x1f351), ("peach")) 739 | entry(Emoji(0x1f350), ("pear")) 740 | entry(Emoji(0x1f4dd), ("pencil")) 741 | entry(Emoji(0x0270f), ("pencil2")) 742 | entry(Emoji(0x1f427), ("penguin")) 743 | entry(Emoji(0x1f614), ("pensive")) 744 | entry(Emoji(0x1f3ad), ("performing_arts")) 745 | entry(Emoji(0x1f623), ("persevere")) 746 | entry(Emoji(0x1f64d), ("person_frowning")) 747 | entry(Emoji(0x1f471), ("person_with_blond_hair")) 748 | entry(Emoji(0x1f64e), ("person_with_pouting_face")) 749 | entry(Emoji(0x0260e), ("phone")) 750 | entry(Emoji(0x1f437), ("pig")) 751 | entry(Emoji(0x1f416), ("pig2")) 752 | entry(Emoji(0x1f43d), ("pig_nose")) 753 | entry(Emoji(0x1f48a), ("pill")) 754 | entry(Emoji(0x1f34d), ("pineapple")) 755 | entry(Emoji(0x02653), ("pisces")) 756 | entry(Emoji(0x1f355), ("pizza")) 757 | entry(Emoji(0x1f447), ("point_down")) 758 | entry(Emoji(0x1f448), ("point_left")) 759 | entry(Emoji(0x1f449), ("point_right")) 760 | entry(Emoji(0x0261d), ("point_up")) 761 | entry(Emoji(0x1f446), ("point_up_2")) 762 | entry(Emoji(0x1f693), ("police_car")) 763 | entry(Emoji(0x1f429), ("poodle")) 764 | entry(Emoji(0x1f4a9), ("poop")) 765 | entry(Emoji(0x1f3e3), ("post_office")) 766 | entry(Emoji(0x1f4ef), ("postal_horn")) 767 | entry(Emoji(0x1f4ee), ("postbox")) 768 | entry(Emoji(0x1f6b0), ("potable_water")) 769 | entry(Emoji(0x1f45d), ("pouch")) 770 | entry(Emoji(0x1f357), ("poultry_leg")) 771 | entry(Emoji(0x1f4b7), ("pound")) 772 | entry(Emoji(0x1f63e), ("pouting_cat")) 773 | entry(Emoji(0x1f64f), ("pray")) 774 | entry(Emoji(0x1f478), ("princess")) 775 | entry(Emoji(0x1f44a), ("punch")) 776 | entry(Emoji(0x1f49c), ("purple_heart")) 777 | entry(Emoji(0x1f45b), ("purse")) 778 | entry(Emoji(0x1f4cc), ("pushpin")) 779 | entry(Emoji(0x1f6ae), ("put_litter_in_its_place")) 780 | entry(Emoji(0x02753), ("question")) 781 | entry(Emoji(0x1f430), ("rabbit")) 782 | entry(Emoji(0x1f407), ("rabbit2")) 783 | entry(Emoji(0x1f40e), ("racehorse")) 784 | entry(Emoji(0x1f4fb), ("radio")) 785 | entry(Emoji(0x1f518), ("radio_button")) 786 | entry(Emoji(0x1f621), ("rage")) 787 | entry(Emoji(0x1f683), ("railway_car")) 788 | entry(Emoji(0x1f308), ("rainbow")) 789 | entry(Emoji(0x0270b), ("raised_hand")) 790 | entry(Emoji(0x1f64c), ("raised_hands")) 791 | entry(Emoji(0x1f64b), ("raising_hand")) 792 | entry(Emoji(0x1f40f), ("ram")) 793 | entry(Emoji(0x1f35c), ("ramen")) 794 | entry(Emoji(0x1f400), ("rat")) 795 | entry(Emoji(0x0267b), ("recycle")) 796 | entry(Emoji(0x1f697), ("red_car")) 797 | entry(Emoji(0x1f534), ("red_circle")) 798 | entry(Emoji(0x000ae), ("registered")) 799 | entry(Emoji(0x0263a), ("relaxed")) 800 | entry(Emoji(0x1f60c), ("relieved")) 801 | entry(Emoji(0x1f501), ("repeat")) 802 | entry(Emoji(0x1f502), ("repeat_one")) 803 | entry(Emoji(0x1f6bb), ("restroom")) 804 | entry(Emoji(0x1f49e), ("revolving_hearts")) 805 | entry(Emoji(0x023ea), ("rewind")) 806 | entry(Emoji(0x1f380), ("ribbon")) 807 | entry(Emoji(0x1f35a), ("rice")) 808 | entry(Emoji(0x1f359), ("rice_ball")) 809 | entry(Emoji(0x1f358), ("rice_cracker")) 810 | entry(Emoji(0x1f391), ("rice_scene")) 811 | entry(Emoji(0x1f48d), ("ring")) 812 | entry(Emoji(0x1f680), ("rocket")) 813 | entry(Emoji(0x1f3a2), ("roller_coaster")) 814 | entry(Emoji(0x1f413), ("rooster")) 815 | entry(Emoji(0x1f339), ("rose")) 816 | entry(Emoji(0x1f6a8), ("rotating_light")) 817 | entry(Emoji(0x1f4cd), ("round_pushpin")) 818 | entry(Emoji(0x1f6a3), ("rowboat")) 819 | entry(Emoji(0x1f3c9), ("rugby_football")) 820 | entry(Emoji(0x1f3c3), ("runner")) 821 | entry(Emoji(0x1f3c3), ("running")) 822 | entry(Emoji(0x1f3bd), ("running_shirt_with_sash")) 823 | entry(Emoji(0x1f202), ("sa")) 824 | entry(Emoji(0x02650), ("sagittarius")) 825 | entry(Emoji(0x026f5), ("sailboat")) 826 | entry(Emoji(0x1f376), ("sake")) 827 | entry(Emoji(0x1f461), ("sandal")) 828 | entry(Emoji(0x1f385), ("santa")) 829 | entry(Emoji(0x1f4e1), ("satellite")) 830 | entry(Emoji(0x1f606), ("satisfied")) 831 | entry(Emoji(0x1f3b7), ("saxophone")) 832 | entry(Emoji(0x1f3eb), ("school")) 833 | entry(Emoji(0x1f392), ("school_satchel")) 834 | entry(Emoji(0x02702), ("scissors")) 835 | entry(Emoji(0x0264f), ("scorpius")) 836 | entry(Emoji(0x1f631), ("scream")) 837 | entry(Emoji(0x1f640), ("scream_cat")) 838 | entry(Emoji(0x1f4dc), ("scroll")) 839 | entry(Emoji(0x1f4ba), ("seat")) 840 | entry(Emoji(0x03299), ("secret")) 841 | entry(Emoji(0x1f648), ("see_no_evil")) 842 | entry(Emoji(0x1f331), ("seedling")) 843 | entry(Emoji(0x1f367), ("shaved_ice")) 844 | entry(Emoji(0x1f411), ("sheep")) 845 | entry(Emoji(0x1f41a), ("shell")) 846 | entry(Emoji(0x1f6a2), ("ship")) 847 | entry(Emoji(0x1f455), ("shirt")) 848 | entry(Emoji(0x1f4a9), ("shit")) 849 | entry(Emoji(0x1f45e), ("shoe")) 850 | entry(Emoji(0x1f6bf), ("shower")) 851 | entry(Emoji(0x1f4f6), ("signal_strength")) 852 | entry(Emoji(0x1f52f), ("six_pointed_star")) 853 | entry(Emoji(0x1f3bf), ("ski")) 854 | entry(Emoji(0x1f480), ("skull")) 855 | entry(Emoji(0x1f634), ("sleeping")) 856 | entry(Emoji(0x1f62a), ("sleepy")) 857 | entry(Emoji(0x1f3b0), ("slot_machine")) 858 | entry(Emoji(0x1f539), ("small_blue_diamond")) 859 | entry(Emoji(0x1f538), ("small_orange_diamond")) 860 | entry(Emoji(0x1f53a), ("small_red_triangle")) 861 | entry(Emoji(0x1f53b), ("small_red_triangle_down")) 862 | entry(Emoji(0x1f604), ("smile")) 863 | entry(Emoji(0x1f638), ("smile_cat")) 864 | entry(Emoji(0x1f603), ("smiley")) 865 | entry(Emoji(0x1f63a), ("smiley_cat")) 866 | entry(Emoji(0x1f608), ("smiling_imp")) 867 | entry(Emoji(0x1f60f), ("smirk")) 868 | entry(Emoji(0x1f63c), ("smirk_cat")) 869 | entry(Emoji(0x1f6ac), ("smoking")) 870 | entry(Emoji(0x1f40c), ("snail")) 871 | entry(Emoji(0x1f40d), ("snake")) 872 | entry(Emoji(0x1f3c2), ("snowboarder")) 873 | entry(Emoji(0x02744), ("snowflake")) 874 | entry(Emoji(0x026c4), ("snowman")) 875 | entry(Emoji(0x1f62d), ("sob")) 876 | entry(Emoji(0x026bd), ("soccer")) 877 | entry(Emoji(0x1f51c), ("soon")) 878 | entry(Emoji(0x1f198), ("sos")) 879 | entry(Emoji(0x1f509), ("sound")) 880 | entry(Emoji(0x1f47e), ("space_invader")) 881 | entry(Emoji(0x02660), ("spades")) 882 | entry(Emoji(0x1f35d), ("spaghetti")) 883 | entry(Emoji(0x02747), ("sparkle")) 884 | entry(Emoji(0x1f387), ("sparkler")) 885 | entry(Emoji(0x02728), ("sparkles")) 886 | entry(Emoji(0x1f496), ("sparkling_heart")) 887 | entry(Emoji(0x1f64a), ("speak_no_evil")) 888 | entry(Emoji(0x1f50a), ("speaker")) 889 | entry(Emoji(0x1f4ac), ("speech_balloon")) 890 | entry(Emoji(0x1f6a4), ("speedboat")) 891 | entry(Emoji(0x02b50), ("star")) 892 | entry(Emoji(0x1f31f), ("star2")) 893 | entry(Emoji(0x1f303), ("stars")) 894 | entry(Emoji(0x1f689), ("station")) 895 | entry(Emoji(0x1f5fd), ("statue_of_liberty")) 896 | entry(Emoji(0x1f682), ("steam_locomotive")) 897 | entry(Emoji(0x1f372), ("stew")) 898 | entry(Emoji(0x1f4cf), ("straight_ruler")) 899 | entry(Emoji(0x1f353), ("strawberry")) 900 | entry(Emoji(0x1f61b), ("stuck_out_tongue")) 901 | entry(Emoji(0x1f61d), ("stuck_out_tongue_closed_eyes")) 902 | entry(Emoji(0x1f61c), ("stuck_out_tongue_winking_eye")) 903 | entry(Emoji(0x1f31e), ("sun_with_face")) 904 | entry(Emoji(0x1f33b), ("sunflower")) 905 | entry(Emoji(0x1f60e), ("sunglasses")) 906 | entry(Emoji(0x02600), ("sunny")) 907 | entry(Emoji(0x1f305), ("sunrise")) 908 | entry(Emoji(0x1f304), ("sunrise_over_mountains")) 909 | entry(Emoji(0x1f3c4), ("surfer")) 910 | entry(Emoji(0x1f363), ("sushi")) 911 | entry(Emoji(0x1f69f), ("suspension_railway")) 912 | entry(Emoji(0x1f613), ("sweat")) 913 | entry(Emoji(0x1f4a6), ("sweat_drops")) 914 | entry(Emoji(0x1f605), ("sweat_smile")) 915 | entry(Emoji(0x1f360), ("sweet_potato")) 916 | entry(Emoji(0x1f3ca), ("swimmer")) 917 | entry(Emoji(0x1f523), ("symbols")) 918 | entry(Emoji(0x1f489), ("syringe")) 919 | entry(Emoji(0x1f389), ("tada")) 920 | entry(Emoji(0x1f38b), ("tanabata_tree")) 921 | entry(Emoji(0x1f34a), ("tangerine")) 922 | entry(Emoji(0x02649), ("taurus")) 923 | entry(Emoji(0x1f695), ("taxi")) 924 | entry(Emoji(0x1f375), ("tea")) 925 | entry(Emoji(0x0260e), ("telephone")) 926 | entry(Emoji(0x1f4de), ("telephone_receiver")) 927 | entry(Emoji(0x1f52d), ("telescope")) 928 | entry(Emoji(0x1f3be), ("tennis")) 929 | entry(Emoji(0x026fa), ("tent")) 930 | entry(Emoji(0x1f4ad), ("thought_balloon")) 931 | entry(Emoji(0x1f44e), ("thumbsdown")) 932 | entry(Emoji(0x1f44d), ("thumbsup")) 933 | entry(Emoji(0x1f3ab), ("ticket")) 934 | entry(Emoji(0x1f42f), ("tiger")) 935 | entry(Emoji(0x1f405), ("tiger2")) 936 | entry(Emoji(0x1f62b), ("tired_face")) 937 | entry(Emoji(0x02122), ("tm")) 938 | entry(Emoji(0x1f6bd), ("toilet")) 939 | entry(Emoji(0x1f5fc), ("tokyo_tower")) 940 | entry(Emoji(0x1f345), ("tomato")) 941 | entry(Emoji(0x1f445), ("tongue")) 942 | entry(Emoji(0x1f51d), ("top")) 943 | entry(Emoji(0x1f3a9), ("tophat")) 944 | entry(Emoji(0x1f69c), ("tractor")) 945 | entry(Emoji(0x1f6a5), ("traffic_light")) 946 | entry(Emoji(0x1f683), ("train")) 947 | entry(Emoji(0x1f686), ("train2")) 948 | entry(Emoji(0x1f68a), ("tram")) 949 | entry(Emoji(0x1f6a9), ("triangular_flag_on_post")) 950 | entry(Emoji(0x1f4d0), ("triangular_ruler")) 951 | entry(Emoji(0x1f531), ("trident")) 952 | entry(Emoji(0x1f624), ("triumph")) 953 | entry(Emoji(0x1f68e), ("trolleybus")) 954 | entry(Emoji(0x1f3c6), ("trophy")) 955 | entry(Emoji(0x1f379), ("tropical_drink")) 956 | entry(Emoji(0x1f420), ("tropical_fish")) 957 | entry(Emoji(0x1f69a), ("truck")) 958 | entry(Emoji(0x1f3ba), ("trumpet")) 959 | entry(Emoji(0x1f455), ("tshirt")) 960 | entry(Emoji(0x1f337), ("tulip")) 961 | entry(Emoji(0x1f422), ("turtle")) 962 | entry(Emoji(0x1f4fa), ("tv")) 963 | entry(Emoji(0x1f500), ("twisted_rightwards_arrows")) 964 | entry(Emoji(0x1f495), ("two_hearts")) 965 | entry(Emoji(0x1f46c), ("two_men_holding_hands")) 966 | entry(Emoji(0x1f46d), ("two_women_holding_hands")) 967 | entry(Emoji(0x1f239), ("u5272")) 968 | entry(Emoji(0x1f234), ("u5408")) 969 | entry(Emoji(0x1f23a), ("u55b6")) 970 | entry(Emoji(0x1f22f), ("u6307")) 971 | entry(Emoji(0x1f237), ("u6708")) 972 | entry(Emoji(0x1f236), ("u6709")) 973 | entry(Emoji(0x1f235), ("u6e80")) 974 | entry(Emoji(0x1f21a), ("u7121")) 975 | entry(Emoji(0x1f238), ("u7533")) 976 | entry(Emoji(0x1f232), ("u7981")) 977 | entry(Emoji(0x1f233), ("u7a7a")) 978 | entry(Emoji(0x02614), ("umbrella")) 979 | entry(Emoji(0x1f612), ("unamused")) 980 | entry(Emoji(0x1f51e), ("underage")) 981 | entry(Emoji(0x1f513), ("unlock")) 982 | entry(Emoji(0x1f199), ("up")) 983 | entry(Emoji(0x0270c), ("v")) 984 | entry(Emoji(0x1f6a6), ("vertical_traffic_light")) 985 | entry(Emoji(0x1f4fc), ("vhs")) 986 | entry(Emoji(0x1f4f3), ("vibration_mode")) 987 | entry(Emoji(0x1f4f9), ("video_camera")) 988 | entry(Emoji(0x1f3ae), ("video_game")) 989 | entry(Emoji(0x1f3bb), ("violin")) 990 | entry(Emoji(0x0264d), ("virgo")) 991 | entry(Emoji(0x1f30b), ("volcano")) 992 | entry(Emoji(0x1f19a), ("vs")) 993 | entry(Emoji(0x1f6b6), ("walking")) 994 | entry(Emoji(0x1f318), ("waning_crescent_moon")) 995 | entry(Emoji(0x1f316), ("waning_gibbous_moon")) 996 | entry(Emoji(0x026a0), ("warning")) 997 | entry(Emoji(0x0231a), ("watch")) 998 | entry(Emoji(0x1f403), ("water_buffalo")) 999 | entry(Emoji(0x1f349), ("watermelon")) 1000 | entry(Emoji(0x1f44b), ("wave")) 1001 | entry(Emoji(0x03030), ("wavy_dash")) 1002 | entry(Emoji(0x1f312), ("waxing_crescent_moon")) 1003 | entry(Emoji(0x1f314), ("waxing_gibbous_moon")) 1004 | entry(Emoji(0x1f6be), ("wc")) 1005 | entry(Emoji(0x1f629), ("weary")) 1006 | entry(Emoji(0x1f492), ("wedding")) 1007 | entry(Emoji(0x1f433), ("whale")) 1008 | entry(Emoji(0x1f40b), ("whale2")) 1009 | entry(Emoji(0x0267f), ("wheelchair")) 1010 | entry(Emoji(0x02705), ("white_check_mark")) 1011 | entry(Emoji(0x026aa), ("white_circle")) 1012 | entry(Emoji(0x1f4ae), ("white_flower")) 1013 | entry(Emoji(0x02b1c), ("white_large_square")) 1014 | entry(Emoji(0x025fd), ("white_medium_small_square")) 1015 | entry(Emoji(0x025fb), ("white_medium_square")) 1016 | entry(Emoji(0x025ab), ("white_small_square")) 1017 | entry(Emoji(0x1f533), ("white_square_button")) 1018 | entry(Emoji(0x1f390), ("wind_chime")) 1019 | entry(Emoji(0x1f377), ("wine_glass")) 1020 | entry(Emoji(0x1f609), ("wink")) 1021 | entry(Emoji(0x1f43a), ("wolf")) 1022 | entry(Emoji(0x1f469), ("woman")) 1023 | entry(Emoji(0x1f45a), ("womans_clothes")) 1024 | entry(Emoji(0x1f452), ("womans_hat")) 1025 | entry(Emoji(0x1f6ba), ("womens")) 1026 | entry(Emoji(0x1f61f), ("worried")) 1027 | entry(Emoji(0x1f527), ("wrench")) 1028 | entry(Emoji(0x0274c), ("x")) 1029 | entry(Emoji(0x1f49b), ("yellow_heart")) 1030 | entry(Emoji(0x1f4b4), ("yen")) 1031 | entry(Emoji(0x1f60b), ("yum")) 1032 | entry(Emoji(0x026a1), ("zap")) 1033 | entry(Emoji(0x1f4a4), ("zzz")) 1034 | } 1035 | } 1036 | 1037 | } 1038 | -------------------------------------------------------------------------------- /src/main/scala-3/com/lightbend/emoji/Emoji.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import scala.util.Try 7 | 8 | /** 9 | * The value class representing a codepoint in the Emoji set. 10 | * 11 | * @param codePoint 12 | * the codepoint representing the Emoji character 13 | */ 14 | class Emoji private (val codePoint: Int) extends AnyVal: 15 | 16 | /** 17 | * Returns the sequence of characters (usually surrogate pairs). 18 | */ 19 | def chars: Array[Char] = Character.toChars(codePoint) 20 | 21 | /** 22 | * Returns the emoji's Unicode name. 23 | */ 24 | def name: String = Emoji.name(this.codePoint) 25 | 26 | /** 27 | * Returns the hexadecimal code. 28 | */ 29 | def toHexString: String = Emoji.toHexString(this.codePoint) 30 | 31 | /** 32 | * A convenience method that prepends "0x" before toHexString 33 | */ 34 | def hex: String = "0x" + toHexString 35 | 36 | /** 37 | * Returns the emoji as a String. Use this if you want smiley faces. 38 | */ 39 | override def toString = new String(chars) 40 | 41 | /** 42 | * This is the singleton object for Emoji. 43 | */ 44 | object Emoji: 45 | 46 | // Don't want this to conflict with shortCode.emoji 47 | extension (string: String) 48 | def codePointEmoji: Emoji = Emoji( 49 | Try(Integer.parseInt(string, 16)).recover { 50 | case e: NumberFormatException => 51 | val stripped = string.replace("0x", "") 52 | Integer.parseInt(stripped, 16) 53 | }.getOrElse { 54 | throw new EmojiNotFound("Cannot parse emoji from hexadecimal string") 55 | } 56 | ) 57 | 58 | extension (codePoint: Int) def emoji: Emoji = Emoji(codePoint) 59 | 60 | /** 61 | * Returns the emoji for the given array of characters, throws EmojiNotFound 62 | */ 63 | def apply(chars: Array[Char]): Emoji = apply(Character.codePointAt(chars, 0)) 64 | 65 | /** 66 | * Returns the emoji given a string containing the codepoint. 67 | */ 68 | def apply(string: String): Emoji = apply(string.codePointAt(0)) 69 | 70 | /** 71 | * Returns the emoji for this codepoint if found, throws EmojiNotFound otherwise. 72 | */ 73 | def apply(codePoint: Int): Emoji = new Emoji(validated(codePoint)) 74 | 75 | /** 76 | * Returns Some(emoji) if found, None otherwise. 77 | */ 78 | def get(codePoint: Int): Option[Emoji] = 79 | if isEmoji(codePoint) then Some(new Emoji(codePoint)) else None 80 | 81 | /** 82 | * Returns true if this is a valid Unicode codepoint, false otherwise. 83 | */ 84 | def isEmoji(codePoint: Int): Boolean = 85 | // there is no codeblock for unicode. 86 | // val block = UnicodeBlock.of(codePoint) 87 | // block == Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS_AND_PICTOGRAPHS || 88 | // block == Character.UnicodeBlock.EMOTICONS || 89 | // block == Character.UnicodeBlock.TRANSPORT_AND_MAP_SYMBOLS || 90 | // block == Character.UnicodeBlock.MISCELLANEOUS_SYMBOLS || 91 | // block == Character.UnicodeBlock.DINGBATS 92 | Character.isValidCodePoint(codePoint) 93 | 94 | /** 95 | * Throws an exception if this is not a valid Unicode codepoint. 96 | */ 97 | def validated(codePoint: Int): Int = 98 | if isEmoji(codePoint) then codePoint else throw new EmojiNotFound("Code point is not emoji!") 99 | 100 | /** 101 | * Returns the unicode name for this codePoint. Throws EmojiNotFound if this is not a valid 102 | * codepoint. 103 | * 104 | * @param codePoint 105 | * the codePoint. 106 | * @return 107 | * the unicode description of the emoji. 108 | */ 109 | def name(codePoint: Int): String = 110 | Option(Character.getName(codePoint)).getOrElse { 111 | throw new EmojiNotFound("No name found for this codePoint") 112 | } 113 | 114 | /** 115 | * Returns the hexadecimal string of the code point. 116 | */ 117 | def toHexString(codePoint: Int): String = codePoint.toHexString 118 | end Emoji 119 | 120 | class EmojiNotFound(msg: String) extends RuntimeException(msg) 121 | -------------------------------------------------------------------------------- /src/main/scala-3/com/lightbend/emoji/ScalaVersionSpecific.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | object ScalaVersionSpecific: 7 | def checkLengths(sc: StringContext, args: Seq[Any]): Unit = 8 | StringContext.checkLengths(args, sc.parts) 9 | -------------------------------------------------------------------------------- /src/main/scala-3/com/lightbend/emoji/ShortCodes.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import scala.util.chaining.given 7 | 8 | import ScalaVersionSpecific.checkLengths 9 | 10 | /** 11 | * An emoji to shortcode mapping. This is a class that should be declared and used as an implicit 12 | * value, so that shortcode mappings don't have to be global across an application. 13 | * 14 | * "import ShortCodes.Defaults.given" to import the default shortcode mapping. "import 15 | * ShortCodes.Implicits.given" to enrich Emoji and String with shortcode methods. 16 | */ 17 | class ShortCodes(template: Option[ShortCodes] = None): 18 | 19 | private val emojiToShortCodes = collection.mutable.Map[Emoji, collection.Set[String]]() 20 | 21 | private val shortCodeToEmoji = collection.mutable.Map[String, Emoji]() 22 | 23 | template.foreach { t => 24 | for ((emoji, shortCodes) <- t.emojiToShortCodes) { 25 | shortCodes.foreach(code => entry(emoji, code)) 26 | } 27 | } 28 | 29 | /** 30 | * Defines a mapping between an emoji and a short code. Emojis may have multiple short code 31 | * mappings. 32 | */ 33 | def entry(emoji: Emoji, shortCode: String): Unit = 34 | emojiToShortCodes.get(emoji) match { 35 | case Some(shortCodes) => 36 | emojiToShortCodes += (emoji -> (shortCodes ++ Set(shortCode))) 37 | case None => 38 | emojiToShortCodes += (emoji -> Set(shortCode)) 39 | } 40 | shortCodeToEmoji += (shortCode -> emoji) 41 | 42 | /** 43 | * Returns the short codes for this emoji. 44 | */ 45 | def shortCodes(emoji: Emoji): Option[collection.Set[String]] = emojiToShortCodes.get(emoji) 46 | 47 | /** 48 | * Returns Some(emoji) if a short code is defined, None otherwise 49 | */ 50 | def emoji(shortCode: String): Option[Emoji] = shortCodeToEmoji.get(shortCode) 51 | 52 | /** 53 | * Returns the set of emojis that have short codes. 54 | */ 55 | def emojis: collection.Set[Emoji] = emojiToShortCodes.keySet 56 | 57 | /** 58 | * Returns the set of short codes mapped to emojis. 59 | */ 60 | def shortCodes: collection.Set[String] = shortCodeToEmoji.keySet 61 | 62 | /** 63 | * Removes emoji from the shortcodes mapping. This removes all the codes that map to the emoji as 64 | * well. 65 | */ 66 | def removeEmoji(emoji: Emoji): Unit = 67 | emojiToShortCodes.remove(emoji).foreach { shortCodes => 68 | shortCodes.foreach { shortCode => 69 | shortCodeToEmoji.remove(shortCode) 70 | } 71 | } 72 | 73 | /** 74 | * Removes a shortcode from the mapping. This does not remove the emoji. 75 | */ 76 | def removeCode(shortCode: String): Unit = 77 | shortCodeToEmoji.remove(shortCode).foreach { emoji => 78 | emojiToShortCodes.get(emoji).map { codes => 79 | val set = codes diff Set(shortCode) 80 | if (set.isEmpty) { 81 | emojiToShortCodes.remove(emoji) 82 | } else { 83 | emojiToShortCodes.put(emoji, set) 84 | } 85 | } 86 | } 87 | 88 | /** 89 | * Completely removes the emoji and shortcodes from the mapping. 90 | */ 91 | def clear(): Unit = 92 | emojiToShortCodes.clear() 93 | shortCodeToEmoji.clear() 94 | end ShortCodes 95 | 96 | /** 97 | * Companion object for shortcodes. 98 | */ 99 | object ShortCodes: 100 | 101 | /** 102 | * Returns the in-scope implicit shortcodes mapping. 103 | */ 104 | def current(using shortCodes: ShortCodes): ShortCodes = shortCodes 105 | 106 | extension (shortCodes: ShortCodes) 107 | def update(emoji: Emoji, shortCode: String): Unit = 108 | shortCodes.entry(emoji, shortCode) 109 | 110 | /** 111 | * Maps short codes onto Emoji and String, so you can say "+1".emoji and thumbsUpEmoji.shortCodes. 112 | */ 113 | extension (shortCode: String) 114 | def emoji(using shortCodes: ShortCodes): Emoji = 115 | shortCodes.emoji(shortCode).getOrElse { 116 | throw new EmojiNotFound("No emoji found for short code") 117 | } 118 | 119 | extension (emoji: Emoji) 120 | def shortCodes(using shortCodes: ShortCodes): Option[collection.Set[String]] = 121 | shortCodes.shortCodes(emoji) 122 | 123 | private val colonSyntax = ":([a-zA-Z0-9_+-]+):".r 124 | 125 | import StringContext.InvalidEscapeException 126 | 127 | // Emojilator 128 | extension (sc: StringContext) 129 | def e(args: Any*)(using shortCodes: ShortCodes): String = 130 | def emojify(s: String): String = colonSyntax.replaceAllIn( 131 | s, 132 | m => 133 | try m.group(1).emoji.toString 134 | catch case _: EmojiNotFound => m.matched 135 | ) 136 | checkLengths(sc, args) 137 | val sb = new java.lang.StringBuilder 138 | def process(part: String): String = emojify(StringContext.processEscapes(part)) 139 | def partly(part: String): Unit = 140 | try sb.append(process(part)) 141 | catch 142 | case e: InvalidEscapeException 143 | if e.index < part.length - 1 && part.charAt(e.index + 1) == ':' => 144 | sb.append(process(part.substring(0, e.index))) 145 | sb.append(":") 146 | partly(part.substring(e.index + 2)) 147 | val pi = sc.parts.iterator 148 | val ai = args.iterator 149 | partly(pi.next()) 150 | while ai.hasNext do 151 | sb.append(ai.next()) 152 | partly(pi.next()) 153 | sb.toString 154 | end extension 155 | 156 | /** 157 | * The default shortcodes mapping, as used by emoji-cheat-sheet. 158 | */ 159 | given ShortCodes = ShortCodes().tap(defaults) 160 | 161 | def defaults(sc: ShortCodes) = 162 | import sc.* 163 | 164 | entry(Emoji(0x1f44d), ("+1")) 165 | entry(Emoji(0x1f44e), ("-1")) 166 | entry(Emoji(0x1f4af), ("100")) 167 | entry(Emoji(0x1f522), ("1234")) 168 | entry(Emoji(0x1f3b1), ("8ball")) 169 | entry(Emoji(0x1f170), ("a")) 170 | entry(Emoji(0x1f18e), ("ab")) 171 | entry(Emoji(0x1f524), ("abc")) 172 | entry(Emoji(0x1f521), ("abcd")) 173 | entry(Emoji(0x1f251), ("accept")) 174 | entry(Emoji(0x1f6a1), ("aerial_tramway")) 175 | entry(Emoji(0x02708), ("airplane")) 176 | entry(Emoji(0x023f0), ("alarm_clock")) 177 | entry(Emoji(0x1f47d), ("alien")) 178 | entry(Emoji(0x1f691), ("ambulance")) 179 | entry(Emoji(0x02693), ("anchor")) 180 | entry(Emoji(0x1f47c), ("angel")) 181 | entry(Emoji(0x1f4a2), ("anger")) 182 | entry(Emoji(0x1f620), ("angry")) 183 | entry(Emoji(0x1f627), ("anguished")) 184 | entry(Emoji(0x1f41c), ("ant")) 185 | entry(Emoji(0x1f34e), ("apple")) 186 | entry(Emoji(0x02652), ("aquarius")) 187 | entry(Emoji(0x02648), ("aries")) 188 | entry(Emoji(0x025c0), ("arrow_backward")) 189 | entry(Emoji(0x023ec), ("arrow_double_down")) 190 | entry(Emoji(0x023eb), ("arrow_double_up")) 191 | entry(Emoji(0x02b07), ("arrow_down")) 192 | entry(Emoji(0x1f53d), ("arrow_down_small")) 193 | entry(Emoji(0x025b6), ("arrow_forward")) 194 | entry(Emoji(0x02935), ("arrow_heading_down")) 195 | entry(Emoji(0x02934), ("arrow_heading_up")) 196 | entry(Emoji(0x02b05), ("arrow_left")) 197 | entry(Emoji(0x02199), ("arrow_lower_left")) 198 | entry(Emoji(0x02198), ("arrow_lower_right")) 199 | entry(Emoji(0x027a1), ("arrow_right")) 200 | entry(Emoji(0x021aa), ("arrow_right_hook")) 201 | entry(Emoji(0x02b06), ("arrow_up")) 202 | entry(Emoji(0x02195), ("arrow_up_down")) 203 | entry(Emoji(0x1f53c), ("arrow_up_small")) 204 | entry(Emoji(0x02196), ("arrow_upper_left")) 205 | entry(Emoji(0x02197), ("arrow_upper_right")) 206 | entry(Emoji(0x1f503), ("arrows_clockwise")) 207 | entry(Emoji(0x1f504), ("arrows_counterclockwise")) 208 | entry(Emoji(0x1f3a8), ("art")) 209 | entry(Emoji(0x1f69b), ("articulated_lorry")) 210 | entry(Emoji(0x1f632), ("astonished")) 211 | entry(Emoji(0x1f45f), ("athletic_shoe")) 212 | entry(Emoji(0x1f3e7), ("atm")) 213 | entry(Emoji(0x1f171), ("b")) 214 | entry(Emoji(0x1f476), ("baby")) 215 | entry(Emoji(0x1f37c), ("baby_bottle")) 216 | entry(Emoji(0x1f424), ("baby_chick")) 217 | entry(Emoji(0x1f6bc), ("baby_symbol")) 218 | entry(Emoji(0x1f519), ("back")) 219 | entry(Emoji(0x1f6c4), ("baggage_claim")) 220 | entry(Emoji(0x1f388), ("balloon")) 221 | entry(Emoji(0x02611), ("ballot_box_with_check")) 222 | entry(Emoji(0x1f38d), ("bamboo")) 223 | entry(Emoji(0x1f34c), ("banana")) 224 | entry(Emoji(0x0203c), ("bangbang")) 225 | entry(Emoji(0x1f3e6), ("bank")) 226 | entry(Emoji(0x1f4ca), ("bar_chart")) 227 | entry(Emoji(0x1f488), ("barber")) 228 | entry(Emoji(0x026be), ("baseball")) 229 | entry(Emoji(0x1f3c0), ("basketball")) 230 | entry(Emoji(0x1f6c0), ("bath")) 231 | entry(Emoji(0x1f6c1), ("bathtub")) 232 | entry(Emoji(0x1f50b), ("battery")) 233 | entry(Emoji(0x1f43b), ("bear")) 234 | entry(Emoji(0x1f41d), ("bee")) 235 | entry(Emoji(0x1f37a), ("beer")) 236 | entry(Emoji(0x1f37b), ("beers")) 237 | entry(Emoji(0x1f41e), ("beetle")) 238 | entry(Emoji(0x1f530), ("beginner")) 239 | entry(Emoji(0x1f514), ("bell")) 240 | entry(Emoji(0x1f371), ("bento")) 241 | entry(Emoji(0x1f6b4), ("bicyclist")) 242 | entry(Emoji(0x1f6b2), ("bike")) 243 | entry(Emoji(0x1f459), ("bikini")) 244 | entry(Emoji(0x1f426), ("bird")) 245 | entry(Emoji(0x1f382), ("birthday")) 246 | entry(Emoji(0x026ab), ("black_circle")) 247 | entry(Emoji(0x1f0cf), ("black_joker")) 248 | entry(Emoji(0x02b1b), ("black_large_square")) 249 | entry(Emoji(0x025fe), ("black_medium_small_square")) 250 | entry(Emoji(0x025fc), ("black_medium_square")) 251 | entry(Emoji(0x02712), ("black_nib")) 252 | entry(Emoji(0x025aa), ("black_small_square")) 253 | entry(Emoji(0x1f532), ("black_square_button")) 254 | entry(Emoji(0x1f33c), ("blossom")) 255 | entry(Emoji(0x1f421), ("blowfish")) 256 | entry(Emoji(0x1f4d8), ("blue_book")) 257 | entry(Emoji(0x1f699), ("blue_car")) 258 | entry(Emoji(0x1f499), ("blue_heart")) 259 | entry(Emoji(0x1f60a), ("blush")) 260 | entry(Emoji(0x1f417), ("boar")) 261 | entry(Emoji(0x026f5), ("boat")) 262 | entry(Emoji(0x1f4a3), ("bomb")) 263 | entry(Emoji(0x1f4d6), ("book")) 264 | entry(Emoji(0x1f516), ("bookmark")) 265 | entry(Emoji(0x1f4d1), ("bookmark_tabs")) 266 | entry(Emoji(0x1f4da), ("books")) 267 | entry(Emoji(0x1f4a5), ("boom")) 268 | entry(Emoji(0x1f462), ("boot")) 269 | entry(Emoji(0x1f490), ("bouquet")) 270 | entry(Emoji(0x1f647), ("bow")) 271 | entry(Emoji(0x1f3b3), ("bowling")) 272 | entry(Emoji(0x1f466), ("boy")) 273 | entry(Emoji(0x1f35e), ("bread")) 274 | entry(Emoji(0x1f470), ("bride_with_veil")) 275 | entry(Emoji(0x1f309), ("bridge_at_night")) 276 | entry(Emoji(0x1f4bc), ("briefcase")) 277 | entry(Emoji(0x1f494), ("broken_heart")) 278 | entry(Emoji(0x1f41b), ("bug")) 279 | entry(Emoji(0x1f4a1), ("bulb")) 280 | entry(Emoji(0x1f685), ("bullettrain_front")) 281 | entry(Emoji(0x1f684), ("bullettrain_side")) 282 | entry(Emoji(0x1f68c), ("bus")) 283 | entry(Emoji(0x1f68f), ("busstop")) 284 | entry(Emoji(0x1f464), ("bust_in_silhouette")) 285 | entry(Emoji(0x1f465), ("busts_in_silhouette")) 286 | entry(Emoji(0x1f335), ("cactus")) 287 | entry(Emoji(0x1f370), ("cake")) 288 | entry(Emoji(0x1f4c6), ("calendar")) 289 | entry(Emoji(0x1f4f2), ("calling")) 290 | entry(Emoji(0x1f42b), ("camel")) 291 | entry(Emoji(0x1f4f7), ("camera")) 292 | entry(Emoji(0x0264b), ("cancer")) 293 | entry(Emoji(0x1f36c), ("candy")) 294 | entry(Emoji(0x1f520), ("capital_abcd")) 295 | entry(Emoji(0x02651), ("capricorn")) 296 | entry(Emoji(0x1f697), ("car")) 297 | entry(Emoji(0x1f4c7), ("card_index")) 298 | entry(Emoji(0x1f3a0), ("carousel_horse")) 299 | entry(Emoji(0x1f431), ("cat")) 300 | entry(Emoji(0x1f408), ("cat2")) 301 | entry(Emoji(0x1f4bf), ("cd")) 302 | entry(Emoji(0x1f4b9), ("chart")) 303 | entry(Emoji(0x1f4c9), ("chart_with_downwards_trend")) 304 | entry(Emoji(0x1f4c8), ("chart_with_upwards_trend")) 305 | entry(Emoji(0x1f3c1), ("checkered_flag")) 306 | entry(Emoji(0x1f352), ("cherries")) 307 | entry(Emoji(0x1f338), ("cherry_blossom")) 308 | entry(Emoji(0x1f330), ("chestnut")) 309 | entry(Emoji(0x1f414), ("chicken")) 310 | entry(Emoji(0x1f6b8), ("children_crossing")) 311 | entry(Emoji(0x1f36b), ("chocolate_bar")) 312 | entry(Emoji(0x1f384), ("christmas_tree")) 313 | entry(Emoji(0x026ea), ("church")) 314 | entry(Emoji(0x1f3a6), ("cinema")) 315 | entry(Emoji(0x1f3aa), ("circus_tent")) 316 | entry(Emoji(0x1f307), ("city_sunrise")) 317 | entry(Emoji(0x1f306), ("city_sunset")) 318 | entry(Emoji(0x1f191), ("cl")) 319 | entry(Emoji(0x1f44f), ("clap")) 320 | entry(Emoji(0x1f3ac), ("clapper")) 321 | entry(Emoji(0x1f4cb), ("clipboard")) 322 | entry(Emoji(0x1f550), ("clock1")) 323 | entry(Emoji(0x1f559), ("clock10")) 324 | entry(Emoji(0x1f565), ("clock1030")) 325 | entry(Emoji(0x1f55a), ("clock11")) 326 | entry(Emoji(0x1f566), ("clock1130")) 327 | entry(Emoji(0x1f55b), ("clock12")) 328 | entry(Emoji(0x1f567), ("clock1230")) 329 | entry(Emoji(0x1f55c), ("clock130")) 330 | entry(Emoji(0x1f551), ("clock2")) 331 | entry(Emoji(0x1f55d), ("clock230")) 332 | entry(Emoji(0x1f552), ("clock3")) 333 | entry(Emoji(0x1f55e), ("clock330")) 334 | entry(Emoji(0x1f553), ("clock4")) 335 | entry(Emoji(0x1f55f), ("clock430")) 336 | entry(Emoji(0x1f554), ("clock5")) 337 | entry(Emoji(0x1f560), ("clock530")) 338 | entry(Emoji(0x1f555), ("clock6")) 339 | entry(Emoji(0x1f561), ("clock630")) 340 | entry(Emoji(0x1f556), ("clock7")) 341 | entry(Emoji(0x1f562), ("clock730")) 342 | entry(Emoji(0x1f557), ("clock8")) 343 | entry(Emoji(0x1f563), ("clock830")) 344 | entry(Emoji(0x1f558), ("clock9")) 345 | entry(Emoji(0x1f564), ("clock930")) 346 | entry(Emoji(0x1f4d5), ("closed_book")) 347 | entry(Emoji(0x1f510), ("closed_lock_with_key")) 348 | entry(Emoji(0x1f302), ("closed_umbrella")) 349 | entry(Emoji(0x02601), ("cloud")) 350 | entry(Emoji(0x02663), ("clubs")) 351 | entry(Emoji(0x1f378), ("cocktail")) 352 | entry(Emoji(0x02615), ("coffee")) 353 | entry(Emoji(0x1f630), ("cold_sweat")) 354 | entry(Emoji(0x1f4a5), ("collision")) 355 | entry(Emoji(0x1f4bb), ("computer")) 356 | entry(Emoji(0x1f38a), ("confetti_ball")) 357 | entry(Emoji(0x1f616), ("confounded")) 358 | entry(Emoji(0x1f615), ("confused")) 359 | entry(Emoji(0x03297), ("congratulations")) 360 | entry(Emoji(0x1f6a7), ("construction")) 361 | entry(Emoji(0x1f477), ("construction_worker")) 362 | entry(Emoji(0x1f3ea), ("convenience_store")) 363 | entry(Emoji(0x1f36a), ("cookie")) 364 | entry(Emoji(0x1f192), ("cool")) 365 | entry(Emoji(0x1f46e), ("cop")) 366 | entry(Emoji(0x000a9), ("copyright")) 367 | entry(Emoji(0x1f33d), ("corn")) 368 | entry(Emoji(0x1f46b), ("couple")) 369 | entry(Emoji(0x1f491), ("couple_with_heart")) 370 | entry(Emoji(0x1f48f), ("couplekiss")) 371 | entry(Emoji(0x1f42e), ("cow")) 372 | entry(Emoji(0x1f404), ("cow2")) 373 | entry(Emoji(0x1f4b3), ("credit_card")) 374 | entry(Emoji(0x1f319), ("crescent_moon")) 375 | entry(Emoji(0x1f40a), ("crocodile")) 376 | entry(Emoji(0x1f38c), ("crossed_flags")) 377 | entry(Emoji(0x1f451), ("crown")) 378 | entry(Emoji(0x1f622), ("cry")) 379 | entry(Emoji(0x1f63f), ("crying_cat_face")) 380 | entry(Emoji(0x1f52e), ("crystal_ball")) 381 | entry(Emoji(0x1f498), ("cupid")) 382 | entry(Emoji(0x027b0), ("curly_loop")) 383 | entry(Emoji(0x1f4b1), ("currency_exchange")) 384 | entry(Emoji(0x1f35b), ("curry")) 385 | entry(Emoji(0x1f36e), ("custard")) 386 | entry(Emoji(0x1f6c3), ("customs")) 387 | entry(Emoji(0x1f300), ("cyclone")) 388 | entry(Emoji(0x1f483), ("dancer")) 389 | entry(Emoji(0x1f46f), ("dancers")) 390 | entry(Emoji(0x1f361), ("dango")) 391 | entry(Emoji(0x1f3af), ("dart")) 392 | entry(Emoji(0x1f4a8), ("dash")) 393 | entry(Emoji(0x1f4c5), ("date")) 394 | entry(Emoji(0x1f333), ("deciduous_tree")) 395 | entry(Emoji(0x1f3ec), ("department_store")) 396 | entry(Emoji(0x1f4a0), ("diamond_shape_with_a_dot_inside")) 397 | entry(Emoji(0x02666), ("diamonds")) 398 | entry(Emoji(0x1f61e), ("disappointed")) 399 | entry(Emoji(0x1f625), ("disappointed_relieved")) 400 | entry(Emoji(0x1f4ab), ("dizzy")) 401 | entry(Emoji(0x1f635), ("dizzy_face")) 402 | entry(Emoji(0x1f6af), ("do_not_litter")) 403 | entry(Emoji(0x1f436), ("dog")) 404 | entry(Emoji(0x1f415), ("dog2")) 405 | entry(Emoji(0x1f4b5), ("dollar")) 406 | entry(Emoji(0x1f38e), ("dolls")) 407 | entry(Emoji(0x1f42c), ("dolphin")) 408 | entry(Emoji(0x1f6aa), ("door")) 409 | entry(Emoji(0x1f369), ("doughnut")) 410 | entry(Emoji(0x1f409), ("dragon")) 411 | entry(Emoji(0x1f432), ("dragon_face")) 412 | entry(Emoji(0x1f457), ("dress")) 413 | entry(Emoji(0x1f42a), ("dromedary_camel")) 414 | entry(Emoji(0x1f4a7), ("droplet")) 415 | entry(Emoji(0x1f4c0), ("dvd")) 416 | entry(Emoji(0x1f4e7), ("e-mail")) 417 | entry(Emoji(0x1f442), ("ear")) 418 | entry(Emoji(0x1f33e), ("ear_of_rice")) 419 | entry(Emoji(0x1f30d), ("earth_africa")) 420 | entry(Emoji(0x1f30e), ("earth_americas")) 421 | entry(Emoji(0x1f30f), ("earth_asia")) 422 | entry(Emoji(0x1f373), ("egg")) 423 | entry(Emoji(0x1f346), ("eggplant")) 424 | entry(Emoji(0x02734), ("eight_pointed_black_star")) 425 | entry(Emoji(0x02733), ("eight_spoked_asterisk")) 426 | entry(Emoji(0x1f50c), ("electric_plug")) 427 | entry(Emoji(0x1f418), ("elephant")) 428 | entry(Emoji(0x02709), ("email")) 429 | entry(Emoji(0x1f51a), ("end")) 430 | entry(Emoji(0x02709), ("envelope")) 431 | entry(Emoji(0x1f4e9), ("envelope_with_arrow")) 432 | entry(Emoji(0x1f4b6), ("euro")) 433 | entry(Emoji(0x1f3f0), ("european_castle")) 434 | entry(Emoji(0x1f3e4), ("european_post_office")) 435 | entry(Emoji(0x1f332), ("evergreen_tree")) 436 | entry(Emoji(0x02757), ("exclamation")) 437 | entry(Emoji(0x1f611), ("expressionless")) 438 | entry(Emoji(0x1f453), ("eyeglasses")) 439 | entry(Emoji(0x1f440), ("eyes")) 440 | entry(Emoji(0x1f44a), ("facepunch")) 441 | entry(Emoji(0x1f3ed), ("factory")) 442 | entry(Emoji(0x1f342), ("fallen_leaf")) 443 | entry(Emoji(0x1f46a), ("family")) 444 | entry(Emoji(0x023e9), ("fast_forward")) 445 | entry(Emoji(0x1f4e0), ("fax")) 446 | entry(Emoji(0x1f628), ("fearful")) 447 | entry(Emoji(0x1f43e), ("feet")) 448 | entry(Emoji(0x1f3a1), ("ferris_wheel")) 449 | entry(Emoji(0x1f4c1), ("file_folder")) 450 | entry(Emoji(0x1f525), ("fire")) 451 | entry(Emoji(0x1f692), ("fire_engine")) 452 | entry(Emoji(0x1f386), ("fireworks")) 453 | entry(Emoji(0x1f313), ("first_quarter_moon")) 454 | entry(Emoji(0x1f31b), ("first_quarter_moon_with_face")) 455 | entry(Emoji(0x1f41f), ("fish")) 456 | entry(Emoji(0x1f365), ("fish_cake")) 457 | entry(Emoji(0x1f3a3), ("fishing_pole_and_fish")) 458 | entry(Emoji(0x0270a), ("fist")) 459 | entry(Emoji(0x1f38f), ("flags")) 460 | entry(Emoji(0x1f526), ("flashlight")) 461 | entry(Emoji(0x1f42c), ("flipper")) 462 | entry(Emoji(0x1f4be), ("floppy_disk")) 463 | entry(Emoji(0x1f3b4), ("flower_playing_cards")) 464 | entry(Emoji(0x1f633), ("flushed")) 465 | entry(Emoji(0x1f301), ("foggy")) 466 | entry(Emoji(0x1f3c8), ("football")) 467 | entry(Emoji(0x1f463), ("footprints")) 468 | entry(Emoji(0x1f374), ("fork_and_knife")) 469 | entry(Emoji(0x026f2), ("fountain")) 470 | entry(Emoji(0x1f340), ("four_leaf_clover")) 471 | entry(Emoji(0x1f193), ("free")) 472 | entry(Emoji(0x1f364), ("fried_shrimp")) 473 | entry(Emoji(0x1f35f), ("fries")) 474 | entry(Emoji(0x1f438), ("frog")) 475 | entry(Emoji(0x1f626), ("frowning")) 476 | entry(Emoji(0x026fd), ("fuelpump")) 477 | entry(Emoji(0x1f315), ("full_moon")) 478 | entry(Emoji(0x1f31d), ("full_moon_with_face")) 479 | entry(Emoji(0x1f3b2), ("game_die")) 480 | entry(Emoji(0x1f48e), ("gem")) 481 | entry(Emoji(0x0264a), ("gemini")) 482 | entry(Emoji(0x1f47b), ("ghost")) 483 | entry(Emoji(0x1f381), ("gift")) 484 | entry(Emoji(0x1f49d), ("gift_heart")) 485 | entry(Emoji(0x1f467), ("girl")) 486 | entry(Emoji(0x1f310), ("globe_with_meridians")) 487 | entry(Emoji(0x1f410), ("goat")) 488 | entry(Emoji(0x026f3), ("golf")) 489 | entry(Emoji(0x1f347), ("grapes")) 490 | entry(Emoji(0x1f34f), ("green_apple")) 491 | entry(Emoji(0x1f4d7), ("green_book")) 492 | entry(Emoji(0x1f49a), ("green_heart")) 493 | entry(Emoji(0x02755), ("grey_exclamation")) 494 | entry(Emoji(0x02754), ("grey_question")) 495 | entry(Emoji(0x1f62c), ("grimacing")) 496 | entry(Emoji(0x1f601), ("grin")) 497 | entry(Emoji(0x1f600), ("grinning")) 498 | entry(Emoji(0x1f482), ("guardsman")) 499 | entry(Emoji(0x1f3b8), ("guitar")) 500 | entry(Emoji(0x1f52b), ("gun")) 501 | entry(Emoji(0x1f487), ("haircut")) 502 | entry(Emoji(0x1f354), ("hamburger")) 503 | entry(Emoji(0x1f528), ("hammer")) 504 | entry(Emoji(0x1f439), ("hamster")) 505 | entry(Emoji(0x0270b), ("hand")) 506 | entry(Emoji(0x1f45c), ("handbag")) 507 | entry(Emoji(0x1f4a9), ("hankey")) 508 | entry(Emoji(0x1f425), ("hatched_chick")) 509 | entry(Emoji(0x1f423), ("hatching_chick")) 510 | entry(Emoji(0x1f3a7), ("headphones")) 511 | entry(Emoji(0x1f649), ("hear_no_evil")) 512 | entry(Emoji(0x02764), ("heart")) 513 | entry(Emoji(0x1f49f), ("heart_decoration")) 514 | entry(Emoji(0x1f60d), ("heart_eyes")) 515 | entry(Emoji(0x1f63b), ("heart_eyes_cat")) 516 | entry(Emoji(0x1f493), ("heartbeat")) 517 | entry(Emoji(0x1f497), ("heartpulse")) 518 | entry(Emoji(0x02665), ("hearts")) 519 | entry(Emoji(0x02714), ("heavy_check_mark")) 520 | entry(Emoji(0x02797), ("heavy_division_sign")) 521 | entry(Emoji(0x1f4b2), ("heavy_dollar_sign")) 522 | entry(Emoji(0x02757), ("heavy_exclamation_mark")) 523 | entry(Emoji(0x02796), ("heavy_minus_sign")) 524 | entry(Emoji(0x02716), ("heavy_multiplication_x")) 525 | entry(Emoji(0x02795), ("heavy_plus_sign")) 526 | entry(Emoji(0x1f681), ("helicopter")) 527 | entry(Emoji(0x1f33f), ("herb")) 528 | entry(Emoji(0x1f33a), ("hibiscus")) 529 | entry(Emoji(0x1f506), ("high_brightness")) 530 | entry(Emoji(0x1f460), ("high_heel")) 531 | entry(Emoji(0x1f52a), ("hocho")) 532 | entry(Emoji(0x1f36f), ("honey_pot")) 533 | entry(Emoji(0x1f41d), ("honeybee")) 534 | entry(Emoji(0x1f434), ("horse")) 535 | entry(Emoji(0x1f3c7), ("horse_racing")) 536 | entry(Emoji(0x1f3e5), ("hospital")) 537 | entry(Emoji(0x1f3e8), ("hotel")) 538 | entry(Emoji(0x02668), ("hotsprings")) 539 | entry(Emoji(0x0231b), ("hourglass")) 540 | entry(Emoji(0x023f3), ("hourglass_flowing_sand")) 541 | entry(Emoji(0x1f3e0), ("house")) 542 | entry(Emoji(0x1f3e1), ("house_with_garden")) 543 | entry(Emoji(0x1f62f), ("hushed")) 544 | entry(Emoji(0x1f368), ("ice_cream")) 545 | entry(Emoji(0x1f366), ("icecream")) 546 | entry(Emoji(0x1f194), ("id")) 547 | entry(Emoji(0x1f250), ("ideograph_advantage")) 548 | entry(Emoji(0x1f47f), ("imp")) 549 | entry(Emoji(0x1f4e5), ("inbox_tray")) 550 | entry(Emoji(0x1f4e8), ("incoming_envelope")) 551 | entry(Emoji(0x1f481), ("information_desk_person")) 552 | entry(Emoji(0x02139), ("information_source")) 553 | entry(Emoji(0x1f607), ("innocent")) 554 | entry(Emoji(0x02049), ("interrobang")) 555 | entry(Emoji(0x1f4f1), ("iphone")) 556 | entry(Emoji(0x1f3ee), ("izakaya_lantern")) 557 | entry(Emoji(0x1f383), ("jack_o_lantern")) 558 | entry(Emoji(0x1f5fe), ("japan")) 559 | entry(Emoji(0x1f3ef), ("japanese_castle")) 560 | entry(Emoji(0x1f47a), ("japanese_goblin")) 561 | entry(Emoji(0x1f479), ("japanese_ogre")) 562 | entry(Emoji(0x1f456), ("jeans")) 563 | entry(Emoji(0x1f602), ("joy")) 564 | entry(Emoji(0x1f639), ("joy_cat")) 565 | entry(Emoji(0x1f511), ("key")) 566 | entry(Emoji(0x1f51f), ("keycap_ten")) 567 | entry(Emoji(0x1f458), ("kimono")) 568 | entry(Emoji(0x1f48b), ("kiss")) 569 | entry(Emoji(0x1f617), ("kissing")) 570 | entry(Emoji(0x1f63d), ("kissing_cat")) 571 | entry(Emoji(0x1f61a), ("kissing_closed_eyes")) 572 | entry(Emoji(0x1f618), ("kissing_heart")) 573 | entry(Emoji(0x1f619), ("kissing_smiling_eyes")) 574 | entry(Emoji(0x1f428), ("koala")) 575 | entry(Emoji(0x1f201), ("koko")) 576 | entry(Emoji(0x1f3ee), ("lantern")) 577 | entry(Emoji(0x1f535), ("large_blue_circle")) 578 | entry(Emoji(0x1f537), ("large_blue_diamond")) 579 | entry(Emoji(0x1f536), ("large_orange_diamond")) 580 | entry(Emoji(0x1f317), ("last_quarter_moon")) 581 | entry(Emoji(0x1f31c), ("last_quarter_moon_with_face")) 582 | entry(Emoji(0x1f606), ("laughing")) 583 | entry(Emoji(0x1f343), ("leaves")) 584 | entry(Emoji(0x1f4d2), ("ledger")) 585 | entry(Emoji(0x1f6c5), ("left_luggage")) 586 | entry(Emoji(0x02194), ("left_right_arrow")) 587 | entry(Emoji(0x021a9), ("leftwards_arrow_with_hook")) 588 | entry(Emoji(0x1f34b), ("lemon")) 589 | entry(Emoji(0x0264c), ("leo")) 590 | entry(Emoji(0x1f406), ("leopard")) 591 | entry(Emoji(0x0264e), ("libra")) 592 | entry(Emoji(0x1f688), ("light_rail")) 593 | entry(Emoji(0x1f517), ("link")) 594 | entry(Emoji(0x1f444), ("lips")) 595 | entry(Emoji(0x1f484), ("lipstick")) 596 | entry(Emoji(0x1f512), ("lock")) 597 | entry(Emoji(0x1f50f), ("lock_with_ink_pen")) 598 | entry(Emoji(0x1f36d), ("lollipop")) 599 | entry(Emoji(0x027bf), ("loop")) 600 | entry(Emoji(0x1f4e2), ("loudspeaker")) 601 | entry(Emoji(0x1f3e9), ("love_hotel")) 602 | entry(Emoji(0x1f48c), ("love_letter")) 603 | entry(Emoji(0x1f505), ("low_brightness")) 604 | entry(Emoji(0x024c2), ("m")) 605 | entry(Emoji(0x1f50d), ("mag")) 606 | entry(Emoji(0x1f50e), ("mag_right")) 607 | entry(Emoji(0x1f004), ("mahjong")) 608 | entry(Emoji(0x1f4eb), ("mailbox")) 609 | entry(Emoji(0x1f4ea), ("mailbox_closed")) 610 | entry(Emoji(0x1f4ec), ("mailbox_with_mail")) 611 | entry(Emoji(0x1f4ed), ("mailbox_with_no_mail")) 612 | entry(Emoji(0x1f468), ("man")) 613 | entry(Emoji(0x1f472), ("man_with_gua_pi_mao")) 614 | entry(Emoji(0x1f473), ("man_with_turban")) 615 | entry(Emoji(0x1f45e), ("mans_shoe")) 616 | entry(Emoji(0x1f341), ("maple_leaf")) 617 | entry(Emoji(0x1f637), ("mask")) 618 | entry(Emoji(0x1f486), ("massage")) 619 | entry(Emoji(0x1f356), ("meat_on_bone")) 620 | entry(Emoji(0x1f4e3), ("mega")) 621 | entry(Emoji(0x1f348), ("melon")) 622 | entry(Emoji(0x1f4dd), ("memo")) 623 | entry(Emoji(0x1f6b9), ("mens")) 624 | entry(Emoji(0x1f687), ("metro")) 625 | entry(Emoji(0x1f3a4), ("microphone")) 626 | entry(Emoji(0x1f52c), ("microscope")) 627 | entry(Emoji(0x1f30c), ("milky_way")) 628 | entry(Emoji(0x1f690), ("minibus")) 629 | entry(Emoji(0x1f4bd), ("minidisc")) 630 | entry(Emoji(0x1f4f4), ("mobile_phone_off")) 631 | entry(Emoji(0x1f4b8), ("money_with_wings")) 632 | entry(Emoji(0x1f4b0), ("moneybag")) 633 | entry(Emoji(0x1f412), ("monkey")) 634 | entry(Emoji(0x1f435), ("monkey_face")) 635 | entry(Emoji(0x1f69d), ("monorail")) 636 | entry(Emoji(0x1f314), ("moon")) 637 | entry(Emoji(0x1f393), ("mortar_board")) 638 | entry(Emoji(0x1f5fb), ("mount_fuji")) 639 | entry(Emoji(0x1f6b5), ("mountain_bicyclist")) 640 | entry(Emoji(0x1f6a0), ("mountain_cableway")) 641 | entry(Emoji(0x1f69e), ("mountain_railway")) 642 | entry(Emoji(0x1f42d), ("mouse")) 643 | entry(Emoji(0x1f401), ("mouse2")) 644 | entry(Emoji(0x1f3a5), ("movie_camera")) 645 | entry(Emoji(0x1f5ff), ("moyai")) 646 | entry(Emoji(0x1f4aa), ("muscle")) 647 | entry(Emoji(0x1f344), ("mushroom")) 648 | entry(Emoji(0x1f3b9), ("musical_keyboard")) 649 | entry(Emoji(0x1f3b5), ("musical_note")) 650 | entry(Emoji(0x1f3bc), ("musical_score")) 651 | entry(Emoji(0x1f507), ("mute")) 652 | entry(Emoji(0x1f485), ("nail_care")) 653 | entry(Emoji(0x1f4db), ("name_badge")) 654 | entry(Emoji(0x1f454), ("necktie")) 655 | entry(Emoji(0x0274e), ("negative_squared_cross_mark")) 656 | entry(Emoji(0x1f610), ("neutral_face")) 657 | entry(Emoji(0x1f195), ("new")) 658 | entry(Emoji(0x1f311), ("new_moon")) 659 | entry(Emoji(0x1f31a), ("new_moon_with_face")) 660 | entry(Emoji(0x1f4f0), ("newspaper")) 661 | entry(Emoji(0x1f196), ("ng")) 662 | entry(Emoji(0x1f515), ("no_bell")) 663 | entry(Emoji(0x1f6b3), ("no_bicycles")) 664 | entry(Emoji(0x026d4), ("no_entry")) 665 | entry(Emoji(0x1f6ab), ("no_entry_sign")) 666 | entry(Emoji(0x1f645), ("no_good")) 667 | entry(Emoji(0x1f4f5), ("no_mobile_phones")) 668 | entry(Emoji(0x1f636), ("no_mouth")) 669 | entry(Emoji(0x1f6b7), ("no_pedestrians")) 670 | entry(Emoji(0x1f6ad), ("no_smoking")) 671 | entry(Emoji(0x1f6b1), ("non-potable_water")) 672 | entry(Emoji(0x1f443), ("nose")) 673 | entry(Emoji(0x1f4d3), ("notebook")) 674 | entry(Emoji(0x1f4d4), ("notebook_with_decorative_cover")) 675 | entry(Emoji(0x1f3b6), ("notes")) 676 | entry(Emoji(0x1f529), ("nut_and_bolt")) 677 | entry(Emoji(0x02b55), ("o")) 678 | entry(Emoji(0x1f17e), ("o2")) 679 | entry(Emoji(0x1f30a), ("ocean")) 680 | entry(Emoji(0x1f419), ("octopus")) 681 | entry(Emoji(0x1f362), ("oden")) 682 | entry(Emoji(0x1f3e2), ("office")) 683 | entry(Emoji(0x1f197), ("ok")) 684 | entry(Emoji(0x1f44c), ("ok_hand")) 685 | entry(Emoji(0x1f646), ("ok_woman")) 686 | entry(Emoji(0x1f474), ("older_man")) 687 | entry(Emoji(0x1f475), ("older_woman")) 688 | entry(Emoji(0x1f51b), ("on")) 689 | entry(Emoji(0x1f698), ("oncoming_automobile")) 690 | entry(Emoji(0x1f68d), ("oncoming_bus")) 691 | entry(Emoji(0x1f694), ("oncoming_police_car")) 692 | entry(Emoji(0x1f696), ("oncoming_taxi")) 693 | entry(Emoji(0x1f4d6), ("open_book")) 694 | entry(Emoji(0x1f4c2), ("open_file_folder")) 695 | entry(Emoji(0x1f450), ("open_hands")) 696 | entry(Emoji(0x1f62e), ("open_mouth")) 697 | entry(Emoji(0x026ce), ("ophiuchus")) 698 | entry(Emoji(0x1f4d9), ("orange_book")) 699 | entry(Emoji(0x1f4e4), ("outbox_tray")) 700 | entry(Emoji(0x1f402), ("ox")) 701 | entry(Emoji(0x1f4e6), ("package")) 702 | entry(Emoji(0x1f4c4), ("page_facing_up")) 703 | entry(Emoji(0x1f4c3), ("page_with_curl")) 704 | entry(Emoji(0x1f4df), ("pager")) 705 | entry(Emoji(0x1f334), ("palm_tree")) 706 | entry(Emoji(0x1f43c), ("panda_face")) 707 | entry(Emoji(0x1f4ce), ("paperclip")) 708 | entry(Emoji(0x1f17f), ("parking")) 709 | entry(Emoji(0x0303d), ("part_alternation_mark")) 710 | entry(Emoji(0x026c5), ("partly_sunny")) 711 | entry(Emoji(0x1f6c2), ("passport_control")) 712 | entry(Emoji(0x1f43e), ("paw_prints")) 713 | entry(Emoji(0x1f351), ("peach")) 714 | entry(Emoji(0x1f350), ("pear")) 715 | entry(Emoji(0x1f4dd), ("pencil")) 716 | entry(Emoji(0x0270f), ("pencil2")) 717 | entry(Emoji(0x1f427), ("penguin")) 718 | entry(Emoji(0x1f614), ("pensive")) 719 | entry(Emoji(0x1f3ad), ("performing_arts")) 720 | entry(Emoji(0x1f623), ("persevere")) 721 | entry(Emoji(0x1f64d), ("person_frowning")) 722 | entry(Emoji(0x1f471), ("person_with_blond_hair")) 723 | entry(Emoji(0x1f64e), ("person_with_pouting_face")) 724 | entry(Emoji(0x0260e), ("phone")) 725 | entry(Emoji(0x1f437), ("pig")) 726 | entry(Emoji(0x1f416), ("pig2")) 727 | entry(Emoji(0x1f43d), ("pig_nose")) 728 | entry(Emoji(0x1f48a), ("pill")) 729 | entry(Emoji(0x1f34d), ("pineapple")) 730 | entry(Emoji(0x02653), ("pisces")) 731 | entry(Emoji(0x1f355), ("pizza")) 732 | entry(Emoji(0x1f447), ("point_down")) 733 | entry(Emoji(0x1f448), ("point_left")) 734 | entry(Emoji(0x1f449), ("point_right")) 735 | entry(Emoji(0x0261d), ("point_up")) 736 | entry(Emoji(0x1f446), ("point_up_2")) 737 | entry(Emoji(0x1f693), ("police_car")) 738 | entry(Emoji(0x1f429), ("poodle")) 739 | entry(Emoji(0x1f4a9), ("poop")) 740 | entry(Emoji(0x1f3e3), ("post_office")) 741 | entry(Emoji(0x1f4ef), ("postal_horn")) 742 | entry(Emoji(0x1f4ee), ("postbox")) 743 | entry(Emoji(0x1f6b0), ("potable_water")) 744 | entry(Emoji(0x1f45d), ("pouch")) 745 | entry(Emoji(0x1f357), ("poultry_leg")) 746 | entry(Emoji(0x1f4b7), ("pound")) 747 | entry(Emoji(0x1f63e), ("pouting_cat")) 748 | entry(Emoji(0x1f64f), ("pray")) 749 | entry(Emoji(0x1f478), ("princess")) 750 | entry(Emoji(0x1f44a), ("punch")) 751 | entry(Emoji(0x1f49c), ("purple_heart")) 752 | entry(Emoji(0x1f45b), ("purse")) 753 | entry(Emoji(0x1f4cc), ("pushpin")) 754 | entry(Emoji(0x1f6ae), ("put_litter_in_its_place")) 755 | entry(Emoji(0x02753), ("question")) 756 | entry(Emoji(0x1f430), ("rabbit")) 757 | entry(Emoji(0x1f407), ("rabbit2")) 758 | entry(Emoji(0x1f40e), ("racehorse")) 759 | entry(Emoji(0x1f4fb), ("radio")) 760 | entry(Emoji(0x1f518), ("radio_button")) 761 | entry(Emoji(0x1f621), ("rage")) 762 | entry(Emoji(0x1f683), ("railway_car")) 763 | entry(Emoji(0x1f308), ("rainbow")) 764 | entry(Emoji(0x0270b), ("raised_hand")) 765 | entry(Emoji(0x1f64c), ("raised_hands")) 766 | entry(Emoji(0x1f64b), ("raising_hand")) 767 | entry(Emoji(0x1f40f), ("ram")) 768 | entry(Emoji(0x1f35c), ("ramen")) 769 | entry(Emoji(0x1f400), ("rat")) 770 | entry(Emoji(0x0267b), ("recycle")) 771 | entry(Emoji(0x1f697), ("red_car")) 772 | entry(Emoji(0x1f534), ("red_circle")) 773 | entry(Emoji(0x000ae), ("registered")) 774 | entry(Emoji(0x0263a), ("relaxed")) 775 | entry(Emoji(0x1f60c), ("relieved")) 776 | entry(Emoji(0x1f501), ("repeat")) 777 | entry(Emoji(0x1f502), ("repeat_one")) 778 | entry(Emoji(0x1f6bb), ("restroom")) 779 | entry(Emoji(0x1f49e), ("revolving_hearts")) 780 | entry(Emoji(0x023ea), ("rewind")) 781 | entry(Emoji(0x1f380), ("ribbon")) 782 | entry(Emoji(0x1f35a), ("rice")) 783 | entry(Emoji(0x1f359), ("rice_ball")) 784 | entry(Emoji(0x1f358), ("rice_cracker")) 785 | entry(Emoji(0x1f391), ("rice_scene")) 786 | entry(Emoji(0x1f48d), ("ring")) 787 | entry(Emoji(0x1f680), ("rocket")) 788 | entry(Emoji(0x1f3a2), ("roller_coaster")) 789 | entry(Emoji(0x1f413), ("rooster")) 790 | entry(Emoji(0x1f339), ("rose")) 791 | entry(Emoji(0x1f6a8), ("rotating_light")) 792 | entry(Emoji(0x1f4cd), ("round_pushpin")) 793 | entry(Emoji(0x1f6a3), ("rowboat")) 794 | entry(Emoji(0x1f3c9), ("rugby_football")) 795 | entry(Emoji(0x1f3c3), ("runner")) 796 | entry(Emoji(0x1f3c3), ("running")) 797 | entry(Emoji(0x1f3bd), ("running_shirt_with_sash")) 798 | entry(Emoji(0x1f202), ("sa")) 799 | entry(Emoji(0x02650), ("sagittarius")) 800 | entry(Emoji(0x026f5), ("sailboat")) 801 | entry(Emoji(0x1f376), ("sake")) 802 | entry(Emoji(0x1f461), ("sandal")) 803 | entry(Emoji(0x1f385), ("santa")) 804 | entry(Emoji(0x1f4e1), ("satellite")) 805 | entry(Emoji(0x1f606), ("satisfied")) 806 | entry(Emoji(0x1f3b7), ("saxophone")) 807 | entry(Emoji(0x1f3eb), ("school")) 808 | entry(Emoji(0x1f392), ("school_satchel")) 809 | entry(Emoji(0x02702), ("scissors")) 810 | entry(Emoji(0x0264f), ("scorpius")) 811 | entry(Emoji(0x1f631), ("scream")) 812 | entry(Emoji(0x1f640), ("scream_cat")) 813 | entry(Emoji(0x1f4dc), ("scroll")) 814 | entry(Emoji(0x1f4ba), ("seat")) 815 | entry(Emoji(0x03299), ("secret")) 816 | entry(Emoji(0x1f648), ("see_no_evil")) 817 | entry(Emoji(0x1f331), ("seedling")) 818 | entry(Emoji(0x1f367), ("shaved_ice")) 819 | entry(Emoji(0x1f411), ("sheep")) 820 | entry(Emoji(0x1f41a), ("shell")) 821 | entry(Emoji(0x1f6a2), ("ship")) 822 | entry(Emoji(0x1f455), ("shirt")) 823 | entry(Emoji(0x1f4a9), ("shit")) 824 | entry(Emoji(0x1f45e), ("shoe")) 825 | entry(Emoji(0x1f6bf), ("shower")) 826 | entry(Emoji(0x1f4f6), ("signal_strength")) 827 | entry(Emoji(0x1f52f), ("six_pointed_star")) 828 | entry(Emoji(0x1f3bf), ("ski")) 829 | entry(Emoji(0x1f480), ("skull")) 830 | entry(Emoji(0x1f634), ("sleeping")) 831 | entry(Emoji(0x1f62a), ("sleepy")) 832 | entry(Emoji(0x1f3b0), ("slot_machine")) 833 | entry(Emoji(0x1f539), ("small_blue_diamond")) 834 | entry(Emoji(0x1f538), ("small_orange_diamond")) 835 | entry(Emoji(0x1f53a), ("small_red_triangle")) 836 | entry(Emoji(0x1f53b), ("small_red_triangle_down")) 837 | entry(Emoji(0x1f604), ("smile")) 838 | entry(Emoji(0x1f638), ("smile_cat")) 839 | entry(Emoji(0x1f603), ("smiley")) 840 | entry(Emoji(0x1f63a), ("smiley_cat")) 841 | entry(Emoji(0x1f608), ("smiling_imp")) 842 | entry(Emoji(0x1f60f), ("smirk")) 843 | entry(Emoji(0x1f63c), ("smirk_cat")) 844 | entry(Emoji(0x1f6ac), ("smoking")) 845 | entry(Emoji(0x1f40c), ("snail")) 846 | entry(Emoji(0x1f40d), ("snake")) 847 | entry(Emoji(0x1f3c2), ("snowboarder")) 848 | entry(Emoji(0x02744), ("snowflake")) 849 | entry(Emoji(0x026c4), ("snowman")) 850 | entry(Emoji(0x1f62d), ("sob")) 851 | entry(Emoji(0x026bd), ("soccer")) 852 | entry(Emoji(0x1f51c), ("soon")) 853 | entry(Emoji(0x1f198), ("sos")) 854 | entry(Emoji(0x1f509), ("sound")) 855 | entry(Emoji(0x1f47e), ("space_invader")) 856 | entry(Emoji(0x02660), ("spades")) 857 | entry(Emoji(0x1f35d), ("spaghetti")) 858 | entry(Emoji(0x02747), ("sparkle")) 859 | entry(Emoji(0x1f387), ("sparkler")) 860 | entry(Emoji(0x02728), ("sparkles")) 861 | entry(Emoji(0x1f496), ("sparkling_heart")) 862 | entry(Emoji(0x1f64a), ("speak_no_evil")) 863 | entry(Emoji(0x1f50a), ("speaker")) 864 | entry(Emoji(0x1f4ac), ("speech_balloon")) 865 | entry(Emoji(0x1f6a4), ("speedboat")) 866 | entry(Emoji(0x02b50), ("star")) 867 | entry(Emoji(0x1f31f), ("star2")) 868 | entry(Emoji(0x1f303), ("stars")) 869 | entry(Emoji(0x1f689), ("station")) 870 | entry(Emoji(0x1f5fd), ("statue_of_liberty")) 871 | entry(Emoji(0x1f682), ("steam_locomotive")) 872 | entry(Emoji(0x1f372), ("stew")) 873 | entry(Emoji(0x1f4cf), ("straight_ruler")) 874 | entry(Emoji(0x1f353), ("strawberry")) 875 | entry(Emoji(0x1f61b), ("stuck_out_tongue")) 876 | entry(Emoji(0x1f61d), ("stuck_out_tongue_closed_eyes")) 877 | entry(Emoji(0x1f61c), ("stuck_out_tongue_winking_eye")) 878 | entry(Emoji(0x1f31e), ("sun_with_face")) 879 | entry(Emoji(0x1f33b), ("sunflower")) 880 | entry(Emoji(0x1f60e), ("sunglasses")) 881 | entry(Emoji(0x02600), ("sunny")) 882 | entry(Emoji(0x1f305), ("sunrise")) 883 | entry(Emoji(0x1f304), ("sunrise_over_mountains")) 884 | entry(Emoji(0x1f3c4), ("surfer")) 885 | entry(Emoji(0x1f363), ("sushi")) 886 | entry(Emoji(0x1f69f), ("suspension_railway")) 887 | entry(Emoji(0x1f613), ("sweat")) 888 | entry(Emoji(0x1f4a6), ("sweat_drops")) 889 | entry(Emoji(0x1f605), ("sweat_smile")) 890 | entry(Emoji(0x1f360), ("sweet_potato")) 891 | entry(Emoji(0x1f3ca), ("swimmer")) 892 | entry(Emoji(0x1f523), ("symbols")) 893 | entry(Emoji(0x1f489), ("syringe")) 894 | entry(Emoji(0x1f389), ("tada")) 895 | entry(Emoji(0x1f38b), ("tanabata_tree")) 896 | entry(Emoji(0x1f34a), ("tangerine")) 897 | entry(Emoji(0x02649), ("taurus")) 898 | entry(Emoji(0x1f695), ("taxi")) 899 | entry(Emoji(0x1f375), ("tea")) 900 | entry(Emoji(0x0260e), ("telephone")) 901 | entry(Emoji(0x1f4de), ("telephone_receiver")) 902 | entry(Emoji(0x1f52d), ("telescope")) 903 | entry(Emoji(0x1f3be), ("tennis")) 904 | entry(Emoji(0x026fa), ("tent")) 905 | entry(Emoji(0x1f4ad), ("thought_balloon")) 906 | entry(Emoji(0x1f44e), ("thumbsdown")) 907 | entry(Emoji(0x1f44d), ("thumbsup")) 908 | entry(Emoji(0x1f3ab), ("ticket")) 909 | entry(Emoji(0x1f42f), ("tiger")) 910 | entry(Emoji(0x1f405), ("tiger2")) 911 | entry(Emoji(0x1f62b), ("tired_face")) 912 | entry(Emoji(0x02122), ("tm")) 913 | entry(Emoji(0x1f6bd), ("toilet")) 914 | entry(Emoji(0x1f5fc), ("tokyo_tower")) 915 | entry(Emoji(0x1f345), ("tomato")) 916 | entry(Emoji(0x1f445), ("tongue")) 917 | entry(Emoji(0x1f51d), ("top")) 918 | entry(Emoji(0x1f3a9), ("tophat")) 919 | entry(Emoji(0x1f69c), ("tractor")) 920 | entry(Emoji(0x1f6a5), ("traffic_light")) 921 | entry(Emoji(0x1f683), ("train")) 922 | entry(Emoji(0x1f686), ("train2")) 923 | entry(Emoji(0x1f68a), ("tram")) 924 | entry(Emoji(0x1f6a9), ("triangular_flag_on_post")) 925 | entry(Emoji(0x1f4d0), ("triangular_ruler")) 926 | entry(Emoji(0x1f531), ("trident")) 927 | entry(Emoji(0x1f624), ("triumph")) 928 | entry(Emoji(0x1f68e), ("trolleybus")) 929 | entry(Emoji(0x1f3c6), ("trophy")) 930 | entry(Emoji(0x1f379), ("tropical_drink")) 931 | entry(Emoji(0x1f420), ("tropical_fish")) 932 | entry(Emoji(0x1f69a), ("truck")) 933 | entry(Emoji(0x1f3ba), ("trumpet")) 934 | entry(Emoji(0x1f455), ("tshirt")) 935 | entry(Emoji(0x1f337), ("tulip")) 936 | entry(Emoji(0x1f422), ("turtle")) 937 | entry(Emoji(0x1f4fa), ("tv")) 938 | entry(Emoji(0x1f500), ("twisted_rightwards_arrows")) 939 | entry(Emoji(0x1f495), ("two_hearts")) 940 | entry(Emoji(0x1f46c), ("two_men_holding_hands")) 941 | entry(Emoji(0x1f46d), ("two_women_holding_hands")) 942 | entry(Emoji(0x1f239), ("u5272")) 943 | entry(Emoji(0x1f234), ("u5408")) 944 | entry(Emoji(0x1f23a), ("u55b6")) 945 | entry(Emoji(0x1f22f), ("u6307")) 946 | entry(Emoji(0x1f237), ("u6708")) 947 | entry(Emoji(0x1f236), ("u6709")) 948 | entry(Emoji(0x1f235), ("u6e80")) 949 | entry(Emoji(0x1f21a), ("u7121")) 950 | entry(Emoji(0x1f238), ("u7533")) 951 | entry(Emoji(0x1f232), ("u7981")) 952 | entry(Emoji(0x1f233), ("u7a7a")) 953 | entry(Emoji(0x02614), ("umbrella")) 954 | entry(Emoji(0x1f612), ("unamused")) 955 | entry(Emoji(0x1f51e), ("underage")) 956 | entry(Emoji(0x1f513), ("unlock")) 957 | entry(Emoji(0x1f199), ("up")) 958 | entry(Emoji(0x0270c), ("v")) 959 | entry(Emoji(0x1f6a6), ("vertical_traffic_light")) 960 | entry(Emoji(0x1f4fc), ("vhs")) 961 | entry(Emoji(0x1f4f3), ("vibration_mode")) 962 | entry(Emoji(0x1f4f9), ("video_camera")) 963 | entry(Emoji(0x1f3ae), ("video_game")) 964 | entry(Emoji(0x1f3bb), ("violin")) 965 | entry(Emoji(0x0264d), ("virgo")) 966 | entry(Emoji(0x1f30b), ("volcano")) 967 | entry(Emoji(0x1f19a), ("vs")) 968 | entry(Emoji(0x1f6b6), ("walking")) 969 | entry(Emoji(0x1f318), ("waning_crescent_moon")) 970 | entry(Emoji(0x1f316), ("waning_gibbous_moon")) 971 | entry(Emoji(0x026a0), ("warning")) 972 | entry(Emoji(0x0231a), ("watch")) 973 | entry(Emoji(0x1f403), ("water_buffalo")) 974 | entry(Emoji(0x1f349), ("watermelon")) 975 | entry(Emoji(0x1f44b), ("wave")) 976 | entry(Emoji(0x03030), ("wavy_dash")) 977 | entry(Emoji(0x1f312), ("waxing_crescent_moon")) 978 | entry(Emoji(0x1f314), ("waxing_gibbous_moon")) 979 | entry(Emoji(0x1f6be), ("wc")) 980 | entry(Emoji(0x1f629), ("weary")) 981 | entry(Emoji(0x1f492), ("wedding")) 982 | entry(Emoji(0x1f433), ("whale")) 983 | entry(Emoji(0x1f40b), ("whale2")) 984 | entry(Emoji(0x0267f), ("wheelchair")) 985 | entry(Emoji(0x02705), ("white_check_mark")) 986 | entry(Emoji(0x026aa), ("white_circle")) 987 | entry(Emoji(0x1f4ae), ("white_flower")) 988 | entry(Emoji(0x02b1c), ("white_large_square")) 989 | entry(Emoji(0x025fd), ("white_medium_small_square")) 990 | entry(Emoji(0x025fb), ("white_medium_square")) 991 | entry(Emoji(0x025ab), ("white_small_square")) 992 | entry(Emoji(0x1f533), ("white_square_button")) 993 | entry(Emoji(0x1f390), ("wind_chime")) 994 | entry(Emoji(0x1f377), ("wine_glass")) 995 | entry(Emoji(0x1f609), ("wink")) 996 | entry(Emoji(0x1f43a), ("wolf")) 997 | entry(Emoji(0x1f469), ("woman")) 998 | entry(Emoji(0x1f45a), ("womans_clothes")) 999 | entry(Emoji(0x1f452), ("womans_hat")) 1000 | entry(Emoji(0x1f6ba), ("womens")) 1001 | entry(Emoji(0x1f61f), ("worried")) 1002 | entry(Emoji(0x1f527), ("wrench")) 1003 | entry(Emoji(0x0274c), ("x")) 1004 | entry(Emoji(0x1f49b), ("yellow_heart")) 1005 | entry(Emoji(0x1f4b4), ("yen")) 1006 | entry(Emoji(0x1f60b), ("yum")) 1007 | entry(Emoji(0x026a1), ("zap")) 1008 | entry(Emoji(0x1f4a4), ("zzz")) 1009 | end defaults 1010 | end ShortCodes 1011 | -------------------------------------------------------------------------------- /src/test/scala-2/com/lightbend/emoji/EmojiSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import org.scalatest.matchers.should.Matchers._ 7 | import org.scalatest.wordspec.AnyWordSpec 8 | 9 | class EmojiSpec extends AnyWordSpec { 10 | 11 | "hex" should { 12 | 13 | "map correctly" in { 14 | val ramen = Emoji(0x1f35c) 15 | ramen.hex shouldBe "0x1f35c" 16 | } 17 | 18 | } 19 | 20 | "toString" should { 21 | "return correct value" in { 22 | val ramen = Emoji(0x1f35c) 23 | ramen.toString shouldBe "\ud83c\udf5c" 24 | } 25 | } 26 | 27 | "name" should { 28 | "return correct value" in { 29 | val ramen = Emoji(0x1f35c) 30 | ramen.name shouldBe "STEAMING BOWL" 31 | } 32 | } 33 | 34 | "equals" should { 35 | "return true" in { 36 | val codePoint = 128515 37 | val e1 = Emoji(codePoint) 38 | val e2 = Emoji(codePoint) 39 | e1.equals(e1) shouldBe (true) 40 | e1.equals(e2) shouldBe (true) 41 | e2.equals(e1) shouldBe (true) 42 | } 43 | 44 | "return false" in { 45 | val e = Emoji(codePoint = 128515) 46 | Emoji(e.codePoint + 1).equals(e) shouldBe (false) 47 | Emoji(e.codePoint - 1).equals(e) shouldBe (false) 48 | } 49 | } 50 | 51 | "hashCode" should { 52 | "hash correctly" in { 53 | val e = Emoji(codePoint = 128515) 54 | e.hashCode shouldBe (e.hashCode) 55 | Emoji(e.codePoint).hashCode shouldBe (e.hashCode) 56 | Emoji(e.codePoint + 1).hashCode should not be (e.hashCode) 57 | Emoji(e.codePoint - 1).hashCode should not be (e.hashCode) 58 | } 59 | } 60 | 61 | "smiling face with open mouth" should { 62 | "pass sanity check \uD83D\uDE03" in { 63 | val e = Emoji(codePoint = 128515) 64 | e.name shouldBe "SMILING FACE WITH OPEN MOUTH" 65 | e.codePoint shouldBe 128515 66 | e.toString shouldBe "\uD83D\uDE03" 67 | Emoji(e.toString).toString shouldBe (e.toString) 68 | Emoji(e.chars).toString shouldBe (e.toString) 69 | Emoji(e.codePoint).toString shouldBe (e.toString) 70 | } 71 | } 72 | 73 | "implicits" should { 74 | 75 | "map hexcode correctly" in { 76 | import Emoji.Implicits._ 77 | 78 | val ramen = Emoji(0x1f35c) 79 | "1f35c".codePointEmoji shouldBe ramen 80 | } 81 | 82 | "map hexcode correctly using a leading 0x" in { 83 | import Emoji.Implicits._ 84 | 85 | val ramen = Emoji(0x1f35c) 86 | "0x1f35c".codePointEmoji shouldBe ramen 87 | } 88 | 89 | "map raw integers correctly" in { 90 | import Emoji.Implicits._ 91 | 92 | val ramen = Emoji(0x1f35c) 93 | 0x1f35c.emoji shouldBe ramen 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/test/scala-2/com/lightbend/emoji/ShortCodesSpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import org.scalatest.matchers.should.Matchers._ 7 | import org.scalatest.wordspec.AnyWordSpec 8 | 9 | import ShortCodes.Implicits._ 10 | 11 | class ShortCodesSpec extends AnyWordSpec { 12 | 13 | "ShortCodes.Implicits" should { 14 | 15 | "map emoji to shortcodes using the implicit class" in { 16 | import ShortCodes.Defaults._ 17 | 18 | val pointRightEmoji = Emoji(0x1f449) 19 | pointRightEmoji.shortCodes shouldBe Some(Set("point_right")) 20 | } 21 | 22 | "map shortcode to emoji using the implicit class" in { 23 | import ShortCodes.Defaults._ 24 | 25 | val pointRightEmoji = new String(Character.toChars(0x1f449)) 26 | "point_right".emoji.toString shouldBe s"$pointRightEmoji" 27 | } 28 | 29 | } 30 | 31 | "ShortCodes" should { 32 | 33 | "default short codes sanity check" in { 34 | import ShortCodes.Defaults._ 35 | 36 | val current = ShortCodes.current 37 | current.shortCodes.nonEmpty shouldBe true 38 | current.emojis.nonEmpty shouldBe true 39 | current.shortCodes.foreach { shortCode => 40 | current.emoji(shortCode) match { 41 | case Some(emoji) => Emoji.isEmoji(emoji.codePoint) shouldBe true 42 | case None => fail(s"Unable to find Emoji for shortCode '${shortCode}") 43 | } 44 | } 45 | } 46 | 47 | "pick up the current shortCode mapping" in { 48 | import ShortCodes.Defaults._ 49 | 50 | val shortCodes = ShortCodes.current 51 | shortCodes shouldBe ShortCodes.Defaults.defaultImplicit 52 | } 53 | 54 | "find emoji given a short code" in { 55 | import ShortCodes.Defaults._ 56 | 57 | val maybeEmoji = ShortCodes.current.emoji("point_right") 58 | maybeEmoji shouldBe Some(Emoji(0x1f449)) 59 | } 60 | 61 | "find short codes given an emoji" in { 62 | import ShortCodes.Defaults._ 63 | 64 | val maybeShortCodes = ShortCodes.current.shortCodes(Emoji(0x1f449)) 65 | maybeShortCodes shouldBe Some(Set("point_right")) 66 | } 67 | 68 | "define a new custom shortcode mapping" in { 69 | implicit val newShortCodes = new ShortCodes(Some(ShortCodes.Defaults.defaultImplicit)) 70 | 71 | val stuckOutTongue = Emoji(0x1f61b) // aka "stuck_out_tongue" 72 | newShortCodes.entry(stuckOutTongue, "silly") 73 | 74 | val silly = ShortCodes.current.emoji("silly").get 75 | stuckOutTongue shouldBe silly 76 | } 77 | 78 | } 79 | 80 | "The Emojilator" should { 81 | 82 | "allow short names between colons" in { 83 | import ShortCodes.Defaults._ 84 | 85 | val eye = "I" 86 | val heart = "heart".emoji 87 | 88 | e"$eye :heart: Scala" shouldBe s"I $heart Scala" 89 | } 90 | 91 | "ignore short names in interpolated args" in { 92 | import ShortCodes.Defaults._ 93 | 94 | val eye = "I" 95 | val heart = ":heart:" 96 | 97 | e"$eye $heart Scala" shouldBe s"I :heart: Scala" 98 | } 99 | 100 | "accept double colon as double colon" in { 101 | import ShortCodes.Defaults._ 102 | 103 | val heart = "heart".emoji 104 | 105 | e"List of fave emojis = :heart: :: Nil" shouldBe s"List of fave emojis = $heart :: Nil" 106 | } 107 | 108 | "accept colon not followed by emoji char as literal colon" in { 109 | import ShortCodes.Defaults._ 110 | 111 | val smiley = "smiley".emoji 112 | 113 | e"Dear Customer: Have a nice day! :) :smiley:" shouldBe s"Dear Customer: Have a nice day! :) $smiley" 114 | } 115 | 116 | "also accept backslash-escaped colon as literal colon" in { 117 | import ShortCodes.Defaults._ 118 | 119 | val eye = "I" 120 | val heart = "heart".emoji 121 | 122 | e"$eye :heart:\: Scala" shouldBe s"I $heart: Scala" 123 | e"$eye \:heart:\: Scala" shouldBe s"I :heart:: Scala" 124 | e"$eye \::heart:\: Scala" shouldBe s"I :$heart: Scala" 125 | } 126 | 127 | "not go kaput on bad short name" in { 128 | import ShortCodes.Defaults._ 129 | 130 | val upper = "+1".emoji 131 | 132 | e":+1: Loved it! So much! :++1:" shouldBe s"$upper Loved it! So much! :++1:" 133 | } 134 | 135 | "gently ignore bad characters" in { 136 | import ShortCodes.Defaults._ 137 | 138 | val upper = "+1".emoji 139 | 140 | e":+1: Love the idea of using :left arrow: in for comprehensions!" shouldBe 141 | s"$upper Love the idea of using :left arrow: in for comprehensions!" 142 | } 143 | } 144 | 145 | } 146 | -------------------------------------------------------------------------------- /src/test/scala-3/com/lightbend/emoji/EmojiSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import Emoji.* 7 | 8 | class EmojiSuite extends munit.FunSuite: 9 | 10 | def assertFalse(b: Boolean) = assert(!b) 11 | 12 | val ramen = Emoji(0x1f35c) 13 | val smiley = Emoji(codePoint = 128515) 14 | 15 | test("hex maps correctly") { 16 | assertEquals(ramen.hex, "0x1f35c") 17 | } 18 | 19 | test("toString shows Unicode value") { 20 | assertEquals(ramen.toString, "\ud83c\udf5c") 21 | } 22 | 23 | test("name returns the name") { 24 | assertEquals(ramen.name, "STEAMING BOWL") 25 | } 26 | 27 | test("equals is reflexive and symmetric") { 28 | val codePoint = 128515 29 | val e1 = Emoji(codePoint) 30 | val e2 = Emoji(codePoint) 31 | assert(e1.equals(e1)) 32 | assert(e1.equals(e2)) 33 | assert(e2.equals(e1)) 34 | } 35 | 36 | test("equals knows when it's not equal") { 37 | val e = Emoji(codePoint = 128515) 38 | assertFalse(Emoji(e.codePoint + 1).equals(e)) 39 | assertFalse(Emoji(e.codePoint - 1).equals(e)) 40 | } 41 | 42 | test("hashCode is the codepoint hash") { 43 | val e = Emoji(codePoint = 128515) 44 | assertEquals(e.hashCode, e.hashCode) 45 | assertEquals(Emoji(e.codePoint).hashCode, e.hashCode) 46 | assertFalse(Emoji(e.codePoint + 1).hashCode == e.hashCode) 47 | assertFalse(Emoji(e.codePoint - 1).hashCode == e.hashCode) 48 | } 49 | 50 | test("smiling face with open mouth is \uD83D\uDE03") { 51 | assertEquals(smiley.name, "SMILING FACE WITH OPEN MOUTH") 52 | assertEquals(smiley.codePoint, 128515) 53 | assertEquals(smiley.toString, "\uD83D\uDE03") 54 | assertEquals(Emoji(smiley.toString).toString, smiley.toString) 55 | assertEquals(Emoji(smiley.chars).toString, smiley.toString) 56 | assertEquals(Emoji(smiley.codePoint).toString, smiley.toString) 57 | } 58 | 59 | test("map hexcode correctly") { 60 | assertEquals("1f35c".codePointEmoji, ramen) 61 | } 62 | 63 | test("map hexcode correctly using a leading 0x") { 64 | assertEquals("0x1f35c".codePointEmoji, ramen) 65 | } 66 | 67 | test("map raw integers correctly") { 68 | assertEquals(0x1f35c.emoji, ramen) 69 | } 70 | -------------------------------------------------------------------------------- /src/test/scala-3/com/lightbend/emoji/ShortCodesSuite.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) Lightbend Inc. 3 | */ 4 | package com.lightbend.emoji 5 | 6 | import ShortCodes.{given, *} 7 | 8 | class ShortCodesSuite extends munit.FunSuite: 9 | 10 | test("map emoji to shortcodes using the implicit class") { 11 | val pointRightEmoji = Emoji(0x1f449) 12 | assertEquals(pointRightEmoji.shortCodes, Some(Set("point_right"))) 13 | } 14 | 15 | test("map shortcode to emoji using the implicit class") { 16 | val pointRightEmoji = new String(Character.toChars(0x1f449)) 17 | assertEquals("point_right".emoji.toString, s"$pointRightEmoji") 18 | } 19 | 20 | test("default short codes sanity check") { 21 | val current = ShortCodes.current 22 | assert(current.shortCodes.nonEmpty) 23 | assert(current.emojis.nonEmpty) 24 | current.shortCodes.foreach { shortCode => 25 | current.emoji(shortCode) match { 26 | case Some(emoji) => assert(Emoji.isEmoji(emoji.codePoint)) 27 | case None => fail(s"Unable to find Emoji for shortCode '${shortCode}") 28 | } 29 | } 30 | } 31 | 32 | test("pick up the current shortCode mapping") { 33 | val shortCodes = ShortCodes.current 34 | assertEquals(shortCodes, ShortCodes.given_ShortCodes) 35 | } 36 | 37 | test("find emoji given a short code") { 38 | val maybeEmoji = ShortCodes.current.emoji("point_right") 39 | assertEquals(maybeEmoji, Some(Emoji(0x1f449))) 40 | } 41 | 42 | test("find short codes given an emoji") { 43 | val maybeShortCodes = ShortCodes.current.shortCodes(Emoji(0x1f449)) 44 | assertEquals(maybeShortCodes, Some(Set("point_right"))) 45 | } 46 | 47 | test("define a new custom shortcode mapping") { 48 | given newShortCodes: ShortCodes = new ShortCodes(Some(ShortCodes.given_ShortCodes)) 49 | 50 | val stuckOutTongue = Emoji(0x1f61b) // aka "stuck_out_tongue" 51 | newShortCodes.entry(stuckOutTongue, "silly") 52 | 53 | val silly = ShortCodes.current.emoji("silly").get 54 | assertEquals(stuckOutTongue, silly) 55 | } 56 | 57 | test("use assignment syntax for custom shortcode mapping") { 58 | given newShortCodes: ShortCodes = new ShortCodes(Some(ShortCodes.given_ShortCodes)) 59 | 60 | val stuckOutTongue = Emoji(0x1f61b) // aka "stuck_out_tongue" 61 | newShortCodes(stuckOutTongue) = "silly" 62 | 63 | val silly = ShortCodes.current.emoji("silly").get 64 | assertEquals(stuckOutTongue, silly) 65 | } 66 | 67 | test("allow short names between colons") { 68 | val eye = "I" 69 | val heart = "heart".emoji 70 | 71 | assertEquals(e"$eye :heart: Scala", s"I $heart Scala") 72 | } 73 | 74 | test("ignore short names in interpolated args") { 75 | val eye = "I" 76 | val heart = ":heart:" 77 | assertEquals(e"$eye $heart Scala", s"I :heart: Scala") 78 | } 79 | 80 | test("accept double colon as double colon") { 81 | val heart = "heart".emoji 82 | assertEquals(e"List of fave emojis = :heart: :: Nil", s"List of fave emojis = $heart :: Nil") 83 | } 84 | 85 | test("accept colon not followed by emoji char as literal colon") { 86 | val smiley = "smiley".emoji 87 | assertEquals( 88 | e"Dear Customer: Have a nice day! :) :smiley:", 89 | s"Dear Customer: Have a nice day! :) $smiley" 90 | ) 91 | } 92 | 93 | test("also accept backslash-escaped colon as literal colon") { 94 | val eye = "I" 95 | val heart = "heart".emoji 96 | assertEquals(e"$eye :heart:\: Scala", s"I $heart: Scala") 97 | assertEquals(e"$eye \:heart:\: Scala", s"I :heart:: Scala") 98 | assertEquals(e"$eye \::heart:\: Scala", s"I :$heart: Scala") 99 | } 100 | 101 | test("not go kaput on bad short name") { 102 | val upper = "+1".emoji 103 | assertEquals(e":+1: Loved it! So much! :++1:", s"$upper Loved it! So much! :++1:") 104 | } 105 | 106 | test("gently ignore bad characters") { 107 | val upper = "+1".emoji 108 | assertEquals( 109 | e":+1: Love the idea of using :left arrow: in for comprehensions!", 110 | s"$upper Love the idea of using :left arrow: in for comprehensions!" 111 | ) 112 | } 113 | --------------------------------------------------------------------------------