import type { Emoji } from "./types.ts";import emojis from "./all.json" assert { type: "json" };import { reUnicode } from "./unicode.ts";
const reEmojiName = /:([a-zA-Z0-9_\-\+]+):/g;
const reTrimSpace = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
const NON_SPACING_MARK = String.fromCharCode(65039); const reNonSpacing = new RegExp(NON_SPACING_MARK, "g");
function stripNSB(code: string): string { return code.replace(reNonSpacing, "");}
function stripColons(str: string): string { const colonIndex = str.indexOf(":"); if (colonIndex > -1) { if (colonIndex === str.length - 1) { str = str.substring(0, colonIndex); return stripColons(str); } else { str = str.substr(colonIndex + 1); return stripColons(str); } }
return str;}
function wrapColons(str: string): string { return str.length > 0 ? ":" + str + ":" : str;}
type EmojiMap = { [alias: string]: Emoji };
const byAlias: EmojiMap = Object.fromEntries( emojis.map((emoji) => emoji.aliases.map((alias) => [alias, emoji])).flat(),);
const byCode: EmojiMap = Object.fromEntries( emojis.map((emoji) => { return [stripNSB(emoji.emoji), emoji]; }),);
export function all(): Emoji[] { return emojis;}
export function aliasMap(): EmojiMap { return byAlias;}
export function codeMap(): EmojiMap { return byCode;}
export function get(alias: string): string { return byAlias[stripColons(alias)]?.emoji;}
export function alias(emoji: string): string { return byCode[stripNSB(emoji)]?.aliases[0];}
export function aliases(emoji: string): string[] { return byCode[stripNSB(emoji)]?.aliases;}
export function infoByAlias(raw: string): Emoji | undefined { return byAlias[stripColons(raw)];}
export function infoByCode(raw: string): Emoji | undefined { return byCode[stripNSB(raw)];}
export function random(): { emoji: string; alias: string } { const random = emojis[Math.floor(Math.random() * emojis.length)]; const emoji = random.emoji; const alias = random.aliases[0]; return { emoji, alias };}
export function strip(str: string): string { return replace(str, "", true);}
export function replace( str: string, replacement: string | ((emoji: Emoji) => string) = "", trim = false,): string { if (!str) return ""; const replace = typeof replacement === "function" ? replacement : () => { return replacement; }; const match = str.match(reUnicode) ?? []; const result = match .map((s, i) => { const emoji = byCode[stripNSB(s)]; if (emoji && trim && match[i + 1] === " ") { match[i + 1] = ""; } return emoji ? replace(emoji) : s; }) .join(""); return trim ? result.replace(reTrimSpace, "") : result;}
export function emojify(str: string) { if (!str) return ""; return str .split(reEmojiName) .map((s, i) => { if (i % 2 === 0) return s; let emoji = get(s); if (!emoji) emoji = wrapColons(s); return emoji; }) .join("");}
export function unemojify(str: string) { return replace(str, (emoji) => wrapColons(emoji.aliases[0]));}
export function emoji(template: TemplateStringsArray, ...args: string[]) { const chunks = []; for (let i = 0; i < template.length; i++) { chunks.push(emojify(template[i])); if (args[i]) chunks.push(emojify(args[i])); } return chunks.join("");}