@ferrucc-io/emoji-picker
Version:
A beautiful and modern emoji picker for React
1,755 lines (1,751 loc) • 745 kB
JavaScript
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
// ../../node_modules/jotai/esm/vanilla.mjs
var keyCount = 0;
function atom(read, write) {
const key = `atom${++keyCount}`;
const config = {
toString() {
return (import.meta.env ? import.meta.env.MODE : void 0) !== "production" && this.debugLabel ? key + ":" + this.debugLabel : key;
}
};
if (typeof read === "function") {
config.read = read;
} else {
config.init = read;
config.read = defaultRead;
config.write = defaultWrite;
}
if (write) {
config.write = write;
}
return config;
}
function defaultRead(get) {
return get(this);
}
function defaultWrite(get, set, arg) {
return set(
this,
typeof arg === "function" ? arg(get(this)) : arg
);
}
var isSelfAtom = (atom2, a) => atom2.unstable_is ? atom2.unstable_is(a) : a === atom2;
var hasInitialValue = (atom2) => "init" in atom2;
var isActuallyWritableAtom = (atom2) => !!atom2.write;
var cancelablePromiseMap = /* @__PURE__ */ new WeakMap();
var isPendingPromise = (value) => {
var _a;
return isPromiseLike(value) && !((_a = cancelablePromiseMap.get(value)) == null ? void 0 : _a[1]);
};
var cancelPromise = (promise, nextValue) => {
const promiseState = cancelablePromiseMap.get(promise);
if (promiseState) {
promiseState[1] = true;
promiseState[0].forEach((fn) => fn(nextValue));
} else if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
throw new Error("[Bug] cancelable promise not found");
}
};
var patchPromiseForCancelability = (promise) => {
if (cancelablePromiseMap.has(promise)) {
return;
}
const promiseState = [/* @__PURE__ */ new Set(), false];
cancelablePromiseMap.set(promise, promiseState);
const settle = () => {
promiseState[1] = true;
};
promise.then(settle, settle);
promise.onCancel = (fn) => {
promiseState[0].add(fn);
};
};
var isPromiseLike = (p) => typeof (p == null ? void 0 : p.then) === "function";
var isAtomStateInitialized = (atomState) => "v" in atomState || "e" in atomState;
var returnAtomValue = (atomState) => {
if ("e" in atomState) {
throw atomState.e;
}
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !("v" in atomState)) {
throw new Error("[Bug] atom state is not initialized");
}
return atomState.v;
};
var addPendingPromiseToDependency = (atom2, promise, dependencyAtomState) => {
if (!dependencyAtomState.p.has(atom2)) {
dependencyAtomState.p.add(atom2);
promise.then(
() => {
dependencyAtomState.p.delete(atom2);
},
() => {
dependencyAtomState.p.delete(atom2);
}
);
}
};
var addDependency = (atom2, atomState, a, aState) => {
var _a;
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && a === atom2) {
throw new Error("[Bug] atom cannot depend on itself");
}
atomState.d.set(a, aState.n);
if (isPendingPromise(atomState.v)) {
addPendingPromiseToDependency(atom2, atomState.v, aState);
}
(_a = aState.m) == null ? void 0 : _a.t.add(atom2);
};
var INTERNAL_flushStoreHook = Symbol.for("JOTAI.EXPERIMENTAL.FLUSHSTOREHOOK");
var buildStore = (...storeArgs) => {
const [
getAtomState,
setAtomState,
atomRead,
atomWrite,
atomOnInit,
atomOnMount
] = storeArgs;
const ensureAtomState = (atom2) => {
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !atom2) {
throw new Error("Atom is undefined or null");
}
let atomState = getAtomState(atom2);
if (!atomState) {
atomState = { d: /* @__PURE__ */ new Map(), p: /* @__PURE__ */ new Set(), n: 0 };
setAtomState(atom2, atomState);
atomOnInit == null ? void 0 : atomOnInit(atom2, store);
}
return atomState;
};
const invalidatedAtoms = /* @__PURE__ */ new WeakMap();
const changedAtoms = /* @__PURE__ */ new Map();
const unmountCallbacks = /* @__PURE__ */ new Set();
const mountCallbacks = /* @__PURE__ */ new Set();
const flushCallbacks = () => {
var _a;
const errors = [];
const call = (fn) => {
try {
fn();
} catch (e) {
errors.push(e);
}
};
do {
(_a = store[INTERNAL_flushStoreHook]) == null ? void 0 : _a.call(store);
const callbacks = /* @__PURE__ */ new Set();
const add = callbacks.add.bind(callbacks);
changedAtoms.forEach((atomState) => {
var _a2;
return (_a2 = atomState.m) == null ? void 0 : _a2.l.forEach(add);
});
changedAtoms.clear();
unmountCallbacks.forEach(add);
unmountCallbacks.clear();
mountCallbacks.forEach(add);
mountCallbacks.clear();
callbacks.forEach(call);
if (changedAtoms.size) {
recomputeInvalidatedAtoms();
}
} while (changedAtoms.size || unmountCallbacks.size || mountCallbacks.size);
if (errors.length) {
throw errors[0];
}
};
const setAtomStateValueOrPromise = (atom2, atomState, valueOrPromise) => {
const hasPrevValue = "v" in atomState;
const prevValue = atomState.v;
const pendingPromise = isPendingPromise(atomState.v) ? atomState.v : null;
if (isPromiseLike(valueOrPromise)) {
patchPromiseForCancelability(valueOrPromise);
for (const a of atomState.d.keys()) {
addPendingPromiseToDependency(atom2, valueOrPromise, ensureAtomState(a));
}
atomState.v = valueOrPromise;
} else {
atomState.v = valueOrPromise;
}
delete atomState.e;
if (!hasPrevValue || !Object.is(prevValue, atomState.v)) {
++atomState.n;
if (pendingPromise) {
cancelPromise(pendingPromise, valueOrPromise);
}
}
};
const readAtomState = (atom2) => {
var _a;
const atomState = ensureAtomState(atom2);
if (isAtomStateInitialized(atomState)) {
if (atomState.m && invalidatedAtoms.get(atom2) !== atomState.n) {
return atomState;
}
if (Array.from(atomState.d).every(
([a, n]) => (
// Recursively, read the atom state of the dependency, and
// check if the atom epoch number is unchanged
readAtomState(a).n === n
)
)) {
return atomState;
}
}
atomState.d.clear();
let isSync = true;
const mountDependenciesIfAsync = () => {
if (atomState.m) {
mountDependencies(atom2, atomState);
recomputeInvalidatedAtoms();
flushCallbacks();
}
};
const getter = (a) => {
if (isSelfAtom(atom2, a)) {
const aState2 = ensureAtomState(a);
if (!isAtomStateInitialized(aState2)) {
if (hasInitialValue(a)) {
setAtomStateValueOrPromise(a, aState2, a.init);
} else {
throw new Error("no atom init");
}
}
return returnAtomValue(aState2);
}
const aState = readAtomState(a);
try {
return returnAtomValue(aState);
} finally {
addDependency(atom2, atomState, a, aState);
if (!isSync) {
mountDependenciesIfAsync();
}
}
};
let controller;
let setSelf;
const options = {
get signal() {
if (!controller) {
controller = new AbortController();
}
return controller.signal;
},
get setSelf() {
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !isActuallyWritableAtom(atom2)) {
console.warn("setSelf function cannot be used with read-only atom");
}
if (!setSelf && isActuallyWritableAtom(atom2)) {
setSelf = (...args) => {
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && isSync) {
console.warn("setSelf function cannot be called in sync");
}
if (!isSync) {
return writeAtom(atom2, ...args);
}
};
}
return setSelf;
}
};
try {
const valueOrPromise = atomRead(atom2, getter, options);
setAtomStateValueOrPromise(atom2, atomState, valueOrPromise);
if (isPromiseLike(valueOrPromise)) {
(_a = valueOrPromise.onCancel) == null ? void 0 : _a.call(valueOrPromise, () => controller == null ? void 0 : controller.abort());
valueOrPromise.then(mountDependenciesIfAsync, mountDependenciesIfAsync);
}
return atomState;
} catch (error) {
delete atomState.v;
atomState.e = error;
++atomState.n;
return atomState;
} finally {
isSync = false;
}
};
const readAtom = (atom2) => returnAtomValue(readAtomState(atom2));
const getMountedOrPendingDependents = (atomState) => {
var _a;
const dependents = /* @__PURE__ */ new Map();
for (const a of ((_a = atomState.m) == null ? void 0 : _a.t) || []) {
const aState = ensureAtomState(a);
if (aState.m) {
dependents.set(a, aState);
}
}
for (const atomWithPendingPromise of atomState.p) {
dependents.set(
atomWithPendingPromise,
ensureAtomState(atomWithPendingPromise)
);
}
return dependents;
};
const invalidateDependents = (atomState) => {
const stack = [atomState];
while (stack.length) {
const aState = stack.pop();
for (const [d, s] of getMountedOrPendingDependents(aState)) {
if (!invalidatedAtoms.has(d)) {
invalidatedAtoms.set(d, s.n);
stack.push(s);
}
}
}
};
const recomputeInvalidatedAtoms = () => {
var _a;
const topSortedReversed = [];
const visiting = /* @__PURE__ */ new WeakSet();
const visited = /* @__PURE__ */ new WeakSet();
const stack = Array.from(changedAtoms);
while (stack.length) {
const [a, aState] = stack[stack.length - 1];
if (visited.has(a)) {
stack.pop();
continue;
}
if (visiting.has(a)) {
if (invalidatedAtoms.get(a) === aState.n) {
topSortedReversed.push([a, aState, aState.n]);
} else {
invalidatedAtoms.delete(a);
changedAtoms.set(a, aState);
}
visited.add(a);
stack.pop();
continue;
}
visiting.add(a);
for (const [d, s] of getMountedOrPendingDependents(aState)) {
if (!visiting.has(d)) {
stack.push([d, s]);
}
}
}
for (let i = topSortedReversed.length - 1; i >= 0; --i) {
const [a, aState, prevEpochNumber] = topSortedReversed[i];
let hasChangedDeps = false;
for (const dep of aState.d.keys()) {
if (dep !== a && changedAtoms.has(dep)) {
hasChangedDeps = true;
break;
}
}
if (hasChangedDeps) {
readAtomState(a);
mountDependencies(a, aState);
if (prevEpochNumber !== aState.n) {
changedAtoms.set(a, aState);
(_a = aState.u) == null ? void 0 : _a.call(aState);
}
}
invalidatedAtoms.delete(a);
}
};
const writeAtomState = (atom2, ...args) => {
let isSync = true;
const getter = (a) => returnAtomValue(readAtomState(a));
const setter = (a, ...args2) => {
var _a;
const aState = ensureAtomState(a);
try {
if (isSelfAtom(atom2, a)) {
if (!hasInitialValue(a)) {
throw new Error("atom not writable");
}
const prevEpochNumber = aState.n;
const v = args2[0];
setAtomStateValueOrPromise(a, aState, v);
mountDependencies(a, aState);
if (prevEpochNumber !== aState.n) {
changedAtoms.set(a, aState);
(_a = aState.u) == null ? void 0 : _a.call(aState);
invalidateDependents(aState);
}
return void 0;
} else {
return writeAtomState(a, ...args2);
}
} finally {
if (!isSync) {
recomputeInvalidatedAtoms();
flushCallbacks();
}
}
};
try {
return atomWrite(atom2, getter, setter, ...args);
} finally {
isSync = false;
}
};
const writeAtom = (atom2, ...args) => {
try {
return writeAtomState(atom2, ...args);
} finally {
recomputeInvalidatedAtoms();
flushCallbacks();
}
};
const mountDependencies = (atom2, atomState) => {
var _a;
if (atomState.m && !isPendingPromise(atomState.v)) {
for (const [a, n] of atomState.d) {
if (!atomState.m.d.has(a)) {
const aState = ensureAtomState(a);
const aMounted = mountAtom(a, aState);
aMounted.t.add(atom2);
atomState.m.d.add(a);
if (n !== aState.n) {
changedAtoms.set(a, aState);
(_a = aState.u) == null ? void 0 : _a.call(aState);
invalidateDependents(aState);
}
}
}
for (const a of atomState.m.d || []) {
if (!atomState.d.has(a)) {
atomState.m.d.delete(a);
const aMounted = unmountAtom(a, ensureAtomState(a));
aMounted == null ? void 0 : aMounted.t.delete(atom2);
}
}
}
};
const mountAtom = (atom2, atomState) => {
var _a;
if (!atomState.m) {
readAtomState(atom2);
for (const a of atomState.d.keys()) {
const aMounted = mountAtom(a, ensureAtomState(a));
aMounted.t.add(atom2);
}
atomState.m = {
l: /* @__PURE__ */ new Set(),
d: new Set(atomState.d.keys()),
t: /* @__PURE__ */ new Set()
};
(_a = atomState.h) == null ? void 0 : _a.call(atomState);
if (isActuallyWritableAtom(atom2)) {
const mounted = atomState.m;
const processOnMount = () => {
let isSync = true;
const setAtom = (...args) => {
try {
return writeAtomState(atom2, ...args);
} finally {
if (!isSync) {
recomputeInvalidatedAtoms();
flushCallbacks();
}
}
};
try {
const onUnmount = atomOnMount(atom2, setAtom);
if (onUnmount) {
mounted.u = () => {
isSync = true;
try {
onUnmount();
} finally {
isSync = false;
}
};
}
} finally {
isSync = false;
}
};
mountCallbacks.add(processOnMount);
}
}
return atomState.m;
};
const unmountAtom = (atom2, atomState) => {
var _a;
if (atomState.m && !atomState.m.l.size && !Array.from(atomState.m.t).some((a) => {
var _a2;
return (_a2 = ensureAtomState(a).m) == null ? void 0 : _a2.d.has(atom2);
})) {
const onUnmount = atomState.m.u;
if (onUnmount) {
unmountCallbacks.add(onUnmount);
}
delete atomState.m;
(_a = atomState.h) == null ? void 0 : _a.call(atomState);
for (const a of atomState.d.keys()) {
const aMounted = unmountAtom(a, ensureAtomState(a));
aMounted == null ? void 0 : aMounted.t.delete(atom2);
}
return void 0;
}
return atomState.m;
};
const subscribeAtom = (atom2, listener) => {
const atomState = ensureAtomState(atom2);
const mounted = mountAtom(atom2, atomState);
const listeners = mounted.l;
listeners.add(listener);
flushCallbacks();
return () => {
listeners.delete(listener);
unmountAtom(atom2, atomState);
flushCallbacks();
};
};
const unstable_derive = (fn) => buildStore(...fn(...storeArgs));
const store = {
get: readAtom,
set: writeAtom,
sub: subscribeAtom,
unstable_derive
};
return store;
};
var deriveDevStoreRev4 = (store) => {
const debugMountedAtoms = /* @__PURE__ */ new Set();
let savedGetAtomState;
let inRestoreAtom = 0;
const derivedStore = store.unstable_derive((...storeArgs) => {
const [getAtomState, setAtomState, , atomWrite] = storeArgs;
savedGetAtomState = getAtomState;
storeArgs[1] = function devSetAtomState(atom2, atomState) {
setAtomState(atom2, atomState);
const originalMounted = atomState.h;
atomState.h = () => {
originalMounted == null ? void 0 : originalMounted();
if (atomState.m) {
debugMountedAtoms.add(atom2);
} else {
debugMountedAtoms.delete(atom2);
}
};
};
storeArgs[3] = function devAtomWrite(atom2, getter, setter, ...args) {
if (inRestoreAtom) {
return setter(atom2, ...args);
}
return atomWrite(atom2, getter, setter, ...args);
};
return storeArgs;
});
const savedStoreSet = derivedStore.set;
const devStore = {
// store dev methods (these are tentative and subject to change without notice)
dev4_get_internal_weak_map: () => ({
get: (atom2) => {
const atomState = savedGetAtomState(atom2);
if (!atomState || atomState.n === 0) {
return void 0;
}
return atomState;
}
}),
dev4_get_mounted_atoms: () => debugMountedAtoms,
dev4_restore_atoms: (values) => {
const restoreAtom = {
read: () => null,
write: (_get, set) => {
++inRestoreAtom;
try {
for (const [atom2, value] of values) {
if (hasInitialValue(atom2)) {
set(atom2, value);
}
}
} finally {
--inRestoreAtom;
}
}
};
savedStoreSet(restoreAtom);
}
};
return Object.assign(derivedStore, devStore);
};
var createStore = () => {
const atomStateMap = /* @__PURE__ */ new WeakMap();
const store = buildStore(
(atom2) => atomStateMap.get(atom2),
(atom2, atomState) => atomStateMap.set(atom2, atomState).get(atom2),
(atom2, ...params) => atom2.read(...params),
(atom2, ...params) => atom2.write(...params),
(atom2, ...params) => {
var _a;
return (_a = atom2.unstable_onInit) == null ? void 0 : _a.call(atom2, ...params);
},
(atom2, ...params) => {
var _a;
return (_a = atom2.onMount) == null ? void 0 : _a.call(atom2, ...params);
}
);
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
return deriveDevStoreRev4(store);
}
return store;
};
var defaultStore;
var getDefaultStore = () => {
if (!defaultStore) {
defaultStore = createStore();
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production") {
globalThis.__JOTAI_DEFAULT_STORE__ || (globalThis.__JOTAI_DEFAULT_STORE__ = defaultStore);
if (globalThis.__JOTAI_DEFAULT_STORE__ !== defaultStore) {
console.warn(
"Detected multiple Jotai instances. It may cause unexpected behavior with the default store. https://github.com/pmndrs/jotai/discussions/2044"
);
}
}
}
return defaultStore;
};
// ../../node_modules/jotai/esm/react.mjs
import ReactExports, { createContext, useContext, useRef, createElement, useReducer, useEffect, useDebugValue, useCallback } from "react";
var StoreContext = createContext(
void 0
);
var useStore = (options) => {
const store = useContext(StoreContext);
return (options == null ? void 0 : options.store) || store || getDefaultStore();
};
var Provider = ({
children,
store
}) => {
const storeRef = useRef(void 0);
if (!store && !storeRef.current) {
storeRef.current = createStore();
}
return createElement(
StoreContext.Provider,
{
value: store || storeRef.current
},
children
);
};
var isPromiseLike2 = (x) => typeof (x == null ? void 0 : x.then) === "function";
var attachPromiseMeta = (promise) => {
promise.status = "pending";
promise.then(
(v) => {
promise.status = "fulfilled";
promise.value = v;
},
(e) => {
promise.status = "rejected";
promise.reason = e;
}
);
};
var use = ReactExports.use || ((promise) => {
if (promise.status === "pending") {
throw promise;
} else if (promise.status === "fulfilled") {
return promise.value;
} else if (promise.status === "rejected") {
throw promise.reason;
} else {
attachPromiseMeta(promise);
throw promise;
}
});
var continuablePromiseMap = /* @__PURE__ */ new WeakMap();
var createContinuablePromise = (promise) => {
let continuablePromise = continuablePromiseMap.get(promise);
if (!continuablePromise) {
continuablePromise = new Promise((resolve, reject) => {
let curr = promise;
const onFulfilled = (me) => (v) => {
if (curr === me) {
resolve(v);
}
};
const onRejected = (me) => (e) => {
if (curr === me) {
reject(e);
}
};
const registerCancelHandler = (p) => {
if ("onCancel" in p && typeof p.onCancel === "function") {
p.onCancel((nextValue) => {
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && nextValue === p) {
throw new Error("[Bug] p is not updated even after cancelation");
}
if (isPromiseLike2(nextValue)) {
continuablePromiseMap.set(nextValue, continuablePromise);
curr = nextValue;
nextValue.then(onFulfilled(nextValue), onRejected(nextValue));
registerCancelHandler(nextValue);
} else {
resolve(nextValue);
}
});
}
};
promise.then(onFulfilled(promise), onRejected(promise));
registerCancelHandler(promise);
});
continuablePromiseMap.set(promise, continuablePromise);
}
return continuablePromise;
};
function useAtomValue(atom2, options) {
const store = useStore(options);
const [[valueFromReducer, storeFromReducer, atomFromReducer], rerender] = useReducer(
(prev) => {
const nextValue = store.get(atom2);
if (Object.is(prev[0], nextValue) && prev[1] === store && prev[2] === atom2) {
return prev;
}
return [nextValue, store, atom2];
},
void 0,
() => [store.get(atom2), store, atom2]
);
let value = valueFromReducer;
if (storeFromReducer !== store || atomFromReducer !== atom2) {
rerender();
value = store.get(atom2);
}
const delay = options == null ? void 0 : options.delay;
useEffect(() => {
const unsub = store.sub(atom2, () => {
if (typeof delay === "number") {
const value2 = store.get(atom2);
if (isPromiseLike2(value2)) {
attachPromiseMeta(createContinuablePromise(value2));
}
setTimeout(rerender, delay);
return;
}
rerender();
});
rerender();
return unsub;
}, [store, atom2, delay]);
useDebugValue(value);
if (isPromiseLike2(value)) {
const promise = createContinuablePromise(value);
return use(promise);
}
return value;
}
function useSetAtom(atom2, options) {
const store = useStore(options);
const setAtom = useCallback(
(...args) => {
if ((import.meta.env ? import.meta.env.MODE : void 0) !== "production" && !("write" in atom2)) {
throw new Error("not writable atom");
}
return store.set(atom2, ...args);
},
[store, atom2]
);
return setAtom;
}
function useAtom(atom2, options) {
return [
useAtomValue(atom2, options),
// We do wrong type assertion here, which results in throwing an error.
useSetAtom(atom2, options)
];
}
// src/EmojiPicker/EmojiPickerSkinTone.tsx
import { useState } from "react";
// ../../node_modules/unicode-emoji-json/data-by-group.json
var data_by_group_default = [
{
name: "Smileys & Emotion",
slug: "smileys_emotion",
emojis: [
{
emoji: "\u{1F600}",
skin_tone_support: false,
name: "grinning face",
slug: "grinning_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F603}",
skin_tone_support: false,
name: "grinning face with big eyes",
slug: "grinning_face_with_big_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F604}",
skin_tone_support: false,
name: "grinning face with smiling eyes",
slug: "grinning_face_with_smiling_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F601}",
skin_tone_support: false,
name: "beaming face with smiling eyes",
slug: "beaming_face_with_smiling_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F606}",
skin_tone_support: false,
name: "grinning squinting face",
slug: "grinning_squinting_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F605}",
skin_tone_support: false,
name: "grinning face with sweat",
slug: "grinning_face_with_sweat",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F923}",
skin_tone_support: false,
name: "rolling on the floor laughing",
slug: "rolling_on_the_floor_laughing",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1F602}",
skin_tone_support: false,
name: "face with tears of joy",
slug: "face_with_tears_of_joy",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F642}",
skin_tone_support: false,
name: "slightly smiling face",
slug: "slightly_smiling_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F643}",
skin_tone_support: false,
name: "upside-down face",
slug: "upside_down_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1FAE0}",
skin_tone_support: false,
name: "melting face",
slug: "melting_face",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1F609}",
skin_tone_support: false,
name: "winking face",
slug: "winking_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F60A}",
skin_tone_support: false,
name: "smiling face with smiling eyes",
slug: "smiling_face_with_smiling_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F607}",
skin_tone_support: false,
name: "smiling face with halo",
slug: "smiling_face_with_halo",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F970}",
skin_tone_support: false,
name: "smiling face with hearts",
slug: "smiling_face_with_hearts",
unicode_version: "11.0",
emoji_version: "11.0"
},
{
emoji: "\u{1F60D}",
skin_tone_support: false,
name: "smiling face with heart-eyes",
slug: "smiling_face_with_heart_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F929}",
skin_tone_support: false,
name: "star-struck",
slug: "star_struck",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F618}",
skin_tone_support: false,
name: "face blowing a kiss",
slug: "face_blowing_a_kiss",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F617}",
skin_tone_support: false,
name: "kissing face",
slug: "kissing_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u263A\uFE0F",
skin_tone_support: false,
name: "smiling face",
slug: "smiling_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F61A}",
skin_tone_support: false,
name: "kissing face with closed eyes",
slug: "kissing_face_with_closed_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F619}",
skin_tone_support: false,
name: "kissing face with smiling eyes",
slug: "kissing_face_with_smiling_eyes",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F972}",
skin_tone_support: false,
name: "smiling face with tear",
slug: "smiling_face_with_tear",
unicode_version: "13.0",
emoji_version: "13.0"
},
{
emoji: "\u{1F60B}",
skin_tone_support: false,
name: "face savoring food",
slug: "face_savoring_food",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F61B}",
skin_tone_support: false,
name: "face with tongue",
slug: "face_with_tongue",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F61C}",
skin_tone_support: false,
name: "winking face with tongue",
slug: "winking_face_with_tongue",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F92A}",
skin_tone_support: false,
name: "zany face",
slug: "zany_face",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F61D}",
skin_tone_support: false,
name: "squinting face with tongue",
slug: "squinting_face_with_tongue",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F911}",
skin_tone_support: false,
name: "money-mouth face",
slug: "money_mouth_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F917}",
skin_tone_support: false,
name: "smiling face with open hands",
slug: "smiling_face_with_open_hands",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F92D}",
skin_tone_support: false,
name: "face with hand over mouth",
slug: "face_with_hand_over_mouth",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1FAE2}",
skin_tone_support: false,
name: "face with open eyes and hand over mouth",
slug: "face_with_open_eyes_and_hand_over_mouth",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1FAE3}",
skin_tone_support: false,
name: "face with peeking eye",
slug: "face_with_peeking_eye",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1F92B}",
skin_tone_support: false,
name: "shushing face",
slug: "shushing_face",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F914}",
skin_tone_support: false,
name: "thinking face",
slug: "thinking_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1FAE1}",
skin_tone_support: false,
name: "saluting face",
slug: "saluting_face",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1F910}",
skin_tone_support: false,
name: "zipper-mouth face",
slug: "zipper_mouth_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F928}",
skin_tone_support: false,
name: "face with raised eyebrow",
slug: "face_with_raised_eyebrow",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F610}",
skin_tone_support: false,
name: "neutral face",
slug: "neutral_face",
unicode_version: "0.7",
emoji_version: "0.7"
},
{
emoji: "\u{1F611}",
skin_tone_support: false,
name: "expressionless face",
slug: "expressionless_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F636}",
skin_tone_support: false,
name: "face without mouth",
slug: "face_without_mouth",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1FAE5}",
skin_tone_support: false,
name: "dotted line face",
slug: "dotted_line_face",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1F636}\u200D\u{1F32B}\uFE0F",
skin_tone_support: false,
name: "face in clouds",
slug: "face_in_clouds",
unicode_version: "13.1",
emoji_version: "13.1"
},
{
emoji: "\u{1F60F}",
skin_tone_support: false,
name: "smirking face",
slug: "smirking_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F612}",
skin_tone_support: false,
name: "unamused face",
slug: "unamused_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F644}",
skin_tone_support: false,
name: "face with rolling eyes",
slug: "face_with_rolling_eyes",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F62C}",
skin_tone_support: false,
name: "grimacing face",
slug: "grimacing_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F62E}\u200D\u{1F4A8}",
skin_tone_support: false,
name: "face exhaling",
slug: "face_exhaling",
unicode_version: "13.1",
emoji_version: "13.1"
},
{
emoji: "\u{1F925}",
skin_tone_support: false,
name: "lying face",
slug: "lying_face",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1FAE8}",
skin_tone_support: false,
name: "shaking face",
slug: "shaking_face",
unicode_version: "15.0",
emoji_version: "15.0"
},
{
emoji: "\u{1F642}\u200D\u2194\uFE0F",
skin_tone_support: false,
name: "head shaking horizontally",
slug: "head_shaking_horizontally",
unicode_version: "15.1",
emoji_version: "15.1"
},
{
emoji: "\u{1F642}\u200D\u2195\uFE0F",
skin_tone_support: false,
name: "head shaking vertically",
slug: "head_shaking_vertically",
unicode_version: "15.1",
emoji_version: "15.1"
},
{
emoji: "\u{1F60C}",
skin_tone_support: false,
name: "relieved face",
slug: "relieved_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F614}",
skin_tone_support: false,
name: "pensive face",
slug: "pensive_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F62A}",
skin_tone_support: false,
name: "sleepy face",
slug: "sleepy_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F924}",
skin_tone_support: false,
name: "drooling face",
slug: "drooling_face",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1F634}",
skin_tone_support: false,
name: "sleeping face",
slug: "sleeping_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1FAE9}",
skin_tone_support: false,
name: "face with bags under eyes",
slug: "face_with_bags_under_eyes",
unicode_version: "16.0",
emoji_version: "16.0"
},
{
emoji: "\u{1F637}",
skin_tone_support: false,
name: "face with medical mask",
slug: "face_with_medical_mask",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F912}",
skin_tone_support: false,
name: "face with thermometer",
slug: "face_with_thermometer",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F915}",
skin_tone_support: false,
name: "face with head-bandage",
slug: "face_with_head_bandage",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F922}",
skin_tone_support: false,
name: "nauseated face",
slug: "nauseated_face",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1F92E}",
skin_tone_support: false,
name: "face vomiting",
slug: "face_vomiting",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F927}",
skin_tone_support: false,
name: "sneezing face",
slug: "sneezing_face",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1F975}",
skin_tone_support: false,
name: "hot face",
slug: "hot_face",
unicode_version: "11.0",
emoji_version: "11.0"
},
{
emoji: "\u{1F976}",
skin_tone_support: false,
name: "cold face",
slug: "cold_face",
unicode_version: "11.0",
emoji_version: "11.0"
},
{
emoji: "\u{1F974}",
skin_tone_support: false,
name: "woozy face",
slug: "woozy_face",
unicode_version: "11.0",
emoji_version: "11.0"
},
{
emoji: "\u{1F635}",
skin_tone_support: false,
name: "face with crossed-out eyes",
slug: "face_with_crossed_out_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F635}\u200D\u{1F4AB}",
skin_tone_support: false,
name: "face with spiral eyes",
slug: "face_with_spiral_eyes",
unicode_version: "13.1",
emoji_version: "13.1"
},
{
emoji: "\u{1F92F}",
skin_tone_support: false,
name: "exploding head",
slug: "exploding_head",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F920}",
skin_tone_support: false,
name: "cowboy hat face",
slug: "cowboy_hat_face",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1F973}",
skin_tone_support: false,
name: "partying face",
slug: "partying_face",
unicode_version: "11.0",
emoji_version: "11.0"
},
{
emoji: "\u{1F978}",
skin_tone_support: false,
name: "disguised face",
slug: "disguised_face",
unicode_version: "13.0",
emoji_version: "13.0"
},
{
emoji: "\u{1F60E}",
skin_tone_support: false,
name: "smiling face with sunglasses",
slug: "smiling_face_with_sunglasses",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F913}",
skin_tone_support: false,
name: "nerd face",
slug: "nerd_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F9D0}",
skin_tone_support: false,
name: "face with monocle",
slug: "face_with_monocle",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F615}",
skin_tone_support: false,
name: "confused face",
slug: "confused_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1FAE4}",
skin_tone_support: false,
name: "face with diagonal mouth",
slug: "face_with_diagonal_mouth",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1F61F}",
skin_tone_support: false,
name: "worried face",
slug: "worried_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F641}",
skin_tone_support: false,
name: "slightly frowning face",
slug: "slightly_frowning_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u2639\uFE0F",
skin_tone_support: false,
name: "frowning face",
slug: "frowning_face",
unicode_version: "0.7",
emoji_version: "0.7"
},
{
emoji: "\u{1F62E}",
skin_tone_support: false,
name: "face with open mouth",
slug: "face_with_open_mouth",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F62F}",
skin_tone_support: false,
name: "hushed face",
slug: "hushed_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F632}",
skin_tone_support: false,
name: "astonished face",
slug: "astonished_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F633}",
skin_tone_support: false,
name: "flushed face",
slug: "flushed_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F97A}",
skin_tone_support: false,
name: "pleading face",
slug: "pleading_face",
unicode_version: "11.0",
emoji_version: "11.0"
},
{
emoji: "\u{1F979}",
skin_tone_support: false,
name: "face holding back tears",
slug: "face_holding_back_tears",
unicode_version: "14.0",
emoji_version: "14.0"
},
{
emoji: "\u{1F626}",
skin_tone_support: false,
name: "frowning face with open mouth",
slug: "frowning_face_with_open_mouth",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F627}",
skin_tone_support: false,
name: "anguished face",
slug: "anguished_face",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F628}",
skin_tone_support: false,
name: "fearful face",
slug: "fearful_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F630}",
skin_tone_support: false,
name: "anxious face with sweat",
slug: "anxious_face_with_sweat",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F625}",
skin_tone_support: false,
name: "sad but relieved face",
slug: "sad_but_relieved_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F622}",
skin_tone_support: false,
name: "crying face",
slug: "crying_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F62D}",
skin_tone_support: false,
name: "loudly crying face",
slug: "loudly_crying_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F631}",
skin_tone_support: false,
name: "face screaming in fear",
slug: "face_screaming_in_fear",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F616}",
skin_tone_support: false,
name: "confounded face",
slug: "confounded_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F623}",
skin_tone_support: false,
name: "persevering face",
slug: "persevering_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F61E}",
skin_tone_support: false,
name: "disappointed face",
slug: "disappointed_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F613}",
skin_tone_support: false,
name: "downcast face with sweat",
slug: "downcast_face_with_sweat",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F629}",
skin_tone_support: false,
name: "weary face",
slug: "weary_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F62B}",
skin_tone_support: false,
name: "tired face",
slug: "tired_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F971}",
skin_tone_support: false,
name: "yawning face",
slug: "yawning_face",
unicode_version: "12.0",
emoji_version: "12.0"
},
{
emoji: "\u{1F624}",
skin_tone_support: false,
name: "face with steam from nose",
slug: "face_with_steam_from_nose",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F621}",
skin_tone_support: false,
name: "enraged face",
slug: "enraged_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F620}",
skin_tone_support: false,
name: "angry face",
slug: "angry_face",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F92C}",
skin_tone_support: false,
name: "face with symbols on mouth",
slug: "face_with_symbols_on_mouth",
unicode_version: "5.0",
emoji_version: "5.0"
},
{
emoji: "\u{1F608}",
skin_tone_support: false,
name: "smiling face with horns",
slug: "smiling_face_with_horns",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F47F}",
skin_tone_support: false,
name: "angry face with horns",
slug: "angry_face_with_horns",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F480}",
skin_tone_support: false,
name: "skull",
slug: "skull",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u2620\uFE0F",
skin_tone_support: false,
name: "skull and crossbones",
slug: "skull_and_crossbones",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F4A9}",
skin_tone_support: false,
name: "pile of poo",
slug: "pile_of_poo",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F921}",
skin_tone_support: false,
name: "clown face",
slug: "clown_face",
unicode_version: "3.0",
emoji_version: "3.0"
},
{
emoji: "\u{1F479}",
skin_tone_support: false,
name: "ogre",
slug: "ogre",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F47A}",
skin_tone_support: false,
name: "goblin",
slug: "goblin",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F47B}",
skin_tone_support: false,
name: "ghost",
slug: "ghost",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F47D}",
skin_tone_support: false,
name: "alien",
slug: "alien",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F47E}",
skin_tone_support: false,
name: "alien monster",
slug: "alien_monster",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F916}",
skin_tone_support: false,
name: "robot",
slug: "robot",
unicode_version: "1.0",
emoji_version: "1.0"
},
{
emoji: "\u{1F63A}",
skin_tone_support: false,
name: "grinning cat",
slug: "grinning_cat",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F638}",
skin_tone_support: false,
name: "grinning cat with smiling eyes",
slug: "grinning_cat_with_smiling_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F639}",
skin_tone_support: false,
name: "cat with tears of joy",
slug: "cat_with_tears_of_joy",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F63B}",
skin_tone_support: false,
name: "smiling cat with heart-eyes",
slug: "smiling_cat_with_heart_eyes",
unicode_version: "0.6",
emoji_version: "0.6"
},
{
emoji: "\u{1F63C}",
skin_tone_support: false,
name: "cat with wry smile",
slug: "cat_with_wry_smile",
unicode_version: "0.